root/MultiPartView.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- IMPLEMENT_DYNCREATE
- CMultiPartView
- BEGIN_MESSAGE_MAP
- AssertValid
- Dump
- OnInitialUpdate
- OnItemchanged
- OnRclick
- OnChar
- ReArrange
- OnSize
- ExecuteFile
- OnDblclk
- PreCreateWindow
- OnMultipartSave2file
/*
* Copyright (C) 2002-2003 chik, s.hiranaka
* For license terms, see the file COPYING in this directory.
*/
// MultiPartView.cpp : インプリメンテーション ファイル
//
#include "stdafx.h"
#include "pochy.h"
#include "MultiPartView.h"
#include "TextView.h"
#include "MainFrm.h"
#include "lib.h"
#include "CodeConvert.h"
#include "direct.h" // for _mkdir
#include "quoted-printable.h"
#include "base64.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMultiPartView
IMPLEMENT_DYNCREATE(CMultiPartView, CListView)
CMultiPartView::CMultiPartView()
{
}
CMultiPartView::~CMultiPartView()
{
/* m_image->Detach();
delete m_image;*/
}
BEGIN_MESSAGE_MAP(CMultiPartView, CListView)
//{{AFX_MSG_MAP(CMultiPartView)
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged)
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_WM_CHAR()
ON_WM_SIZE()
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
ON_COMMAND(ID_MULTIPART_SAVE2FILE, OnMultipartSave2file)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMultiPartView 描画
void CMultiPartView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: この位置に描画用のコードを追加してください
}
/////////////////////////////////////////////////////////////////////////////
// CMultiPartView 診断
#ifdef _DEBUG
void CMultiPartView::AssertValid() const
{
CListView::AssertValid();
}
void CMultiPartView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMultiPartView メッセージ ハンドラ
void CMultiPartView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CListCtrl& lc = GetListCtrl();
CPochyApp *app = (CPochyApp *)AfxGetApp();
CString num;
char* Column[] = { "mime/type", "encoding", "ファイル名" };
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("TextViewColor", "BkColorR", 0),
app->GetProfileInt("TextViewColor", "BkColorG", 0),
app->GetProfileInt("TextViewColor", "BkColorB", 0));
lc.SetBkColor(m_colorEdit);
// テキストの背景色
m_colorEdit = RGB(
app->GetProfileInt("TextViewColor", "BkColorR", DEF_BKG_COLOR_R),
app->GetProfileInt("TextViewColor", "BkColorG", DEF_BKG_COLOR_G),
app->GetProfileInt("TextViewColor", "BkColorB", DEF_BKG_COLOR_B));
lc.SetTextBkColor(m_colorEdit);
// 文字の色
m_colorEdit = RGB(
app->GetProfileInt("TextViewColor", "TxtColorR", DEF_TXT_COLOR_R),
app->GetProfileInt("TextViewColor", "TxtColorG", DEF_TXT_COLOR_G),
app->GetProfileInt("TextViewColor", "TxtColorB", DEF_TXT_COLOR_B));
lc.SetTextColor(m_colorEdit);
// リストビューへカラムを設定
lvc.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
for(int i = 0; i < 3; i++){
lvc.pszText = Column[i];
num.Format("%d", i);
lvc.cx = app->GetProfileInt("MultiPartViewColumn", num.GetBuffer(0), 150);
if(lvc.cx > 1000 || lvc.cx < 1){
lvc.cx = 150;
}
lc.InsertColumn(i, &lvc);
}
// setting system icon image.
m_image.Create(16, 16, ILC_COLORDDB | ILC_MASK, 1, 100);
// lc.SetImageList(&m_image, LVSIL_SMALL);
// m_image.Add(NULL);
}
void CMultiPartView::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
m_index = pNMListView->iItem; // 現在選択されているItemを保存しておく
CPochyApp* app = (CPochyApp*)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
CTextView *tv = (CTextView*)mf->m_pTextV;
tv->DisplayPart(m_index);
*pResult = 0;
}
void CMultiPartView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
POINT pt;
if(m_index != -1){
PostMessage(WM_NULL, 0, 0); // this is point
GetCursorPos(&pt);
CMenu menu;
menu.LoadMenu(IDR_MULTIPART_POPUP);
CMenu *pPopup = menu.GetSubMenu(0);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, (int)pt.x, (int)pt.y, this);
}
*pResult = 0;
}
void CMultiPartView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CPochyApp* app = (CPochyApp*)AfxGetApp();
CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
if(mf->Char(nChar))
return;
switch(nChar){
case VK_RETURN: // 添付ファイルの場合起動
// ExecuteFile();
break;
case 'n':
// SelectNext();
break;
case 'p':
// SelectPrev();
break;
default:
break;
}
CListView::OnChar(nChar, nRepCnt, nFlags);
}
void CMultiPartView::ReArrange()
{
int i,width;
CPoint p;
CRect rect;
CListCtrl& lc = GetListCtrl();
p.x = 0;
p.y = 0;
GetClientRect(rect);
width = rect.right;
for(i=0;i<lc.GetItemCount();i++){
lc.SetItemPosition(i,p);
lc.GetItemRect(i,rect,LVIR_BOUNDS);
if(width <= rect.right && i){
p.x = 0;
p.y = rect.bottom;
lc.SetItemPosition(i,p);
lc.GetItemRect(i,rect,LVIR_BOUNDS);
}
p.x = rect.right + 20;
}
}
void CMultiPartView::OnSize(UINT nType, int cx, int cy)
{
CListView::OnSize(nType, cx, cy);
}
void CMultiPartView::ExecuteFile()
{
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;
CTextView *tv = (CTextView *)mf->m_pTextV;
CString file_name;
CString body;
CStringArray buf;
CString msg_id;
tv->m_md.GetBody(m_index, buf);
g_cstra2cstr(buf, body, g_cstra_getsize(buf));
if(m_index != -1){
// 添付ファイルの場合
if(!tv->m_md.GetFileName(m_index).IsEmpty()){
if(!g_is_there(app->m_app_path+"\\attached")) // attachedフォルダがない場合は作る
_mkdir(app->m_app_path+"\\attached");
file_name = tv->m_md.GetFileName(m_index);
FILE* file = fopen(app->m_app_path+"\\attached\\"+file_name, "wb");
// base64の処理
if(tv->GetCurrentCTE() == BASE64){
body.Remove('\r');
body.Remove('\n');
char* in = body.GetBuffer(0);
char* out = new char[body.GetLength()];
int len = from64tobits(out, in, strlen(in));
if(tv->GetCurrentCTE() == SEVEN_BIT || tv->GetCurrentCTE() == EIGHT_BIT){
CString cstr_out = out;
CCodeConvert cc(cstr_out);
cstr_out = cc.ToSjis();
out = cstr_out.GetBuffer(0);
}
fwrite(out, sizeof(char), len, file);
fclose(file);
delete out;
}
// quoted-pritableの処理
else if(tv->GetCurrentCTE() == QUOTED_PRINTABLE){
char* in2 = body.GetBuffer(0);
char* out2 = new char[body.GetLength()+10];
int len = fromQPtobits(out2, in2, strlen(in2));
if(tv->GetCurrentCTE() == SEVEN_BIT || tv->GetCurrentCTE() == EIGHT_BIT){
CString cstr_out = out2;
CCodeConvert cc(cstr_out);
cstr_out = cc.ToSjis();
out2 = cstr_out.GetBuffer(0);
}
fwrite(out2, sizeof(char), len, file);
fclose(file);
delete out2;
}else{
if(tv->GetCurrentCTE() == SEVEN_BIT || tv->GetCurrentCTE() == EIGHT_BIT){
CCodeConvert cc(body);
body = cc.ToSjis();
}
fwrite(body.GetBuffer(0), sizeof(char), body.GetLength(), file);
fclose(file);
}
// ファイルを開いちゃう
ShellExecute(NULL, "open", app->m_app_path+"\\attached\\"+file_name, NULL, NULL, SW_SHOW);
}
// text/htmlの場合(text/htmlでbase64 quoted-printableの処理が必要)
else if(g_cstr_compare(tv->m_md.GetContentType(m_index), "Text/Html")){
if(BASE64 == tv->GetCurrentCTE()){
char* in_base64 = body.GetBuffer(0);
char* out_base64 = new char[body.GetLength()];
int len = from64tobits(out_base64, in_base64, strlen(in_base64));
body.Empty();
body = out_base64;
delete out_base64;
}
else if(QUOTED_PRINTABLE == tv->GetCurrentCTE()){
char* in_qp = body.GetBuffer(0);
char* out_qp = new char[body.GetLength()];
int len = fromQPtobits(out_qp, in_qp, strlen(in_qp));
body.Empty();
body = out_qp;
delete out_qp;
}
msg_id = tv->m_md.m_hi.GetMsgID();
msg_id = g_ma(msg_id);
msg_id.Replace(".", "_");
file_name = msg_id + ".html";
if(!g_is_there(app->m_app_path+"\\temp")) // tempフォルダがない場合は作る
_mkdir(app->m_app_path+"\\temp");
FILE* file = fopen(app->m_app_path+"\\temp\\"+file_name, "wb");
// sjis変換
CCodeConvert cc(body);
body = cc.ToSjis();
fwrite(body.GetBuffer(0), sizeof(char), body.GetLength(), file);
fclose(file);
// ファイルを開いちゃう
ShellExecute(NULL, "open", app->m_app_path+"\\temp\\"+file_name, NULL, NULL, SW_SHOW);
}
// text/plainの場合(text/plainでbase64 quoted-printableの処理が必要)
else if(g_cstr_compare(tv->m_md.GetContentType(m_index), "Text/Plain")){
if(BASE64 == tv->GetCurrentCTE()){
char* in_base64 = body.GetBuffer(0);
char* out_base64 = new char[body.GetLength()];
int len = from64tobits(out_base64, in_base64, strlen(in_base64));
body.Empty();
body = out_base64;
delete out_base64;
}
else if(QUOTED_PRINTABLE == tv->GetCurrentCTE()){
char* in_qp = body.GetBuffer(0);
char* out_qp = new char[body.GetLength()];
int len = fromQPtobits(out_qp, in_qp, strlen(in_qp));
body.Empty();
body = out_qp;
delete out_qp;
}
msg_id = tv->m_md.m_hi.GetMsgID();
msg_id = g_ma(msg_id);
msg_id.Replace(".", "_");
file_name = msg_id + ".txt";
if(!g_is_there(app->m_app_path+"\\temp")) /* tempフォルダがない場合は作る */
_mkdir(app->m_app_path+"\\temp");
FILE* file = fopen(app->m_app_path+"\\temp\\"+file_name, "wb");
// sjis変換
CCodeConvert cc(body);
body = cc.ToSjis();
fwrite(body.GetBuffer(0), sizeof(char), body.GetLength(), file);
fclose(file);
// ファイルを開いちゃう
CString editor_path = app->GetProfileString("Editor", "Path", "notepad");
if(editor_path.IsEmpty())
editor_path = "notepad";
// ファイルpathをsetting.iniで指定されたeditorで開く
ShellExecute(NULL,NULL, editor_path, "\""+app->m_app_path+"\\temp\\"+file_name+"\"", NULL, SW_SHOWNORMAL);
}
// message/rfc822の場合
else if(g_cstr_compare(tv->m_md.GetContentType(m_index), "message/rfc822")){
if(BASE64 == tv->GetCurrentCTE()){
char* in_base64 = body.GetBuffer(0);
char* out_base64 = new char[body.GetLength()];
int len = from64tobits(out_base64, in_base64, strlen(in_base64));
body.Empty();
body = out_base64;
delete out_base64;
}
else if(QUOTED_PRINTABLE == tv->GetCurrentCTE()){
char* in_qp = body.GetBuffer(0);
char* out_qp = new char[body.GetLength()];
int len = fromQPtobits(out_qp, in_qp, strlen(in_qp));
body.Empty();
body = out_qp;
delete out_qp;
}
msg_id = tv->m_md.m_hi.GetMsgID();
msg_id = g_ma(msg_id);
msg_id.Replace(".", "_");
file_name = msg_id + ".txt";
if(!g_is_there(app->m_app_path+"\\temp")) /* tempフォルダがない場合は作る */
_mkdir(app->m_app_path+"\\temp");
FILE* file = fopen(app->m_app_path+"\\temp\\"+file_name, "wb");
// sjis変換
CCodeConvert cc(body);
body = cc.ToSjis();
fwrite(body.GetBuffer(0), sizeof(char), body.GetLength(), file);
fclose(file);
// ファイルを開いちゃう
CString editor_path = app->GetProfileString("Editor", "Path", "notepad");
if(editor_path.IsEmpty())
editor_path = "notepad";
// ファイルpathをsetting.iniで指定されたeditorで開く
ShellExecute(NULL,NULL, editor_path, "\""+app->m_app_path+"\\temp\\"+file_name+"\"", NULL, SW_SHOWNORMAL);
}
}
}
void CMultiPartView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
ExecuteFile();
*pResult = 0;
}
BOOL CMultiPartView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= LVS_SINGLESEL;
return CListView::PreCreateWindow(cs);
}
void CMultiPartView::OnMultipartSave2file()
{
CString path;
CString b_cstr;
CStringArray b_cstra;
CString Outbuf;
CString file_name;
char *pOutbuf;
int len;
FILE *file;
CPochyApp *app = (CPochyApp *)AfxGetApp();
CMainFrame *mf = (CMainFrame *)app->m_pMainWnd;
CTextView *tv = (CTextView *)mf->m_pTextV;
CListCtrl& lc = GetListCtrl();
file_name = tv->m_md.GetFileName(m_index);
CFileDialog dlg( FALSE, NULL, file_name, OFN_HIDEREADONLY, NULL, this );
if( dlg.DoModal() == IDOK ){
path = dlg.GetPathName();
if(g_is_there(path)){
if(IDYES != AfxMessageBox(path+"\r\n\r\nは既に存在します。上書きしてもよいですか?", MB_YESNO))
return;
}
file = fopen(path.GetBuffer(0), "wb");
tv->m_md.GetBody(m_index, b_cstra);
g_cstra2cstr(b_cstra, b_cstr, g_cstra_getsize(b_cstra));
// base64でエンコードされた添付ファイルの場合
if(tv->GetCurrentCTE() == BASE64){
b_cstr.Remove('\r');
b_cstr.Remove('\n');
pOutbuf = Outbuf.GetBuffer(b_cstr.GetLength());
len = from64tobits(pOutbuf, b_cstr.GetBuffer(0), b_cstr.GetLength());
fwrite(pOutbuf, sizeof(char), len, file);
}
// quoted-printableの場合
else if(tv->GetCurrentCTE() == QUOTED_PRINTABLE){
pOutbuf = Outbuf.GetBuffer(b_cstr.GetLength()+10);
len = fromQPtobits(pOutbuf, b_cstr.GetBuffer(0), b_cstr.GetLength());
fwrite(pOutbuf, sizeof(char), len, file);
}
else{ // その他の場合(7bit 8bit bin
CCodeConvert cc(b_cstr);
b_cstr = cc.ToSjis();
fwrite(b_cstr.GetBuffer(0), sizeof(char), b_cstr.GetLength(), file);
}
fclose(file);
}
}