root/MainFrm.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- CMainFrame
- CMainFrame
- OnCreate
- PreCreateWindow
- AssertValid
- Dump
- OnCreateClient
- OnProgCreate
- SetStatusBarText
- OnFetchmail
- OnUpdateFetchmail
- OnUpdateRetrieve
- OnTransfer
- OnSize
- OnUpdateReply
- OnGpgDec
- OnUpdateGpgDec
- OnUpdateGpg
- OnRetrieve
- OnDestroy
- OnSetting
- OnReply
- OnDraft
- OnAddress
- OnUpdateTransfer
- OnInfo
- Char
- SwitchView
- OnUpdateInfo
- OnUpdateSetting
- CreateToolbar
- OnToolbarDropDown
- OnReplyQuotation
- OnReplyNoQuotation
- OnGpg
- ReArrangeSplit
- HideMultiPartView
- OnTimer
- UpdateButton
- SetStatusBarProgress
- GetStatusBarText
- GetStatusBarProgress
- OnSettingGeneral
- OnSettingAccount
- OnDisplayHeader
- OnDisplayRawMail
- OnSettingFilter
- OnSettingNewAccount
- OnTransferQuotation
- OnGpgKeyManagement
- OnClose
- OnCopyData
- OnChar
/*
* Copyright (C) 2002-2003 chik, s.hiranaka
* For license terms, see the file COPYING in this directory.
*/
// MainFrm.cpp : CMainFrame クラスの動作の定義を行います。
#include "stdafx.h"
#include "Pochy.h"
#include "MainFrm.h"
#include "FolderView.h"
#include "AccountView.h"
#include "TextView.h"
#include "Sock.h"
#include "CodeConvert.h"
#include "FetchMail.h"
#include "Retrieve.h"
#include "SettingAccountDlg.h"
#include "lib.h"
#include "MimeEncode.h"
//#include "_regex.h"
#include "Gpg.h"
#include "PassPhraseDlg.h"
#include "direct.h" // _mkdir
#include "GpgDlg.h"
#include "MainAddressBookDlg.h"
#include "SettingGeneralDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_FETCH_MAIL, OnFetchmail)
ON_UPDATE_COMMAND_UI(ID_FETCH_MAIL, OnUpdateFetchmail)
ON_UPDATE_COMMAND_UI(ID_RETRIEVE, OnUpdateRetrieve)
ON_COMMAND(ID_TRANSFER, OnTransfer)
ON_WM_SIZE()
ON_UPDATE_COMMAND_UI(ID_REPLY, OnUpdateReply)
ON_COMMAND(ID_GPG_DEC, OnGpgDec)
ON_COMMAND(ID_GPG, OnGpg)
ON_UPDATE_COMMAND_UI(ID_GPG_DEC, OnUpdateGpgDec)
ON_UPDATE_COMMAND_UI(ID_GPG, OnUpdateGpg)
ON_COMMAND(ID_RETRIEVE, OnRetrieve)
ON_WM_DESTROY()
ON_COMMAND(ID_SETTING, OnSetting)
ON_COMMAND(ID_REPLY, OnReply)
ON_COMMAND(ID_DRAFT, OnDraft)
ON_COMMAND(ID_ADDRESS, OnAddress)
ON_UPDATE_COMMAND_UI(ID_TRANSFER, OnUpdateTransfer)
ON_COMMAND(ID_INFO, OnInfo)
ON_UPDATE_COMMAND_UI(ID_INFO, OnUpdateInfo)
ON_UPDATE_COMMAND_UI(ID_SETTING, OnUpdateSetting)
ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)
ON_COMMAND(ID_REPLY_QUOTATION, OnReplyQuotation)
ON_COMMAND(ID_REPLY_NO_QUOTATION, OnReplyNoQuotation)
ON_WM_TIMER()
ON_COMMAND(ID_SETTING_GENERAL, OnSettingGeneral)
ON_COMMAND(ID_SETTING_ACCOUNT, OnSettingAccount)
ON_COMMAND(ID_DISPLAY_HEADER, OnDisplayHeader)
ON_COMMAND(ID_DISPLAY_RAW_MAIL, OnDisplayRawMail)
ON_COMMAND(ID_SETTING_FILTER, OnSettingFilter)
ON_COMMAND(ID_SETTING_NEW_ACCOUNT, OnSettingNewAccount)
ON_COMMAND(ID_TRANSFER_QUOTATION, OnTransferQuotation)
ON_COMMAND(ID_GPG_MAIN_KEY_MANAGEMENT, OnGpgKeyManagement)
ON_WM_CLOSE()
ON_WM_COPYDATA()
ON_WM_CHAR()
//}}AFX_MSG_MAP
ON_COMMAND(WM_PROGCREATE, OnProgCreate)
END_MESSAGE_MAP()
static UINT indicators[] = { ID_INDICATOR_TEXT, ID_INDICATOR_PROGRESS, ID_INDICATOR_FOLDER, };
/*
{
ID_SEPARATOR, // ステータス ライン インジケータ
ID_INDICATOR_KANA,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};*/
/////////////////////////////////////////////////////////////////////////////
// CMainFrame クラスの構築/消滅
CMainFrame::CMainFrame()
{
m_flag = FALSE;
m_multipart_hide = FALSE;
m_button_reply = FALSE;
m_button_transfer = FALSE;
m_button_gpg_dec = FALSE;
m_button_info = FALSE;
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1; // 作成に失敗
/* if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){
TRACE0("Failed to create toolbar\n");
return -1; // 作成に失敗
}*/
// toolbarの作成
if(!CreateToolbar())
return -1;
// statusbarの作成
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT))){
TRACE0("Failed to create status bar\n");
return -1; // 作成に失敗
}
if (m_wndStatusBar.GetSafeHwnd()){
m_wndStatusBar.SetPaneInfo(0, ID_INDICATOR_TEXT, SBPS_STRETCH /*| SBPS_POPOUT | SBPS_NOBORDERS*/, NULL);
m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_PROGRESS, NULL, 200);
m_wndStatusBar.SetPaneInfo(2, ID_INDICATOR_FOLDER, NULL, 150);
}
// iniファイルから前回のウィンドウ位置を取得
CPochyApp *app = (CPochyApp *)AfxGetApp();
CRect rcWnd;
// 前回のウィンドウ位置を復元する
rcWnd.left = app->GetProfileInt("wndPlace", "Left", 0);
rcWnd.top = app->GetProfileInt("wndPlace", "Top", 0);
rcWnd.right = app->GetProfileInt("wndPlace", "Right", 700);
rcWnd.bottom = app->GetProfileInt("wndPlace", "Bottom", 520);
MoveWindow(rcWnd);
// resurrect status of bar
this->m_wndToolBar.ShowWindow(app->GetProfileInt("ToolBar", "IsVisible", SW_SHOW));
this->m_wndStatusBar.ShowWindow(app->GetProfileInt("StatusBar", "IsVisible", SW_SHOW));
// 自動受信を呼び出す(ontimerが実行される)
int minute = app->GetProfileInt("AutoFetch", "minute", 0);
if(minute >= 1){
SetTimer(1, minute*60000, NULL);
}
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// ウィンドウクラス名を登録
// ウィンドウが見つけやすくなるかも?^^;
if (cs.lpszName){
WNDCLASS wc;
::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc);
// _T()で囲っていないとdebugモードで失敗する(?)
wc.lpszClassName = _T("_PochyClass"); // 好きな名前を設定
AfxRegisterClass(&wc);
cs.lpszClass = wc.lpszClassName;
}
if(!CFrameWnd::PreCreateWindow(cs))
return FALSE;
// TODO: この位置で CREATESTRUCT cs を修正して、Window クラスやスタイルを修正してください。
cs.style ^= FWS_ADDTOTITLE;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame クラスの診断
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame メッセージ ハンドラ
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
int x, y;
lpcs->cx;
lpcs->cy;
// 分割ウィンドウを作成します
m_wndSplitV.CreateStatic(this,1,2);
m_wndSplitH.CreateStatic(&m_wndSplitV,2,1,WS_CHILD|WS_VISIBLE,m_wndSplitV.IdFromRowCol(0,1));
m_wndSplitT.CreateStatic(&m_wndSplitH,2,1,WS_CHILD|WS_VISIBLE,m_wndSplitH.IdFromRowCol(0,0));
m_wndSplitT2.CreateStatic(&m_wndSplitV,2,1,WS_CHILD|WS_VISIBLE,m_wndSplitV.IdFromRowCol(0,0));
m_wndSplitT2.CreateView(0,0,RUNTIME_CLASS(CAccountView),CSize(0, 0),pContext);
m_wndSplitT2.CreateView(1,0,RUNTIME_CLASS(CFolderView),CSize(0, 0),pContext);
m_wndSplitT2.NoBorder();
m_wndSplitT2.SetStaticBorder(TRUE);
m_wndSplitH.CreateView(1,0,RUNTIME_CLASS(CMultiPartView),CSize(0, 0),pContext);
m_wndSplitT.CreateView(0,0,RUNTIME_CLASS(CSummaryView),CSize(0, 0),pContext);
m_wndSplitT.CreateView(1,0,RUNTIME_CLASS(CTextView),CSize(0, 0),pContext);
/* それぞれのVIEWへのポインタを保存しておく
後でVIEW同士での参照が必要になった場合は
GetParentFrameでCMainFrameのポインタを取得して、そのメンバであるm_pTV、m_pLV取得する */
m_pListV = (CSummaryView*)m_wndSplitT.GetPane(0, 0);
m_pAcntV = (CAccountView*)m_wndSplitT2.GetPane(0, 0);
m_pTreeV = (CFolderView*)m_wndSplitT2.GetPane(1, 0);
m_pTextV = (CTextView*)m_wndSplitT.GetPane(1, 0);
m_pMultiV = (CMultiPartView*)m_wndSplitH.GetPane(1, 0);
x = app->GetProfileInt("SplitWnd", "LeftPaneWidth", 180);
m_wndSplitV.SetColumnInfo(0, x, 10);
m_wndSplitT2.SetRowInfo(0, 20, 10);
y = app->GetProfileInt("SplitWnd", "SummaryViewHeight", 300);
m_wndSplitT.SetRowInfo(0, y, 10);
y = app->GetProfileInt("SplitWnd", "TextViewHeight", 300);
m_wndSplitT.SetRowInfo(1, y, 10);
this->HideMultiPartView(TRUE);
m_flag = TRUE;
return TRUE;
}
void CMainFrame::OnProgCreate()
{
CRect rect;
m_wndStatusBar.GetItemRect(1, &rect);
m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH, rect, &m_wndStatusBar, -1); //PBS_SMOOTH
}
void CMainFrame::SetStatusBarText(int pane, LPCSTR buf)
{
// cannot use PostMessage, as the panel type is not set correctly
::SendMessage(m_wndStatusBar, SB_SETTEXT, (WPARAM)pane | 0, (LPARAM)(LPSTR)buf);
}
void CMainFrame::OnFetchmail()
{
this->m_pAcntV->SetFetchStatus(this->m_pAcntV->GetCurrentAccountName(), TRUE);
AfxBeginThread(FetchMail, this->m_pAcntV->GetCurrentAccountName());
}
void CMainFrame::OnUpdateFetchmail(CCmdUI* pCmdUI)
{
int index = m_pAcntV->GetAccountNum(m_pAcntV->GetCurrentAccountName());
pCmdUI->Enable(m_pAcntV->m_data[index].button_fetchmail);
}
void CMainFrame::OnUpdateRetrieve(CCmdUI* pCmdUI)
{
int index = m_pAcntV->GetAccountNum(m_pAcntV->GetCurrentAccountName());
pCmdUI->Enable(m_pAcntV->m_data[index].button_retrieve);
}
void CMainFrame::OnTransfer()
{
this->OnTransferQuotation();
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
if(m_flag)
ReArrangeSplit();
CRect rect;
if(m_wndStatusBar.m_hWnd != NULL)
m_wndStatusBar.GetItemRect(1, rect);
if(m_progress.m_hWnd != NULL)
m_progress.MoveWindow(rect);
}
void CMainFrame::OnUpdateReply(CCmdUI* pCmdUI)
{
pCmdUI->Enable(this->m_button_reply);
}
void CMainFrame::OnGpgDec()
{
CGpg gpg;
CString buf;
CString header;
CString body;
// パスフレーズを入力してもらう
CPochyApp* app = (CPochyApp*)AfxGetApp();
if(app->m_gpg_passphrase.IsEmpty()){
CPassPhraseDlg pf;
pf.SetFlag(GPG);
if(pf.DoModal() != IDOK)
return;
}
CString pass = app->m_gpg_passphrase;
// デコードする
buf = gpg.Decode(m_pTextV->GetCurrentPath(), pass);
if(buf.IsEmpty()){
app->m_gpg_passphrase.Empty();
return;
}
CStringArray old_header;
m_pTextV->m_md.m_hi.GetAllUnDecoded(old_header);
if(m_pTextV->IsPgpMime()){ // pgp/mimeの場合
CMimeDecode md;
md.DoIt2(buf);
CStringArray new_header;
md.m_hi.GetAllUnDecoded(new_header);
CString content_type;
CString content_transfer_encoding;
CString content_disposition;
// 暗号化された文章内のcanonical mimeと既存のmimeとの整合性をとる
int i=0;
while(i < new_header.GetSize()){
if(0 == new_header.GetAt(i).Find("Content-Type"))
content_type = new_header.GetAt(i);
if(0 == new_header.GetAt(i).Find("Content-Transfer-Encoding"))
content_transfer_encoding = new_header.GetAt(i);
if(0 == new_header.GetAt(i).Find("Content-Disposition"))
content_disposition = new_header.GetAt(i);
i++;
}
int j=0;
while(j < old_header.GetSize()){
if(0 == old_header.GetAt(j).Find("Content-Type")){
if(content_type.IsEmpty())
old_header.SetAt(j, "Content-Type: Text/Plain; charset=ISO-2022-JP\r\n");
else
old_header.SetAt(j, content_type);
}
j++;
}
j=0;
while(j < old_header.GetSize()){
if(0 == old_header.GetAt(j).Find("Content-Transfer-Encoding")){
if(content_transfer_encoding.IsEmpty())
old_header.SetAt(j, "Content-Transfer-Encoding: 7bit\r\n");
else
old_header.SetAt(j, content_transfer_encoding);
}
j++;
}
j=0;
while(j < old_header.GetSize()){
if(0 == old_header.GetAt(j).Find("Content-Disposition"))
if(content_disposition.IsEmpty())
old_header.RemoveAt(j);
else
old_header.SetAt(j, content_disposition);
j++;
}
body = buf.Mid(buf.Find("\r\n\r\n")+4);
}else{
body = buf; // べたに貼り付けられていた場合
}
g_cstra2cstr(old_header, header, g_cstra_getsize(old_header));
header.TrimRight();
header += "\r\n";
m_pTextV->Update2(header+"\r\n"+body);
}
void CMainFrame::OnUpdateGpgDec(CCmdUI* pCmdUI)
{
pCmdUI->Enable(this->m_button_gpg_dec);
}
void CMainFrame::OnUpdateGpg(CCmdUI* pCmdUI)
{
CPochyApp *app = (CPochyApp*)AfxGetApp();
pCmdUI->Enable(app->m_gpg_enable);
}
void CMainFrame::OnRetrieve()
{
CRetrieve Retrieve;
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString path;
path = app->m_app_path;
path += m_pTreeV->GetItemPath(m_pTreeV->GetTreeCtrl().GetSelectedItem());
Retrieve.GoRetrieve(path, FIRST);
}
void CMainFrame::OnDestroy()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
WINDOWPLACEMENT wndPlace;
CString num;
// ウィンドウの位置を取得
GetWindowPlacement(&wndPlace);
// ウィンドウの位置をiniファイルに保存
app->WriteProfileInt("WndPlace", "Left", wndPlace.rcNormalPosition.left);
app->WriteProfileInt("WndPlace", "Top", wndPlace.rcNormalPosition.top);
app->WriteProfileInt("WndPlace", "Right", wndPlace.rcNormalPosition.right);
app->WriteProfileInt("WndPlace", "Bottom", wndPlace.rcNormalPosition.bottom);
// ウィンドウの状態をiniファイルへ保存(最大化、アイコン化、それ以外)
if(this->IsZoomed())
app->WriteProfileInt("WndPlace", "Zoom", 1);
else if(this->IsIconic())
app->WriteProfileInt("WndPlace", "Zoom", 1);
else
app->WriteProfileInt("WndPlace", "Zoom", 0);
// サマリビューのカラムの幅をiniファイルへ保存
for(int i = 0; i < 5; i++){
num.Format("%d", i);
app->WriteProfileInt("SummaryViewColumn", num.GetBuffer(0), m_pListV->GetListCtrl().GetColumnWidth(i));
}
// multipartviewのカラムの幅をiniファイルへ保存
for(i = 0; i < 3; i++){
num.Format("%d", i);
app->WriteProfileInt("MultiPartViewColumn", num.GetBuffer(0), m_pMultiV->GetListCtrl().GetColumnWidth(i));
}
// 各スプリットウィンドウのサイズをiniファイルへ保存
int current;
int max;
m_wndSplitV.GetColumnInfo(0, current, max);
app->WriteProfileInt("SplitWnd", "LeftPaneWidth", current);
m_wndSplitT.GetRowInfo(0, current, max);
app->WriteProfileInt("SplitWnd", "SummaryViewHeight", current);
/*
typedef struct tagLOGFONT { // lf
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
*/
for(i=0; i<app->m_draft_array.GetSize(); i++){
app->m_draft_array[i]->ShowWindow(SW_SHOW);
if(app->m_draft_array[i]->IsIconic())
app->m_draft_array[i]->ShowWindow(SW_RESTORE);
app->m_draft_array[i]->SetForegroundWindow();
app->m_draft_array[i]->SaveToDraft(TRUE);
app->m_draft_array[i]->DestroyWindow();
}
CFrameWnd::OnDestroy();
}
void CMainFrame::OnSetting()
{
this->OnSettingAccount();
}
void CMainFrame::OnReply()
{
// 設定で選べるようにする
this->OnReplyQuotation();
}
void CMainFrame::OnDraft()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString path = app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\account.ini";
// initializing
app->m_me.Initialize();
// setting "from" field
CString from;
GetPrivateProfileString("mailbox", "address", "", from.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
from.ReleaseBuffer();
app->m_me.SetFrom(from);
// setting "cc" field
CString cc;
GetPrivateProfileString("def_address", "cc", "", cc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
cc.ReleaseBuffer();
app->m_me.SetCc(cc);
// setting "bcc" field
CString bcc;
GetPrivateProfileString("def_address", "address", "", bcc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
bcc.ReleaseBuffer();
app->m_me.SetBcc(bcc);
// setting "reply-to" field
CString reply_to;
GetPrivateProfileString("def_address", "reply_to", "", reply_to.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
reply_to.ReleaseBuffer();
app->m_me.SetReplyTo(reply_to);
// setting "message-id" field
app->m_me.SetMessageID(g_gen_msgid(from));
// getitng signature
CString signature;
g_file2cstring(app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\signature", signature);
// setting mail body
app->m_me.AddText("\r\n"+signature);
// create window
app->CreateDraftFrame(this->m_pAcntV->GetCurrentAccountName());
}
void CMainFrame::OnAddress()
{
CMainAddressBookDlg ad;
ad.DoModal();
}
void CMainFrame::OnUpdateTransfer(CCmdUI* pCmdUI)
{
pCmdUI->Enable(this->m_button_transfer);
}
void CMainFrame::OnInfo()
{
this->OnDisplayHeader();
}
// OnCharは大文字、小文字の区別あり
BOOL CMainFrame::Char(UINT nChar)
{
int sc;
CRetrieve Retrieve;
CPochyApp* app = (CPochyApp*)AfxGetApp();
if(app->m_retrieving){//検索中はESCキー以外をうけつけない
if(nChar==27)
app->m_retrieving = 0;
return TRUE;
}
switch(nChar){
case 9:
Retrieve.GoRetrieve(m_pListV->m_path, CONTINUE);
break;
case 'i':
if(!m_pAcntV->IsFetching(m_pAcntV->GetCurrentAccountName()))
OnFetchmail();
return TRUE;
case 'w': // 新規作成
OnDraft();
return TRUE;
case 'a': // 引用なし返信
if(this->m_button_reply==TRUE)
OnReplyNoQuotation();
return TRUE;
case 'A': // 引用あり返信
if(this->m_button_reply==TRUE)
OnReplyQuotation();
return TRUE;
case 'f': // 転送
if(this->m_button_transfer==TRUE)
OnTransfer();
return TRUE;
case 'o': // ウィンドウフォーカスの移動
SwitchView();
return TRUE;
// case VK_RETURN:
case ' ': // textviewのスクロール
m_pTextV->SetFocus();// フォーカスしないと、クリックしたときに問題が起きる
sc = m_pTextV->GetScrollPos(SB_VERT);
if(sc >= m_pTextV->GetScrollLimit(SB_VERT))
sc = -m_pTextV->GetRichEditCtrl().GetLineCount();
else
sc = 7;
m_pTextV->GetRichEditCtrl().LineScroll(sc);
return TRUE;
case 6: // Ctrl+f
OnRetrieve();
return TRUE;
// case 'r':
// this->m_pListV->ReBuildSummary(this->m_pListV->m_path, SMRY_COLUMN_FROM);
// return TRUE;
}
return FALSE;
}
void CMainFrame::SwitchView()
{
CWnd* wnd = GetFocus();
if(wnd == m_pTreeV)
m_pListV->SetFocus();
else if(wnd == m_pListV)
m_pTextV->SetFocus();
else if(wnd == m_pTextV && !m_multipart_hide)
m_pMultiV->SetFocus();
else if(wnd == m_pTextV && m_multipart_hide)
m_pAcntV->SetFocus();
else if(wnd == m_pMultiV)
m_pAcntV->SetFocus();
else
m_pTreeV->SetFocus();
}
void CMainFrame::OnUpdateInfo(CCmdUI* pCmdUI)
{
pCmdUI->Enable(this->m_button_info);
}
void CMainFrame::OnUpdateSetting(CCmdUI* pCmdUI)
{
int index = m_pAcntV->GetAccountNum(m_pAcntV->GetCurrentAccountName());
pCmdUI->Enable(m_pAcntV->m_data[index].button_setting);
}
BOOL CMainFrame::CreateToolbar()
{
DWORD dwTBStyle, dwStyle;
dwTBStyle = TBSTYLE_FLAT; // この辺のスタイルは適当に
dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC;
if(!m_wndToolBar.CreateEx(this, dwTBStyle, dwStyle)){
TRACE0("Failed to create toolbar\n");
return FALSE; // fail to create
}
CImageList img;
HINSTANCE hInst = AfxFindResourceHandle((LPCTSTR)IDR_TEST, RT_BITMAP);
ASSERT(hInst != NULL);
img.Attach(ImageList_LoadImage(hInst, (LPCTSTR)IDR_MAINFRAME, WIDTH_ICON_MAIN, 0, /*CLR_NONE*/RGB(255, 255, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION));
m_wndToolBar.GetToolBarCtrl().SetImageList(&img);
img.Detach();
m_wndToolBar.SetSizes(CSize(WIDTH_ICON_MAIN+7, HEIGHT_ICON_MAIN+6), CSize(WIDTH_ICON_MAIN, HEIGHT_ICON_MAIN));
m_wndToolBar.SetButtons(NULL, 9);
m_wndToolBar.SetButtonInfo( 0, ID_DRAFT, TBSTYLE_BUTTON, 0);
m_wndToolBar.SetButtonInfo( 1, ID_FETCH_MAIL, TBSTYLE_BUTTON, 1);
m_wndToolBar.SetButtonInfo( 2, ID_REPLY, TBSTYLE_BUTTON, 2);
m_wndToolBar.SetButtonInfo( 3, ID_TRANSFER, TBSTYLE_BUTTON, 3);
m_wndToolBar.SetButtonInfo( 4, ID_ADDRESS, TBSTYLE_BUTTON, 4);
m_wndToolBar.SetButtonInfo( 5, ID_GPG, TBSTYLE_BUTTON, 5);
m_wndToolBar.SetButtonInfo( 6, ID_RETRIEVE, TBSTYLE_BUTTON, 6);
m_wndToolBar.SetButtonInfo( 7, ID_SETTING, TBSTYLE_BUTTON, 7);
m_wndToolBar.SetButtonInfo( 8, ID_INFO, TBSTYLE_BUTTON, 8);
//m_wndToolBar.SetButtonInfo(2, 0, TBSTYLE_SEP, 6);
// dropdown menu
m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
// reply
DWORD style = m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_REPLY));
style |= TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_REPLY), style);
// transfer
style = m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_TRANSFER));
style |= TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_TRANSFER), style);
// gpg
style = m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_GPG));
style |= TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_GPG), style);
// information
style = m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_INFO));
style |= TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_INFO), style);
// setting
style = m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_SETTING));
style |= TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_SETTING), style);
return TRUE;
}
void CMainFrame::OnToolbarDropDown(NMTOOLBAR* pnmtb, LRESULT *plr)
{
CWnd *wnd = &m_wndToolBar;
UINT id;
// Switch on button command id's
switch (pnmtb->iItem)
{
case ID_REPLY:
id = IDR_MAINFRAME_POPUP_REPLY;
break;
case ID_TRANSFER:
id = IDR_MAINFRAME_POPUP_TRANSFER;
break;
case ID_GPG:
id = IDR_MAINFRAME_POPUP_GPG;
break;
case ID_INFO:
id = IDR_MAINFRAME_POPUP_INFO;
break;
case ID_SETTING:
id = IDR_MAINFRAME_POPUP_SETTING;
break;
default:
return;
}
// load and display popup menu
CMenu menu;
menu.LoadMenu(id);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup);
CRect rc;
wnd->SendMessage(TB_GETRECT, pnmtb->iItem, (LPARAM)&rc);
wnd->ClientToScreen(&rc);
pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL, rc.left, rc.bottom, this, &rc);
}
void CMainFrame::OnReplyQuotation()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
// とりあえず初期化
app->m_me.Initialize();
// toの設定(reply-toがあった場合は、reply-toを優先
if(m_pTextV->GetCurrentReplyTo().IsEmpty()){
app->m_me.SetTo(m_pTextV->GetCurrentFrom());
}else{
app->m_me.SetTo(m_pTextV->GetCurrentReplyTo());
}
// ccの設定
if(!m_pTextV->GetCurrentCc().IsEmpty())
app->m_me.SetCc(m_pTextV->GetCurrentCc());
// fromの設定
CString path = app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\account.ini";
CString address;
GetPrivateProfileString("mailbox", "address", "", address.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
address.ReleaseBuffer();
app->m_me.SetFrom(address);
// subjectの設定
if(m_pTextV->GetCurrentSubject().Find("Re:") == 0 || m_pTextV->GetCurrentSubject().Find("RE:") == 0){
app->m_me.SetSubject(m_pTextV->GetCurrentSubject());
}else{
app->m_me.SetSubject("Re: "+m_pTextV->GetCurrentSubject());
}
// setting "cc" field
CString cc;
GetPrivateProfileString("def_address", "cc", "", cc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
cc.ReleaseBuffer();
app->m_me.SetCc(cc);
// setting "bcc" field
CString bcc;
GetPrivateProfileString("def_address", "address", "", bcc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
bcc.ReleaseBuffer();
app->m_me.SetBcc(bcc);
// setting "reply-to" field
CString reply_to;
GetPrivateProfileString("def_address", "reply_to", "", reply_to.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
reply_to.ReleaseBuffer();
app->m_me.SetReplyTo(reply_to);
// message-idの設定
app->m_me.SetMessageID(g_gen_msgid(address));
// In-reply-toの設定
app->m_me.SetInReplyTo(m_pTextV->GetCurrentMsgID());
// 本文に引用符を設定
CString body = m_pTextV->GetCurrentBody();
body.Replace("\r\n","\r\n> ");
body = "> "+body+"\r\n";
// 署名
CString signature;
g_file2cstring(app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\signature", signature);
// 本文を設定
app->m_me.AddText(body+"\r\n"+signature);
// ドラフトフレームを作成
app->CreateDraftFrame(this->m_pAcntV->GetCurrentAccountName());
}
void CMainFrame::OnReplyNoQuotation()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
// mimeencodeクラスメンバの初期化
app->m_me.Initialize();
// To の設定
if(!m_pTextV->GetCurrentReplyTo().IsEmpty())
app->m_me.SetTo(m_pTextV->GetCurrentReplyTo());
else
app->m_me.SetTo(m_pTextV->GetCurrentFrom());
// From の設定
CString path = app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\account.ini";
CString address;
GetPrivateProfileString("mailbox", "address", "", address.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
address.ReleaseBuffer();
app->m_me.SetFrom(address);
// setting "cc" field
// ccの設定
CString cc;
GetPrivateProfileString("def_address", "cc", "", cc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
cc.ReleaseBuffer();
if(!m_pTextV->GetCurrentCc().IsEmpty() && !cc.IsEmpty()){
app->m_me.SetCc(m_pTextV->GetCurrentCc()+", "+cc);
}else if(!m_pTextV->GetCurrentCc().IsEmpty() && cc.IsEmpty()){
app->m_me.SetCc(m_pTextV->GetCurrentCc());
}else if(m_pTextV->GetCurrentCc().IsEmpty() && !cc.IsEmpty()){
app->m_me.SetCc(cc);
}
// setting "bcc" field
CString bcc;
GetPrivateProfileString("def_address", "address", "", bcc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
bcc.ReleaseBuffer();
app->m_me.SetBcc(bcc);
// setting "reply-to" field
CString reply_to;
GetPrivateProfileString("def_address", "reply_to", "", reply_to.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
reply_to.ReleaseBuffer();
app->m_me.SetReplyTo(reply_to);
// message-idの設定
app->m_me.SetMessageID(g_gen_msgid(address));
// In-reply-toの設定
app->m_me.SetInReplyTo(m_pTextV->GetCurrentMsgID());
// Subjectの設定
if(m_pTextV->GetCurrentSubject().Find("Re:") == 0)
app->m_me.SetSubject(m_pTextV->GetCurrentSubject());
else if(m_pTextV->GetCurrentSubject().Find("RE:") == 0)
app->m_me.SetSubject(m_pTextV->GetCurrentSubject());
else
app->m_me.SetSubject("Re: "+m_pTextV->GetCurrentSubject());
CString signature;
g_file2cstring(app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\signature", signature);
// 本文を設定
MULTIPART_STRUCT2 data;
data.m_body = signature;
data.m_type = "Text/Plain; charset=ISO-2022-JP";
data.m_encoding_type = "7bit";
app->m_me.AddMultipart(data);
app->CreateDraftFrame(this->m_pAcntV->GetCurrentAccountName());
}
void CMainFrame::OnGpg()
{
this->OnGpgKeyManagement();
}
void CMainFrame::ReArrangeSplit()
{
CRect rect;
int bar_horizonal = 0; // とりあえず0にしとくので、multi_heightにbarの幅を加えた値を与える必要がある
// summaryview textview multipartview をあわせた高さ
m_wndSplitV.GetPane(0,1)->GetClientRect(&rect);
rect.NormalizeRect();
int height = rect.Height();
rect.SetRectEmpty();
// multipartviewの高さがHT_MULTI_HEIGHTになるように設定
m_wndSplitH.SetRowInfo(0, height-(HT_MULTI_HEIGHT+bar_horizonal), 0);
m_wndSplitH.SetRowInfo(1, HT_MULTI_HEIGHT, 0);
m_wndSplitH.RecalcLayout();
}
void CMainFrame::HideMultiPartView(BOOL b)
{
if(b && m_multipart_hide == FALSE){
m_wndSplitH.HideRow(1);
m_multipart_hide = TRUE;
}else if(!b && m_multipart_hide == TRUE){
m_wndSplitH.ShowRow();
m_multipart_hide = FALSE;
}
}
void CMainFrame::OnTimer(UINT nIDEvent)
{
if(!m_pAcntV->IsFetching(m_pAcntV->GetCurrentAccountName())){
OnFetchmail();
}
CFrameWnd::OnTimer(nIDEvent);
}
void CMainFrame::UpdateButton(BOOL b, CString account)
{
int index = m_pAcntV->GetAccountNum(account);
m_pAcntV->m_data[index].button_fetchmail = b;
m_pAcntV->m_data[index].button_setting = b;
m_pAcntV->m_data[index].button_retrieve = b;
}
void CMainFrame::SetStatusBarProgress(int current, int upper)
{
if(m_progress.m_hWnd == NULL)
SendMessage(WM_COMMAND, WM_PROGCREATE, NULL);
// prepare for progress bar.
m_progress.SetRange32(0, upper);
m_progress.SetPos(current);
}
CString CMainFrame::GetStatusBarText()
{
return m_wndStatusBar.GetPaneText(0);
}
void CMainFrame::GetStatusBarProgress(int ¤t, int &upper)
{
int low;
m_progress.GetRange(low, upper);
current = m_progress.GetPos();
}
void CMainFrame::OnSettingGeneral()
{
CSettingGeneralDlg sd;
sd.DoModal();
}
void CMainFrame::OnSettingAccount()
{
CSettingAccountDlg sd;
sd.DoModal();
}
void CMainFrame::OnDisplayHeader()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString file_name = g_ma(m_pTextV->GetCurrentMsgID())+"_header.txt";
if(!g_is_there(app->m_app_path+"\\temp")) // if attached folder does not exist, create.
_mkdir(app->m_app_path+"\\temp");
CString file_path = app->m_app_path+"\\temp\\"+file_name;
FILE* file = fopen(file_path, "wb");
fwrite(m_pTextV->GetCurrentRawHeader().GetBuffer(0), sizeof(char), m_pTextV->GetCurrentRawHeader().GetLength(), file);
fclose(file);
CString editor_path = app->GetProfileString("Editor", "Path", "notepad");
if(editor_path.IsEmpty())
editor_path = "notepad";
file_path = "\""+file_path+"\"";
// open file with editor designated in setting.ini.
ShellExecute(NULL,NULL, editor_path, file_path, NULL, SW_NORMAL);
}
void CMainFrame::OnDisplayRawMail()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString editor_path = app->GetProfileString("Editor", "Path", "notepad");
if(editor_path.IsEmpty())
editor_path = "notepad";
// open file with editor designated in setting.ini.
ShellExecute(NULL,NULL, editor_path, "\""+m_pTextV->GetCurrentPath()+"\"", NULL, SW_NORMAL);
}
void CMainFrame::OnSettingFilter()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString file = app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\"+"filter";
// if filter file does not exist, create.
if(!g_is_there(file)){
g_cstring2file(FILTER_INSTRUCTION, file);
}
CString path = app->GetProfileString("Editor", "Path", "notepad");
if(path.IsEmpty())
path = "notepad";
file = "\""+file+"\"";
// open file with editor designated in setting.ini.
ShellExecute(NULL,NULL, path, file, NULL, SW_SHOWNORMAL);
}
void CMainFrame::OnSettingNewAccount()
{
CPochyApp* app = (CPochyApp*)AfxGetApp();
CString name;
for(int i=0;;i++){
name.Format("NewAccount%d", i);
if(g_is_there(app->m_app_path+"\\"+name)){
continue;
}else{
break;
}
}
this->m_pAcntV->CreateNewAccount(name);
this->m_pTreeV->ConstructTree(name);
// multipartviewが表示されていれば隠す
this->m_pListV->Clear();
this->m_pTextV->Clear();
}
void CMainFrame::OnTransferQuotation()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
// とりあえず初期化
app->m_me.Initialize();
// fromの設定
CString path = app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\account.ini";
CString address;
GetPrivateProfileString("mailbox", "address", "", address.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
address.ReleaseBuffer();
app->m_me.SetFrom(address);
// setting "cc" field
CString cc;
GetPrivateProfileString("def_address", "cc", "", cc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
cc.ReleaseBuffer();
app->m_me.SetCc(cc);
// setting "bcc" field
CString bcc;
GetPrivateProfileString("def_address", "address", "", bcc.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
bcc.ReleaseBuffer();
app->m_me.SetBcc(bcc);
// setting "reply-to" field
CString reply_to;
GetPrivateProfileString("def_address", "reply_to", "", reply_to.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
reply_to.ReleaseBuffer();
app->m_me.SetReplyTo(reply_to);
// message-idの設定
app->m_me.SetMessageID(g_gen_msgid(address));
// subjectの設定
app->m_me.SetSubject("Fw: "+m_pTextV->GetCurrentSubject());
// 本文に引用元情報を設定
CString message;
message += "\r\nFowarded by ";
message += app->m_me.GetFrom()+"\r\n";
message += "----- Original Message -----\r\n";
if(!m_pTextV->GetCurrentFrom().IsEmpty())
message += "From: "+m_pTextV->GetCurrentFrom()+"\r\n";
if(!m_pTextV->GetCurrentTo().IsEmpty())
message += "To: "+m_pTextV->GetCurrentTo()+"\r\n";
if(!m_pTextV->GetCurrentCc().IsEmpty())
message += "Cc: "+m_pTextV->GetCurrentCc()+"\r\n";
if(!m_pTextV->GetCurrentDate())
message += "Date: "+m_pTextV->GetCurrentDate()+"\r\n";
if(!m_pTextV->GetCurrentSubject())
message += "Subject: "+m_pTextV->GetCurrentSubject()+"\r\n";
message += "---\r\n\r\n";
CString body = m_pTextV->GetCurrentBody();
body = message+body;
// 署名を本文に挿入する(転送なのでつけなくても良いかも?)
CString signature;
g_file2cstring(app->m_app_path+"\\"+m_pAcntV->GetCurrentAccountName()+"\\signature", signature);
// 本文を設定
app->m_me.AddText(body+"\r\n"+signature);
app->CreateDraftFrame(this->m_pAcntV->GetCurrentAccountName());
}
void CMainFrame::OnGpgKeyManagement()
{
CGpgDlg gd;
gd.DoModal();
}
void CMainFrame::OnClose()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
if(this->m_wndToolBar.IsWindowVisible()){
app->WriteProfileInt("ToolBar", "IsVisible", SW_SHOW);
}else{
app->WriteProfileInt("ToolBar", "IsVisible", SW_HIDE);
}
if(this->m_wndStatusBar.IsWindowVisible()){
app->WriteProfileInt("StatusBar", "IsVisible", SW_SHOW);
}else{
app->WriteProfileInt("StatusBar", "IsVisible", SW_HIDE);
}
CFrameWnd::OnClose();
}
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
CString mailto;
if(pCopyDataStruct->dwData == WM_MAILTO){
mailto = (char *)pCopyDataStruct->lpData;
if(!mailto.IsEmpty() && mailto.Find("mailto:") == 0){
CPochyApp *app = (CPochyApp *)AfxGetApp();
// getting default account name
CString def_account = app->GetProfileString("DefaultMailBox", "BoxName");
app->m_me.Initialize();
// setting To
if(mailto.Find("?", 7) != -1){ // mailto:hoge@hoge.com?subject=PGP%20Key&Body=Please%20send%20keyとか
// subject, body is not implemented.
app->m_me.SetTo(mailto.Mid(7, mailto.Find("?", 7)-7));
}else{
app->m_me.SetTo(mailto.Mid(7));
}
if(!def_account.IsEmpty()){
// setting From
CString path = app->m_app_path+"\\"+def_account+"\\account.ini";
CString address;
GetPrivateProfileString("mailbox", "address", "", address.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
address.ReleaseBuffer();
app->m_me.SetFrom(address);
// setting message-id
app->m_me.SetMessageID(g_gen_msgid(address));
// getting signature.
CString signature;
g_file2cstring(app->m_app_path+"\\"+def_account+"\\signature", signature);
// set main text.
app->m_me.AddText(signature);
// draftframe
app->CreateDraftFrame(def_account);
}else{
CString hostname;
char *tmp = hostname.GetBuffer(255);
DWORD size=255;
::GetUserName(tmp, &size);
hostname.ReleaseBuffer();
app->m_me.SetFrom("");
app->m_me.AddText("");
app->m_me.SetMessageID(g_gen_msgid(hostname));
// draftframe
app->CreateDraftFrame(this->m_pAcntV->GetFirstAccountName());
}
}
}
return CFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
}
void CMainFrame::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
AfxMessageBox("this");
this->Char(nChar);
CFrameWnd::OnChar(nChar, nRepCnt, nFlags);
}