Skip to content

Commit

Permalink
Added support for direct open of mail file by double-left-click. Enha…
Browse files Browse the repository at this point in the history
…nced handling of inline text blocks.
  • Loading branch information
zigm committed Oct 13, 2023
1 parent 79200ce commit 5c491db
Show file tree
Hide file tree
Showing 16 changed files with 254 additions and 28 deletions.
8 changes: 8 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@

Changes
---

v 1.0.3.39

- To improve mboxview, please post reviews on what works, what doesn't, create bug tickets and enhancement requests.;
- Enhanced handling of text/html and text/plain inline blocks as both the attachments and message text when required.;
- Enhanced MBox Viewer to open mail archive file directly by double-left-clicking on the file.;
- Updated User Manual to describe new and updated features.;

v 1.0.3.38

- To improve mboxview, please post reviews on what works, what doesn't, create bug tickets and enhancement requests;
Expand Down
6 changes: 6 additions & 0 deletions ReadMe.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ The LICENSE.txt file was added in v1.0.3.4 to make the licensing explicit and to

Changes
---
v 1.0.3.39

- To improve mboxview, please post reviews on what works, what doesn't, create bug tickets and enhancement requests.;
- Enhanced handling of text/html and text/plain inline blocks as both the attachments and message text when required.;
- Enhanced MBox Viewer to open mail archive file directly by double-left-clicking on the file.;
- Updated User Manual to describe new and updated features.;

v 1.0.3.38

Expand Down
Binary file modified UserGuide.odt
Binary file not shown.
Binary file modified UserGuide.pdf
Binary file not shown.
8 changes: 8 additions & 0 deletions mboxview.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@
</DebugInformationFormat>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -351,6 +352,7 @@
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<StackReserveSize>2097152</StackReserveSize>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
Expand Down Expand Up @@ -390,6 +392,7 @@
</DebugInformationFormat>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -402,6 +405,7 @@
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<StackReserveSize>2097152</StackReserveSize>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
Expand Down Expand Up @@ -532,6 +536,7 @@
<ExceptionHandling>Async</ExceptionHandling>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<OmitFramePointers>false</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -544,6 +549,7 @@
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<StackReserveSize>2097152</StackReserveSize>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
Expand Down Expand Up @@ -576,6 +582,7 @@
<CallingConvention>FastCall</CallingConvention>
<ExceptionHandling>Async</ExceptionHandling>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -588,6 +595,7 @@
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<StackReserveSize>2097152</StackReserveSize>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
Expand Down
12 changes: 8 additions & 4 deletions src/ChildView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)


BOOL bEmlPrewviewMode = CMainFrame::m_commandLineParms.m_bEmlPreviewMode;
BOOL bDirectFileOpenMode = CMainFrame::m_commandLineParms.m_bDirectFileOpenMode;

if (bEmlPrewviewMode)
treeSize.cx = 0;
Expand Down Expand Up @@ -197,7 +198,7 @@ int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
else if (m_msgViewPosition == 3) // windows on left
{
msgSize.cx = msg_frameCx_TreeNotInHide;
if (bEmlPrewviewMode)
if (bEmlPrewviewMode && !bDirectFileOpenMode)
msgSize.cx = frameSize.cx*2;
msgSize.cy = 200;
}
Expand All @@ -220,20 +221,23 @@ int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
listSize.cx = frameSize.cx - treeSize.cx;
listSize.cy = list_frameCy_TreeNotInHide;
if (bEmlPrewviewMode)
if (bEmlPrewviewMode && !bDirectFileOpenMode)
listSize.cy = 0;
else if (bDirectFileOpenMode)
listSize.cy = 90;

}
else if (m_msgViewPosition == 2) // windows on right
{
listSize.cx = list_frameCx_TreeNotInHide;
if (bEmlPrewviewMode)
if (bEmlPrewviewMode && !bDirectFileOpenMode)
listSize.cx = 0;
listSize.cy = 200;
}
else if (m_msgViewPosition == 3) // windows on left
{
listSize.cx = list_frameCx_TreeNotInHide;
if (bEmlPrewviewMode)
if (bEmlPrewviewMode && !bDirectFileOpenMode)
listSize.cx = 0;
listSize.cy = 200;
}
Expand Down
4 changes: 4 additions & 0 deletions src/MainFrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct CommandLineParms
{
m_bEmlPreviewMode = FALSE; m_progressBarDelay = -1;
m_exportEml = FALSE; m_traceCase = 0; m_bEmlPreviewFolderExisted = FALSE;
m_hasOptions = FALSE; m_bDirectFileOpenMode = FALSE;
}
void Clear()
{
Expand All @@ -94,6 +95,7 @@ struct CommandLineParms
}
int VerifyParameters();
//
BOOL m_hasOptions;
CString m_allCommanLineOptions;
//
CString m_mboxListFilePath;
Expand All @@ -103,6 +105,8 @@ struct CommandLineParms
CString m_mboxFolderPath;
CString m_mboxFileNameOrPath;
BOOL m_bEmlPreviewFolderExisted;
// only file name as cpmmand line param
BOOL m_bDirectFileOpenMode;
//
int m_progressBarDelay;
BOOL m_exportEml;
Expand Down
87 changes: 84 additions & 3 deletions src/MboxMail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,43 @@ UINT getCodePageFromHtmlBody(SimpleString *buffer, std::string &charset);

bool MailBodyContent::IsAttachment()
{
if (!m_attachmentName.IsEmpty() ||
// Temp fix in 1.0.3.39 for incorrect determination of attachment type. Review in v1.0.3.40 UNICODE
if (((m_contentType.CompareNoCase("text/html") == 0) || (m_contentType.CompareNoCase("text/plain") == 0)) &&
(m_contentDisposition.CompareNoCase("attachment") != 0))
{
return false;
}
// end fix
else if (!m_attachmentName.IsEmpty() ||
!m_contentId.IsEmpty() ||
!m_contentLocation.IsEmpty() ||
(m_contentDisposition.CompareNoCase("attachment") == 0)
)
{
return true;
}
else
return false;
}

bool MailBodyContent::IsInlineAttachment()
{
// Temp fix in 1.0.3.39 for incorrect determination of attachment type. Review in v1.0.3.40 UNICODE
if (((m_contentType.CompareNoCase("text/html") == 0) || (m_contentType.CompareNoCase("text/plain") == 0)) &&
(m_contentDisposition.CompareNoCase("inline") == 0))
{
if (!m_attachmentName.IsEmpty() ||
!m_contentId.IsEmpty() ||
!m_contentLocation.IsEmpty())
return true;
else
return false;
}
else
return false;
}


struct MsgIdHash {
public:
hashsum_t operator()(const MboxMail *key) const
Expand Down Expand Up @@ -5161,7 +5188,7 @@ int MboxMail::printAttachmentNamesAsHtml(CFile *fpm, int mailPosition, SimpleStr
body = m->m_ContentDetailsArray[j];

BOOL showAttachment = FALSE;
if (body->IsAttachment())
if (body->IsAttachment() || body->IsInlineAttachment())
{
if (showAllAttachments || !body->m_isEmbeddedImage)
showAttachment = TRUE;
Expand Down Expand Up @@ -5429,7 +5456,7 @@ int MboxMail::printAttachmentNamesAsText(CFile *fpm, int mailPosition, SimpleStr
body = m->m_ContentDetailsArray[j];

BOOL showAttachment = FALSE;
if (body->IsAttachment())
if (body->IsAttachment() || body->IsInlineAttachment())
{
if (showAllAttachments || !body->m_isEmbeddedImage)
showAttachment = TRUE;
Expand Down Expand Up @@ -7192,6 +7219,38 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, int mailPosition, SimpleString *o
return ret;
}


int MboxMail::AppendInlineAttachmentNameSeparatorLine(MailBodyContent* body, int bodyCnt, SimpleString* outbuf, int textType)
{
if (bodyCnt > 0)
{
if (body->m_contentDisposition.CompareNoCase("inline") == 0)
{
if (!body->m_attachmentName.IsEmpty())
{
if (textType == 0)
{
outbuf->Append("\n\n\n----- ");
outbuf->Append((LPCSTR)body->m_attachmentName, body->m_attachmentName.GetLength());
outbuf->Append(" ---------------------\n\n");
}
else
{
CString bdycharset = "UTF-8"; // FIXMEFIXME
//outbuf->Append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=" + bdycharset + "\">");
outbuf->Append("\r\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=");
outbuf->Append((LPCSTR)bdycharset, bdycharset.GetLength());
outbuf->Append("\"><body><span><br><br><br>----- ");
outbuf->Append((LPCSTR)body->m_attachmentName, body->m_attachmentName.GetLength());
outbuf->Append(" ---------------------<br><br>");
outbuf->Append("</span></body></html>\r\n");
}
}
}
}
return 0;
}

int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf, UINT &pageCode, int textType)
{
_int64 fileOffset;
Expand Down Expand Up @@ -7227,11 +7286,14 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf

body = m->m_ContentDetailsArray[j];

#if 0
// Not correct if Content-Disposition is "inline"
if ((!body->m_attachmentName.IsEmpty()) ||
(body->m_contentDisposition.CompareNoCase("attachment") == 0))
{
continue;
}
#endif
if (textType == 0)
{
if (body->m_contentType.CompareNoCase("text/plain") != 0)
Expand All @@ -7246,6 +7308,13 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf
continue;
}
}
#if 1
// Fix for content-type of type text
if (body->m_contentDisposition.CompareNoCase("attachment") == 0)
{
continue;
}
#endif

if (bodyCnt == 0)
{
Expand Down Expand Up @@ -7313,11 +7382,14 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf
{
int needLength = dlength + outbuf->Count();
outbuf->Resize(needLength);
AppendInlineAttachmentNameSeparatorLine(body, bodyCnt, outbuf, textType);
char *outptr = outbuf->Data(outbuf->Count());

int retlen = d64.GetOutput((unsigned char*)outptr, dlength);
if (retlen > 0)
{
outbuf->SetCount(outbuf->Count() + retlen);
}

// All below blocks are commented out.
// they were used to; test enhanced support for Gmal Labels
Expand Down Expand Up @@ -7459,6 +7531,7 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf
{
int needLength = dlength + outbuf->Count();
outbuf->Resize(needLength);
AppendInlineAttachmentNameSeparatorLine(body, bodyCnt, outbuf, textType);
char *outptr = outbuf->Data(outbuf->Count());

int retlen = dGP.GetOutput((unsigned char*)outptr, dlength);
Expand All @@ -7483,8 +7556,11 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf
{
// in case we have multiple bodies of the same type ?? not sure it is valid case/concern
// asking for trouble ??
_ASSERTE((body->m_contentTransferEncoding.CompareNoCase("base64") != 0) &&
(body->m_contentTransferEncoding.CompareNoCase("quoted-printable") != 0));
if (!reencodeCurrent && !reencodeNew)
{
AppendInlineAttachmentNameSeparatorLine(body, bodyCnt, outbuf, textType);
outbuf->Append(bodyBegin, bodyLength);
}
else
Expand All @@ -7493,6 +7569,10 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf
}
}

// reencodeCurrent and reencodeNew are always set to FALSE for HTML text block
if ((reencodeCurrent || reencodeNew) && (textType == 1))
_ASSERTE(FALSE);

if (reencodeCurrent || reencodeNew)
{
SimpleString *result;
Expand All @@ -7514,6 +7594,7 @@ int MboxMail::GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf
else
; // don't touch outbuf
}

if (reencodeNew)
{
SimpleString *wBuff = MboxMail::m_largelocal1;
Expand Down
2 changes: 2 additions & 0 deletions src/MboxMail.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ class MailBodyContent
bool m_isEmbeddedImage;

bool IsAttachment();
bool IsInlineAttachment();
};

unsigned long StrHash(const char* buf, const UINT length);
Expand Down Expand Up @@ -619,6 +620,7 @@ class MboxMail
//
static int GetMailBody_mboxview(CFile &fpm, int mailPosition, SimpleString *outbuf, UINT &pageCode, int textMinorType = 0); // 0 if text/plain, 1 if text/html
static int GetMailBody_mboxview(CFile &fpm, MboxMail *m, SimpleString *outbuf, UINT &pageCode, int textMinorType = 0);
static int AppendInlineAttachmentNameSeparatorLine(MailBodyContent* body, int bodyCnt, SimpleString* outbuf, int textType);
//
static int GetMailBody_MailBody(CFile &fpm, int mailPosition, SimpleString *outbuf, UINT &pageCode);
static int GetMailBody_CMimeMessage(CMimeMessage &mail, int mailPosition, SimpleString *outbuf, UINT &pageCode);
Expand Down
32 changes: 32 additions & 0 deletions src/MimeHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,36 @@ bool MboxCMimeHelper::IsInlineAttachment(CMimeBody* pBP)
return true;
else
return false;
}

bool MboxCMimeHelper::IsAttachmentDisposition(CMimeBody* pBP)
{
CString name;
CString fileName;
CString disposition;

Name(pBP, name);
Filename(pBP, fileName);
GetContentDisposition(pBP, disposition);
int dispositionMatchRet = disposition.CompareNoCase("attachment");
if (dispositionMatchRet == 0)
return true;
else
return false;
}

bool MboxCMimeHelper::IsInlineDisposition(CMimeBody* pBP)
{
CString name;
CString fileName;
CString disposition;

Name(pBP, name);
Filename(pBP, fileName);
GetContentDisposition(pBP, disposition);
int dispositionMatchRet = disposition.CompareNoCase("inline");
if (dispositionMatchRet == 0)
return true;
else
return false;
}
Loading

0 comments on commit 5c491db

Please sign in to comment.