From 7ebe0d01cf3a65f5a5e40f64ba26682e071deb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 30 Aug 2007 19:32:38 +0000 Subject: [PATCH] first part of a big cleanup of the Mail code * separated window, app and context menu code * got rid of all the global variables (which were accessed completely without locking, and the code with regards to the preference window sill needs fixing) * extracted some defines and helper functions to MailSupport.cpp, though I later saw Utilities.cpp... * got rid of the FONT_SIZE define which was used in some (but not all) controls to override the system font size * worked in Header.cpp to get the controls layout font sensitive with correct alignment too, some problems remain when resizing the window git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22122 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mail/ComboBox.cpp | 2 +- src/apps/mail/Content.cpp | 46 +- src/apps/mail/Content.h | 7 +- src/apps/mail/Enclosures.cpp | 31 +- src/apps/mail/FindWindow.cpp | 4 +- src/apps/mail/Header.cpp | 163 ++- src/apps/mail/Header.h | 5 +- src/apps/mail/Jamfile | 12 +- src/apps/mail/Mail.h | 348 ----- src/apps/mail/MailApp.cpp | 1254 ++++++++++++++++++ src/apps/mail/MailApp.h | 137 ++ src/apps/mail/MailPopUpMenu.cpp | 106 ++ src/apps/mail/MailPopUpMenu.h | 60 + src/apps/mail/MailSupport.cpp | 173 +++ src/apps/mail/MailSupport.h | 84 ++ src/apps/mail/{Mail.cpp => MailWindow.cpp} | 1325 ++------------------ src/apps/mail/MailWindow.h | 188 +++ src/apps/mail/Messages.h | 120 ++ src/apps/mail/Prefs.cpp | 16 +- src/apps/mail/Signature.cpp | 18 +- src/apps/mail/Status.cpp | 7 +- 21 files changed, 2381 insertions(+), 1725 deletions(-) delete mode 100644 src/apps/mail/Mail.h create mode 100644 src/apps/mail/MailApp.cpp create mode 100644 src/apps/mail/MailApp.h create mode 100644 src/apps/mail/MailPopUpMenu.cpp create mode 100644 src/apps/mail/MailPopUpMenu.h create mode 100644 src/apps/mail/MailSupport.cpp create mode 100644 src/apps/mail/MailSupport.h rename src/apps/mail/{Mail.cpp => MailWindow.cpp} (70%) create mode 100644 src/apps/mail/MailWindow.h create mode 100644 src/apps/mail/Messages.h diff --git a/src/apps/mail/ComboBox.cpp b/src/apps/mail/ComboBox.cpp index 8e327a864a..fccc89c775 100644 --- a/src/apps/mail/ComboBox.cpp +++ b/src/apps/mail/ComboBox.cpp @@ -1265,7 +1265,7 @@ BComboBox::TextView() void BComboBox::SetDivider(float divide) { - float diff = fDivider - divide; + float diff = fDivider - divide; fDivider = divide; fText->MoveBy(-diff, 0); diff --git a/src/apps/mail/Content.cpp b/src/apps/mail/Content.cpp index 045f75c8a1..feb574459d 100644 --- a/src/apps/mail/Content.cpp +++ b/src/apps/mail/Content.cpp @@ -32,11 +32,6 @@ names are registered trademarks or trademarks of their respective holders. All rights reserved. */ -//-------------------------------------------------------------------- -// -// Content.cpp -// -//-------------------------------------------------------------------- #include #include @@ -72,7 +67,10 @@ All rights reserved. #include -#include "Mail.h" +#include "MailApp.h" +#include "MailSupport.h" +#include "MailWindow.h" +#include "Messages.h" #include "Content.h" #include "Utilities.h" #include "FieldMsg.h" @@ -99,9 +97,6 @@ const rgb_color kQuoteColors[] = }; const int32 kNumQuoteColors = 3; -extern bool header_flag; -extern bool gColoredQuotes; - void Unicode2UTF8(int32 c, char **out); @@ -573,15 +568,13 @@ TextRunArray::~TextRunArray() // #pragma mark - -TContentView::TContentView(BRect rect, bool incoming, BEmailMessage *mail, BFont *font) - : BView(rect, "m_content", B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), +TContentView::TContentView(BRect rect, bool incoming, BEmailMessage *mail, + BFont* font, bool showHeader, bool coloredQuotes) + : BView(rect, "m_content", B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), fFocus(false), fIncoming(incoming) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - - BFont v_font = *be_plain_font; - v_font.SetSize(FONT_SIZE); fOffset = 12; BRect r(rect); @@ -593,7 +586,8 @@ TContentView::TContentView(BRect rect, bool incoming, BEmailMessage *mail, BFont text.OffsetTo(0, 0); text.InsetBy(5, 5); - fTextView = new TTextView(r, text, fIncoming, mail, this, font); + fTextView = new TTextView(r, text, fIncoming, mail, this, font, + showHeader, coloredQuotes); BScrollView *scroll = new BScrollView("", fTextView, B_FOLLOW_ALL, 0, true, true); AddChild(scroll); } @@ -768,12 +762,6 @@ TContentView::Focus(bool focus) void TContentView::FrameResized(float /* width */, float /* height */) { - BFont v_font = *be_plain_font; - v_font.SetSize(FONT_SIZE); - - font_height fHeight; - v_font.GetHeight(&fHeight); - BRect r(fTextView->Bounds()); r.OffsetTo(0, 0); r.InsetBy(5, 5); @@ -785,10 +773,12 @@ TContentView::FrameResized(float /* width */, float /* height */) // #pragma mark - -TTextView::TTextView(BRect frame, BRect text, bool incoming, BEmailMessage *mail, - TContentView *view, BFont *font) - : BTextView(frame, "", text, B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE), - fHeader(header_flag), +TTextView::TTextView(BRect frame, BRect text, bool incoming, + BEmailMessage *mail, TContentView *view, BFont *font, + bool showHeader, bool coloredQuotes) + : BTextView(frame, "", text, B_FOLLOW_ALL, B_WILL_DRAW | B_NAVIGABLE), + fHeader(showHeader), + fColoredQuotes(coloredQuotes), fReady(false), fYankBuffer(NULL), fLastPosition(-1), @@ -2355,7 +2345,7 @@ TTextView::Reader::Insert(const char *line, int32 count, bool isHyperLink, bool BFont font(fView->Font()); TextRunArray style(count / 8 + 8); - if (gColoredQuotes && !isHeader && !isHyperLink) + if (fView->fColoredQuotes && !isHeader && !isHyperLink) FillInQuoteTextRuns(fView, line, count, font, &style.Array(), style.MaxEntries()); else { text_run_array &array = style.Array(); @@ -3067,7 +3057,7 @@ TTextView::AddQuote(int32 start, int32 finish) free(text); Delete(); - if (gColoredQuotes) { + if (fColoredQuotes) { const BFont *font = Font(); TextRunArray style(targetLength / 8 + 8); @@ -3144,7 +3134,7 @@ TTextView::RemoveQuote(int32 start, int32 finish) if (removed) { Delete(); - if (gColoredQuotes) { + if (fColoredQuotes) { const BFont *font = Font(); TextRunArray style(length / 8 + 8); diff --git a/src/apps/mail/Content.h b/src/apps/mail/Content.h index ee9f88a32e..bcd5d51c1b 100644 --- a/src/apps/mail/Content.h +++ b/src/apps/mail/Content.h @@ -116,7 +116,8 @@ class TSavePanel; class TContentView : public BView { public: - TContentView(BRect, bool incoming, BEmailMessage *mail, BFont *); + TContentView(BRect, bool incoming, BEmailMessage *mail, BFont*, + bool showHeader, bool coloredQuotes); virtual void MessageReceived(BMessage *); void FindString(const char *); void Focus(bool); @@ -140,7 +141,8 @@ enum { class TTextView : public BTextView { public: - TTextView(BRect, BRect, bool incoming, BEmailMessage *mail, TContentView *,BFont *); + TTextView(BRect, BRect, bool incoming, BEmailMessage *mail, + TContentView *, BFont *, bool showHeader, bool coloredQuotes); ~TTextView(); virtual void AttachedToWindow(); @@ -175,6 +177,7 @@ class TTextView : public BTextView const BFont *Font() const { return &fFont; } bool fHeader; + bool fColoredQuotes; bool fReady; private: diff --git a/src/apps/mail/Enclosures.cpp b/src/apps/mail/Enclosures.cpp index e69d885b87..a958ce303b 100644 --- a/src/apps/mail/Enclosures.cpp +++ b/src/apps/mail/Enclosures.cpp @@ -39,7 +39,6 @@ All rights reserved. // and the view containing the list and handling the messages (TEnclosuresView). //-------------------------------------------------------------------- -#include "Mail.h" #include "Enclosures.h" #include @@ -48,6 +47,7 @@ All rights reserved. #include #include #include +#include #include #include @@ -58,9 +58,13 @@ All rights reserved. #include #include +#include "MailApp.h" +#include "MailSupport.h" +#include "MailWindow.h" +#include "Messages.h" -//==================================================================== +static const float kPlainFontSizeScale = 0.9; static status_t GetTrackerIcon(BMimeType &type, BBitmap *icon, icon_size iconSize) @@ -125,10 +129,10 @@ TEnclosuresView::TEnclosuresView(BRect rect, BRect wind_rect) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - BFont font = *be_plain_font; - font.SetSize(FONT_SIZE); - font_height fHeight; - font.GetHeight(&fHeight); + BFont font(be_plain_font); + font.SetSize(font.Size() * kPlainFontSizeScale); + SetFont(&font); + fOffset = 12; BRect r; @@ -166,16 +170,13 @@ TEnclosuresView::Draw(BRect where) { BView::Draw(where); - BFont font = *be_plain_font; - font.SetSize(FONT_SIZE); - SetFont(&font); SetHighColor(0, 0, 0); SetLowColor(ViewColor()); - font_height fHeight; - font.GetHeight(&fHeight); + font_height fh; + GetFontHeight(&fh); - MovePenTo(ENCLOSE_TEXT_H, ENCLOSE_TEXT_V + fHeight.ascent); + MovePenTo(ENCLOSE_TEXT_H, ENCLOSE_TEXT_V + fh.ascent); DrawString(ENCLOSE_TEXT); } @@ -396,8 +397,8 @@ TListView::AttachedToWindow() { BListView::AttachedToWindow(); - BFont font = *be_plain_font; - font.SetSize(FONT_SIZE); + BFont font(be_plain_font); + font.SetSize(font.Size() * kPlainFontSizeScale); SetFont(&font); } @@ -509,7 +510,7 @@ TListItem::DrawItem(BView *owner, BRect r, bool /* complete */) owner->SetHighColor(0, 0, 0); BFont font = *be_plain_font; - font.SetSize(FONT_SIZE); + font.SetSize(font.Size() * kPlainFontSizeScale); owner->SetFont(&font); owner->MovePenTo(r.left + 24, r.bottom - 4); diff --git a/src/apps/mail/FindWindow.cpp b/src/apps/mail/FindWindow.cpp index a7d2d5968d..5baffa3e58 100644 --- a/src/apps/mail/FindWindow.cpp +++ b/src/apps/mail/FindWindow.cpp @@ -38,7 +38,9 @@ All rights reserved. // =========================================================================== #include "FindWindow.h" -#include "Mail.h" +#include "MailApp.h" +#include "MailWindow.h" +#include "Messages.h" #include "AutoTextControl.h" #include diff --git a/src/apps/mail/Header.cpp b/src/apps/mail/Header.cpp index 254d91de96..7e9e700147 100644 --- a/src/apps/mail/Header.cpp +++ b/src/apps/mail/Header.cpp @@ -32,7 +32,10 @@ names are registered trademarks or trademarks of their respective holders. All rights reserved. */ -#include "Mail.h" +#include "MailApp.h" +#include "MailSupport.h" +#include "MailWindow.h" +#include "Messages.h" #include "Header.h" #include "Utilities.h" #include "QueryMenu.h" @@ -46,6 +49,7 @@ All rights reserved. #include #include #include +#include #include #include #include @@ -69,13 +73,13 @@ All rights reserved. using namespace BPrivate; using std::map; -extern uint32 gDefaultChain; - const char* kDateLabel = "Date:"; const uint32 kMsgFrom = 'hFrm'; const uint32 kMsgEncoding = 'encd'; const uint32 kMsgAddressChosen = 'acsn'; +static const float kTextControlDividerOffset = 0; +static const float kMenuFieldDividerOffset = 6; class QPopupMenu : public QueryMenu { public: @@ -116,21 +120,26 @@ mail_to_filter(const char* text, int32& length, const text_run_array*& runs) } +static const float kPlainFontSizeScale = 0.9; + + // #pragma mark - THeaderView THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, - BEmailMessage *mail, bool resending, uint32 defaultCharacterSet) + BEmailMessage *mail, bool resending, uint32 defaultCharacterSet, + uint32 defaultChain) : BBox(rect, "m_header", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW, B_NO_BORDER), fAccountMenu(NULL), fEncodingMenu(NULL), - fChain(gDefaultChain), + fChain(defaultChain), fAccountTo(NULL), fAccount(NULL), fBcc(NULL), fCc(NULL), fSubject(NULL), fTo(NULL), + fDateLabel(NULL), fDate(NULL), fIncoming(incoming), fCharacterSetUserSees(defaultCharacterSet), @@ -143,13 +152,19 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, BMenuField* field; BMessage* msg; - BFont font = *be_plain_font; - font.SetSize(FONT_SIZE); - SetFont(&font); - float x = font.StringWidth( /* The longest title string in the header area */ + float x = StringWidth( /* The longest title string in the header area */ MDR_DIALECT_CHOICE ("Enclosures: ","添付ファイル:")) + 9; float y = TO_FIELD_V; + float menuFieldHeight; + BMenuBar* dummy = new BMenuBar(BRect(0, 0, 100, 15), "Dummy"); + AddChild(dummy); + float width; + dummy->GetPreferredSize(&width, &menuFieldHeight); + menuFieldHeight += floorf(be_plain_font->Size() / 1.15); + dummy->RemoveSelf(); + delete dummy; + if (!fIncoming) { InitEmailCompletion(); InitGroupCompletion(); @@ -195,8 +210,8 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, item->SetMarked(true); markedCharSet = true; } - if (font.StringWidth(name.String()) > widestCharacterSet) - widestCharacterSet = font.StringWidth(name.String()); + if (StringWidth(name.String()) > widestCharacterSet) + widestCharacterSet = StringWidth(name.String()); } msg = new BMessage(kMsgEncoding); @@ -226,31 +241,34 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, if (fIncoming && !resending) { // Set up the character set pop-up menu on the right of "To" box. r.Set (windowRect.Width() - widestCharacterSet - - font.StringWidth (DECODING_TEXT) - 2 * SEPARATOR_MARGIN, - y - 2, windowRect.Width() - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT + 2); + StringWidth (DECODING_TEXT) - 2 * SEPARATOR_MARGIN, y - 2, + windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight + 2); field = new BMenuField (r, "decoding", DECODING_TEXT, fEncodingMenu, true /* fixedSize */, B_FOLLOW_TOP | B_FOLLOW_RIGHT, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); - field->SetFont (&font); - field->SetDivider (font.StringWidth(DECODING_TEXT) + 5); + field->SetDivider(field->StringWidth(DECODING_TEXT) + 5); AddChild(field); - r.Set(x - font.StringWidth(FROM_TEXT) - 11, y, - field->Frame().left - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT); + r.Set(SEPARATOR_MARGIN, y, + field->Frame().left - SEPARATOR_MARGIN, y + menuFieldHeight); sprintf(string, FROM_TEXT); } else { - r.Set(x - 11, y, windowRect.Width() - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT); + r.Set(x - 12, y, windowRect.Width() - SEPARATOR_MARGIN, + y + menuFieldHeight); string[0] = 0; } - y += FIELD_HEIGHT; - fTo = new TTextControl(r, string, new BMessage(TO_FIELD), fIncoming, resending, - B_FOLLOW_LEFT_RIGHT); + y += menuFieldHeight; + 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); @@ -259,11 +277,12 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, fTo->SetModificationMessage(msg); if (!fIncoming || resending) { - r.right = r.left + 8; - r.left = r.right - be_plain_font->StringWidth(TO_TEXT) - 30; + r.right = r.left - 5; + r.left = r.right - be_plain_font->StringWidth(TO_TEXT) - 15; r.top -= 1; fToMenu = new QPopupMenu(TO_TEXT); - field = new BMenuField(r, "", "", fToMenu, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW); + field = new BMenuField(r, "", "", fToMenu, + B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW); field->SetDivider(0.0); field->SetEnabled(true); AddChild(field); @@ -273,14 +292,13 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, if (!fIncoming || resending) { // Put the character set box on the right of the From field. r.Set(windowRect.Width() - widestCharacterSet - - font.StringWidth(ENCODING_TEXT) - 2 * SEPARATOR_MARGIN, - y - 2, windowRect.Width() - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT + 2); + StringWidth(ENCODING_TEXT) - 2 * SEPARATOR_MARGIN, + y - 2, windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight + 2); field = new BMenuField (r, "encoding", ENCODING_TEXT, fEncodingMenu, true /* fixedSize */, - B_FOLLOW_TOP | B_FOLLOW_LEFT, + B_FOLLOW_TOP | B_FOLLOW_RIGHT, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); - field->SetFont(&font); - field->SetDivider(font.StringWidth(ENCODING_TEXT) + 5); + field->SetDivider(field->StringWidth(ENCODING_TEXT) + 5); AddChild(field); // And now the "from account" pop-up menu, on the left side, taking the @@ -303,7 +321,7 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, msg->AddInt32("id", chain->ID()); - if (gDefaultChain == chain->ID()) { + if (defaultChain == chain->ID()) { item->SetMarked(true); marked = true; } @@ -322,30 +340,36 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, fChain = ~0UL; } // default chain is invalid, set to marked - gDefaultChain = fChain; + // TODO: do this differently, no casting and knowledge + // of TMailApp here.... + if (TMailApp* app = dynamic_cast(be_app)) + app->SetDefaultChain(fChain); } } - r.Set(x - font.StringWidth(FROM_TEXT) - 11, y - 2, - field->Frame().left - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT + 2); + r.Set(SEPARATOR_MARGIN, y - 2, + field->Frame().left - SEPARATOR_MARGIN, y + menuFieldHeight + 2); field = new BMenuField(r, "account", FROM_TEXT, fAccountMenu, true /* fixedSize */, - B_FOLLOW_TOP | B_FOLLOW_LEFT, + B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW | B_NAVIGABLE | B_NAVIGABLE_JUMP); - field->SetFont(&font); - field->SetDivider(font.StringWidth(FROM_TEXT) + 11); AddChild(field); + field->SetDivider(x - 12 - SEPARATOR_MARGIN + kMenuFieldDividerOffset); + field->SetAlignment(B_ALIGN_RIGHT); +// field->MenuBar()->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT); - y += FIELD_HEIGHT; + y += menuFieldHeight; } else { // To: account bool account = count_pop_accounts() > 0; - r.Set(x - font.StringWidth(TO_TEXT) - 11, y, - windowRect.Width() - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT); + r.Set(SEPARATOR_MARGIN, y, + windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight); if (account) r.right -= SEPARATOR_MARGIN + ACCOUNT_FIELD_WIDTH; fAccountTo = new TTextControl(r, TO_TEXT, 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) { @@ -354,26 +378,27 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, fAccount->SetEnabled(false); AddChild(fAccount); } - y += FIELD_HEIGHT; + y += menuFieldHeight; } --y; - r.Set(x - font.StringWidth(SUBJECT_TEXT) - 11, y, - windowRect.Width() - SEPARATOR_MARGIN, y + TO_FIELD_HEIGHT); - y += FIELD_HEIGHT; + r.Set(SEPARATOR_MARGIN, y, + windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight); + y += menuFieldHeight; fSubject = new TTextControl(r, SUBJECT_TEXT, 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 - 11, y, CC_FIELD_H + CC_FIELD_WIDTH, y + CC_FIELD_HEIGHT); + 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); @@ -382,19 +407,20 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, (msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_CC); fCc->SetModificationMessage(msg); - r.right = r.left + 9; - r.left = r.right - be_plain_font->StringWidth(CC_TEXT) - 30; + r.right = r.left - 5; + r.left = r.right - be_plain_font->StringWidth(CC_TEXT) - 15; r.top -= 1; fCcMenu = new QPopupMenu(CC_TEXT); - field = new BMenuField(r, "", "", fCcMenu, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW); + field = new BMenuField(r, "", "", fCcMenu, + 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(BCC_TEXT), y, - windowRect.Width() - SEPARATOR_MARGIN, y + BCC_FIELD_HEIGHT); - y += FIELD_HEIGHT; + windowRect.Width() - SEPARATOR_MARGIN, y + menuFieldHeight); + y += menuFieldHeight; fBcc = new TTextControl(r, "", new BMessage(BCC_FIELD), fIncoming, false, B_FOLLOW_LEFT_RIGHT); fBcc->SetFilter(mail_to_filter); @@ -404,26 +430,34 @@ THeaderView::THeaderView(BRect rect, BRect windowRect, bool incoming, (msg = new BMessage(FIELD_CHANGED))->AddInt32("bitmask", FIELD_BCC); fBcc->SetModificationMessage(msg); - r.right = r.left + 9; - r.left = r.right - be_plain_font->StringWidth(BCC_TEXT) - 30; + r.right = r.left - 5; + r.left = r.right - be_plain_font->StringWidth(BCC_TEXT) - 15; r.top -= 1; fBccMenu = new QPopupMenu(BCC_TEXT); - field = new BMenuField(r, "", "", fBccMenu, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW); + field = new BMenuField(r, "", "", fBccMenu, + B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW); field->SetDivider(0.0); field->SetEnabled(true); AddChild(field); } else { - r.Set(x - font.StringWidth(kDateLabel) - 10, y + 4, - windowRect.Width(), y + TO_FIELD_HEIGHT + 1); - y += TO_FIELD_HEIGHT + 5; + y -= SEPARATOR_MARGIN; + r.Set(SEPARATOR_MARGIN, y, x - 12 - 1, y + menuFieldHeight + 1); + 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 + 1); fDate = new BStringView(r, "", ""); - AddChild(fDate); - fDate->SetFont(&font); + AddChild(fDate); fDate->SetHighColor(0, 0, 0); + y += menuFieldHeight + 5; + LoadMessage(mail); } - ResizeTo(Bounds().Width(),y); + ResizeTo(Bounds().Width(), y); } @@ -656,7 +690,7 @@ THeaderView::LoadMessage(BEmailMessage *mail) // Set the date on this message const char *dateField = mail->Date(); char string[256]; - sprintf(string, "%s %s", kDateLabel, dateField != NULL ? dateField : "Unknown"); + sprintf(string, "%s", dateField != NULL ? dateField : "Unknown"); fDate->SetText(string); // Set contents of header fields @@ -711,18 +745,11 @@ TTextControl::TTextControl(BRect rect, char *label, BMessage *msg, void TTextControl::AttachedToWindow() { - BFont font = *be_plain_font; - BTextView *text; - SetHighColor(0, 0, 0); // BTextControl::AttachedToWindow(); BComboBox::AttachedToWindow(); - font.SetSize(FONT_SIZE); - SetFont(&font); - SetDivider(StringWidth(fLabel) + 6); - text = (BTextView *)ChildAt(0); - text->SetFont(&font); + SetDivider(Divider() + kTextControlDividerOffset); } diff --git a/src/apps/mail/Header.h b/src/apps/mail/Header.h index c208f26abb..b46e58de5d 100644 --- a/src/apps/mail/Header.h +++ b/src/apps/mail/Header.h @@ -56,8 +56,6 @@ All rights reserved. #define TO_FIELD_V 7 #define TO_FIELD_WIDTH 270 #define FROM_FIELD_WIDTH 280 -#define TO_FIELD_HEIGHT 16 -#define FIELD_HEIGHT 24 #define ACCOUNT_TEXT "Account:" #define ACCOUNT_FIELD_WIDTH 165 @@ -91,7 +89,7 @@ class QPopupMenu; class THeaderView : public BBox { public: THeaderView(BRect, BRect, bool incoming, BEmailMessage *mail, - bool resending, uint32 defaultCharacterSet); + bool resending, uint32 defaultCharacterSet, uint32 defaultChain); virtual void MessageReceived(BMessage *); virtual void AttachedToWindow(void); @@ -106,6 +104,7 @@ class THeaderView : public BBox { TTextControl *fCc; TTextControl *fSubject; TTextControl *fTo; + BStringView *fDateLabel; BStringView *fDate; bool fIncoming; uint32 fCharacterSetUserSees; diff --git a/src/apps/mail/Jamfile b/src/apps/mail/Jamfile index d4cdb608ca..b7a45c5ac9 100644 --- a/src/apps/mail/Jamfile +++ b/src/apps/mail/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src apps mail ; SetSubDirSupportedPlatformsBeOSCompatible ; +AddSubDirSupportedPlatforms libbe_test ; if $(TARGET_PLATFORM) != haiku { UsePublicHeaders mail ; @@ -20,7 +21,10 @@ Application Mail : Enclosures.cpp FindWindow.cpp Header.cpp - Mail.cpp + MailApp.cpp + MailPopUpMenu.cpp + MailSupport.cpp + MailWindow.cpp Prefs.cpp QueryMenu.cpp Signature.cpp @@ -35,3 +39,9 @@ LinkAgainst Mail : be tracker $(TARGET_LIBSTDC++) libmail.so libtextencoding.so Package haiku-maildaemon-cvs : Mail : boot beos apps ; + + +if ( $(TARGET_PLATFORM) = libbe_test ) { + HaikuInstall install-test-apps : $(HAIKU_APP_TEST_DIR) : Mail + : tests!apps ; +} diff --git a/src/apps/mail/Mail.h b/src/apps/mail/Mail.h deleted file mode 100644 index f64dbdb229..0000000000 --- a/src/apps/mail/Mail.h +++ /dev/null @@ -1,348 +0,0 @@ -/* -Open Tracker License - -Terms and Conditions - -Copyright (c) 1991-2001, Be Incorporated. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice applies to all licensees -and shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Be Incorporated shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -this Software without prior written authorization from Be Incorporated. - -BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks -of Be Incorporated in the United States and other countries. Other brand product -names are registered trademarks or trademarks of their respective holders. -All rights reserved. -*/ - -//-------------------------------------------------------------------- -// -// Mail.h -// -//-------------------------------------------------------------------- - -#ifndef _MAIL_H -#define _MAIL_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAX_DICTIONARIES 8 -#define TITLE_BAR_HEIGHT 25 -#define WIND_WIDTH 457 -#define WIND_HEIGHT 400 -#define RIGHT_BOUNDARY 8191 -#define SEPARATOR_MARGIN 7 -#define FONT_SIZE 11.0 -#define QUOTE "> " - -enum MESSAGES { - REFS_RECEIVED = 64, - LIST_INVOKED, - WINDOW_CLOSED, - CHANGE_FONT, - RESET_BUTTONS, - PREFS_CHANGED, - CHARSET_CHOICE_MADE -}; - -enum TEXT { - SUBJECT_FIELD = REFS_RECEIVED + 64, - TO_FIELD, - ENCLOSE_FIELD, - CC_FIELD, - BCC_FIELD, - NAME_FIELD -}; - -enum MENUS { - /* app */ - M_NEW = SUBJECT_FIELD + 64, - M_PREFS, - M_EDIT_SIGNATURE, - M_FONT, - M_STYLE, - M_SIZE, - M_BEGINNER, - M_EXPERT, - /* file */ - M_REPLY, - M_REPLY_TO_SENDER, - M_REPLY_ALL, - M_FORWARD, - M_FORWARD_WITHOUT_ATTACHMENTS, - M_RESEND, - M_COPY_TO_NEW, - M_HEADER, - M_RAW, - M_SEND_NOW, - M_SAVE_AS_DRAFT, - M_SAVE, - M_PRINT_SETUP, - M_PRINT, - M_DELETE, - M_DELETE_PREV, - M_DELETE_NEXT, - M_CLOSE_READ, - M_CLOSE_SAVED, - M_CLOSE_SAME, - M_CLOSE_CUSTOM, - M_STATUS, - M_OPEN_MAIL_BOX, - M_OPEN_MAIL_FOLDER, - /* edit */ - M_SELECT, - M_QUOTE, - M_REMOVE_QUOTE, - M_CHECK_SPELLING, - M_SIGNATURE, - M_RANDOM_SIG, - M_SIG_MENU, - M_FIND, - M_FIND_AGAIN, - /* encls */ - M_ADD, - M_REMOVE, - M_OPEN, - M_COPY, - /* nav */ - M_NEXTMSG, - M_PREVMSG, - M_SAVE_POSITION, - /* Spam GUI button and menu items. Order is important. */ - M_SPAM_BUTTON, - M_TRAIN_SPAM_AND_DELETE, - M_TRAIN_SPAM, - M_UNTRAIN, - M_TRAIN_GENUINE, - - M_REDO -}; - -enum USER_LEVEL { - L_BEGINNER = 0, - L_EXPERT -}; - -enum WINDOW_TYPES { - MAIL_WINDOW = 0, - PREFS_WINDOW, - SIG_WINDOW -}; - -class TMailWindow; -class THeaderView; -class TEnclosuresView; -class TContentView; -class TMenu; -class TPrefsWindow; -class TSignatureWindow; -class BMenuItem; -class BmapButton; - -class BFile; -class BFilePanel; -class ButtonBar; -class BMenuBar; -class Words; -class BEmailMessage; - -//==================================================================== - -class TMailApp : public BApplication { - public: - TMailApp(); - ~TMailApp(); - - virtual void AboutRequested(); - virtual void ArgvReceived(int32, char **); - virtual void MessageReceived(BMessage *); - virtual bool QuitRequested(); - virtual void ReadyToRun(); - virtual void RefsReceived(BMessage *); - - TMailWindow *FindWindow(const entry_ref &); - void FontChange(); - TMailWindow *NewWindow(const entry_ref *rec = NULL, const char *to = NULL, - bool resend = false, BMessenger *messenger = NULL); - - BFont fFont; - - private: - void ClearPrintSettings(); - void CheckForSpamFilterExistence(); - - status_t GetSettingsPath(BPath &path); - status_t LoadOldSettings(); - status_t SaveSettings(); - status_t LoadSettings(); - - BList fWindowList; - int32 fWindowCount; - TPrefsWindow *fPrefsWindow; - TSignatureWindow *fSigWindow; - - uint8 fPreviousShowButtonBar; -}; - -//-------------------------------------------------------------------- - -class BMailMessage; - -class TMailWindow : public BWindow { - public: - TMailWindow(BRect, const char *, const entry_ref *, const char *, - const BFont *font, bool, BMessenger *trackerMessenger); - virtual ~TMailWindow(); - - virtual void FrameResized(float width, float height); - virtual void MenusBeginning(); - virtual void MessageReceived(BMessage*); - virtual bool QuitRequested(); - virtual void Show(); - virtual void Zoom(BPoint, float, float); - virtual void WindowActivated(bool state); - - void SetTo(const char *mailTo, const char *subject, const char *ccTo = NULL, - const char *bccTo = NULL, const BString *body = NULL, BMessage *enclosures = NULL); - void AddSignature(BMailMessage *); - void Forward(entry_ref *, TMailWindow *, bool includeAttachments); - void Print(); - void PrintSetup(); - void Reply(entry_ref *, TMailWindow *, uint32); - void CopyMessage(entry_ref *ref, TMailWindow *src); - status_t Send(bool); - status_t SaveAsDraft( void ); - status_t OpenMessage(entry_ref *ref, uint32 characterSetForDecoding = B_MAIL_NULL_CONVERSION); - - status_t GetMailNodeRef(node_ref &nodeRef) const; - BEmailMessage *Mail() const { return fMail; } - - bool GetTrackerWindowFile(entry_ref *, bool dir) const; - void SaveTrackerPosition(entry_ref *); - void SetOriginatingWindow(BWindow *window); - - void SetCurrentMessageRead(); - void SetTrackerSelectionToCurrent(); - TMailWindow* FrontmostWindow(); - void UpdateViews(); - - protected: - void SetTitleForMessage(); - void AddEnclosure(BMessage *msg); - void BuildButtonBar(); - status_t TrainMessageAs (const char *CommandWord); - - private: - BEmailMessage *fMail; - entry_ref *fRef; // Reference to currently displayed file - int32 fFieldState; - BFilePanel *fPanel; - BMenuBar *fMenuBar; - BMenuItem *fAdd; - BMenuItem *fCut; - BMenuItem *fCopy; - BMenuItem *fHeader; - BMenuItem *fPaste; - BMenuItem *fPrint; - BMenuItem *fPrintSetup; - BMenuItem *fQuote; - BMenuItem *fRaw; - BMenuItem *fRemove; - BMenuItem *fRemoveQuote; - BMenuItem *fSendNow; - BMenuItem *fSendLater; - BMenuItem *fUndo; - BMenuItem *fRedo; - BMenuItem *fNextMsg; - BMenuItem *fPrevMsg; - BMenuItem *fDeleteNext; - BMenuItem *fSpelling; - BMenu *fSaveAddrMenu; - ButtonBar *fButtonBar; - BmapButton *fSendButton; - BmapButton *fSaveButton; - BmapButton *fPrintButton; - BmapButton *fSigButton; - BRect fZoom; - TContentView *fContentView; - THeaderView *fHeaderView; - TEnclosuresView *fEnclosuresView; - TMenu *fSignature; - BMessenger fTrackerMessenger; - // Talks to tracker window that this was launched from. - - entry_ref fPrevRef, fNextRef; - bool fPrevTrackerPositionSaved : 1; - bool fNextTrackerPositionSaved : 1; - - static BList sWindowList; - static BLocker sWindowListLock; - - bool fSigAdded; - bool fIncoming; - bool fReplying; - bool fResending; - bool fSent; - bool fDraft; - bool fChanged; - - char *fStartingText; - entry_ref fRepliedMail; - BMessenger *fOriginatingWindow; -}; - -class TMenu: public BPopUpMenu { - public: - TMenu(const char* name, const char* attribute, int32, bool popup = false, - bool addRandom = true); - ~TMenu(); - - virtual BPoint ScreenLocation(void); - virtual void AttachedToWindow(); - - void BuildMenu(); - - private: - char* fAttribute; - bool fPopup, fAddRandom; - int32 fMessage; -}; - -//==================================================================== - -int32 header_len(BFile *); -extern Words *gWords[MAX_DICTIONARIES]; -extern Words *gExactWords[MAX_DICTIONARIES]; -extern int32 gUserDict; -extern BFile *gUserDictFile; -extern int32 gDictCount; - -#endif // #ifndef _MAIL_H diff --git a/src/apps/mail/MailApp.cpp b/src/apps/mail/MailApp.cpp new file mode 100644 index 0000000000..8138c6e117 --- /dev/null +++ b/src/apps/mail/MailApp.cpp @@ -0,0 +1,1254 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ + + +#include "MailApp.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +using namespace BPrivate ; + +#ifdef HAIKU_TARGET_PLATFORM_BEOS + #include +#endif + +#include "ButtonBar.h" +#include "Content.h" +#include "Enclosures.h" +#include "FieldMsg.h" +#include "FindWindow.h" +#include "Header.h" +#include "MailSupport.h" +#include "MailWindow.h" +#include "Messages.h" +#include "Prefs.h" +#include "QueryMenu.h" +#include "Signature.h" +#include "Status.h" +#include "String.h" +#include "Utilities.h" +#include "Words.h" + + +static const char *kDictDirectory = "word_dictionary"; +static const char *kIndexDirectory = "word_index"; +static const char *kWordsPath = "/boot/optional/goodies/words"; +static const char *kExact = ".exact"; +static const char *kMetaphone = ".metaphone"; + + +// #pragma mark - +int +main() +{ + TMailApp().Run(); + return B_OK; +} + + +// #pragma mark - + + +TMailApp::TMailApp() + : BApplication("application/x-vnd.Be-MAIL"), + fWindowCount(0), + fPrefsWindow(NULL), + fSigWindow(NULL), + + fPrintSettings(NULL), + + fWrapMode(true), + fShowHeader(false), + fAttachAttributes(true), + fColoredQuotes(true), + fShowButtonBar(true), + fWarnAboutUnencodableCharacters(true), + fStartWithSpellCheckOn(false), + fShowSpamGUI(true), + fMailCharacterSet(B_MS_WINDOWS_CONVERSION), + fContentFont(be_fixed_font) +{ + // set default values + fContentFont.SetSize(12.0); + fSignature = (char *)malloc(strlen(SIG_NONE) + 1); + strcpy(fSignature, SIG_NONE); + fReplyPreamble = (char *)malloc(1); + fReplyPreamble[0] = '\0'; + + fMailWindowFrame.Set(0, 0, 0, 0); + fSignatureWindowFrame.Set(6, TITLE_BAR_HEIGHT, 6 + kSigWidth, TITLE_BAR_HEIGHT + kSigHeight); + fPrefsWindowPos.Set(6, TITLE_BAR_HEIGHT); + + // Find and read settings file. + LoadSettings(); + + _CheckForSpamFilterExistence(); + fContentFont.SetSpacing(B_BITMAP_SPACING); + fLastMailWindowFrame = fMailWindowFrame; +} + + +TMailApp::~TMailApp() +{ +} + + +void +TMailApp::AboutRequested() +{ + BAlert *alert = new BAlert("about", "Mail\n\n" + "written by Robert Polic\n" + "enhanced by the Dr. Zoidberg crew\n\n" + "Copyright 2007, Haiku.\n", "Ok"); + BTextView *view = alert->TextView(); + BFont font; + + view->SetStylable(true); + + view->GetFont(&font); + font.SetSize(font.Size() + 7.0f); + font.SetFace(B_BOLD_FACE); + view->SetFontAndColor(0, 4, &font); + + alert->Go(); +} + + +void +TMailApp::ArgvReceived(int32 argc, char **argv) +{ + BEntry entry; + BString names; + BString ccNames; + BString bccNames; + BString subject; + BString body; + BMessage enclosure(B_REFS_RECEIVED); + // a "mailto:" with no name should open an empty window + // so remember if we got a "mailto:" even if there isn't a name + // that goes along with it (this allows deskbar replicant to open + // an empty message even when Mail is already running) + bool gotmailto = false; + + for (int32 loop = 1; loop < argc; loop++) + { + if (strcmp(argv[loop], "-h") == 0 + || strcmp(argv[loop], "--help") == 0) + { + printf(" usage: %s [ mailto:
] [ -subject \"\" ] [ ccto:
] [ bccto:
] " + "[ -body \" ] [ ...] \n", + argv[0]); + fPrintHelpAndExit = true; + be_app->PostMessage(B_QUIT_REQUESTED); + return; + } + else if (strncmp(argv[loop], "mailto:", 7) == 0) + { + if (names.Length()) + names += ", "; + char *options; + if ((options = strchr(argv[loop],'?')) != NULL) + { + names.Append(argv[loop] + 7, options - argv[loop] - 7); + if (!strncmp(++options,"subject=",8)) + subject = options + 8; + } + else + names += argv[loop] + 7; + gotmailto = true; + } + else if (strncmp(argv[loop], "ccto:", 5) == 0) + { + if (ccNames.Length()) + ccNames += ", "; + ccNames += argv[loop] + 5; + } + else if (strncmp(argv[loop], "bccto:", 6) == 0) + { + if (bccNames.Length()) + bccNames += ", "; + bccNames += argv[loop] + 6; + } + else if (strcmp(argv[loop], "-subject") == 0) + subject = argv[++loop]; + else if (strcmp(argv[loop], "-body") == 0 && argv[loop + 1]) + body = argv[++loop]; + else if (strncmp(argv[loop], "enclosure:", 10) == 0) + { + BEntry tmp(argv[loop] + 10, true); + if (tmp.InitCheck() == B_OK && tmp.Exists()) + { + entry_ref ref; + tmp.GetRef(&ref); + enclosure.AddRef("refs", &ref); + } + } + else if (entry.SetTo(argv[loop]) == B_NO_ERROR) + { + BMessage msg(B_REFS_RECEIVED); + entry_ref ref; + entry.GetRef(&ref); + msg.AddRef("refs", &ref); + RefsReceived(&msg); + } + } + + if (gotmailto || names.Length() || ccNames.Length() || bccNames.Length() || subject.Length() + || body.Length() || enclosure.HasRef("refs")) + { + TMailWindow *window = NewWindow(NULL, names.String()); + window->SetTo(names.String(), subject.String(), ccNames.String(), bccNames.String(), + &body, &enclosure); + window->Show(); + } +} + + +void +TMailApp::MessageReceived(BMessage *msg) +{ + TMailWindow *window = NULL; + entry_ref ref; + + switch (msg->what) + { + case M_NEW: + { + int32 type; + msg->FindInt32("type", &type); + switch (type) + { + case M_NEW: + window = NewWindow(); + break; + + case M_RESEND: + { + msg->FindRef("ref", &ref); + BNode file(&ref); + BString string = ""; + + if (file.InitCheck() == B_OK) + ReadAttrString(&file, B_MAIL_ATTR_TO, &string); + + window = NewWindow(&ref, string.String(), true); + break; + } + case M_FORWARD: + case M_FORWARD_WITHOUT_ATTACHMENTS: + { + TMailWindow *sourceWindow; + if (msg->FindPointer("window", (void **)&sourceWindow) < B_OK + || !sourceWindow->Lock()) + break; + + msg->FindRef("ref", &ref); + window = NewWindow(); + if (window->Lock()) { + window->Forward(&ref, sourceWindow, type == M_FORWARD); + window->Unlock(); + } + sourceWindow->Unlock(); + break; + } + + case M_REPLY: + case M_REPLY_TO_SENDER: + case M_REPLY_ALL: + case M_COPY_TO_NEW: + { + TMailWindow *sourceWindow; + if (msg->FindPointer("window", (void **)&sourceWindow) < B_OK + || !sourceWindow->Lock()) + break; + msg->FindRef("ref", &ref); + window = NewWindow(); + if (window->Lock()) { + if (type == M_COPY_TO_NEW) + window->CopyMessage(&ref, sourceWindow); + else + window->Reply(&ref, sourceWindow, type); + window->Unlock(); + } + sourceWindow->Unlock(); + break; + } + } + if (window) + window->Show(); + break; + } + + case M_PREFS: + if (fPrefsWindow) + fPrefsWindow->Activate(true); + else + { + fPrefsWindow = new TPrefsWindow(BRect(fPrefsWindowPos.x, + fPrefsWindowPos.y, fPrefsWindowPos.x + PREF_WIDTH, + fPrefsWindowPos.y + PREF_HEIGHT), + &fContentFont, NULL, &fWrapMode, &fAttachAttributes, + &fColoredQuotes, &fDefaultChain, &fUseAccountFrom, + &fReplyPreamble, &fSignature, &fMailCharacterSet, + &fWarnAboutUnencodableCharacters, + &fStartWithSpellCheckOn, &fShowButtonBar); + fPrefsWindow->Show(); + fPreviousShowButtonBar = fShowButtonBar; + } + break; + + case PREFS_CHANGED: + { + // Do we need to update the state of the button bars? + if (fPreviousShowButtonBar != fShowButtonBar) { + // Notify all Mail windows + TMailWindow *window; + for (int32 i = 0; (window=(TMailWindow *)fWindowList.ItemAt(i)) != NULL; i++) { + window->Lock(); + window->UpdateViews(); + window->Unlock(); + } + fPreviousShowButtonBar = fShowButtonBar; + } + break; + } + + case M_EDIT_SIGNATURE: + if (fSigWindow) + fSigWindow->Activate(true); + else { + fSigWindow = new TSignatureWindow(fSignatureWindowFrame); + fSigWindow->Show(); + } + break; + + case M_FONT: + FontChange(); + break; + + case REFS_RECEIVED: + if (msg->HasPointer("window")) + { + msg->FindPointer("window", (void **)&window); + BMessage message(*msg); + window->PostMessage(&message, window); + } + break; + + case WINDOW_CLOSED: + switch (msg->FindInt32("kind")) { + case MAIL_WINDOW: + { + TMailWindow *window; + if( msg->FindPointer( "window", (void **)&window ) == B_OK ) + fWindowList.RemoveItem(window); + fWindowCount--; + break; + } + + case PREFS_WINDOW: + fPrefsWindow = NULL; + msg->FindPoint("window pos", &fPrefsWindowPos); + break; + + case SIG_WINDOW: + fSigWindow = NULL; + msg->FindRect("window frame", &fSignatureWindowFrame); + break; + } + + if (!fWindowCount && !fSigWindow && !fPrefsWindow) + be_app->PostMessage(B_QUIT_REQUESTED); + break; + + case B_REFS_RECEIVED: + RefsReceived(msg); + break; + + case B_PRINTER_CHANGED: + _ClearPrintSettings(); + break; + + default: + BApplication::MessageReceived(msg); + } +} + + +bool +TMailApp::QuitRequested() +{ + if (!BApplication::QuitRequested()) + return false; + + fMailWindowFrame = fLastMailWindowFrame; + // Last closed window becomes standard window size. + + // Shut down the spam server if it's still running. If the user has trained it on a message, it will stay + // open. This is actually a good thing if there's quite a bit of spam -- no waiting for the thing to start + // up for each message, but it has no business staying that way if the user isn't doing anything with e-mail. :) + if (be_roster->IsRunning(kSpamServerSignature)) { + team_id serverTeam = be_roster->TeamFor(kSpamServerSignature); + if (serverTeam >= 0) { + int32 errorCode = B_SERVER_NOT_FOUND; + BMessenger messengerToSpamServer(kSpamServerSignature, serverTeam, &errorCode); + if (messengerToSpamServer.IsValid()) { + BMessage quitMessage(B_QUIT_REQUESTED); + messengerToSpamServer.SendMessage(&quitMessage); + } + } + + } + + SaveSettings(); + return true; +} + + +void +TMailApp::ReadyToRun() +{ + // Create needed indices for META:group, META:email, MAIL:draft, + // INDEX_SIGNATURE, INDEX_STATUS on the boot volume + + BVolume volume; + BVolumeRoster().GetBootVolume(&volume); + + fs_create_index(volume.Device(), "META:group", B_STRING_TYPE, 0); + fs_create_index(volume.Device(), "META:email", B_STRING_TYPE, 0); + fs_create_index(volume.Device(), "MAIL:draft", B_INT32_TYPE, 0); + fs_create_index(volume.Device(), INDEX_SIGNATURE, B_STRING_TYPE, 0); + fs_create_index(volume.Device(), INDEX_STATUS, B_STRING_TYPE, 0); + + // Load dictionaries + BPath indexDir; + BPath dictionaryDir; + BPath dataPath; + BPath indexPath; + BDirectory directory; + BEntry entry; + + // Locate user settings directory + find_directory(B_BEOS_ETC_DIRECTORY, &indexDir, true); + dictionaryDir = indexDir; + + // Setup directory paths + indexDir.Append(kIndexDirectory); + dictionaryDir.Append(kDictDirectory); + + // Create directories if needed + directory.CreateDirectory(indexDir.Path(), NULL); + directory.CreateDirectory(dictionaryDir.Path(), NULL); + + dataPath = dictionaryDir; + dataPath.Append("words"); + + // Only Load if Words Dictionary + if (BEntry(kWordsPath).Exists() || BEntry(dataPath.Path()).Exists()) + { + // If "/boot/optional/goodies/words" exists but there is no system dictionary, copy words + if (!BEntry(dataPath.Path()).Exists() && BEntry(kWordsPath).Exists()) + { + BFile words(kWordsPath, B_READ_ONLY); + BFile copy(dataPath.Path(), B_WRITE_ONLY | B_CREATE_FILE); + char buffer[4096]; + ssize_t size; + + while ((size = words.Read( buffer, 4096)) > 0) + copy.Write(buffer, size); + BNodeInfo(©).SetType("text/plain"); + } + + // Create user dictionary if it does not exist + dataPath = dictionaryDir; + dataPath.Append("user"); + if (!BEntry(dataPath.Path()).Exists()) + { + BFile user(dataPath.Path(), B_WRITE_ONLY | B_CREATE_FILE); + BNodeInfo(&user).SetType("text/plain"); + } + + // Load dictionaries + directory.SetTo(dictionaryDir.Path()); + + BString leafName; + gUserDict = -1; + + while (gDictCount < MAX_DICTIONARIES + && directory.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) + { + dataPath.SetTo(&entry); + + // Identify the user dictionary + if (strcmp("user", dataPath.Leaf()) == 0) + { + gUserDictFile = new BFile(dataPath.Path(), B_WRITE_ONLY | B_OPEN_AT_END); + gUserDict = gDictCount; + } + + indexPath = indexDir; + leafName.SetTo(dataPath.Leaf()); + leafName.Append(kMetaphone); + indexPath.Append(leafName.String()); + gWords[gDictCount] = new Words(dataPath.Path(), indexPath.Path(), true); + + indexPath = indexDir; + leafName.SetTo(dataPath.Leaf()); + leafName.Append(kExact); + indexPath.Append(leafName.String()); + gExactWords[gDictCount] = new Words(dataPath.Path(), indexPath.Path(), false); + gDictCount++; + } + } + + // Create a new window if starting up without any extra arguments. + + if (!fPrintHelpAndExit && !fWindowCount) + { + TMailWindow *window; + window = NewWindow(); + window->Show(); + } +} + + +void +TMailApp::RefsReceived(BMessage *msg) +{ + bool have_names = false; + BString names; + char type[B_FILE_NAME_LENGTH]; + int32 item = 0; + BFile file; + TMailWindow *window; + entry_ref ref; + + // + // If a tracker window opened me, get a messenger from it. + // + BMessenger messenger; + if (msg->HasMessenger("TrackerViewToken")) + msg->FindMessenger("TrackerViewToken", &messenger); + + while (msg->HasRef("refs", item)) { + msg->FindRef("refs", item++, &ref); + if ((window = FindWindow(ref)) != NULL) + window->Activate(true); + else { + file.SetTo(&ref, O_RDONLY); + if (file.InitCheck() == B_NO_ERROR) { + BNodeInfo node(&file); + node.GetType(type); + if (!strcmp(type, B_MAIL_TYPE)) { + window = NewWindow(&ref, NULL, false, &messenger); + window->Show(); + } else if(!strcmp(type, "application/x-person")) { + /* Got a People contact info file, see if it has an Email address. */ + BString name; + BString email; + attr_info info; + char *attrib; + + if (file.GetAttrInfo("META:email", &info) == B_NO_ERROR) { + attrib = (char *) malloc(info.size + 1); + file.ReadAttr("META:email", B_STRING_TYPE, 0, attrib, info.size); + attrib[info.size] = 0; // Just in case it wasn't NUL terminated. + email << attrib; + free(attrib); + + /* we got something... */ + if (email.Length() > 0) { + /* see if we can get a username as well */ + if(file.GetAttrInfo("META:name", &info) == B_NO_ERROR) { + attrib = (char *) malloc(info.size + 1); + file.ReadAttr("META:name", B_STRING_TYPE, 0, attrib, info.size); + attrib[info.size] = 0; // Just in case it wasn't NUL terminated. + name << "\"" << attrib << "\" "; + email.Prepend("<"); + email.Append(">"); + free(attrib); + } + + if (names.Length() == 0) { + names << name << email; + } else { + names << ", " << name << email; + } + have_names = true; + email.SetTo(""); + name.SetTo(""); + } + } + } + else if (!strcmp(type, kDraftType)) + { + window = NewWindow(); + + // If it's a draft message, open it + window->OpenMessage(&ref); + window->Show(); + } + } /* end of else(file.InitCheck() == B_NO_ERROR */ + } + } + + if (have_names) { + window = NewWindow(NULL, names.String()); + window->Show(); + } +} + + +TMailWindow * +TMailApp::FindWindow(const entry_ref &ref) +{ + BEntry entry(&ref); + if (entry.InitCheck() < B_OK) + return NULL; + + node_ref nodeRef; + if (entry.GetNodeRef(&nodeRef) < B_OK) + return NULL; + + BWindow *window; + int32 index = 0; + while ((window = WindowAt(index++)) != NULL) { + TMailWindow *mailWindow = dynamic_cast(window); + if (mailWindow == NULL) + continue; + + node_ref mailNodeRef; + if (mailWindow->GetMailNodeRef(mailNodeRef) == B_OK + && mailNodeRef == nodeRef) + return mailWindow; + } + + return NULL; +} + + +void +TMailApp::_CheckForSpamFilterExistence() +{ + // Looks at the filter settings to see if the user is using a spam filter. + // If there is one there, set fShowSpamGUI to TRUE, otherwise to FALSE. + + int32 addonNameIndex; + const char *addonNamePntr; + BDirectory inChainDir; + BPath path; + BEntry settingsEntry; + BFile settingsFile; + BMessage settingsMessage; + + fShowSpamGUI = false; + + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) + return; + path.Append("Mail/chains/inbound"); + if (inChainDir.SetTo(path.Path()) != B_OK) + return; + + while (inChainDir.GetNextEntry (&settingsEntry, true /* traverse */) == B_OK) { + if (!settingsEntry.IsFile()) + continue; + if (settingsFile.SetTo (&settingsEntry, B_READ_ONLY) != B_OK) + continue; + if (settingsMessage.Unflatten (&settingsFile) != B_OK) + continue; + for (addonNameIndex = 0; B_OK == settingsMessage.FindString ( + "filter_addons", addonNameIndex, &addonNamePntr); + addonNameIndex++) { + if (strstr (addonNamePntr, "Spam Filter") != NULL) { + fShowSpamGUI = true; // Found it! + return; + } + } + } +} + + +void +TMailApp::SetPrintSettings(const BMessage* printSettings) +{ + BAutolock _(this); + + if (printSettings == fPrintSettings) + return; + + delete fPrintSettings; + if (printSettings) + fPrintSettings = new BMessage(*printSettings); + else + fPrintSettings = NULL; +} + + +bool +TMailApp::HasPrintSettings() +{ + BAutolock _(this); + return fPrintSettings != NULL; +} + + +BMessage +TMailApp::PrintSettings() +{ + BAutolock _(this); + return BMessage(*fPrintSettings); +} + + +void +TMailApp::_ClearPrintSettings() +{ + delete fPrintSettings; + fPrintSettings = NULL; +} + + +void +TMailApp::SetLastWindowFrame(BRect frame) +{ + BAutolock _(this); + fLastMailWindowFrame = frame; +} + + +status_t +TMailApp::GetSettingsPath(BPath &path) +{ + status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (status != B_OK) + return status; + + path.Append("Mail"); + return create_directory(path.Path(), 0755); +} + + +status_t +TMailApp::LoadOldSettings() +{ + BPath path; + status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (status != B_OK) + return status; + + path.Append("Mail_data"); + + BFile file; + status = file.SetTo(path.Path(), B_READ_ONLY); + if (status != B_OK) + return status; + + file.Read(&fMailWindowFrame, sizeof(BRect)); +// file.Read(&level, sizeof(level)); + + font_family fontFamily; + font_style fontStyle; + float size; + file.Read(&fontFamily, sizeof(font_family)); + file.Read(&fontStyle, sizeof(font_style)); + file.Read(&size, sizeof(float)); + if (size >= 9) + fContentFont.SetSize(size); + + if (fontFamily[0] && fontStyle[0]) + fContentFont.SetFamilyAndStyle(fontFamily, fontStyle); + + file.Read(&fSignatureWindowFrame, sizeof(BRect)); + file.Read(&fShowHeader, sizeof(bool)); + file.Read(&fWrapMode, sizeof(bool)); + file.Read(&fPrefsWindowPos, sizeof(BPoint)); + + int32 length; + if (file.Read(&length, sizeof(int32)) < (ssize_t)sizeof(int32)) + return B_IO_ERROR; + + free(fSignature); + fSignature = NULL; + + if (length > 0) { + fSignature = (char *)malloc(length); + if (fSignature == NULL) + return B_NO_MEMORY; + + file.Read(fSignature, length); + } + + file.Read(&fMailCharacterSet, sizeof(int32)); + if (fMailCharacterSet != B_MAIL_UTF8_CONVERSION + && fMailCharacterSet != B_MAIL_US_ASCII_CONVERSION + && BCharacterSetRoster::GetCharacterSetByConversionID(fMailCharacterSet) == NULL) + fMailCharacterSet = B_MS_WINDOWS_CONVERSION; + + if (file.Read(&length, sizeof(int32)) == (ssize_t)sizeof(int32)) { + char *findString = (char *)malloc(length + 1); + if (findString == NULL) + return B_NO_MEMORY; + + file.Read(findString, length); + findString[length] = '\0'; + FindWindow::SetFindString(findString); + free(findString); + } + if (file.Read(&fShowButtonBar, sizeof(uint8)) < (ssize_t)sizeof(uint8)) + fShowButtonBar = true; + if (file.Read(&fUseAccountFrom, sizeof(int32)) < (ssize_t)sizeof(int32) + || fUseAccountFrom < ACCOUNT_USE_DEFAULT + || fUseAccountFrom > ACCOUNT_FROM_MAIL) + fUseAccountFrom = ACCOUNT_USE_DEFAULT; + if (file.Read(&fColoredQuotes, sizeof(bool)) < (ssize_t)sizeof(bool)) + fColoredQuotes = true; + + if (file.Read(&length, sizeof(int32)) == (ssize_t)sizeof(int32)) { + free(fReplyPreamble); + fReplyPreamble = (char *)malloc(length + 1); + if (fReplyPreamble == NULL) + return B_NO_MEMORY; + + file.Read(fReplyPreamble, length); + fReplyPreamble[length] = '\0'; + } + + file.Read(&fAttachAttributes, sizeof(bool)); + file.Read(&fWarnAboutUnencodableCharacters, sizeof(bool)); + + return B_OK; +} + + +status_t +TMailApp::SaveSettings() +{ + BMailSettings chainSettings; + + if (fDefaultChain != ~0UL) { + chainSettings.SetDefaultOutboundChainID(fDefaultChain); + chainSettings.Save(); + } + + BPath path; + status_t status = GetSettingsPath(path); + if (status != B_OK) + return status; + + path.Append("BeMail Settings~"); + + BFile file; + status = file.SetTo(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); + if (status != B_OK) + return status; + + BMessage settings('BeMl'); + settings.AddRect("MailWindowSize", fMailWindowFrame); +// settings.AddInt32("ExperienceLevel", level); + + font_family fontFamily; + font_style fontStyle; + fContentFont.GetFamilyAndStyle(&fontFamily, &fontStyle); + + settings.AddString("FontFamily", fontFamily); + settings.AddString("FontStyle", fontStyle); + settings.AddFloat("FontSize", fContentFont.Size()); + + settings.AddRect("SignatureWindowSize", fSignatureWindowFrame); + settings.AddBool("ShowHeadersMode", fShowHeader); + settings.AddBool("WordWrapMode", fWrapMode); + settings.AddPoint("PreferencesWindowLocation", fPrefsWindowPos); + settings.AddString("SignatureText", fSignature); + settings.AddInt32("CharacterSet", fMailCharacterSet); + settings.AddString("FindString", FindWindow::GetFindString()); + settings.AddInt8("ShowButtonBar", fShowButtonBar); + settings.AddInt32("UseAccountFrom", fUseAccountFrom); + settings.AddBool("ColoredQuotes", fColoredQuotes); + settings.AddString("ReplyPreamble", fReplyPreamble); + settings.AddBool("AttachAttributes", fAttachAttributes); + settings.AddBool("WarnAboutUnencodableCharacters", fWarnAboutUnencodableCharacters); + settings.AddBool("StartWithSpellCheck", fStartWithSpellCheckOn); + + BEntry entry; + status = entry.SetTo(path.Path()); + if (status != B_OK) + return status; + + status = settings.Flatten(&file); + if (status == B_OK) { + // replace original settings file + status = entry.Rename("BeMail Settings", true); + } else + entry.Remove(); + + return status; +} + + +status_t +TMailApp::LoadSettings() +{ + BMailSettings chainSettings; + fDefaultChain = chainSettings.DefaultOutboundChainID(); + + BPath path; + status_t status = GetSettingsPath(path); + if (status != B_OK) + return status; + + path.Append("BeMail Settings"); + + BFile file; + status = file.SetTo(path.Path(), B_READ_ONLY); + if (status != B_OK) + return LoadOldSettings(); + + BMessage settings; + status = settings.Unflatten(&file); + if (status < B_OK || settings.what != 'BeMl') { + // the current settings are corrupted, try old ones + return LoadOldSettings(); + } + + BRect rect; + if (settings.FindRect("MailWindowSize", &rect) == B_OK) + fMailWindowFrame = rect; + + int32 int32Value; +// if (settings.FindInt32("ExperienceLevel", &int32Value) == B_OK) +// level = int32Value; + + const char *fontFamily; + if (settings.FindString("FontFamily", &fontFamily) == B_OK) { + const char *fontStyle; + if (settings.FindString("FontStyle", &fontStyle) == B_OK) { + float size; + if (settings.FindFloat("FontSize", &size) == B_OK) { + if (size >= 7) + fContentFont.SetSize(size); + + if (fontFamily[0] && fontStyle[0]) { + fContentFont.SetFamilyAndStyle(fontFamily[0] ? fontFamily : NULL, + fontStyle[0] ? fontStyle : NULL); + } + } + } + } + + if (settings.FindRect("SignatureWindowSize", &rect) == B_OK) + fSignatureWindowFrame = rect; + + bool boolValue; + if (settings.FindBool("ShowHeadersMode", &boolValue) == B_OK) + fShowHeader = boolValue; + + if (settings.FindBool("WordWrapMode", &boolValue) == B_OK) + fWrapMode = boolValue; + + BPoint point; + if (settings.FindPoint("PreferencesWindowLocation", &point) == B_OK) + fPrefsWindowPos = point; + + const char *string; + if (settings.FindString("SignatureText", &string) == B_OK) { + free(fSignature); + fSignature = strdup(string); + } + + if (settings.FindInt32("CharacterSet", &int32Value) == B_OK) + fMailCharacterSet = int32Value; + if (fMailCharacterSet != B_MAIL_UTF8_CONVERSION + && fMailCharacterSet != B_MAIL_US_ASCII_CONVERSION + && BCharacterSetRoster::GetCharacterSetByConversionID(fMailCharacterSet) == NULL) + fMailCharacterSet = B_MS_WINDOWS_CONVERSION; + + if (settings.FindString("FindString", &string) == B_OK) + FindWindow::SetFindString(string); + + int8 int8Value; + if (settings.FindInt8("ShowButtonBar", &int8Value) == B_OK) + fShowButtonBar = int8Value; + + if (settings.FindInt32("UseAccountFrom", &int32Value) == B_OK) + fUseAccountFrom = int32Value; + if (fUseAccountFrom < ACCOUNT_USE_DEFAULT + || fUseAccountFrom > ACCOUNT_FROM_MAIL) + fUseAccountFrom = ACCOUNT_USE_DEFAULT; + + if (settings.FindBool("ColoredQuotes", &boolValue) == B_OK) + fColoredQuotes = boolValue; + + if (settings.FindString("ReplyPreamble", &string) == B_OK) { + free(fReplyPreamble); + fReplyPreamble = strdup(string); + } + + if (settings.FindBool("AttachAttributes", &boolValue) == B_OK) + fAttachAttributes = boolValue; + + if (settings.FindBool("WarnAboutUnencodableCharacters", &boolValue) == B_OK) + fWarnAboutUnencodableCharacters = boolValue; + + if (settings.FindBool("StartWithSpellCheck", &boolValue) == B_OK) + fStartWithSpellCheckOn = boolValue; + + return B_OK; +} + + +void +TMailApp::FontChange() +{ + int32 index = 0; + BMessage msg; + BWindow *window; + + msg.what = CHANGE_FONT; + msg.AddPointer("font", &fContentFont); + + for (;;) { + window = WindowAt(index++); + if (!window) + break; + + window->PostMessage(&msg); + } +} + + +TMailWindow * +TMailApp::NewWindow(const entry_ref *ref, const char *to, bool resend, + BMessenger *trackerMessenger) +{ + BScreen screen(B_MAIN_SCREEN_ID); + BRect screen_frame = screen.Frame(); + + BRect r; + if ((fMailWindowFrame.Width() > 1) && (fMailWindowFrame.Height() > 1)) + r = fMailWindowFrame; + else + r.Set(6, TITLE_BAR_HEIGHT, 6 + WIND_WIDTH, TITLE_BAR_HEIGHT + WIND_HEIGHT); + + r.OffsetBy(fWindowCount * 20, fWindowCount * 20); + + if ((r.left - 6) < screen_frame.left) + r.OffsetTo(screen_frame.left + 8, r.top); + + if ((r.left + 20) > screen_frame.right) + r.OffsetTo(6, r.top); + + if ((r.top - 26) < screen_frame.top) + r.OffsetTo(r.left, screen_frame.top + 26); + + if ((r.top + 20) > screen_frame.bottom) + r.OffsetTo(r.left, TITLE_BAR_HEIGHT); + + if (r.Width() < WIND_WIDTH) + r.right = r.left + WIND_WIDTH; + + fWindowCount++; + + BString title; + BFile file; + if (!resend && ref && file.SetTo(ref, O_RDONLY) == B_NO_ERROR) { + BString name; + if (ReadAttrString(&file, B_MAIL_ATTR_NAME, &name) == B_NO_ERROR) { + title << name; + BString subject; + if (ReadAttrString(&file, B_MAIL_ATTR_SUBJECT, &subject) == B_NO_ERROR) + title << " -> " << subject; + } + } + if (title == "") + title = "Mail"; + + TMailWindow *window = new TMailWindow(r, title.String(), this, ref, to, + &fContentFont, resend, trackerMessenger); + fWindowList.AddItem(window); + + return window; +} + + +// #pragma mark - settings + + +BString +TMailApp::Signature() +{ + BAutolock _(this); + return BString(fSignature); +} + + +BString +TMailApp::ReplyPreamble() +{ + BAutolock _(this); + return BString(fReplyPreamble); +} + + +bool +TMailApp::WrapMode() +{ + BAutolock _(this); + return fWrapMode; +} + + +void +TMailApp::SetShowHeader(bool show) +{ + BAutolock _(this); + fShowHeader = show; +} + + +bool +TMailApp::ShowHeader() +{ + BAutolock _(this); + return fShowHeader; +} + + +bool +TMailApp::AttachAttributes() +{ + BAutolock _(this); + return fAttachAttributes; +} + + +bool +TMailApp::ColoredQuotes() +{ + BAutolock _(this); + return fColoredQuotes; +} + + +uint8 +TMailApp::ShowButtonBar() +{ + BAutolock _(this); + return fShowButtonBar; +} + + +bool +TMailApp::WarnAboutUnencodableCharacters() +{ + BAutolock _(this); + return fWarnAboutUnencodableCharacters; +} + + +bool +TMailApp::StartWithSpellCheckOn() +{ + BAutolock _(this); + return fStartWithSpellCheckOn; +} + + +void +TMailApp::SetDefaultChain(uint32 chain) +{ + BAutolock _(this); + fDefaultChain = chain; +} + + +uint32 +TMailApp::DefaultChain() +{ + BAutolock _(this); + return fDefaultChain; +} + + +int32 +TMailApp::UseAccountFrom() +{ + BAutolock _(this); + return fUseAccountFrom; +} + + +uint32 +TMailApp::MailCharacterSet() +{ + BAutolock _(this); + return fMailCharacterSet; +} + + +BFont +TMailApp::ContentFont() +{ + BAutolock _(this); + return fContentFont; +} + diff --git a/src/apps/mail/MailApp.h b/src/apps/mail/MailApp.h new file mode 100644 index 0000000000..fc34fa12dd --- /dev/null +++ b/src/apps/mail/MailApp.h @@ -0,0 +1,137 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ +#ifndef _MAIL_APP_H +#define _MAIL_APP_H + +#include +#include +#include +#include +#include + + +class BFile; +class BMessenger; +class TMailWindow; +class TPrefsWindow; +class TSignatureWindow; + + +class TMailApp : public BApplication { + public: + TMailApp(); + virtual ~TMailApp(); + + virtual void AboutRequested(); + virtual void ArgvReceived(int32, char**); + virtual void MessageReceived(BMessage*); + virtual bool QuitRequested(); + virtual void ReadyToRun(); + virtual void RefsReceived(BMessage*); + + TMailWindow* FindWindow(const entry_ref&); + void FontChange(); + TMailWindow* NewWindow(const entry_ref* rec = NULL, + const char* to = NULL, bool resend = false, + BMessenger* messenger = NULL); + + void SetPrintSettings(const BMessage* settings); + bool HasPrintSettings(); + BMessage PrintSettings(); + + void SetLastWindowFrame(BRect frame); + + // TODO: move these into a MailSettings class + BString Signature(); + BString ReplyPreamble(); + bool WrapMode(); + void SetShowHeader(bool show); + bool ShowHeader(); + bool AttachAttributes(); + bool ColoredQuotes(); + uint8 ShowButtonBar(); + bool WarnAboutUnencodableCharacters(); + bool StartWithSpellCheckOn(); + void SetDefaultChain(uint32 chain); + uint32 DefaultChain(); + int32 UseAccountFrom(); + uint32 MailCharacterSet(); + bool ShowSpamGUI() const + { return fShowSpamGUI; } + BFont ContentFont(); + + private: + void _ClearPrintSettings(); + void _CheckForSpamFilterExistence(); + + status_t GetSettingsPath(BPath &path); + status_t LoadOldSettings(); + status_t SaveSettings(); + status_t LoadSettings(); + + BList fWindowList; + int32 fWindowCount; + TPrefsWindow* fPrefsWindow; + TSignatureWindow* fSigWindow; + + uint8 fPreviousShowButtonBar; + + BRect fMailWindowFrame; + BRect fLastMailWindowFrame; + BRect fSignatureWindowFrame; + BPoint fPrefsWindowPos; + + BMessage* fPrintSettings; + + bool fPrintHelpAndExit; + + // TODO: these should go into a settings class + char* fSignature; + char* fReplyPreamble; + bool fWrapMode; + bool fShowHeader; + bool fAttachAttributes; + bool fColoredQuotes; + uint8 fShowButtonBar; + bool fWarnAboutUnencodableCharacters; + bool fStartWithSpellCheckOn; + bool fShowSpamGUI; + uint32 fDefaultChain; + int32 fUseAccountFrom; + uint32 fMailCharacterSet; + BFont fContentFont; +}; + + +#endif // #ifndef _MAIL_H diff --git a/src/apps/mail/MailPopUpMenu.cpp b/src/apps/mail/MailPopUpMenu.cpp new file mode 100644 index 0000000000..de893224a3 --- /dev/null +++ b/src/apps/mail/MailPopUpMenu.cpp @@ -0,0 +1,106 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ + + +#include "MailPopUpMenu.h" + +#include +#include + +#include +#include + +#include + +#include "MailSupport.h" +#include "Messages.h" + + +TMenu::TMenu(const char *name, const char *attribute, int32 message, bool popup, + bool addRandom) + : BPopUpMenu(name, false, false), + fPopup(popup), + fAddRandom(addRandom), + fMessage(message) +{ + fAttribute = strdup(attribute); + BuildMenu(); +} + + +TMenu::~TMenu() +{ + free(fAttribute); +} + + +void +TMenu::AttachedToWindow() +{ + BuildMenu(); + BPopUpMenu::AttachedToWindow(); +} + + +BPoint +TMenu::ScreenLocation(void) +{ + if (fPopup) + return BPopUpMenu::ScreenLocation(); + + return BMenu::ScreenLocation(); +} + + +void +TMenu::BuildMenu() +{ + RemoveItems(0, CountItems(), true); + add_query_menu_items(this, fAttribute, fMessage, NULL, fPopup); + + if (fAddRandom && CountItems() > 0) { + AddItem(new BSeparatorItem(), 0); + + BMessage *msg = new BMessage(M_RANDOM_SIG); + if (!fPopup) { + AddItem(new BMenuItem(MDR_DIALECT_CHOICE ("Random","R) 自動決定"), msg, + '0'), 0); + } else { + AddItem(new BMenuItem(MDR_DIALECT_CHOICE ("Random","R) 自動決定"), msg), + 0); + } + } +} + + diff --git a/src/apps/mail/MailPopUpMenu.h b/src/apps/mail/MailPopUpMenu.h new file mode 100644 index 0000000000..62c7a1a543 --- /dev/null +++ b/src/apps/mail/MailPopUpMenu.h @@ -0,0 +1,60 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ +#ifndef _MAIL_POPUPMENU_H +#define _MAIL_POPUPMENU_H + + +#include + + +class TMenu: public BPopUpMenu { + public: + TMenu(const char* name, const char* attribute, + int32 message, bool popup = false, + bool addRandom = true); + virtual ~TMenu(); + + virtual BPoint ScreenLocation(void); + virtual void AttachedToWindow(); + + void BuildMenu(); + + private: + char* fAttribute; + bool fPopup; + bool fAddRandom; + int32 fMessage; +}; + +#endif // _MAIL_POPUPMENU_H diff --git a/src/apps/mail/MailSupport.cpp b/src/apps/mail/MailSupport.cpp new file mode 100644 index 0000000000..f73313bad8 --- /dev/null +++ b/src/apps/mail/MailSupport.cpp @@ -0,0 +1,173 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ + + +#include "MailSupport.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "Utilities.h" + + +using namespace BPrivate ; + +#ifdef HAIKU_TARGET_PLATFORM_BEOS + #include +#endif + + +#include "Words.h" + +// global variables +Words* gWords[MAX_DICTIONARIES]; +Words* gExactWords[MAX_DICTIONARIES]; + +int32 gUserDict; +BFile* gUserDictFile; +int32 gDictCount = 0; + +// int32 level = L_BEGINNER; + +const char* kSpamServerSignature = "application/x-vnd.agmsmith.spamdbm"; +const char* kDraftPath = "mail/draft"; +const char* kDraftType = "text/x-vnd.Be-MailDraft"; +const char* kMailFolder = "mail"; +const char* kMailboxFolder = "mail/mailbox"; + + +int32 +header_len(BFile *file) +{ + char *buffer; + int32 length; + int32 result = 0; + off_t size; + + if (file->ReadAttr(B_MAIL_ATTR_HEADER, B_INT32_TYPE, 0, &result, + sizeof(int32)) != sizeof(int32)) { + file->GetSize(&size); + buffer = (char *)malloc(size); + if (buffer) { + file->Seek(0, 0); + if (file->Read(buffer, size) == size) { + while ((length = linelen(buffer + result, size - result, true)) > 2) + result += length; + + result += length; + } + free(buffer); + file->WriteAttr(B_MAIL_ATTR_HEADER, B_INT32_TYPE, 0, &result, sizeof(int32)); + } + } + return result; +} + + +int32 +add_query_menu_items(BMenu* menu, const char* attribute, uint32 what, + const char* format, bool popup) +{ + BVolume volume; + BVolumeRoster().GetBootVolume(&volume); + + BQuery query; + query.SetVolume(&volume); + query.PushAttr(attribute); + query.PushString("*"); + query.PushOp(B_EQ); + query.Fetch(); + + int32 index = 0; + BEntry entry; + while (query.GetNextEntry(&entry) == B_OK) { + BFile file(&entry, B_READ_ONLY); + if (file.InitCheck() == B_OK) { + BMessage* message = new BMessage(what); + + entry_ref ref; + entry.GetRef(&ref); + message->AddRef("ref", &ref); + + BString value; + if (file.ReadAttrString(attribute, &value) < B_OK) + continue; + + message->AddString("attribute", value.String()); + + char name[256]; + if (format != NULL) + snprintf(name, sizeof(name), format, value.String()); + else + strlcpy(name, value.String(), sizeof(name)); + + if (index < 9 && !popup) + menu->AddItem(new BMenuItem(name, message, '1' + index)); + else + menu->AddItem(new BMenuItem(name, message)); + index++; + } + } + + return index; +} + diff --git a/src/apps/mail/MailSupport.h b/src/apps/mail/MailSupport.h new file mode 100644 index 0000000000..f7ce12b2b4 --- /dev/null +++ b/src/apps/mail/MailSupport.h @@ -0,0 +1,84 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ +#ifndef _MAIL_SUPPORT_H +#define _MAIL_SUPPORT_H + + +#include + + +#define MAX_DICTIONARIES 8 +#define TITLE_BAR_HEIGHT 25 +#define WIND_WIDTH 457 +#define WIND_HEIGHT 400 +#define RIGHT_BOUNDARY 8191 +#define SEPARATOR_MARGIN 7 +#define QUOTE "> " + + +enum USER_LEVEL { + L_BEGINNER = 0, + L_EXPERT +}; + +enum WINDOW_TYPES { + MAIL_WINDOW = 0, + PREFS_WINDOW, + SIG_WINDOW +}; + + +class BFile; +class Words; + + +int32 header_len(BFile*); +int32 add_query_menu_items(BMenu* menu, const char* attribute, uint32 what, + const char* format, bool popup = false); + + +extern Words* gWords[MAX_DICTIONARIES]; +extern Words* gExactWords[MAX_DICTIONARIES]; +extern int32 gUserDict; +extern BFile* gUserDictFile; +extern int32 gDictCount; + +extern const char* kSpamServerSignature; +extern const char* kDraftPath; +extern const char* kDraftType; +extern const char* kMailFolder; +extern const char* kMailboxFolder; + + +#endif // _MAIL_SUPPORT_H diff --git a/src/apps/mail/Mail.cpp b/src/apps/mail/MailWindow.cpp similarity index 70% rename from src/apps/mail/Mail.cpp rename to src/apps/mail/MailWindow.cpp index 880f804f68..17b0233de5 100644 --- a/src/apps/mail/Mail.cpp +++ b/src/apps/mail/MailWindow.cpp @@ -32,11 +32,8 @@ names are registered trademarks or trademarks of their respective holders. All rights reserved. */ -//-------------------------------------------------------------------- -// -// Mail.cpp -// -//-------------------------------------------------------------------- + +#include "MailWindow.h" #include #include @@ -75,19 +72,22 @@ using namespace BPrivate ; #include #endif -#include "Mail.h" -#include "Header.h" +#include "ButtonBar.h" #include "Content.h" #include "Enclosures.h" +#include "FieldMsg.h" +#include "FindWindow.h" +#include "Header.h" +#include "Messages.h" +#include "MailApp.h" +#include "MailPopUpMenu.h" +#include "MailSupport.h" #include "Prefs.h" +#include "QueryMenu.h" #include "Signature.h" #include "Status.h" #include "String.h" -#include "FindWindow.h" #include "Utilities.h" -#include "ButtonBar.h" -#include "QueryMenu.h" -#include "FieldMsg.h" #include "Words.h" @@ -109,22 +109,6 @@ const char *kRedoStrings[] = { MDR_DIALECT_CHOICE ("Redo Drop", "Z) やり直し(ドロップ)") }; -// Spam related globals. -static bool gShowSpamGUI = true; -static BMessenger gMessengerToSpamServer; -static const char *kSpamServerSignature = "application/x-vnd.agmsmith.spamdbm"; - -static const char *kDraftPath = "mail/draft"; -static const char *kDraftType = "text/x-vnd.Be-MailDraft"; -static const char *kMailFolder = "mail"; -static const char *kMailboxFolder = "mail/mailbox"; - -static const char *kDictDirectory = "word_dictionary"; -static const char *kIndexDirectory = "word_index"; -static const char *kWordsPath = "/boot/optional/goodies/words"; -static const char *kExact = ".exact"; -static const char *kMetaphone = ".metaphone"; - // Text for both the main menu and the pop-up menu. static const char *kSpamMenuItemTextArray[] = { @@ -134,1103 +118,20 @@ static const char *kSpamMenuItemTextArray[] = { "Mark as Genuine" // M_TRAIN_GENUINE }; -// global variables -bool gHelpOnly = false; -bool header_flag = false; -static bool sWrapMode = true; -bool attachAttributes_mode = true; -bool gColoredQuotes = true; -static uint8 sShowButtonBar = true; -char *gReplyPreamble; -char *signature; -// int32 level = L_BEGINNER; -entry_ref open_dir; -BMessage *print_settings = NULL; -BPoint prefs_window; -BRect signature_window; -BRect mail_window; -BRect last_window; -uint32 gMailCharacterSet = B_MS_WINDOWS_CONVERSION; -bool gWarnAboutUnencodableCharacters = true; -Words *gWords[MAX_DICTIONARIES], *gExactWords[MAX_DICTIONARIES]; -int32 gUserDict; -BFile *gUserDictFile; -int32 gDictCount = 0; -bool gStartWithSpellCheckOn = false; -uint32 gDefaultChain; -int32 gUseAccountFrom; // static list for tracking of Windows BList TMailWindow::sWindowList; BLocker TMailWindow::sWindowListLock; -//==================================================================== - -int -main() -{ - TMailApp().Run(); - return B_NO_ERROR; -} - - -int32 -add_query_menu_items(BMenu* menu, const char* attribute, uint32 what, - const char* format, bool popup = false) -{ - BVolume volume; - BVolumeRoster().GetBootVolume(&volume); - - BQuery query; - query.SetVolume(&volume); - query.PushAttr(attribute); - query.PushString("*"); - query.PushOp(B_EQ); - query.Fetch(); - - int32 index = 0; - BEntry entry; - while (query.GetNextEntry(&entry) == B_OK) { - BFile file(&entry, B_READ_ONLY); - if (file.InitCheck() == B_OK) { - BMessage* message = new BMessage(what); - - entry_ref ref; - entry.GetRef(&ref); - message->AddRef("ref", &ref); - - BString value; - if (file.ReadAttrString(attribute, &value) < B_OK) - continue; - - message->AddString("attribute", value.String()); - - char name[256]; - if (format != NULL) - snprintf(name, sizeof(name), format, value.String()); - else - strlcpy(name, value.String(), sizeof(name)); - - if (index < 9 && !popup) - menu->AddItem(new BMenuItem(name, message, '1' + index)); - else - menu->AddItem(new BMenuItem(name, message)); - index++; - } - } - - return index; -} - - -int32 -header_len(BFile *file) -{ - char *buffer; - int32 length; - int32 result = 0; - off_t size; - - if (file->ReadAttr(B_MAIL_ATTR_HEADER, B_INT32_TYPE, 0, &result, sizeof(int32)) != sizeof(int32)) - { - file->GetSize(&size); - buffer = (char *)malloc(size); - if (buffer) - { - file->Seek(0, 0); - if (file->Read(buffer, size) == size) - { - while ((length = linelen(buffer + result, size - result, true)) > 2) - result += length; - - result += length; - } - free(buffer); - file->WriteAttr(B_MAIL_ATTR_HEADER, B_INT32_TYPE, 0, &result, sizeof(int32)); - } - } - return result; -} - - // #pragma mark - -TMailApp::TMailApp() - : BApplication("application/x-vnd.Be-MAIL"), - fFont(*be_plain_font), - fWindowCount(0), - fPrefsWindow(NULL), - fSigWindow(NULL) -{ - // set default values - fFont.SetSize(FONT_SIZE); - signature = (char *)malloc(strlen(SIG_NONE) + 1); - strcpy(signature, SIG_NONE); - gReplyPreamble = (char *)malloc(1); - gReplyPreamble[0] = '\0'; - - mail_window.Set(0, 0, 0, 0); - signature_window.Set(6, TITLE_BAR_HEIGHT, 6 + kSigWidth, TITLE_BAR_HEIGHT + kSigHeight); - prefs_window.Set(6, TITLE_BAR_HEIGHT); - - // Find and read settings file. - LoadSettings(); - - CheckForSpamFilterExistence(); - fFont.SetSpacing(B_BITMAP_SPACING); - last_window = mail_window; -} - - -TMailApp::~TMailApp() -{ -} - - -void -TMailApp::AboutRequested() -{ - BAlert *alert = new BAlert("about", "Mail\n\n" - "written by Robert Polic\n" - "enhanced by the Dr. Zoidberg crew\n\n" - "Copyright 2007, Haiku.\n", "Ok"); - BTextView *view = alert->TextView(); - BFont font; - - view->SetStylable(true); - - view->GetFont(&font); - font.SetSize(font.Size() + 7.0f); - font.SetFace(B_BOLD_FACE); - view->SetFontAndColor(0, 4, &font); - - alert->Go(); -} - - -void -TMailApp::ArgvReceived(int32 argc, char **argv) -{ - BEntry entry; - BString names; - BString ccNames; - BString bccNames; - BString subject; - BString body; - BMessage enclosure(B_REFS_RECEIVED); - // a "mailto:" with no name should open an empty window - // so remember if we got a "mailto:" even if there isn't a name - // that goes along with it (this allows deskbar replicant to open - // an empty message even when Mail is already running) - bool gotmailto = false; - - for (int32 loop = 1; loop < argc; loop++) - { - if (strcmp(argv[loop], "-h") == 0 - || strcmp(argv[loop], "--help") == 0) - { - printf(" usage: %s [ mailto:
] [ -subject \"\" ] [ ccto:
] [ bccto:
] " - "[ -body \" ] [ ...] \n", - argv[0]); - gHelpOnly = true; - be_app->PostMessage(B_QUIT_REQUESTED); - return; - } - else if (strncmp(argv[loop], "mailto:", 7) == 0) - { - if (names.Length()) - names += ", "; - char *options; - if ((options = strchr(argv[loop],'?')) != NULL) - { - names.Append(argv[loop] + 7, options - argv[loop] - 7); - if (!strncmp(++options,"subject=",8)) - subject = options + 8; - } - else - names += argv[loop] + 7; - gotmailto = true; - } - else if (strncmp(argv[loop], "ccto:", 5) == 0) - { - if (ccNames.Length()) - ccNames += ", "; - ccNames += argv[loop] + 5; - } - else if (strncmp(argv[loop], "bccto:", 6) == 0) - { - if (bccNames.Length()) - bccNames += ", "; - bccNames += argv[loop] + 6; - } - else if (strcmp(argv[loop], "-subject") == 0) - subject = argv[++loop]; - else if (strcmp(argv[loop], "-body") == 0 && argv[loop + 1]) - body = argv[++loop]; - else if (strncmp(argv[loop], "enclosure:", 10) == 0) - { - BEntry tmp(argv[loop] + 10, true); - if (tmp.InitCheck() == B_OK && tmp.Exists()) - { - entry_ref ref; - tmp.GetRef(&ref); - enclosure.AddRef("refs", &ref); - } - } - else if (entry.SetTo(argv[loop]) == B_NO_ERROR) - { - BMessage msg(B_REFS_RECEIVED); - entry_ref ref; - entry.GetRef(&ref); - msg.AddRef("refs", &ref); - RefsReceived(&msg); - } - } - - if (gotmailto || names.Length() || ccNames.Length() || bccNames.Length() || subject.Length() - || body.Length() || enclosure.HasRef("refs")) - { - TMailWindow *window = NewWindow(NULL, names.String()); - window->SetTo(names.String(), subject.String(), ccNames.String(), bccNames.String(), - &body, &enclosure); - window->Show(); - } -} - - -void -TMailApp::MessageReceived(BMessage *msg) -{ - TMailWindow *window = NULL; - entry_ref ref; - - switch (msg->what) - { - case M_NEW: - { - int32 type; - msg->FindInt32("type", &type); - switch (type) - { - case M_NEW: - window = NewWindow(); - break; - - case M_RESEND: - { - msg->FindRef("ref", &ref); - BNode file(&ref); - BString string = ""; - - if (file.InitCheck() == B_OK) - ReadAttrString(&file, B_MAIL_ATTR_TO, &string); - - window = NewWindow(&ref, string.String(), true); - break; - } - case M_FORWARD: - case M_FORWARD_WITHOUT_ATTACHMENTS: - { - TMailWindow *sourceWindow; - if (msg->FindPointer("window", (void **)&sourceWindow) < B_OK - || !sourceWindow->Lock()) - break; - - msg->FindRef("ref", &ref); - window = NewWindow(); - if (window->Lock()) { - window->Forward(&ref, sourceWindow, type == M_FORWARD); - window->Unlock(); - } - sourceWindow->Unlock(); - break; - } - - case M_REPLY: - case M_REPLY_TO_SENDER: - case M_REPLY_ALL: - case M_COPY_TO_NEW: - { - TMailWindow *sourceWindow; - if (msg->FindPointer("window", (void **)&sourceWindow) < B_OK - || !sourceWindow->Lock()) - break; - msg->FindRef("ref", &ref); - window = NewWindow(); - if (window->Lock()) { - if (type == M_COPY_TO_NEW) - window->CopyMessage(&ref, sourceWindow); - else - window->Reply(&ref, sourceWindow, type); - window->Unlock(); - } - sourceWindow->Unlock(); - break; - } - } - if (window) - window->Show(); - break; - } - - case M_PREFS: - if (fPrefsWindow) - fPrefsWindow->Activate(true); - else - { - fPrefsWindow = new TPrefsWindow(BRect(prefs_window.x, - prefs_window.y, prefs_window.x + PREF_WIDTH, - prefs_window.y + PREF_HEIGHT), - &fFont, NULL, &sWrapMode, &attachAttributes_mode, - &gColoredQuotes, &gDefaultChain, &gUseAccountFrom, - &gReplyPreamble, &signature, &gMailCharacterSet, - &gWarnAboutUnencodableCharacters, - &gStartWithSpellCheckOn, &sShowButtonBar); - fPrefsWindow->Show(); - fPreviousShowButtonBar = sShowButtonBar; - } - break; - - case PREFS_CHANGED: - { - // Do we need to update the state of the button bars? - if (fPreviousShowButtonBar != sShowButtonBar) { - // Notify all Mail windows - TMailWindow *window; - for (int32 i = 0; (window=(TMailWindow *)fWindowList.ItemAt(i)) != NULL; i++) { - window->Lock(); - window->UpdateViews(); - window->Unlock(); - } - fPreviousShowButtonBar = sShowButtonBar; - } - break; - } - - case M_EDIT_SIGNATURE: - if (fSigWindow) - fSigWindow->Activate(true); - else { - fSigWindow = new TSignatureWindow(signature_window); - fSigWindow->Show(); - } - break; - - case M_FONT: - FontChange(); - break; - - case REFS_RECEIVED: - if (msg->HasPointer("window")) - { - msg->FindPointer("window", (void **)&window); - BMessage message(*msg); - window->PostMessage(&message, window); - } - break; - - case WINDOW_CLOSED: - switch (msg->FindInt32("kind")) - { - case MAIL_WINDOW: - { - TMailWindow *window; - if( msg->FindPointer( "window", (void **)&window ) == B_OK ) - fWindowList.RemoveItem( window ); - fWindowCount--; - break; - } - - case PREFS_WINDOW: - fPrefsWindow = NULL; - break; - - case SIG_WINDOW: - fSigWindow = NULL; - break; - } - - if (!fWindowCount && !fSigWindow && !fPrefsWindow) - be_app->PostMessage(B_QUIT_REQUESTED); - break; - - case B_REFS_RECEIVED: - RefsReceived(msg); - break; - - case B_PRINTER_CHANGED: - ClearPrintSettings(); - break; - - default: - BApplication::MessageReceived(msg); - } -} - - -bool -TMailApp::QuitRequested() -{ - if (!BApplication::QuitRequested()) - return false; - - mail_window = last_window; - // Last closed window becomes standard window size. - - // Shut down the spam server if it's still running. If the user has trained it on a message, it will stay - // open. This is actually a good thing if there's quite a bit of spam -- no waiting for the thing to start - // up for each message, but it has no business staying that way if the user isn't doing anything with e-mail. :) - if (be_roster->IsRunning(kSpamServerSignature)) { - team_id serverTeam = be_roster->TeamFor(kSpamServerSignature); - if (serverTeam >= 0) { - int32 errorCode = B_SERVER_NOT_FOUND; - gMessengerToSpamServer = BMessenger (kSpamServerSignature, serverTeam, &errorCode); - if (gMessengerToSpamServer.IsValid()) { - BMessage quitMessage(B_QUIT_REQUESTED); - gMessengerToSpamServer.SendMessage(&quitMessage); - } - } - - } - - SaveSettings(); - return true; -} - - -void -TMailApp::ReadyToRun() -{ - // Create needed indices for META:group, META:email, MAIL:draft, - // INDEX_SIGNATURE, INDEX_STATUS on the boot volume - - BVolume volume; - BVolumeRoster().GetBootVolume(&volume); - - fs_create_index(volume.Device(), "META:group", B_STRING_TYPE, 0); - fs_create_index(volume.Device(), "META:email", B_STRING_TYPE, 0); - fs_create_index(volume.Device(), "MAIL:draft", B_INT32_TYPE, 0); - fs_create_index(volume.Device(), INDEX_SIGNATURE, B_STRING_TYPE, 0); - fs_create_index(volume.Device(), INDEX_STATUS, B_STRING_TYPE, 0); - - // Load dictionaries - BPath indexDir; - BPath dictionaryDir; - BPath dataPath; - BPath indexPath; - BDirectory directory; - BEntry entry; - - // Locate user settings directory - find_directory(B_BEOS_ETC_DIRECTORY, &indexDir, true); - dictionaryDir = indexDir; - - // Setup directory paths - indexDir.Append(kIndexDirectory); - dictionaryDir.Append(kDictDirectory); - - // Create directories if needed - directory.CreateDirectory(indexDir.Path(), NULL); - directory.CreateDirectory(dictionaryDir.Path(), NULL); - - dataPath = dictionaryDir; - dataPath.Append("words"); - - // Only Load if Words Dictionary - if (BEntry(kWordsPath).Exists() || BEntry(dataPath.Path()).Exists()) - { - // If "/boot/optional/goodies/words" exists but there is no system dictionary, copy words - if (!BEntry(dataPath.Path()).Exists() && BEntry(kWordsPath).Exists()) - { - BFile words(kWordsPath, B_READ_ONLY); - BFile copy(dataPath.Path(), B_WRITE_ONLY | B_CREATE_FILE); - char buffer[4096]; - ssize_t size; - - while ((size = words.Read( buffer, 4096)) > 0) - copy.Write(buffer, size); - BNodeInfo(©).SetType("text/plain"); - } - - // Create user dictionary if it does not exist - dataPath = dictionaryDir; - dataPath.Append("user"); - if (!BEntry(dataPath.Path()).Exists()) - { - BFile user(dataPath.Path(), B_WRITE_ONLY | B_CREATE_FILE); - BNodeInfo(&user).SetType("text/plain"); - } - - // Load dictionaries - directory.SetTo(dictionaryDir.Path()); - - BString leafName; - gUserDict = -1; - - while (gDictCount < MAX_DICTIONARIES - && directory.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) - { - dataPath.SetTo(&entry); - - // Identify the user dictionary - if (strcmp("user", dataPath.Leaf()) == 0) - { - gUserDictFile = new BFile(dataPath.Path(), B_WRITE_ONLY | B_OPEN_AT_END); - gUserDict = gDictCount; - } - - indexPath = indexDir; - leafName.SetTo(dataPath.Leaf()); - leafName.Append(kMetaphone); - indexPath.Append(leafName.String()); - gWords[gDictCount] = new Words(dataPath.Path(), indexPath.Path(), true); - - indexPath = indexDir; - leafName.SetTo(dataPath.Leaf()); - leafName.Append(kExact); - indexPath.Append(leafName.String()); - gExactWords[gDictCount] = new Words(dataPath.Path(), indexPath.Path(), false); - gDictCount++; - } - } - - // Create a new window if starting up without any extra arguments. - - if (!gHelpOnly && !fWindowCount) - { - TMailWindow *window; - window = NewWindow(); - window->Show(); - } -} - - -void -TMailApp::RefsReceived(BMessage *msg) -{ - bool have_names = false; - BString names; - char type[B_FILE_NAME_LENGTH]; - int32 item = 0; - BFile file; - TMailWindow *window; - entry_ref ref; - - // - // If a tracker window opened me, get a messenger from it. - // - BMessenger messenger; - if (msg->HasMessenger("TrackerViewToken")) - msg->FindMessenger("TrackerViewToken", &messenger); - - while (msg->HasRef("refs", item)) { - msg->FindRef("refs", item++, &ref); - if ((window = FindWindow(ref)) != NULL) - window->Activate(true); - else { - file.SetTo(&ref, O_RDONLY); - if (file.InitCheck() == B_NO_ERROR) { - BNodeInfo node(&file); - node.GetType(type); - if (!strcmp(type, B_MAIL_TYPE)) { - window = NewWindow(&ref, NULL, false, &messenger); - window->Show(); - } else if(!strcmp(type, "application/x-person")) { - /* Got a People contact info file, see if it has an Email address. */ - BString name; - BString email; - attr_info info; - char *attrib; - - if (file.GetAttrInfo("META:email", &info) == B_NO_ERROR) { - attrib = (char *) malloc(info.size + 1); - file.ReadAttr("META:email", B_STRING_TYPE, 0, attrib, info.size); - attrib[info.size] = 0; // Just in case it wasn't NUL terminated. - email << attrib; - free(attrib); - - /* we got something... */ - if (email.Length() > 0) { - /* see if we can get a username as well */ - if(file.GetAttrInfo("META:name", &info) == B_NO_ERROR) { - attrib = (char *) malloc(info.size + 1); - file.ReadAttr("META:name", B_STRING_TYPE, 0, attrib, info.size); - attrib[info.size] = 0; // Just in case it wasn't NUL terminated. - name << "\"" << attrib << "\" "; - email.Prepend("<"); - email.Append(">"); - free(attrib); - } - - if (names.Length() == 0) { - names << name << email; - } else { - names << ", " << name << email; - } - have_names = true; - email.SetTo(""); - name.SetTo(""); - } - } - } - else if (!strcmp(type, kDraftType)) - { - window = NewWindow(); - - // If it's a draft message, open it - window->OpenMessage(&ref); - window->Show(); - } - } /* end of else(file.InitCheck() == B_NO_ERROR */ - } - } - - if (have_names) { - window = NewWindow(NULL, names.String()); - window->Show(); - } -} - - -TMailWindow * -TMailApp::FindWindow(const entry_ref &ref) -{ - BEntry entry(&ref); - if (entry.InitCheck() < B_OK) - return NULL; - - node_ref nodeRef; - if (entry.GetNodeRef(&nodeRef) < B_OK) - return NULL; - - BWindow *window; - int32 index = 0; - while ((window = WindowAt(index++)) != NULL) { - TMailWindow *mailWindow = dynamic_cast(window); - if (mailWindow == NULL) - continue; - - node_ref mailNodeRef; - if (mailWindow->GetMailNodeRef(mailNodeRef) == B_OK - && mailNodeRef == nodeRef) - return mailWindow; - } - - return NULL; -} - - -void -TMailApp::CheckForSpamFilterExistence() -{ - // Looks at the filter settings to see if the user is using a spam filter. - // If there is one there, set gShowSpamGUI to TRUE, otherwise to FALSE. - - int32 addonNameIndex; - const char *addonNamePntr; - BDirectory inChainDir; - BPath path; - BEntry settingsEntry; - BFile settingsFile; - BMessage settingsMessage; - - gShowSpamGUI = false; - - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) - return; - path.Append("Mail/chains/inbound"); - if (inChainDir.SetTo(path.Path()) != B_OK) - return; - - while (inChainDir.GetNextEntry (&settingsEntry, true /* traverse */) == B_OK) { - if (!settingsEntry.IsFile()) - continue; - if (settingsFile.SetTo (&settingsEntry, B_READ_ONLY) != B_OK) - continue; - if (settingsMessage.Unflatten (&settingsFile) != B_OK) - continue; - for (addonNameIndex = 0; B_OK == settingsMessage.FindString ( - "filter_addons", addonNameIndex, &addonNamePntr); - addonNameIndex++) { - if (strstr (addonNamePntr, "Spam Filter") != NULL) { - gShowSpamGUI = true; // Found it! - return; - } - } - } -} - - -void -TMailApp::ClearPrintSettings() -{ - delete print_settings; - print_settings = NULL; -} - - -status_t -TMailApp::GetSettingsPath(BPath &path) -{ - status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); - if (status != B_OK) - return status; - - path.Append("Mail"); - return create_directory(path.Path(), 0755); -} - - -status_t -TMailApp::LoadOldSettings() -{ - BPath path; - status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); - if (status != B_OK) - return status; - - path.Append("Mail_data"); - - BFile file; - status = file.SetTo(path.Path(), B_READ_ONLY); - if (status != B_OK) - return status; - - file.Read(&mail_window, sizeof(BRect)); -// file.Read(&level, sizeof(level)); - - font_family fontFamily; - font_style fontStyle; - float size; - file.Read(&fontFamily, sizeof(font_family)); - file.Read(&fontStyle, sizeof(font_style)); - file.Read(&size, sizeof(float)); - if (size >= 9) - fFont.SetSize(size); - - if (fontFamily[0] && fontStyle[0]) - fFont.SetFamilyAndStyle(fontFamily, fontStyle); - - file.Read(&signature_window, sizeof(BRect)); - file.Read(&header_flag, sizeof(bool)); - file.Read(&sWrapMode, sizeof(bool)); - file.Read(&prefs_window, sizeof(BPoint)); - - int32 length; - if (file.Read(&length, sizeof(int32)) < (ssize_t)sizeof(int32)) - return B_IO_ERROR; - - free(signature); - signature = NULL; - - if (length > 0) { - signature = (char *)malloc(length); - if (signature == NULL) - return B_NO_MEMORY; - - file.Read(signature, length); - } - - file.Read(&gMailCharacterSet, sizeof(int32)); - if (gMailCharacterSet != B_MAIL_UTF8_CONVERSION - && gMailCharacterSet != B_MAIL_US_ASCII_CONVERSION - && BCharacterSetRoster::GetCharacterSetByConversionID(gMailCharacterSet) == NULL) - gMailCharacterSet = B_MS_WINDOWS_CONVERSION; - - if (file.Read(&length, sizeof(int32)) == (ssize_t)sizeof(int32)) { - char *findString = (char *)malloc(length + 1); - if (findString == NULL) - return B_NO_MEMORY; - - file.Read(findString, length); - findString[length] = '\0'; - FindWindow::SetFindString(findString); - free(findString); - } - if (file.Read(&sShowButtonBar, sizeof(uint8)) < (ssize_t)sizeof(uint8)) - sShowButtonBar = true; - if (file.Read(&gUseAccountFrom, sizeof(int32)) < (ssize_t)sizeof(int32) - || gUseAccountFrom < ACCOUNT_USE_DEFAULT - || gUseAccountFrom > ACCOUNT_FROM_MAIL) - gUseAccountFrom = ACCOUNT_USE_DEFAULT; - if (file.Read(&gColoredQuotes, sizeof(bool)) < (ssize_t)sizeof(bool)) - gColoredQuotes = true; - - if (file.Read(&length, sizeof(int32)) == (ssize_t)sizeof(int32)) { - free(gReplyPreamble); - gReplyPreamble = (char *)malloc(length + 1); - if (gReplyPreamble == NULL) - return B_NO_MEMORY; - - file.Read(gReplyPreamble, length); - gReplyPreamble[length] = '\0'; - } - - file.Read(&attachAttributes_mode, sizeof(bool)); - file.Read(&gWarnAboutUnencodableCharacters, sizeof(bool)); - - return B_OK; -} - - -status_t -TMailApp::SaveSettings() -{ - BMailSettings chainSettings; - - if (gDefaultChain != ~0UL) { - chainSettings.SetDefaultOutboundChainID(gDefaultChain); - chainSettings.Save(); - } - - BPath path; - status_t status = GetSettingsPath(path); - if (status != B_OK) - return status; - - path.Append("BeMail Settings~"); - - BFile file; - status = file.SetTo(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); - if (status != B_OK) - return status; - - BMessage settings('BeMl'); - settings.AddRect("MailWindowSize", mail_window); -// settings.AddInt32("ExperienceLevel", level); - - font_family fontFamily; - font_style fontStyle; - fFont.GetFamilyAndStyle(&fontFamily, &fontStyle); - - settings.AddString("FontFamily", fontFamily); - settings.AddString("FontStyle", fontStyle); - settings.AddFloat("FontSize", fFont.Size()); - - settings.AddRect("SignatureWindowSize", signature_window); - settings.AddBool("ShowHeadersMode", header_flag); - settings.AddBool("WordWrapMode", sWrapMode); - settings.AddPoint("PreferencesWindowLocation", prefs_window); - settings.AddString("SignatureText", signature); - settings.AddInt32("CharacterSet", gMailCharacterSet); - settings.AddString("FindString", FindWindow::GetFindString()); - settings.AddInt8("ShowButtonBar", sShowButtonBar); - settings.AddInt32("UseAccountFrom", gUseAccountFrom); - settings.AddBool("ColoredQuotes", gColoredQuotes); - settings.AddString("ReplyPreamble", gReplyPreamble); - settings.AddBool("AttachAttributes", attachAttributes_mode); - settings.AddBool("WarnAboutUnencodableCharacters", gWarnAboutUnencodableCharacters); - settings.AddBool("StartWithSpellCheck", gStartWithSpellCheckOn); - - BEntry entry; - status = entry.SetTo(path.Path()); - if (status != B_OK) - return status; - - status = settings.Flatten(&file); - if (status == B_OK) { - // replace original settings file - status = entry.Rename("BeMail Settings", true); - } else - entry.Remove(); - - return status; -} - - -status_t -TMailApp::LoadSettings() -{ - BMailSettings chainSettings; - gDefaultChain = chainSettings.DefaultOutboundChainID(); - - BPath path; - status_t status = GetSettingsPath(path); - if (status != B_OK) - return status; - - path.Append("BeMail Settings"); - - BFile file; - status = file.SetTo(path.Path(), B_READ_ONLY); - if (status != B_OK) - return LoadOldSettings(); - - BMessage settings; - status = settings.Unflatten(&file); - if (status < B_OK || settings.what != 'BeMl') { - // the current settings are corrupted, try old ones - return LoadOldSettings(); - } - - BRect rect; - if (settings.FindRect("MailWindowSize", &rect) == B_OK) - mail_window = rect; - - int32 int32Value; -// if (settings.FindInt32("ExperienceLevel", &int32Value) == B_OK) -// level = int32Value; - - const char *fontFamily; - if (settings.FindString("FontFamily", &fontFamily) == B_OK) { - const char *fontStyle; - if (settings.FindString("FontStyle", &fontStyle) == B_OK) { - float size; - if (settings.FindFloat("FontSize", &size) == B_OK) { - if (size >= 7) - fFont.SetSize(size); - - if (fontFamily[0] && fontStyle[0]) { - fFont.SetFamilyAndStyle(fontFamily[0] ? fontFamily : NULL, - fontStyle[0] ? fontStyle : NULL); - } - } - } - } - - if (settings.FindRect("SignatureWindowSize", &rect) == B_OK) - signature_window = rect; - - bool boolValue; - if (settings.FindBool("ShowHeadersMode", &boolValue) == B_OK) - header_flag = boolValue; - - if (settings.FindBool("WordWrapMode", &boolValue) == B_OK) - sWrapMode = boolValue; - - BPoint point; - if (settings.FindPoint("PreferencesWindowLocation", &point) == B_OK) - prefs_window = point; - - const char *string; - if (settings.FindString("SignatureText", &string) == B_OK) { - free(signature); - signature = strdup(string); - } - - if (settings.FindInt32("CharacterSet", &int32Value) == B_OK) - gMailCharacterSet = int32Value; - if (gMailCharacterSet != B_MAIL_UTF8_CONVERSION - && gMailCharacterSet != B_MAIL_US_ASCII_CONVERSION - && BCharacterSetRoster::GetCharacterSetByConversionID(gMailCharacterSet) == NULL) - gMailCharacterSet = B_MS_WINDOWS_CONVERSION; - - if (settings.FindString("FindString", &string) == B_OK) - FindWindow::SetFindString(string); - - int8 int8Value; - if (settings.FindInt8("ShowButtonBar", &int8Value) == B_OK) - sShowButtonBar = int8Value; - - if (settings.FindInt32("UseAccountFrom", &int32Value) == B_OK) - gUseAccountFrom = int32Value; - if (gUseAccountFrom < ACCOUNT_USE_DEFAULT - || gUseAccountFrom > ACCOUNT_FROM_MAIL) - gUseAccountFrom = ACCOUNT_USE_DEFAULT; - - if (settings.FindBool("ColoredQuotes", &boolValue) == B_OK) - gColoredQuotes = boolValue; - - if (settings.FindString("ReplyPreamble", &string) == B_OK) { - free(gReplyPreamble); - gReplyPreamble = strdup(string); - } - - if (settings.FindBool("AttachAttributes", &boolValue) == B_OK) - attachAttributes_mode = boolValue; - - if (settings.FindBool("WarnAboutUnencodableCharacters", &boolValue) == B_OK) - gWarnAboutUnencodableCharacters = boolValue; - - if (settings.FindBool("StartWithSpellCheck", &boolValue) == B_OK) - gStartWithSpellCheckOn = boolValue; - - return B_OK; -} - - -void -TMailApp::FontChange() -{ - int32 index = 0; - BMessage msg; - BWindow *window; - - msg.what = CHANGE_FONT; - msg.AddPointer("font", &fFont); - - for (;;) { - window = WindowAt(index++); - if (!window) - break; - - window->PostMessage(&msg); - } -} - - -TMailWindow * -TMailApp::NewWindow(const entry_ref *ref, const char *to, bool resend, - BMessenger *trackerMessenger) -{ - BScreen screen(B_MAIN_SCREEN_ID); - BRect screen_frame = screen.Frame(); - - BRect r; - if ((mail_window.Width() > 1) && (mail_window.Height() > 1)) - r = mail_window; - else - r.Set(6, TITLE_BAR_HEIGHT, 6 + WIND_WIDTH, TITLE_BAR_HEIGHT + WIND_HEIGHT); - - r.OffsetBy(fWindowCount * 20, fWindowCount * 20); - - if ((r.left - 6) < screen_frame.left) - r.OffsetTo(screen_frame.left + 8, r.top); - - if ((r.left + 20) > screen_frame.right) - r.OffsetTo(6, r.top); - - if ((r.top - 26) < screen_frame.top) - r.OffsetTo(r.left, screen_frame.top + 26); - - if ((r.top + 20) > screen_frame.bottom) - r.OffsetTo(r.left, TITLE_BAR_HEIGHT); - - if (r.Width() < WIND_WIDTH) - r.right = r.left + WIND_WIDTH; - - fWindowCount++; - - BString title; - BFile file; - if (!resend && ref && file.SetTo(ref, O_RDONLY) == B_NO_ERROR) { - BString name; - if (ReadAttrString(&file, B_MAIL_ATTR_NAME, &name) == B_NO_ERROR) { - title << name; - BString subject; - if (ReadAttrString(&file, B_MAIL_ATTR_SUBJECT, &subject) == B_NO_ERROR) - title << " -> " << subject; - } - } - if (title == "") - title = "Mail"; - - TMailWindow *window = new TMailWindow(r, title.String(), ref, to, &fFont, resend, - trackerMessenger); - fWindowList.AddItem(window); - - return window; -} - - -// #pragma mark - - - -TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, - const char *to, const BFont *font, bool resending, BMessenger *messenger) +TMailWindow::TMailWindow(BRect rect, const char* title, TMailApp* app, + const entry_ref* ref, const char* to, const BFont* font, bool resending, + BMessenger* messenger) : BWindow(rect, title, B_DOCUMENT_WINDOW, 0), + fApp(app), fFieldState(0), fPanel(NULL), fSendButton(NULL), @@ -1420,8 +321,7 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, item->SetTarget(NULL, this); menu->AddItem(new BMenuItem(MDR_DIALECT_CHOICE ("Find", "F) 検索") B_UTF8_ELLIPSIS, new BMessage(M_FIND), 'F')); menu->AddItem(new BMenuItem(MDR_DIALECT_CHOICE ("Find Again", "G) 次を検索"), new BMessage(M_FIND_AGAIN), 'G')); - if (!fIncoming) - { + if (!fIncoming) { menu->AddSeparatorItem(); menu->AddItem(fQuote =new BMenuItem( MDR_DIALECT_CHOICE ("Quote","Q) 引用符をつける"), @@ -1434,7 +334,7 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, MDR_DIALECT_CHOICE ("Check Spelling","H) スペルチェック"), new BMessage( M_CHECK_SPELLING ), ';' ); menu->AddItem(fSpelling); - if (gStartWithSpellCheckOn) + if (fApp->StartWithSpellCheckOn()) PostMessage (M_CHECK_SPELLING); } menu->AddSeparatorItem(); @@ -1449,7 +349,7 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, if (!resending && fIncoming) { menu = new BMenu("View"); menu->AddItem(fHeader = new BMenuItem(MDR_DIALECT_CHOICE ("Show Header","H) ヘッダーを表示"), new BMessage(M_HEADER), 'H')); - if (header_flag) + if (fApp->ShowHeader()) fHeader->SetMarked(true); menu->AddItem(fRaw = new BMenuItem(MDR_DIALECT_CHOICE ("Show Raw Message"," メッセージを生で表示"), new BMessage(M_RAW))); menu_bar->AddItem(menu); @@ -1525,7 +425,7 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, // Spam Menu - if (gShowSpamGUI) { + if (fApp->ShowSpamGUI()) { menu = new BMenu("Spam Filtering"); menu->AddItem(new BMenuItem("Mark as Spam and Move to Trash", new BMessage(M_TRAIN_SPAM_AND_DELETE), 'K')); @@ -1561,19 +461,19 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, menu_bar->AddItem(menu); } - Lock(); AddChild(menu_bar); height = menu_bar->Bounds().bottom + 1; - Unlock(); // // Button Bar // float bbwidth = 0, bbheight = 0; - if (sShowButtonBar) { + bool showButtonBar = fApp->ShowButtonBar(); + + if (showButtonBar) { BuildButtonBar(); - fButtonBar->ShowLabels(sShowButtonBar == 1); + fButtonBar->ShowLabels(showButtonBar); fButtonBar->Arrange(/* True for all buttons same size, false to just fit */ MDR_DIALECT_CHOICE (true, true)); fButtonBar->GetPreferredSize(&bbwidth, &bbheight); @@ -1586,26 +486,24 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, r.top = r.bottom = height + bbheight + 1; fHeaderView = new THeaderView (r, rect, fIncoming, fMail, resending, (resending || !fIncoming) - ? gMailCharacterSet // Use preferences setting for composing mail. - : B_MAIL_NULL_CONVERSION); // Default is automatic selection for reading mail. + ? fApp->MailCharacterSet() // Use preferences setting for composing mail. + : B_MAIL_NULL_CONVERSION, // Default is automatic selection for reading mail. + fApp->DefaultChain()); r = Frame(); r.OffsetTo(0, 0); r.top = fHeaderView->Frame().bottom - 1; - fContentView = new TContentView(r, fIncoming, fMail, const_cast(font)); + fContentView = new TContentView(r, fIncoming, fMail, + const_cast(font), fApp->ShowHeader(), fApp->ColoredQuotes()); // TContentView needs to be properly const, for now cast away constness - Lock(); AddChild(fHeaderView); if (fEnclosuresView) AddChild(fEnclosuresView); AddChild(fContentView); - Unlock(); if (to) { - Lock(); fHeaderView->fTo->SetText(to); - Unlock(); } SetSizeLimits(WIND_WIDTH, RIGHT_BOUNDARY, @@ -1618,8 +516,10 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, // If auto-signature, add signature to the text here. // - if (!fIncoming && strcmp(signature, SIG_NONE) != 0) { - if (strcmp(signature, SIG_RANDOM) == 0) + BString signature = fApp->Signature(); + + if (!fIncoming && strcmp(signature.String(), SIG_NONE) != 0) { + if (strcmp(signature.String(), SIG_RANDOM) == 0) PostMessage(M_RANDOM_SIG); else { // @@ -1631,7 +531,7 @@ TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref, BQuery query; query.SetVolume(&volume); query.PushAttr(INDEX_SIGNATURE); - query.PushString(signature); + query.PushString(signature.String()); query.PushOp(B_EQ); query.Fetch(); @@ -1704,7 +604,7 @@ TMailWindow::BuildButtonBar() button->InvokeOnButton(B_SECONDARY_MOUSE_BUTTON); fPrintButton = bbar->AddButton(MDR_DIALECT_CHOICE ("Print","印刷"), 16, new BMessage(M_PRINT)); bbar->AddButton(MDR_DIALECT_CHOICE ("Trash","削除"), 0, new BMessage(M_DELETE_NEXT)); - if (gShowSpamGUI) { + if (fApp->ShowSpamGUI()) { button = bbar->AddButton("Spam", 48, new BMessage(M_SPAM_BUTTON)); button->InvokeOnButton(B_SECONDARY_MOUSE_BUTTON); } @@ -1729,12 +629,14 @@ TMailWindow::UpdateViews() float bbwidth = 0, bbheight = 0; float nextY = fMenuBar->Frame().bottom+1; + bool showButtonBar = fApp->ShowButtonBar(); + // Show/Hide Button Bar - if (sShowButtonBar) { + if (showButtonBar) { // Create the Button Bar if needed if (!fButtonBar) BuildButtonBar(); - fButtonBar->ShowLabels(sShowButtonBar == 1); + fButtonBar->ShowLabels(showButtonBar); fButtonBar->Arrange(/* True for all buttons same size, false to just fit */ MDR_DIALECT_CHOICE (true, true)); fButtonBar->GetPreferredSize( &bbwidth, &bbheight); @@ -1763,8 +665,9 @@ TMailWindow::UpdateViews() TMailWindow::~TMailWindow() { + fApp->SetLastWindowFrame(Frame()); + delete fMail; - last_window = Frame(); delete fPanel; delete fOriginatingWindow; @@ -2287,11 +1190,12 @@ TMailWindow::MessageReceived(BMessage *msg) } case M_HEADER: { - header_flag = !fHeader->IsMarked(); - fHeader->SetMarked(header_flag); + bool showHeader = !fHeader->IsMarked(); + fApp->SetShowHeader(showHeader); + fHeader->SetMarked(showHeader); BMessage message(M_HEADER); - message.AddBool("header", header_flag); + message.AddBool("header", showHeader); PostMessage(&message, fContentView->fTextView); break; } @@ -2454,11 +1358,10 @@ TMailWindow::MessageReceived(BMessage *msg) } case M_ADD: - if (!fPanel) - { + if (!fPanel) { BMessenger me(this); BMessage msg(REFS_RECEIVED); - fPanel = new BFilePanel(B_OPEN_PANEL, &me, &open_dir, false, true, &msg); + fPanel = new BFilePanel(B_OPEN_PANEL, &me, &fOpenFolder, false, true, &msg); } else if (!fPanel->Window()->IsHidden()) fPanel->Window()->Activate(); @@ -2616,8 +1519,7 @@ TMailWindow::AddEnclosure(BMessage *msg) if (fEnclosuresView == NULL) return; - if (msg && msg->HasRef("refs")) - { + if (msg && msg->HasRef("refs")) { // Add enclosure to view PostMessage(msg, fEnclosuresView); @@ -2627,7 +1529,7 @@ TMailWindow::AddEnclosure(BMessage *msg) msg->FindRef("refs", &ref); entry.SetTo(&ref); entry.GetParent(&entry); - entry.GetRef(&open_dir); + entry.GetRef(&fOpenFolder); } } @@ -2747,7 +1649,7 @@ TMailWindow::Zoom(BPoint /*pos*/, float /*x*/, float /*y*/) BRect s_frame = screen.Frame(); r = Frame(); - width = 80 * ((TMailApp*)be_app)->fFont.StringWidth("M") + + width = 80 * fApp->ContentFont().StringWidth("M") + (r.Width() - fContentView->fTextView->Bounds().Width() + 6); if (width > (s_frame.Width() - 8)) width = s_frame.Width() - 8; @@ -2819,7 +1721,10 @@ TMailWindow::Forward(entry_ref *ref, TMailWindow *window, bool includeAttachment if (mail == NULL) return; - fMail = mail->ForwardMessage(gUseAccountFrom == ACCOUNT_FROM_MAIL, includeAttachments); + uint32 useAccountFrom = fApp->UseAccountFrom(); + + fMail = mail->ForwardMessage(useAccountFrom == ACCOUNT_FROM_MAIL, + includeAttachments); BFile file(ref, O_RDONLY); if (file.InitCheck() < B_NO_ERROR) @@ -2829,7 +1734,7 @@ TMailWindow::Forward(entry_ref *ref, TMailWindow *window, bool includeAttachment // set mail account - if (gUseAccountFrom == ACCOUNT_FROM_MAIL) { + if (useAccountFrom == ACCOUNT_FROM_MAIL) { fHeaderView->fChain = fMail->Account(); BMenu *menu = fHeaderView->fAccountMenu; @@ -2871,21 +1776,19 @@ TMailWindow::Print() { BPrintJob print(Title()); - if (!print_settings) - { + if (!fApp->HasPrintSettings()) { if (print.Settings()) { - print_settings = print.Settings(); + fApp->SetPrintSettings(print.Settings()); } else { PrintSetup(); - if (!print_settings) + if (!fApp->HasPrintSettings()) return; } } - print.SetSettings(new BMessage(*print_settings)); + print.SetSettings(new BMessage(fApp->PrintSettings())); - if (print.ConfigJob() == B_NO_ERROR) - { + if (print.ConfigJob() == B_NO_ERROR) { int32 curPage = 1; int32 lastLine = 0; BTextView header_view(print.PrintableRect(),"header",print.PrintableRect().OffsetByCopy(BPoint(-print.PrintableRect().left,-print.PrintableRect().top)),B_FOLLOW_ALL_SIDES); @@ -2956,17 +1859,15 @@ TMailWindow::Print() void TMailWindow::PrintSetup() { - BPrintJob print("mail_print"); - status_t result; + BPrintJob printJob("mail_print"); - if (print_settings) - print.SetSettings(new BMessage(*print_settings)); - - if ((result = print.ConfigPage()) == B_NO_ERROR) - { - delete print_settings; - print_settings = print.Settings(); + if (fApp->HasPrintSettings()) { + BMessage printSettings = fApp->PrintSettings(); + printJob.SetSettings(new BMessage(printSettings)); } + + if (printJob.ConfigPage() == B_OK) + fApp->SetPrintSettings(printJob.Settings()); } @@ -3042,8 +1943,10 @@ TMailWindow::Reply(entry_ref *ref, TMailWindow *window, uint32 type) else type = B_MAIL_REPLY_TO; + uint32 useAccountFrom = fApp->UseAccountFrom(); + fMail = mail->ReplyMessage(mail_reply_to_mode(type), - gUseAccountFrom == ACCOUNT_FROM_MAIL, QUOTE); + useAccountFrom == ACCOUNT_FROM_MAIL, QUOTE); // set header fields fHeaderView->fTo->SetText(fMail->To()); @@ -3057,8 +1960,8 @@ TMailWindow::Reply(entry_ref *ref, TMailWindow *window, uint32 type) // set mail account - if ((gUseAccountFrom == ACCOUNT_FROM_MAIL) || (chainID > -1)) { - if (gUseAccountFrom == ACCOUNT_FROM_MAIL) + if ((useAccountFrom == ACCOUNT_FROM_MAIL) || (chainID > -1)) { + if (useAccountFrom == ACCOUNT_FROM_MAIL) fHeaderView->fChain = fMail->Account(); else fHeaderView->fChain = chainID; @@ -3075,7 +1978,12 @@ TMailWindow::Reply(entry_ref *ref, TMailWindow *window, uint32 type) // create preamble string - char preamble[1024], *from = gReplyPreamble, *to = preamble; + BString replyPreamble = fApp->ReplyPreamble(); + + char preamble[1024]; + const char* from = replyPreamble.String(); + char* to = preamble; + while (*from) { if (*from == '%') { // insert special content @@ -3167,7 +2075,7 @@ TMailWindow::Reply(entry_ref *ref, TMailWindow *window, uint32 type) fContentView->fTextView->Insert((const char *)QUOTE); } - if (gColoredQuotes) { + if (fApp->ColoredQuotes()) { const BFont *font = fContentView->fTextView->Font(); int32 length = fContentView->fTextView->TextLength(); @@ -3193,7 +2101,7 @@ TMailWindow::Reply(entry_ref *ref, TMailWindow *window, uint32 type) status_t TMailWindow::Send(bool now) { - uint32 characterSetToUse = gMailCharacterSet; + uint32 characterSetToUse = fApp->MailCharacterSet(); mail_encoding encodingForBody = quoted_printable; mail_encoding encodingForHeaders = quoted_printable; @@ -3270,7 +2178,7 @@ TMailWindow::Send(bool now) tempString.UnlockBuffer (tempStringLength); // Count up the number of unencoded characters and warn the user about them. - if (gWarnAboutUnencodableCharacters) { + if (fApp->WarnAboutUnencodableCharacters()) { int32 offset = 0; int count = 0; while (offset >= 0) { @@ -3368,8 +2276,8 @@ TMailWindow::Send(bool now) // the content text is always added to make sure there is a mail body fMail->SetBodyTextTo(""); - fContentView->fTextView->AddAsContent(fMail, sWrapMode, characterSetToUse, - encodingForBody); + fContentView->fTextView->AddAsContent(fMail, fApp->WrapMode(), + characterSetToUse, encodingForBody); if (fEnclosuresView != NULL) { TListItem *item; @@ -3383,7 +2291,7 @@ TMailWindow::Send(bool now) if (!entry.Exists()) continue; - fMail->Attach(item->Ref(), attachAttributes_mode); + fMail->Attach(item->Ref(), fApp->AttachAttributes()); } } if (fHeaderView->fChain != ~0L) @@ -3608,7 +2516,7 @@ TMailWindow::TrainMessageAs(const char *CommandWord) // Get a connection to the spam database server. Launch if needed. - if (!gMessengerToSpamServer.IsValid()) { + if (!fMessengerToSpamServer.IsValid()) { // Make sure the server is running. if (!be_roster->IsRunning (kSpamServerSignature)) { errorCode = be_roster->Launch (kSpamServerSignature); @@ -3636,8 +2544,8 @@ TMailWindow::TrainMessageAs(const char *CommandWord) if (serverTeam < 0) goto ErrorExit; - gMessengerToSpamServer = BMessenger (kSpamServerSignature, serverTeam, &errorCode); - if (!gMessengerToSpamServer.IsValid()) + fMessengerToSpamServer = BMessenger (kSpamServerSignature, serverTeam, &errorCode); + if (!fMessengerToSpamServer.IsValid()) goto ErrorExit; } @@ -3652,7 +2560,7 @@ TMailWindow::TrainMessageAs(const char *CommandWord) if (errorCode != B_OK) goto ErrorExit; replyMessage.MakeEmpty(); - errorCode = gMessengerToSpamServer.SendMessage(&scriptingMessage, + errorCode = fMessengerToSpamServer.SendMessage(&scriptingMessage, &replyMessage); if (errorCode != B_OK || replyMessage.FindInt32("error", &errorCode) != B_OK @@ -3687,7 +2595,7 @@ TMailWindow::SetTitleForMessage() else title = fMail->Subject(); - if (gShowSpamGUI && fRef != NULL) { + if (fApp->ShowSpamGUI() && fRef != NULL) { BString classification; BNode node (fRef); char numberString [30]; @@ -3880,60 +2788,3 @@ TMailWindow::FrontmostWindow() } -//==================================================================== -// #pragma mark - - - -TMenu::TMenu(const char *name, const char *attribute, int32 message, bool popup, - bool addRandom) - : BPopUpMenu(name, false, false), - fPopup(popup), - fAddRandom(addRandom), - fMessage(message) -{ - fAttribute = strdup(attribute); - BuildMenu(); -} - - -TMenu::~TMenu() -{ - free(fAttribute); -} - - -void -TMenu::AttachedToWindow() -{ - BuildMenu(); - BPopUpMenu::AttachedToWindow(); -} - - -BPoint -TMenu::ScreenLocation(void) -{ - if (fPopup) - return BPopUpMenu::ScreenLocation(); - - return BMenu::ScreenLocation(); -} - - -void -TMenu::BuildMenu() -{ - RemoveItems(0, CountItems(), true); - add_query_menu_items(this, fAttribute, fMessage, NULL, fPopup); - - if (fAddRandom && CountItems() > 0) { - AddItem(new BSeparatorItem(), 0); - - BMessage *msg = new BMessage(M_RANDOM_SIG); - if (!fPopup) - AddItem(new BMenuItem(MDR_DIALECT_CHOICE ("Random","R) 自動決定"), msg, '0'), 0); - else - AddItem(new BMenuItem(MDR_DIALECT_CHOICE ("Random","R) 自動決定"), msg), 0); - } -} - diff --git a/src/apps/mail/MailWindow.h b/src/apps/mail/MailWindow.h new file mode 100644 index 0000000000..66fb89d5a5 --- /dev/null +++ b/src/apps/mail/MailWindow.h @@ -0,0 +1,188 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ +#ifndef _MAIL_WINDOW_H +#define _MAIL_WINDOW_H + + +#include +#include +#include +#include +#include +#include + +#include + + +class TContentView; +class TEnclosuresView; +class THeaderView; +class TMailApp; +class TMenu; +class TPrefsWindow; +class TSignatureWindow; + +class BEmailMessage; +class BFile; +class BFilePanel; +class BMailMessage; +class BMenuBar; +class BMenuItem; +class BmapButton; +class ButtonBar; +class Words; + +class TMailWindow : public BWindow { + public: + TMailWindow(BRect frame, const char* title, + TMailApp* app, const entry_ref* ref, + const char* to, const BFont *font, + bool resending, + BMessenger* trackerMessenger); + virtual ~TMailWindow(); + + virtual void FrameResized(float width, float height); + virtual void MenusBeginning(); + virtual void MessageReceived(BMessage*); + virtual bool QuitRequested(); + virtual void Show(); + virtual void Zoom(BPoint, float, float); + virtual void WindowActivated(bool state); + + void SetTo(const char* mailTo, const char* subject, + const char* ccTo = NULL, + const char* bccTo = NULL, + const BString* body = NULL, + BMessage* enclosures = NULL); + void AddSignature(BMailMessage*); + void Forward(entry_ref*, TMailWindow*, + bool includeAttachments); + void Print(); + void PrintSetup(); + void Reply(entry_ref*, TMailWindow*, uint32); + void CopyMessage(entry_ref* ref, TMailWindow* src); + status_t Send(bool); + status_t SaveAsDraft(); + status_t OpenMessage(entry_ref* ref, + uint32 characterSetForDecoding + = B_MAIL_NULL_CONVERSION); + + status_t GetMailNodeRef(node_ref &nodeRef) const; + BEmailMessage* Mail() const { return fMail; } + + bool GetTrackerWindowFile(entry_ref*, + bool dir) const; + void SaveTrackerPosition(entry_ref*); + void SetOriginatingWindow(BWindow* window); + + void SetCurrentMessageRead(); + void SetTrackerSelectionToCurrent(); + TMailWindow* FrontmostWindow(); + void UpdateViews(); + + protected: + void SetTitleForMessage(); + void AddEnclosure(BMessage* msg); + void BuildButtonBar(); + status_t TrainMessageAs(const char* commandWord); + + private: + TMailApp* fApp; + + BEmailMessage* fMail; + entry_ref* fRef; + // Reference to currently displayed file + int32 fFieldState; + BFilePanel* fPanel; + BMenuBar* fMenuBar; + BMenuItem* fAdd; + BMenuItem* fCut; + BMenuItem* fCopy; + BMenuItem* fHeader; + BMenuItem* fPaste; + BMenuItem* fPrint; + BMenuItem* fPrintSetup; + BMenuItem* fQuote; + BMenuItem* fRaw; + BMenuItem* fRemove; + BMenuItem* fRemoveQuote; + BMenuItem* fSendNow; + BMenuItem* fSendLater; + BMenuItem* fUndo; + BMenuItem* fRedo; + BMenuItem* fNextMsg; + BMenuItem* fPrevMsg; + BMenuItem* fDeleteNext; + BMenuItem* fSpelling; + BMenu* fSaveAddrMenu; + + ButtonBar* fButtonBar; + BmapButton* fSendButton; + BmapButton* fSaveButton; + BmapButton* fPrintButton; + BmapButton* fSigButton; + + BRect fZoom; + TContentView* fContentView; + THeaderView* fHeaderView; + TEnclosuresView* fEnclosuresView; + TMenu* fSignature; + BMessenger fTrackerMessenger; + // Talks to tracker window that this was launched from. + BMessenger fMessengerToSpamServer; + + entry_ref fPrevRef; + entry_ref fNextRef; + bool fPrevTrackerPositionSaved : 1; + bool fNextTrackerPositionSaved : 1; + + entry_ref fOpenFolder; + + bool fSigAdded : 1; + bool fIncoming : 1; + bool fReplying : 1; + bool fResending : 1; + bool fSent : 1; + bool fDraft : 1; + bool fChanged : 1; + + static BList sWindowList; + static BLocker sWindowListLock; + + char* fStartingText; + entry_ref fRepliedMail; + BMessenger* fOriginatingWindow; +}; + +#endif // _MAIL_WINDOW_H diff --git a/src/apps/mail/Messages.h b/src/apps/mail/Messages.h new file mode 100644 index 0000000000..498332de12 --- /dev/null +++ b/src/apps/mail/Messages.h @@ -0,0 +1,120 @@ +/* +Open Tracker License + +Terms and Conditions + +Copyright (c) 1991-2001, Be Incorporated. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice applies to all licensees +and shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Be Incorporated shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from Be Incorporated. + +BeMail(TM), Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks +of Be Incorporated in the United States and other countries. Other brand product +names are registered trademarks or trademarks of their respective holders. +All rights reserved. +*/ +#ifndef _MESSAGES_H +#define _MESSAGES_H + +enum MESSAGES { + REFS_RECEIVED = 64, + LIST_INVOKED, + WINDOW_CLOSED, + CHANGE_FONT, + RESET_BUTTONS, + PREFS_CHANGED, + CHARSET_CHOICE_MADE +}; + +enum TEXT { + SUBJECT_FIELD = REFS_RECEIVED + 64, + TO_FIELD, + ENCLOSE_FIELD, + CC_FIELD, + BCC_FIELD, + NAME_FIELD +}; + +enum MENUS { + /* app */ + M_NEW = SUBJECT_FIELD + 64, + M_PREFS, + M_EDIT_SIGNATURE, + M_FONT, + M_STYLE, + M_SIZE, + M_BEGINNER, + M_EXPERT, + /* file */ + M_REPLY, + M_REPLY_TO_SENDER, + M_REPLY_ALL, + M_FORWARD, + M_FORWARD_WITHOUT_ATTACHMENTS, + M_RESEND, + M_COPY_TO_NEW, + M_HEADER, + M_RAW, + M_SEND_NOW, + M_SAVE_AS_DRAFT, + M_SAVE, + M_PRINT_SETUP, + M_PRINT, + M_DELETE, + M_DELETE_PREV, + M_DELETE_NEXT, + M_CLOSE_READ, + M_CLOSE_SAVED, + M_CLOSE_SAME, + M_CLOSE_CUSTOM, + M_STATUS, + M_OPEN_MAIL_BOX, + M_OPEN_MAIL_FOLDER, + /* edit */ + M_SELECT, + M_QUOTE, + M_REMOVE_QUOTE, + M_CHECK_SPELLING, + M_SIGNATURE, + M_RANDOM_SIG, + M_SIG_MENU, + M_FIND, + M_FIND_AGAIN, + /* encls */ + M_ADD, + M_REMOVE, + M_OPEN, + M_COPY, + /* nav */ + M_NEXTMSG, + M_PREVMSG, + M_SAVE_POSITION, + /* Spam GUI button and menu items. Order is important. */ + M_SPAM_BUTTON, + M_TRAIN_SPAM_AND_DELETE, + M_TRAIN_SPAM, + M_UNTRAIN, + M_TRAIN_GENUINE, + + M_REDO +}; + +#endif // _MESSAGES_H diff --git a/src/apps/mail/Prefs.cpp b/src/apps/mail/Prefs.cpp index 6c118e91e6..51629f7279 100644 --- a/src/apps/mail/Prefs.cpp +++ b/src/apps/mail/Prefs.cpp @@ -32,11 +32,8 @@ names are registered trademarks or trademarks of their respective holders. All rights reserved. */ -//-------------------------------------------------------------------- -// -// Prefs.cpp -// -//-------------------------------------------------------------------- + +#include "Prefs.h" #include #include @@ -56,8 +53,10 @@ All rights reserved. using namespace BPrivate; -#include "Mail.h" -#include "Prefs.h" +#include "MailApp.h" +#include "MailSupport.h" +#include "MailWindow.h" +#include "Messages.h" #define BUTTON_WIDTH 70 #define BUTTON_HEIGHT 20 @@ -304,10 +303,9 @@ TPrefsWindow::TPrefsWindow(BRect rect, BFont *font, int32 *level, bool *wrap, TPrefsWindow::~TPrefsWindow() { - prefs_window = Frame().LeftTop(); - BMessage msg(WINDOW_CLOSED); msg.AddInt32("kind", PREFS_WINDOW); + msg.AddPoint("window pos", Frame().LeftTop()); be_app->PostMessage(&msg); } diff --git a/src/apps/mail/Signature.cpp b/src/apps/mail/Signature.cpp index e3fc859003..c88aac92d8 100644 --- a/src/apps/mail/Signature.cpp +++ b/src/apps/mail/Signature.cpp @@ -31,25 +31,25 @@ of Be Incorporated in the United States and other countries. Other brand product names are registered trademarks or trademarks of their respective holders. All rights reserved. */ - -//-------------------------------------------------------------------- -// -// Signature.cpp -// -//-------------------------------------------------------------------- +#include "Signature.h" #include #include #include + #include #include #include -#include "Mail.h" -#include "Signature.h" +#include "MailApp.h" +#include "MailPopUpMenu.h" +#include "MailSupport.h" +#include "MailWindow.h" +#include "Messages.h" #include + extern BRect signature_window; extern const char *kUndoStrings[]; extern const char *kRedoStrings[]; @@ -114,7 +114,6 @@ TSignatureWindow::TSignatureWindow(BRect rect) TSignatureWindow::~TSignatureWindow() { - signature_window = Frame(); } @@ -245,6 +244,7 @@ TSignatureWindow::QuitRequested() if (Clear()) { BMessage msg(WINDOW_CLOSED); msg.AddInt32("kind", SIG_WINDOW); + msg.AddRect("window frame", Frame()); be_app->PostMessage(&msg); return true; diff --git a/src/apps/mail/Status.cpp b/src/apps/mail/Status.cpp index 4f40e67cb2..34f65d79f0 100644 --- a/src/apps/mail/Status.cpp +++ b/src/apps/mail/Status.cpp @@ -31,9 +31,6 @@ of Be Incorporated in the United States and other countries. Other brand product names are registered trademarks or trademarks of their respective holders. All rights reserved. */ - - -#include "Mail.h" #include "Status.h" #include @@ -52,6 +49,10 @@ All rights reserved. #include #include +#include "MailApp.h" +#include "MailWindow.h" +#include "Messages.h" + #define STATUS_TEXT "Status:" #define STATUS_FIELD_H 10