root/SummaryView.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- IMPLEMENT_DYNCREATE
- CSummaryView
- BEGIN_MESSAGE_MAP
- AssertValid
- Dump
- OnInitialUpdate
- OnGetdispinfo
- PreCreateWindow
- SetStack
- SetItem
- AddList
- OnChildNotify
- OnChar
- UpdateColumn
- SetStatus
- ClearStatus
- UnmarkStatus
- MarkDStatus
- SelectNext
- SelectPrev
- DeleteMail
- WriteList
- OnDblclk
- OnKeyDown
- OnSetFocus
- OnBegindrag
- SaveMail
- SaveMail
- PreTranslateMessage
- OnColumnclick
- QuickSortPartition
- QuickSortSwapStack
- QuickSort
- SetColumnOrderStatus
- ReBuildSummary
- OnLButtonUp
- OnRclick
- OnPopupDel
- OnPopupHeaderInfo
- OnPopupRawmailInfo
- OnPopupRebuild
- ClearAllMail
- MoveMail
- Clear
- GetSelectedMail
/*
* Copyright (C) 2002-2003 chik, s.hiranaka
* For license terms, see the file COPYING in this directory.
*/
// SummaryView.cpp : インプリメンテーション ファイル
//
#include "stdafx.h"
#include "Pochy.h"
#include "SummaryView.h"
#include "FolderView.h"
#include "MainFrm.h"
#include "CodeConvert.h"
#include "StrTok.h"
#include "MimeDecode.h"
#include "lib.h"
#include "direct.h" // _mkdir
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSummaryView
IMPLEMENT_DYNCREATE(CSummaryView, CListView)
CSummaryView::CSummaryView()
{
this->m_stack_num = 0;
this->m_status_changed = FALSE;
this->m_index = -1;
}
CSummaryView::~CSummaryView()
{
WriteList();
}
BEGIN_MESSAGE_MAP(CSummaryView, CListView)
//{{AFX_MSG_MAP(CSummaryView)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
ON_WM_CHAR()
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
ON_WM_KEYDOWN()
ON_WM_SETFOCUS()
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_WM_LBUTTONUP()
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_COMMAND(ID_SUMMARYVIEW_DEL, OnPopupDel)
ON_COMMAND(ID_SUMMARYVIEW_HEADER_INFO, OnPopupHeaderInfo)
ON_COMMAND(ID_SUMMARYVIEW_RAWMAIL_INFO, OnPopupRawmailInfo)
ON_COMMAND(ID_SUMMARYVIEW_REBUILD, OnPopupRebuild)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSummaryView 描画
void CSummaryView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: この位置に描画用のコードを追加してください
}
/////////////////////////////////////////////////////////////////////////////
// CSummaryView 診断
#ifdef _DEBUG
void CSummaryView::AssertValid() const
{
CListView::AssertValid();
}
void CSummaryView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSummaryView メッセージ ハンドラ
void CSummaryView::OnInitialUpdate()
{
CListCtrl& lc = GetListCtrl();
CPochyApp *app = (CPochyApp *)AfxGetApp();
int i;
CString num;
char* Column[] = { "状態", "サイズ", "件名", "差出人", "日付" };
LV_COLUMN lvc;
DWORD dwStyle;
HWND hWnd;
// 現在のスタイルから、レポートスタイルへ変更
hWnd = lc.GetSafeHwnd();
dwStyle = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, (dwStyle &~ LVS_TYPEMASK) | LVS_REPORT);
lc.SetExtendedStyle(LVS_EX_FULLROWSELECT);
// 色の設定
COLORREF m_colorEdit;
// 背景色
m_colorEdit = RGB(
app->GetProfileInt("SummaryViewColor", "BkColorR", 0),
app->GetProfileInt("SummaryViewColor", "BkColorG", 0),
app->GetProfileInt("SummaryViewColor", "BkColorB", 0));
lc.SetBkColor(m_colorEdit);
// テキストの背景色
m_colorEdit = RGB(
app->GetProfileInt("SummaryViewColor", "BkColorR", DEF_BKG_COLOR_R),
app->GetProfileInt("SummaryViewColor", "BkColorG", DEF_BKG_COLOR_G),
app->GetProfileInt("SummaryViewColor", "BkColorB", DEF_BKG_COLOR_B));
lc.SetTextBkColor(m_colorEdit);
// 文字の色
m_colorEdit = RGB(
app->GetProfileInt("SummaryViewColor", "TxtColorR", DEF_TXT_COLOR_R),
app->GetProfileInt("SummaryViewColor", "TxtColorG", DEF_TXT_COLOR_G),
app->GetProfileInt("SummaryViewColor", "TxtColorB", DEF_TXT_COLOR_B));
lc.SetTextColor(m_colorEdit);
// リストビューへカラムを設定
lvc.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
for(i = 0; i < 5; i++){
lvc.pszText = Column[i];
num.Format("%d", i);
lvc.cx = app->GetProfileInt("SummaryViewColumn", num.GetBuffer(0), 100);
if(lvc.cx > 1000){
lvc.cx = 100;
}
lc.InsertColumn(i, &lvc);
}
// リストビューへデータを格納する
m_index = -1;
}
void CSummaryView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO *pDispInfo = (LV_DISPINFO*)pNMHDR;
int num = pDispInfo->item.iItem;
char *buf;
if(pDispInfo->item.mask & LVIF_TEXT){
switch(pDispInfo->item.iSubItem){
case 0:
buf = m_array_list[m_stack_num-num-1].m_str6.GetBuffer(0);
lstrcpy(pDispInfo->item.pszText, buf);
break;
case 1:
buf = m_array_list[m_stack_num-num-1].m_str1.GetBuffer(0);
lstrcpy(pDispInfo->item.pszText, buf);
break;
case 2:
buf = m_array_list[m_stack_num-num-1].m_str2.GetBuffer(0);
lstrcpy(pDispInfo->item.pszText, buf);
break;
case 3:
buf = m_array_list[m_stack_num-num-1].m_str3.GetBuffer(0);
lstrcpy(pDispInfo->item.pszText, buf);
break;
case 4:
buf = m_array_list[m_stack_num-num-1].m_str4.GetBuffer(0);
lstrcpy(pDispInfo->item.pszText, buf);
break;
}
}
*pResult = 0;
}
BOOL CSummaryView::PreCreateWindow(CREATESTRUCT& cs)
{
// ListViewをownerdataに変更→高速に表示されるようになる
// SetItemCountExを実行することで、OnGetdispinfoが呼ばれる
cs.style |= LVS_OWNERDATA
| LVS_REPORT
/*| LVS_SINGLESEL*/
| LVS_SHOWSELALWAYS;
// LVS_SORTDESCENDING LVS_SORTASCENDING
return CListView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CSummaryView メッセージ ハンドラでない関数
int CSummaryView::SetStack(CString path)
{
CString tmp;
CString message;
SLISTSTACK list;
CStrTok StrTok;
CStdioFile ReadFile;
if(!ReadFile.Open(path+"\\list", CFile::modeRead | CFile::typeText)){
#if 0 // listがない場合はつくるようにする
message.Format("CSummaryView: cannot open %s\\list", path.GetBuffer(0));
AfxMessageBox(message.GetBuffer(0));
return -1;
#else
// CString NullBuf;
// NullBuf.Empty();
g_fcreate(path+"\\list");
if(!ReadFile.Open(path+"\\list", CFile::modeRead | CFile::typeText)){
message.Format("CSummaryView: cannot open %s\\list", path.GetBuffer(0));
AfxMessageBox(message.GetBuffer(0));
return -1;
}
#endif
}
// ArrayListに代入
m_array_list.RemoveAll();
int n=0;
while(ReadFile.ReadString(tmp)){
for(int i=1; i<9; i++){
switch(i){
case 1:
list.m_str1 = StrTok.Tokenize(tmp.GetBuffer(0), "\x02");
break;
case 2:
list.m_str2 = StrTok.Tokenize(NULL, "\x02");
break;
case 3:
list.m_str3 = StrTok.Tokenize(NULL, "\x02");
break;
case 4:
list.m_str4 = StrTok.Tokenize(NULL, "\x02");
break;
case 5:
list.m_str5 = StrTok.Tokenize(NULL, "\x02");
break;
case 6:
list.m_str6 = StrTok.Tokenize(NULL, "\x02");
if(-1 != list.m_str6.Find("N")){
m_unread++;
}
break;
case 7:
list.m_str7 = StrTok.Tokenize(NULL, "\x02");
break;
case 8:
list.m_str8 = StrTok.Tokenize(NULL, "\x02");
break;
case 9:
list.m_str9 = StrTok.Tokenize(NULL, "\x02");
break;
}
}
n++;
m_array_list.Add(list);
tmp.Empty();
}
ReadFile.Close();
return(n);
}
void CSummaryView::SetItem(CString path)
{
WriteList(); // 取り合えず現在の内容をlistに保存
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)this->GetParentFrame();
CListCtrl& lc = GetListCtrl();
lc.DeleteAllItems();
m_path = path; // 現在表示しようとしているlistファイルのあるフォルダのパスをm_pathに保存
m_unread = 0;
CString current_account = mf->m_pAcntV->GetCurrentAccountName();
// リストビューのカラムの幅をiniファイルへ保存
CString num;
for(int i = 0; i < 5; i++){
num.Format("%d", i);
app->WriteProfileInt("SummaryViewColumn", num.GetBuffer(0), lc.GetColumnWidth(i));
}
// listviewのコラムを必要に応じて変更する
if(path == app->m_app_path+"\\"+current_account+"\\outbox"
|| path == app->m_app_path+"\\"+current_account+"\\draft")
this->UpdateColumn(SMRY_COLUMN_TO);
else
this->UpdateColumn(SMRY_COLUMN_FROM);
m_stack_num = SetStack(path);
CString unread;
unread.Format("未読 %d メール数 %d", m_unread, m_stack_num);
mf->SetStatusBarText(2, unread);
m_index = -1; // 何も選択されていない状態
if(m_stack_num != -1)
lc.SetItemCountEx(m_stack_num, LVSICF_NOSCROLL); // これでOnGetDispinfoが呼ばれる
}
void CSummaryView::AddList(SLISTSTACK *pList)
{
CListCtrl& lc = GetListCtrl();
m_stack_num++;
m_array_list.Add(*pList);
lc.InsertItem(0, pList->m_str1.GetBuffer(0)); // オーナードローなのでサブアイテムはOnGetdispinfoで処理される
if(m_index != -1)
m_index++;
}
BOOL CSummaryView::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult)
{
if(message == WM_NOTIFY){
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)lParam;
// 別のアイテムが選択された後に呼ばれる
if( pNMListView->hdr.code == LVN_ITEMCHANGED && pNMListView->uNewState == 3 &&
m_index != pNMListView->iItem )
{
CPochyApp* app = (CPochyApp*)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CTextView *tv = (CTextView*)mf->m_pTextV;
CFolderView *fv = (CFolderView *)mf->m_pTreeV;
CAccountView *av = (CAccountView*)mf->m_pAcntV;
m_index = pNMListView->iItem;
BOOL b = ClearStatus(m_index);
m_status_changed |= b;
if(b){
CString unread;
unread.Format("未読 %d メール数 %d", --m_unread, m_stack_num);
mf->SetStatusBarText(2, unread);
}
// mainframeの各ボタンを有効にする
mf->m_button_reply = TRUE;
mf->m_button_transfer = TRUE;
mf->m_button_info = TRUE;
tv->Update(m_path + "\\" + m_array_list[m_stack_num-m_index-1].m_str5);
*pLResult = 0;
}
}
return CListView::OnChildNotify(message, wParam, lParam, pLResult);
}
void CSummaryView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
int i;
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CFolderView *fv = (CFolderView *)mf->m_pTreeV;
CStringArray cstra;
CUIntArray ia;
CString current_account = mf->m_pAcntV->GetCurrentAccountName();
if(mf->Char(nChar))
return;
switch(nChar){
case 'd':
if(this->m_index != -1){
this->m_status_changed |= this->MarkDStatus(m_index);
this->SelectNext();
}
break;
case 'u':
if(this->m_index != -1){
this->m_status_changed |= UnmarkStatus(m_index);
this->SelectNext();
}
break;
case 'x':
for(i=0; i < this->m_array_list.GetSize(); i++){
if(this->m_array_list.GetAt(i).m_str6.Find("D") != -1){
ia.Add(i);
}
}
if(fv->GetSelectedItemKind() != FV_TRASH){
this->MoveMail(ia, app->m_app_path+"\\"+current_account+"\\trash", SMRY_COLUMN_FROM);
}else{
CString null;
null.Empty();
this->MoveMail(ia, null, SMRY_COLUMN_FROM);
}
break;
case '<':
this->GetListCtrl().SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
this->GetListCtrl().EnsureVisible(0, TRUE);
break;
case '>':
this->GetListCtrl().SetItemState(this->m_stack_num-1, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
this->GetListCtrl().EnsureVisible(this->m_stack_num-1, TRUE);
break;
default:
break;
}
}
void CSummaryView::UpdateColumn(int flag)
{
CListCtrl& lc = this->GetListCtrl();
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString num;
LV_COLUMN lvc;
char* Column1[] = { "状態", "サイズ", "件名", "差出人", "日付" };
char* Column2[] = { "状態", "サイズ", "件名", "宛先", "日付" };
lvc.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
int i;
for(i = 0; i < 5; i++) lc.DeleteColumn(0);
if(flag == SMRY_COLUMN_FROM){
for(i = 0; i < 5; i++){
lvc.pszText = Column1[i];
num.Format("%d", i);
lvc.cx = app->GetProfileInt("SummaryViewColumn", num.GetBuffer(0), 100);
lc.InsertColumn(i, &lvc);
}
}
if(flag == SMRY_COLUMN_TO){
for(i = 0; i < 5; i++){
lvc.pszText = Column2[i];
num.Format("%d", i);
lvc.cx = app->GetProfileInt("SummaryViewColumn", num.GetBuffer(0), 100);
lc.InsertColumn(i, &lvc);
}
}
int status = GetPrivateProfileInt("list", "order", 0, this->m_path+"\\folder.ini");
this->SetColumnOrderStatus(status);
}
void CSummaryView::SetStatus(int nItem, CString status)
{
if(this->m_index > -1 && this->m_index < m_stack_num){
this->m_array_list[this->m_stack_num-nItem-1].m_str6 = status;
this->GetListCtrl().RedrawItems(nItem,nItem);
}
}
BOOL CSummaryView::ClearStatus(int nItem)
{
CString buf;
buf = this->m_array_list.GetAt(this->m_stack_num-nItem-1).m_str6;
if(buf.Left(1)=="N"){
SetStatus(nItem, " "+buf.Right(1));
return TRUE;
}
return FALSE;
}
BOOL CSummaryView::UnmarkStatus(int nItem)
{
CString buf;
buf = this->m_array_list.GetAt(this->m_stack_num-nItem-1).m_str6;
if(buf.Left(1)=="D"){
this->SetStatus(nItem, " "+buf.Right(1));
return TRUE;
}
return FALSE;
}
BOOL CSummaryView::MarkDStatus(int nItem)
{
CString buf;
buf = this->m_array_list.GetAt(this->m_stack_num-nItem-1).m_str6;
if(buf.Left(1)!="D"){
this->SetStatus(nItem, "D"+buf.Right(1));
return TRUE;
}
return FALSE;
}
void CSummaryView::SelectNext()
{
if(this->m_index < m_stack_num -1){
this->GetListCtrl().SetItemState(this->m_index+1, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
this->GetListCtrl().EnsureVisible(this->m_index, TRUE);
this->GetListCtrl().RedrawItems(this->m_index, this->m_index);
this->UpdateWindow();
}
}
void CSummaryView::SelectPrev()
{
if(this->m_index > 0){
this->GetListCtrl().SetItemState(this->m_index-1,LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
this->GetListCtrl().EnsureVisible(this->m_index, TRUE);
this->GetListCtrl().RedrawItems(this->m_index, this->m_index);
this->UpdateWindow();
}
}
void CSummaryView::DeleteMail(CUIntArray &index_array)
{
if(index_array.GetSize() < 1){
return;
}
CWaitCursor wait_cursor; // turn cursor into sandglass
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CTextView *tv = (CTextView *)mf->m_pTextV;
CStringArray cstra;
int i = index_array.GetSize()-1;
while(i >= 0){
DeleteFile(m_path+"\\"+m_array_list.GetAt(m_stack_num-index_array.GetAt(i)-1).m_str5);
this->m_array_list.RemoveAt(m_stack_num-index_array.GetAt(i)-1);
this->m_stack_num--;
i--;
}
// something is changed.
this->GetListCtrl().DeleteAllItems();
this->m_index = -1;
this->GetListCtrl().SetItemCountEx(m_stack_num, LVSICF_NOSCROLL);
this->m_status_changed = TRUE;
this->WriteList();
tv->Clear();
}
void CSummaryView::WriteList()
{
if(!m_status_changed)
return;
this->m_status_changed = FALSE;
FILE *file;
if(!(file = fopen(m_path + "\\list", "wb"))){
AfxMessageBox("error: fopen in WriteList()");
return;
}
CWaitCursor wait_cursor; // turn cursor into sandglass
CString str;
for(int i=0;i<this->m_array_list.GetSize();i++){
str = m_array_list.GetAt(i).m_str1;
str += "\x02" + m_array_list.GetAt(i).m_str2;
str += "\x02" + m_array_list.GetAt(i).m_str3;
str += "\x02" + m_array_list.GetAt(i).m_str4;
str += "\x02" + m_array_list.GetAt(i).m_str5;
str += "\x02" + m_array_list.GetAt(i).m_str6;
str += "\x02" + m_array_list.GetAt(i).m_str7;
str += "\x02" + m_array_list.GetAt(i).m_str8;
str += "\x02" + m_array_list.GetAt(i).m_str9;
str += "\r\n";
fwrite(str, sizeof(char),str.GetLength(),file);
}
fclose(file);
}
void CSummaryView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CFolderView *fv = (CFolderView*)mf->m_pTreeV;
POSITION Pos = this->GetListCtrl().GetFirstSelectedItemPosition();
int index = (int)Pos-1;
if((fv->GetSelectedItemKind() == FV_DRAFT ||
fv->GetSelectedItemKind() == FV_OUTBOX) &&
index != -1)
{
CMimeDecode md;
if(!md.DoIt(m_path + "\\" + this->m_array_list[m_stack_num-index-1].m_str5)){
return;
}
app->m_me.Initialize();
app->m_me.SetTo(md.m_hi.GetTo());
app->m_me.SetCc(md.m_hi.GetCc());
app->m_me.SetBcc(md.m_hi.GetBcc());
app->m_me.SetFrom(md.m_hi.GetFrom());
app->m_me.SetSubject(md.m_hi.GetSubject());
app->m_me.SetReplyTo(md.m_hi.GetReplyTo());
app->m_me.SetMessageID(md.m_hi.GetMsgID());
app->m_me.SetInReplyTo(md.m_hi.GetInReplyTo());
if(md.IsPgpMime())
app->m_me.SetMode(ME_MODE_PGP);
else
app->m_me.SetMode(ME_MODE_NONE);
MULTIPART_STRUCT2 data;
int i=0;
while(i < md.HowManyPart()){
CStringArray body;
data.m_content_type = md.GetRawCT(i);
data.m_content_transfer_encoding = md.GetRawCTE(i);
data.m_content_disposition = md.GetRawCD(i);
md.GetBody(i, body);
g_cstra2cstr(body, data.m_body, g_cstra_getsize(body));
data.m_encoding_type = md.GetEncodingType(i);
data.m_file_name = md.GetFileName(i);
data.m_type = md.GetContentType(i);
app->m_me.AddMultipart(data);
i++;
}
if(fv->GetSelectedItemKind() == FV_DRAFT){
CUIntArray ia;
this->GetSelectedMail(ia);
this->DeleteMail(ia);
}
app->CreateDraftFrame(mf->m_pAcntV->GetCurrentAccountName());
}
*pResult = 0;
}
void CSummaryView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CFolderView *fv = (CFolderView *)mf->m_pTreeV;
CStringArray cstra;
CString message;
CUIntArray ia;
CString current_account = mf->m_pAcntV->GetCurrentAccountName();
switch(nChar){
case 46: // if press del key, delete mail
this->GetSelectedMail(ia);
if(this->m_index == -1){
return;
}
if(fv->GetSelectedItemKind() != FV_TRASH){
if(ia.GetSize() == 1){
message = this->m_array_list[this->m_stack_num-this->m_index-1].m_str2+"\r\n\r\ntrashに移してもよいですか?";
}else if(ia.GetSize() > 1){
message = "\r\n\r\ntrashに移してもよいですか?";
}
if(IDYES == AfxMessageBox(message, MB_YESNO)){
this->MoveMail(ia, app->m_app_path+"\\"+current_account+"\\trash", SMRY_COLUMN_FROM);
}
}else{
if(ia.GetSize() == 1){
message = this->m_array_list[this->m_stack_num-this->m_index-1].m_str2+"\r\n\r\n削除してもよいですか?";
}else if(ia.GetSize() > 1){
message = "\r\n\r\n削除してもよいですか?";
}
if(IDYES == AfxMessageBox(message, MB_YESNO)){
this->DeleteMail(ia);
}
}
break;
default:
break;
}
CListView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSummaryView::OnSetFocus(CWnd* pOldWnd)
{
CListView::OnSetFocus(pOldWnd);
}
void CSummaryView::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CUIntArray ia;
CListCtrl &lc = GetListCtrl();
CPochyApp* app = (CPochyApp*)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CFolderView* fv = mf->m_pTreeV;
fv->m_ListItemDrag = pNMListView->iItem;
fv->m_hitemDrag = NULL;
POINT pt;
pt.x = pt.y = 8;
this->GetSelectedMail(ia);
if(ia.GetSize() > 1){
fv->m_drag_image.BeginDrag(1, CPoint(8, 8));
}else{
fv->m_drag_image.BeginDrag(0, CPoint(8, 8));
}
pt = pNMListView->ptAction;
ClientToScreen(&pt);
fv->m_drag_image.DragEnter(NULL, pt);
fv->m_bLDragging = TRUE;
fv->m_hitemDrop = NULL;
fv->SetCapture();
*pResult = 0;
}
BOOL CSummaryView::SaveMail(CString path, CString mail, int mail_status, int what_kind_box)
{
if(path.IsEmpty()){
return FALSE;
}
CString header;
CString list;
CString subject;
CString to;
CString from;
CString date;
CString seq;
CString size;
CString buf;
CString stat;
CString message_id;
CString in_reply_to;
CString char_set;
int num;
SLISTSTACK data;
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;
num = g_get_min_num(path);
// CStringにseq番号をセットする(メール保存用)
seq.Format("%d", num);
// メールの保存
CCodeConvert cc(mail);
mail = cc.ToJis();
g_cstring2file(mail, path + "\\" + seq);
// メールサイズの取得(必ずメールを保存した後に)
size.Format("%d", g_getfs(path + "\\" + seq));
// メールからヘッダだけ抜き出してdecodeし必要なヘッダ情報を取得する
CHeaderInfo hi;
CStringArray cstra;
header = mail.Left(mail.Find("\r\n\r\n")+2);
g_cstr2cstra(header, cstra,"\r\n");
hi.DoIt(cstra);
subject = hi.GetSubject();
subject.Remove('\r');
subject.Remove('\n');
to = hi.GetTo();
to.Remove('\r');
to.Remove('\n');
from = hi.GetFrom();
from.Remove('\r');
from.Remove('\n');
message_id = hi.GetMsgID();
message_id.Remove('\r');
message_id.Remove('\n');
in_reply_to = hi.GetInReplyTo();
in_reply_to.Remove('\r');
in_reply_to.Remove('\n');
char_set = hi.GetCharset();
char_set.Remove('\r');
char_set.Remove('\n');
date = hi.GetDate();
// dateを持たないメールの場合
if(date.IsEmpty()){
CTime t = CTime::GetCurrentTime();
date.Format("%02d/%02d/%d %02d:%02d:%02d",
t.GetYear(),
t.GetMonth(),
t.GetDay(),
t.GetHour(),
t.GetMinute(),
t.GetSecond());
}
// statの設定
if(hi.GetBoundary().IsEmpty() && mail_status == SMRY_STATUS_NEW)
stat = "N ";
else if(!hi.GetBoundary().IsEmpty() && mail_status == SMRY_STATUS_NONE)
stat = " M";
else if(hi.GetBoundary().IsEmpty() && mail_status == SMRY_STATUS_NONE)
stat = " ";
else
stat = "NM";
// listの設定
list += size;
list += "\x02";
list += subject;
list += "\x02";
// 保存先によってサマリーに表示される情報が違うため
if(what_kind_box == SMRY_COLUMN_TO)
list += to;
else
list += from;
list += "\x02";
list += date;
list += "\x02";
list += seq;
list += "\x02";
list += stat;
list += "\x02";
list += message_id;
list += "\x02";
list += in_reply_to;
list += "\x02";
list += char_set;
list += "\r\n";
// listviewのためのデータを保存
CStdioFile Write2List;
if(!Write2List.Open(path + "\\list",
CFile::modeCreate
|CFile::modeNoTruncate
|CFile::modeWrite
|CFile::typeBinary))
{
AfxMessageBox("CStdioFile: error cannot open list file");
return FALSE;
}
Write2List.SeekToEnd();
Write2List.WriteString(list);
Write2List.Close();
data.m_str1 = size;
data.m_str2 = subject;
// 保存先によってサマリーに表示される情報が違うため
if(what_kind_box == SMRY_COLUMN_TO)
data.m_str3 = to;
else
data.m_str3 = from;
data.m_str4 = date;
data.m_str5 = seq;
data.m_str6 = stat;
data.m_str7 = message_id;
data.m_str8 = in_reply_to;
data.m_str9 = char_set;
// 保存先が現在表示されているフォルダなら以下を実行
if(m_path == path){
AddList(&data);
if(m_index != -1){
m_index++;
}
// 未読メールの数m_unreadを++する
if(stat.Find("N") != -1){
CString unread;
unread.Format("未読 %d メール数 %d", ++m_unread, m_stack_num);
mf->SetStatusBarText(2, unread);
}
}
return TRUE;
}
BOOL CSummaryView::SaveMail(CString path, CStringArray &mail, int mail_status, int what_kind_box)
{
if(path.IsEmpty()){
return FALSE;
}
CString header;
CString list;
CString subject;
CString to;
CString from;
CString date;
CString seq;
CString size;
CString buf;
CString stat;
CString message_id;
CString in_reply_to;
CString char_set;
int num;
SLISTSTACK data;
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;
// seeking for minimum num. this is used as name of file when mail is saved. MH?
num = g_get_min_num(path);
seq.Format("%d", num);
// saving mail in MH format ? is this MH format or not, I don't know precisely.
g_cstra2file(path + "\\" + seq, mail);
// getting size of mail (this must be done after saving mail)
size.Format("%d", g_getfs(path + "\\" + seq));
// decoding mail and getting neccesary information.
CHeaderInfo hi;
hi.DoIt(mail);
subject = hi.GetSubject();
subject.Remove('\r');
subject.Remove('\n');
to = hi.GetTo();
to.Remove('\r');
to.Remove('\n');
from = hi.GetFrom();
from.Remove('\r');
from.Remove('\n');
message_id = hi.GetMsgID();
message_id.Remove('\r');
message_id.Remove('\n');
in_reply_to = hi.GetInReplyTo();
in_reply_to.Remove('\r');
in_reply_to.Remove('\n');
char_set = hi.GetCharset();
char_set.Remove('\r');
char_set.Remove('\n');
date = hi.GetDate();
// if mail don't have any information about DATE, below is done.
if(date.IsEmpty()){
CTime t = CTime::GetCurrentTime();
date.Format("%02d/%02d/%02d %02d:%02d:%02d",
t.GetYear(),
t.GetMonth(),
t.GetDay(),
t.GetHour(),
t.GetMinute(),
t.GetSecond());
}
// set current status to stat.
if(hi.GetBoundary().IsEmpty() && mail_status == SMRY_STATUS_NEW)
stat = "N ";
else if(!hi.GetBoundary().IsEmpty() && mail_status == SMRY_STATUS_NONE)
stat = " M";
else if(hi.GetBoundary().IsEmpty() && mail_status == SMRY_STATUS_NONE)
stat = " ";
else
stat = "NM";
// setting content of cummaryview into list.
list += size;
list += "\x02";
list += subject;
list += "\x02";
// content of summaryview is changable up to which folder is seleceted.
// especialy, outbox is selected, summaryview display [To] address instead of [From] address.
if(what_kind_box == SMRY_COLUMN_TO)
list += to;
else
list += from;
list += "\x02";
list += date;
list += "\x02";
list += seq;
list += "\x02";
list += stat;
list += "\x02";
list += message_id;
list += "\x02";
list += in_reply_to;
list += "\x02";
list += char_set;
list += "\r\n";
// saving data for summaryview.
CStdioFile Write2List;
if(!Write2List.Open(path + "\\list",
CFile::modeCreate
|CFile::modeNoTruncate
|CFile::modeWrite
|CFile::typeBinary))
{
AfxMessageBox("CStdioFile: error cannot open list file");
return FALSE;
}
Write2List.SeekToEnd();
Write2List.WriteString(list);
Write2List.Close();
data.m_str1 = size;
data.m_str2 = subject;
// content of summaryview is changing up to which folder is selected in folderview.
// if outbox is selected, summaryview display [To] address instead of [From].
// if other box but outbox is selected, viceversa.
if(what_kind_box == SMRY_COLUMN_TO)
data.m_str3 = to;
else
data.m_str3 = from;
data.m_str4 = date;
data.m_str5 = seq;
data.m_str6 = stat;
data.m_str7 = message_id;
data.m_str8 = in_reply_to;
data.m_str9 = char_set;
// if saving to current displayed folder, need to increment m_index.
// m_index is variable of current selected item number.
if(m_path == path){
AddList(&data);
if(m_index != -1){
m_index++;
}
// number of unreaded mail is incremented
if(stat.Find("N") != -1){
CString unread;
unread.Format("未読 %d メール数 %d", ++m_unread, m_stack_num);
mf->SetStatusBarText(2, unread);
}
}
return TRUE;
}
BOOL CSummaryView::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN){
if(pMsg->wParam == 78){ // pressing [n] is same as [PgDn].
pMsg->wParam = 40;
}
else if(pMsg->wParam == 80){ // pressing [p] is same as [PgUp].
pMsg->wParam = 38;
}
}
return CListView::PreTranslateMessage(pMsg);
}
// quick sort, is not completed. this cannot work very fast.
void CSummaryView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
if(m_stack_num == 0) return;
CPochyApp* app = (CPochyApp*)AfxGetApp();
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CWaitCursor wait_cursor;
// get current message status from folder.ini
int order;
int num = GetPrivateProfileInt("list", "order", 0, m_path+"\\folder.ini");
// change colum message depending on message order
if(num/10 == pNMListView->iSubItem){
switch(num%10){
case 0:
num = pNMListView->iSubItem*10+1;
order = 1;
break;
case 1:
num = pNMListView->iSubItem*10+2;
order = 2;
break;
case 2:
num = pNMListView->iSubItem*10;
order = 0;
break;
}
}else{
num = pNMListView->iSubItem*10+1;
order = 1;
}
this->SetColumnOrderStatus(num);
// save current message order status to folder.ini
CString buf;
buf.Format("%d", num);
WritePrivateProfileString("list", "order", buf, m_path+"\\folder.ini");
// start quicksort
switch(pNMListView->iSubItem){
case 0:
m_status_changed = TRUE;
this->QuickSort(0, m_array_list.GetUpperBound(), 0, order);
break;
case 1:
m_status_changed = TRUE;
this->QuickSort(1, m_array_list.GetUpperBound(), 1, order);
break;
case 2:
m_status_changed = TRUE;
this->QuickSort(0, m_array_list.GetUpperBound(), 2, order);
break;
case 3:
m_status_changed = TRUE;
this->QuickSort(0, m_array_list.GetUpperBound(), 3, order);
break;
case 4:
m_status_changed = TRUE;
this->QuickSort(0, m_array_list.GetUpperBound(), 4, order);
break;
}
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CTextView *tv =(CTextView*)mf->m_pTextV;
CListCtrl &lc = GetListCtrl();
m_index = -1;
lc.DeleteAllItems();
tv->SetWindowText("");
mf->HideMultiPartView(TRUE);
lc.SetItemCountEx(m_stack_num, LVSICF_NOSCROLL);
*pResult = 0;
}
// below is implementation of quick sort, fuckin dirty code, need to be modified later.
int CSummaryView::QuickSortPartition(int start, int end, int item_num, int order)
{
int i, j, k;
CString pivot;
CString buf1;
CString buf2;
i = start;
j = end;
k = (end+start)/2;
this->QuickSortSwapStack(k, end);
if(order != 0){
switch(item_num){
case 0:
if(order == 1){
pivot = m_array_list.GetAt(end).m_str6+m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str6+m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) < 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str6+m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) > 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}else if(order == 2){
pivot = m_array_list.GetAt(end).m_str6+m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str6+m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) > 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str6+m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) < 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}
break;
case 1:
int c;
c = atoi(m_array_list.GetAt(end).m_str1);
if(order == 1){
for(;;){
while(i<j){
if(c < atoi(m_array_list.GetAt(i).m_str1))
break;
i++;
}
while(i<j){
if(c > atoi(m_array_list.GetAt(j).m_str1))
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}else if(order == 2){
for(;;){
while(i<j){
if(c > atoi(m_array_list.GetAt(i).m_str1))
break;
i++;
}
while(i<j){
if(c < atoi(m_array_list.GetAt(j).m_str1))
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}
break;
case 2:
if(order == 1){
pivot = m_array_list.GetAt(end).m_str2+m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str2+m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) < 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str2+m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) > 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}else if(order == 2){
pivot = m_array_list.GetAt(end).m_str2+m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str2+m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) > 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str2+m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) < 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}
break;
case 3:
if(order == 1){
pivot = m_array_list.GetAt(end).m_str3+m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str3+m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) < 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str3+m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) > 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}else if(order == 2){
pivot = m_array_list.GetAt(end).m_str3+m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str3+m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) > 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str3+m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) < 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}
break;
case 4:
if(order == 1){
pivot = m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) < 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) > 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}else if(order == 2){
pivot = m_array_list.GetAt(end).m_str4;
for(;;){
while(i<j){
buf1 = m_array_list.GetAt(i).m_str4;
if(_stricmp(buf1, pivot) > 0)
break;
i++;
}
while(i<j){
buf2 = m_array_list.GetAt(j).m_str4;
if(_stricmp(buf2, pivot) < 0)
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}
break;
}
}else if(order == 0){
int c;
c = atoi(m_array_list.GetAt(end).m_str5);
for(;;){
while(i<j){
if(c < atoi(m_array_list.GetAt(i).m_str5))
break;
i++;
}
while(i<j){
if(c > atoi(m_array_list.GetAt(j).m_str5))
break;
j--;
}
if(i >= j)
break;
this->QuickSortSwapStack(i, j);
}
}
this->QuickSortSwapStack(i, end);
return i;
}
// swap all member of SLISTSTACK one another.
void CSummaryView::QuickSortSwapStack(int i, int j)
{
SLISTSTACK tmp;
tmp.m_str1 = m_array_list.GetAt(i).m_str1;
tmp.m_str2 = m_array_list.GetAt(i).m_str2;
tmp.m_str3 = m_array_list.GetAt(i).m_str3;
tmp.m_str4 = m_array_list.GetAt(i).m_str4;
tmp.m_str5 = m_array_list.GetAt(i).m_str5;
tmp.m_str6 = m_array_list.GetAt(i).m_str6;
tmp.m_str7 = m_array_list.GetAt(i).m_str7;
tmp.m_str8 = m_array_list.GetAt(i).m_str8;
tmp.m_str9 = m_array_list.GetAt(i).m_str9;
tmp.m_str10 = m_array_list.GetAt(i).m_str10;
tmp.m_str11 = m_array_list.GetAt(i).m_str11;
tmp.m_str12 = m_array_list.GetAt(i).m_str12;
m_array_list.SetAt(i, m_array_list.GetAt(j));
m_array_list.SetAt(j, tmp);
}
// entry function of quick sort.
void CSummaryView::QuickSort(int start, int end, int item_num, int order)
{
if(start >= end)
return;
int p = this->QuickSortPartition(start, end, item_num, order);
this->QuickSort(start, p-1, item_num, order);
this->QuickSort(p+1, end, item_num, order);
}
// marking message order on header control of summaryview.
void CSummaryView::SetColumnOrderStatus(int status)
{
int column = status/10;
int order = status%10;
LV_COLUMN clm;
CString buf;
clm.mask = LVCF_TEXT;
clm.cchTextMax = BUF_LENGTH;
// clear all marking
for(int i=0; i<5; i++){
clm.pszText = buf.GetBuffer(BUF_LENGTH);
this->GetListCtrl().GetColumn(i, &clm);
buf.ReleaseBuffer();
buf.Replace("▲", ""); buf.Replace("▼", "");
clm.pszText = buf.GetBuffer(0);
this->GetListCtrl().SetColumn(i, &clm);
buf.ReleaseBuffer();
}
// set column order on header control.
clm.pszText = buf.GetBuffer(BUF_LENGTH);
this->GetListCtrl().GetColumn(column, &clm);
buf.ReleaseBuffer();
switch(order){
case 1:
buf+="▼";
break;
case 2:
buf+="▲";
break;
}
clm.pszText = buf.GetBuffer(0);
this->GetListCtrl().SetColumn(column, &clm);
buf.ReleaseBuffer();
}
void CSummaryView::ReBuildSummary(CString path, int mode)
{
CFileFind ff;
BOOL b;
CHeaderInfo hi;
CStringArray header;
SLISTSTACK data;
m_array_list.RemoveAll();
m_stack_num = 0;
m_status_changed = TRUE;
b = ff.FindFile(path+"\\*.*");
while(b){
header.RemoveAll();
b = ff.FindNextFile();
if(ff.IsDots())
continue;
if(ff.IsDirectory())
continue;
if(ff.GetFileName().SpanExcluding("0123456789").IsEmpty()){
g_file2cstra(path+"\\"+ff.GetFileName(), header); // this is reason why so slow
hi.DoIt(header);
CString size;
size.Format("%d", g_getfs(path + "\\" + ff.GetFileName()));
CString subject = hi.GetSubject();
subject.Remove('\r');
subject.Remove('\n');
CString to = hi.GetTo();
to.Remove('\r');
to.Remove('\n');
CString from = hi.GetFrom();
from.Remove('\r');
from.Remove('\n');
CString message_id = hi.GetMsgID();
message_id.Remove('\r');
message_id.Remove('\n');
CString in_reply_to = hi.GetInReplyTo();
in_reply_to.Remove('\r');
in_reply_to.Remove('\n');
CString char_set = hi.GetCharset();
char_set.Remove('\r');
char_set.Remove('\n');
CString date = hi.GetDate();
CString stat;
// statの設定
if(hi.GetBoundary().IsEmpty())
stat = "N ";
else
stat = "NM";
data.m_str1 = size;
data.m_str2 = subject;
// 保存先によってサマリーに表示される情報が違うため
if(mode == SMRY_COLUMN_TO)
data.m_str3 = to;
else
data.m_str3 = from;
data.m_str4 = date;
data.m_str5 = ff.GetFileName();
data.m_str6 = stat;
data.m_str7 = message_id;
data.m_str8 = in_reply_to;
data.m_str9 = char_set;
m_array_list.Add(data);
m_stack_num++;
}
}
this->QuickSort(0, m_array_list.GetSize()-1, NULL, 0);
this->SetItem(path);
}
void CSummaryView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CFolderView *fv = (CFolderView*)mf->m_pTreeV;
fv->SendMessage(WM_CANCELMODE);
CListView::OnLButtonUp(nFlags, point);
}
void CSummaryView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
const MSG* msg = GetCurrentMessage();
CPoint pt1 = msg->pt;
CPoint pt2 = msg->pt;
ScreenToClient(&pt1);
CMenu menu;
menu.LoadMenu(IDR_SUMMARYVIEW_POPUP);
CUIntArray ia;
this->GetSelectedMail(ia);
if(ia.GetSize() > 1){
// 削除を無効にする
menu.EnableMenuItem(ID_SUMMARYVIEW_HEADER_INFO, MF_GRAYED);
menu.EnableMenuItem(ID_SUMMARYVIEW_RAWMAIL_INFO, MF_GRAYED);
}else{
// 有効にする
menu.EnableMenuItem(ID_SUMMARYVIEW_HEADER_INFO, MF_ENABLED);
menu.EnableMenuItem(ID_SUMMARYVIEW_RAWMAIL_INFO, MF_ENABLED);
}
CMenu *popup = menu.GetSubMenu(0);
popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON |TPM_LEFTBUTTON, (int)pt2.x, (int)pt2.y, this);
*pResult = 0;
}
void CSummaryView::OnPopupDel()
{
if(this->m_index == -1){
return;
}
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CFolderView *fv = (CFolderView *)mf->m_pTreeV;
CStringArray cstra;
CUIntArray ia;
CString message;
CString current_account = mf->m_pAcntV->GetCurrentAccountName();
this->GetSelectedMail(ia);
if(fv->GetSelectedItemKind() != FV_TRASH){
if(ia.GetSize() == 1){
message = this->m_array_list[this->m_stack_num-this->m_index-1].m_str2+"\r\n\r\ntrashに移してもよいですか?";
}else if(ia.GetSize() > 1){
message = "\r\n\r\ntrashに移してもよいですか?";
}
if(IDYES != AfxMessageBox(message, MB_YESNO)){
return;
}
this->MoveMail(ia, app->m_app_path+"\\"+current_account+"\\trash", SMRY_COLUMN_FROM);
}else{
if(ia.GetSize() == 1){
message = this->m_array_list[this->m_stack_num-this->m_index-1].m_str2+"\r\n\r\n削除してもよいですか?";
}else if(ia.GetSize() > 1){
message = "\r\n\r\n削除してもよいですか?";
}
if(IDYES != AfxMessageBox(message, MB_YESNO)){
return;
}
this->DeleteMail(ia);
}
}
void CSummaryView::OnPopupHeaderInfo()
{
if(this->m_index == -1){
return;
}
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;
CTextView *tv = (CTextView *)mf->m_pTextV;
CString file_name = g_ma(tv->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(tv->GetCurrentRawHeader().GetBuffer(0),
sizeof(char),
tv->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 CSummaryView::OnPopupRawmailInfo()
{
if(this->m_index == -1){
return;
}
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;
CTextView *tv = (CTextView *)mf->m_pTextV;
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,
"\""+tv->GetCurrentPath()+"\"",
NULL,
SW_NORMAL);
}
void CSummaryView::OnPopupRebuild()
{
CWaitCursor wait_cursor; // turn cursor into sandglass
this->ReBuildSummary(this->m_path, SMRY_COLUMN_FROM);
}
void CSummaryView::ClearAllMail(CString path)
{
CFileFind ff;
CWaitCursor wait_cursor; // turn cursor into sandglass
BOOL b = ff.FindFile(path+"\\*.*");
if(b){
while(b){
b = ff.FindNextFile();
if(!ff.IsDirectory() && !ff.IsDots()){
DeleteFile(path+"\\"+ff.GetFileName());
}
}
if(path == this->m_path){
// refresh summaryview
this->m_array_list.RemoveAll();
this->SetItem(path);
}
}
}
void CSummaryView::MoveMail(CUIntArray &index_array, CString to, int what_kind_box)
{
if(to.IsEmpty() || index_array.GetSize() < 1){
return;
}
CWaitCursor wait_cursor; // turn cursor into sandglass
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CTextView *tv = (CTextView *)mf->m_pTextV;
CStringArray cstra;
int i=0;
while(i < index_array.GetSize()){
cstra.RemoveAll();
g_file2cstra(this->m_path+"\\"+this->m_array_list.GetAt(this->m_stack_num-index_array.GetAt(i)-1).m_str5, cstra);
this->SaveMail(to, cstra, SMRY_STATUS_NONE, what_kind_box);
i++;
}
this->DeleteMail(index_array);
}
void CSummaryView::Clear()
{
// first of all, save current summary list into list file
WriteList();
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame*)this->GetParentFrame();
CListCtrl& lc = GetListCtrl();
// delete all item;
lc.DeleteAllItems();
this->m_array_list.RemoveAll();
this->m_stack_num = 0;
this->m_path.Empty();
this->m_unread = 0;
this->m_index = -1;
// save width of listview column into ini file
CString num;
for(int i = 0; i < 5; i++){
num.Format("%d", i);
app->WriteProfileInt("SummaryViewColumn", num.GetBuffer(0), lc.GetColumnWidth(i));
}
// change column text for default
this->UpdateColumn(SMRY_COLUMN_FROM);
// renew infomation of mail in statusbar
mf->SetStatusBarText(2, "未読 0 メール数 0");
}
void CSummaryView::GetSelectedMail(CUIntArray &index_array)
{
POSITION pos = this->GetListCtrl().GetFirstSelectedItemPosition();
index_array.RemoveAll();
while(pos){
index_array.Add(this->GetListCtrl().GetNextSelectedItem(pos));
}
}