gecko-dev/cmd/winfe/mailmisc.cpp
1998-06-22 21:19:46 +00:00

4084 lines
108 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "stdafx.h"
#include "shcut.h"
#include "msgcom.h"
#include "msg_srch.h"
#include "prefapi.h"
#include "msgtmpl.h"
#include "netsdoc.h"
#include "mailmisc.h"
#include "mailpriv.h"
#include "msgview.h"
#include "fldrfrm.h"
#include "thrdfrm.h"
#include "msgfrm.h"
#include "wfemsg.h"
#include "intl_csi.h"
#include "fegui.h"
#include "addrfrm.h" //for MOZ_NEWADDR
#include "rdfglobal.h"
#ifndef _AFXDLL
#undef new
#endif
IMPLEMENT_DYNCREATE(CFolderView, COutlinerView)
#ifndef _AFXDLL
#define new DEBUG_NEW
#endif
#define COL_LEFT_MARGIN ((m_cxChar+1)/2)
#define EXTRATEXT_SIZE 128
extern "C" const char* FE_GetFolderDirectory(MWContext *pContext);
#ifdef _WIN32
extern "C" BOOL UpdateMapiDll(void);
#endif
int WFE_MSGTranslateFolderIcon( uint8 level, int32 iFlags, BOOL bOpen )
{
int folderTable[] = { IDX_MAILFOLDERCLOSED, IDX_MAILFOLDEROPEN,
IDX_MAILFOLDERCLOSEDNEW, IDX_MAILFOLDEROPENNEW,
// 4
IDX_NEWSGROUP, IDX_NEWSGROUP,
IDX_NEWSGROUP, IDX_NEWSGROUP,
// 8
IDX_LOCALMAIL, IDX_LOCALMAIL,
IDX_LOCALMAIL, IDX_LOCALMAIL,
// 12
IDX_REMOTEMAIL, IDX_REMOTEMAIL,
IDX_REMOTEMAIL, IDX_REMOTEMAIL,
// 16
IDX_NEWSHOST, IDX_NEWSHOST,
IDX_NEWSHOST, IDX_NEWSHOST,
// 20
IDX_INBOXCLOSED, IDX_INBOXOPEN,
IDX_INBOXCLOSEDNEW, IDX_INBOXOPENNEW,
// 24
IDX_OUTBOXCLOSED, IDX_OUTBOXOPEN,
IDX_OUTBOXCLOSED, IDX_OUTBOXOPEN,
// 28
IDX_SENTCLOSED, IDX_SENTOPEN,
IDX_SENTCLOSED, IDX_SENTOPEN,
// 32
IDX_DRAFTSCLOSED, IDX_DRAFTSOPEN,
IDX_DRAFTSCLOSED, IDX_DRAFTSOPEN,
// 36
IDX_TRASH, IDX_TRASHOPEN,
IDX_TRASH, IDX_TRASHOPEN,
// 40
IDX_TEMPLATECLOSE, IDX_TEMPLATEOPEN,
IDX_TEMPLATECLOSE, IDX_TEMPLATEOPEN,
// 44
IDX_SHARECLOSED, IDX_SHAREOPEN,
IDX_SHARECLOSED, IDX_SHAREOPEN,
// 48
IDX_PUBLICCLOSED, IDX_PUBLICOPEN,
IDX_PUBLICCLOSED, IDX_PUBLICOPEN,
};
int idx = 0;
if (iFlags & MSG_FOLDER_FLAG_NEWSGROUP)
idx = 4;
else if (level < 2)
{
if (iFlags & MSG_FOLDER_FLAG_NEWS_HOST)
idx = 16;
else if (iFlags & MSG_FOLDER_FLAG_IMAPBOX)
idx = 12;
else
idx = 8;
}
else
{
if (iFlags & MSG_FOLDER_FLAG_INBOX)
idx = 20;
else if (iFlags & MSG_FOLDER_FLAG_QUEUE)
idx = 24;
else if (iFlags & MSG_FOLDER_FLAG_DRAFTS)
idx = 32;
else if (iFlags & MSG_FOLDER_FLAG_TRASH )
idx = 36;
else if (iFlags & MSG_FOLDER_FLAG_SENTMAIL )
idx = 28;
else if (iFlags & MSG_FOLDER_FLAG_TEMPLATES )
idx = 40;
else if (iFlags & MSG_FOLDER_FLAG_PERSONAL_SHARED )
idx = 44;
else if (iFlags & MSG_FOLDER_FLAG_IMAP_OTHER_USER )
idx = 44;
else if (iFlags & MSG_FOLDER_FLAG_IMAP_PUBLIC )
idx = 48;
}
idx += bOpen ? 1 : 0;
idx += iFlags & MSG_FOLDER_FLAG_GOT_NEW ? 2 : 0;
return folderTable[idx];
}
void WFE_MSGBuildMessagePopup( HMENU hmenu, BOOL bNews, BOOL bInHeaders, MWContext *pContext )
{
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_REPLY, szLoadString( IDS_MENU_REPLY ) );
if ( bNews ) {
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_POSTREPLY, szLoadString( IDS_MENU_POSTREPLY ) );
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_POSTANDREPLY, szLoadString( IDS_MENU_POSTMAILREPLY ) );
} else {
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_REPLYALL, szLoadString( IDS_MENU_REPLYALL ) );
}
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_FORWARD, szLoadString( IDS_MENU_FORWARD ) );
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_FORWARDQUOTED, szLoadString( IDS_MENU_FORWARDQUOTED ) );
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_FORWARDINLINE, szLoadString(IDS_MENU_FORWARDINLINE));
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
#ifdef MOZ_NEWADDR
WFE_MSGBuildAddAddressBookPopups(hmenu, ::GetMenuItemCount(hmenu), TRUE, pContext);
#else
HMENU hAddMenu = ::CreatePopupMenu();
::AppendMenu( hAddMenu, MF_STRING, ID_MESSAGE_ADDSENDER, szLoadString( IDS_POPUP_ADDSENDER ) );
::AppendMenu( hAddMenu, MF_STRING, ID_MESSAGE_ADDALL, szLoadString( IDS_POPUP_ADDALL ) );
::AppendMenu( hmenu, MF_STRING|MF_POPUP, (UINT) hAddMenu, szLoadString( IDS_POPUP_ADDTOADDRESSBOOK ) );
#endif
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
if (bInHeaders) {
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_KILL, szLoadString( IDS_POPUP_IGNORETHREAD ) );
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_WATCH, szLoadString( IDS_POPUP_WATCHTHREAD ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
if (!bNews) {
HMENU hPriorityMenu = ::CreatePopupMenu();
::AppendMenu( hPriorityMenu, MF_STRING, ID_PRIORITY_LOWEST, szLoadString( IDS_POPUP_LOWEST ) );
::AppendMenu( hPriorityMenu, MF_STRING, ID_PRIORITY_LOW, szLoadString( IDS_POPUP_LOW ) );
::AppendMenu( hPriorityMenu, MF_STRING, ID_PRIORITY_NORMAL, szLoadString( IDS_POPUP_NORMAL ) );
::AppendMenu( hPriorityMenu, MF_STRING, ID_PRIORITY_HIGH, szLoadString( IDS_POPUP_HIGH ) );
::AppendMenu( hPriorityMenu, MF_STRING, ID_PRIORITY_HIGHEST, szLoadString( IDS_POPUP_HIGHEST ) );
::AppendMenu( hmenu, MF_STRING|MF_POPUP, (UINT) hPriorityMenu, szLoadString( IDS_POPUP_PRIORITY ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
}
}
UINT nID = FIRST_MOVE_MENU_ID;
HMENU hFileMenu = CreatePopupMenu();
CMailNewsFrame::UpdateMenu( NULL, hFileMenu, nID );
::AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT) hFileMenu, szLoadString( IDS_POPUP_FILE ) );
::AppendMenu( hmenu, MF_STRING, CASTUINT(ID_EDIT_DELETEMESSAGE),
szLoadString( CASTUINT(bNews ? IDS_POPUP_CANCELMESSAGE : IDS_POPUP_DELETEMESSAGE )) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_SAVEMESSAGES, szLoadString( IDS_POPUP_SAVEMESSAGE ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_PRINT, szLoadString( IDS_POPUP_PRINTMESSAGE ) );
}
//////////////////////////////////////////////////////////////////////////////
// CBiffCX
class CBiffCX: public CStubsCX
{
public:
CBiffCX(): CStubsCX(Network, MWContextBiff) {};
virtual void DestroyContext();
};
void CBiffCX::DestroyContext()
{
MSG_BiffCleanupContext(GetContext());
CStubsCX::DestroyContext();
}
//////////////////////////////////////////////////////////////////////////////
// CMessagePrefs
CMsgPrefs g_MsgPrefs;
#ifdef _WIN32
static TCHAR lpszEventMailBeep[] = _T("AppEvents\\EventLabels\\MailBeep");
static TCHAR lpszSchemeMailBeep[] = _T("AppEvents\\Schemes\\Apps\\.Default\\MailBeep");
static TCHAR lpszCurrent[] = _T(".current");
static TCHAR lpszChord[] = _T("chord.wav");
#endif
static char lpszSounds[] = "Sounds";
static char lpszMailBeep[] = "MailBeep";
void WFE_MSGInit()
{
#ifdef _WIN32
if (sysInfo.m_bWin4) {
TCHAR szBuf[_MAX_PATH];
LONG lBufSize = _MAX_PATH;
if ( ::RegQueryValue(HKEY_CURRENT_USER, lpszEventMailBeep, szBuf, &lBufSize) !=
ERROR_SUCCESS ) {
::RegSetValue(HKEY_CURRENT_USER, lpszEventMailBeep, REG_SZ,
szLoadString(IDS_MAILSOUND), _tcslen(szLoadString(IDS_MAILSOUND)));
}
HKEY hkey;
if ( ::RegCreateKey(HKEY_CURRENT_USER, lpszSchemeMailBeep, &hkey) ==
ERROR_SUCCESS ) {
lBufSize = _MAX_PATH;
if ( ::RegQueryValue(hkey, lpszCurrent, szBuf, &lBufSize) !=
ERROR_SUCCESS ) {
::RegSetValue(hkey, lpszCurrent, REG_SZ,
lpszChord, _tcslen(lpszChord));
}
::RegCloseKey(hkey);
}
}
else
#endif
{
char szBuf[_MAX_PATH * 2];
LONG lBufSize = _MAX_PATH * 2;
::GetProfileString(lpszSounds, lpszMailBeep, szLoadString(IDS_MAILSOUND16), szBuf, lBufSize );
::WriteProfileString(lpszSounds, lpszMailBeep, szBuf);
}
g_MsgPrefs.Init();
}
void WFE_MSGShutdown()
{
// Don't do anything if we never called WFE_MSGInit
if (g_MsgPrefs.m_bInitialized)
{
MSG_DestroyMaster(WFE_MSGGetMaster());
MSG_ShutdownMsgLib();
g_MsgPrefs.Shutdown();
}
}
// returns the master. If there isn't one then it
// creates one.
MSG_Master* WFE_MSGGetMaster()
{
return g_MsgPrefs.GetMaster();
}
// returns the current value of the master.
MSG_Master* WFE_MSGGetMasterValue()
{
return g_MsgPrefs.GetMasterValue();
}
CMsgPrefs::CMsgPrefs()
{
m_pMaster = NULL;
m_bInitialized = FALSE;
}
PR_CALLBACK cbMsgPrefs(const char *prefName, void *pData)
{
XP_Bool bPref;
char *pszPref = NULL;
switch ((int) pData) {
case 0:
bPref= TRUE;
PREF_GetBoolPref("mailnews.reuse_thread_window", &bPref);
g_MsgPrefs.m_bThreadReuse = bPref;
break;
case 1:
bPref= TRUE;
PREF_GetBoolPref("mailnews.reuse_message_window", &bPref);
g_MsgPrefs.m_bMessageReuse = bPref;
break;
case 2:
bPref= TRUE;
PREF_GetBoolPref("mailnews.message_in_thread_window", &bPref);
g_MsgPrefs.m_bThreadPaneMaxed = !bPref;
break;
case 3:
PREF_CopyCharPref("mail.directory", &pszPref);
if (pszPref)
g_MsgPrefs.m_csMailDir = pszPref;
break;
case 4:
PREF_CopyCharPref("network.hosts.pop_server", &pszPref);
if (pszPref) {
g_MsgPrefs.m_csMailHost = pszPref;
}
break;
case 5:
PREF_CopyCharPref("news.directory", &pszPref);
if (pszPref)
g_MsgPrefs.m_csNewsDir = pszPref;
break;
case 6:
PREF_CopyCharPref("network.hosts.nntp_server", &pszPref);
if (pszPref) {
NET_SetNewsHost(pszPref);
g_MsgPrefs.m_csNewsHost = pszPref;
}
break;
case 7:
PREF_CopyCharPref("mail.identity.useremail", &pszPref);
if (pszPref)
g_MsgPrefs.m_csUsersEmailAddr = pszPref;
break;
case 8:
PREF_CopyCharPref("mail.identity.username", &pszPref);
if (pszPref)
g_MsgPrefs.m_csUsersFullName = pszPref;
break;
case 9:
PREF_CopyCharPref("mail.identity.organization", &pszPref);
if (pszPref)
g_MsgPrefs.m_csUsersOrganization = pszPref;
break;
case 10:
PREF_CopyCharPref("mail.signature_file", &pszPref);
if (pszPref) {
XP_FREEIF(g_MsgPrefs.m_pszUserSig);
g_MsgPrefs.m_pszUserSig = wfe_ReadUserSig(pszPref);
}
break;
case 11:
break;
case 12:
{
for(CGenericFrame * f = theApp.m_pFrameList; f; f = f->m_pNext)
f->PostMessage(WM_COMMAND, (WPARAM) ID_DONEGOINGOFFLINE, (LPARAM) 0);
}
break;
case 13:
#ifdef _WIN32
UpdateMapiDll();
#endif
break;
case 14:
bPref= TRUE;
PREF_GetBoolPref("ldap_1.autoComplete.showDialogForMultipleMatches", &bPref);
g_MsgPrefs.m_bShowCompletionPicker = bPref;
break;
default:
ASSERT(0);
}
XP_FREEIF(pszPref);
return PREF_NOERROR;
}
void CMsgPrefs::Init()
{
m_bInitialized = TRUE;
m_pFolderTemplate = new CFolderTemplate(IDR_MAILFRAME,
RUNTIME_CLASS(CNetscapeDoc),
RUNTIME_CLASS(CFolderFrame), // mail window
RUNTIME_CLASS(CFolderView));
m_pThreadTemplate = new CThreadTemplate(IDR_MAILTHREAD,
RUNTIME_CLASS(CNetscapeDoc),
RUNTIME_CLASS(C3PaneMailFrame), // 3 pane mail window
RUNTIME_CLASS(CMailNewsSplitter));
m_pMsgTemplate = new CMessageTemplate(IDR_MESSAGEFRAME,
RUNTIME_CLASS(CNetscapeDoc),
RUNTIME_CLASS(CMessageFrame), // mail message window
RUNTIME_CLASS(CMessageView));
theApp.AddDocTemplate(m_pFolderTemplate);
theApp.AddDocTemplate(m_pThreadTemplate);
theApp.AddDocTemplate(m_pMsgTemplate);
int32 prefInt = 0;
char *prefStr = NULL;
// Set up mail directory (must be before creation of msg prefs)
CString msg = theApp.m_UserDirectory;
msg += "\\mail";
PREF_SetDefaultCharPref("mail.directory", msg);
PREF_CopyCharPref("mail.directory", &prefStr);
if (prefStr)
m_csMailDir = prefStr;
XP_FREEIF(prefStr);
// Initialize the message library
MSG_InitMsgLib();
// Create the MSG lib pref structure
m_pMsgPrefs = MSG_CreatePrefs();
//
// Read in user identity stuff
//
PREF_CopyCharPref("mail.identity.username",&prefStr);
m_csUsersFullName = prefStr;
XP_FREEIF(prefStr);
PREF_CopyCharPref("mail.identity.useremail",&prefStr);
m_csUsersEmailAddr = prefStr;
XP_FREEIF(prefStr);
PREF_CopyCharPref("mail.identity.organization",&prefStr);
m_csUsersOrganization = prefStr;
XP_FREEIF(prefStr);
PREF_CopyCharPref("mail.signature_file", &prefStr);
m_pszUserSig = wfe_ReadUserSig(prefStr);
XP_FREEIF(prefStr);
//
// Set up the POP3 server
//
PREF_CopyCharPref("network.hosts.pop_server", &prefStr);
if (prefStr) {
g_MsgPrefs.m_csMailHost = prefStr;
}
XP_FREEIF(prefStr);
XP_Bool prefBool= FALSE;
PREF_GetBoolPref("mail.remember_password",&prefBool);
prefStr = NULL;
PREF_CopyCharPref("mail.pop_password",&prefStr);
if(prefStr && prefBool) {
NET_SetPopPassword(prefStr);
}
XP_FREEIF(prefStr);
//
// Set up the SMTP server
//
PREF_CopyCharPref("network.hosts.smtp_server", &prefStr);
NET_SetMailRelayHost(prefStr);
XP_FREEIF(prefStr);
PREF_SetBoolPref("news.show_pretty_names", TRUE);
//
// Set up the NNTP server
//
PREF_CopyCharPref("network.hosts.nntp_server", &prefStr);
NET_SetNewsHost(prefStr);
m_csNewsHost = prefStr;
XP_FREEIF(prefStr);
// Set up news directory
msg = theApp.m_UserDirectory;
msg += "\\news";
PREF_SetDefaultCharPref("news.directory",msg);
PREF_CopyCharPref("news.directory",&prefStr);
m_csNewsDir = prefStr;
XP_FREEIF(prefStr);
// Check that the news directory exists
// Don't show error messagebox according bug#37398
if(FEU_SanityCheckDir(m_csNewsDir))
{
NET_ReadNewsrcFileMappings();
}
//
// Compose prefs
//
prefBool = TRUE;
PREF_GetBoolPref("mail.strictly_mime", &prefBool);
MIME_ConformToStandard(prefBool);
//
// Set up window prefs
//
prefBool= TRUE;
PREF_GetBoolPref("mailnews.reuse_thread_window", &prefBool);
m_bThreadReuse = prefBool;
prefBool= TRUE;
PREF_GetBoolPref("mailnews.reuse_message_window", &prefBool);
m_bMessageReuse = prefBool;
prefBool= TRUE;
PREF_GetBoolPref("mailnews.message_in_thread_window", &prefBool);
m_bThreadPaneMaxed = !prefBool;
prefBool = TRUE;
PREF_GetBoolPref("ldap_1.autoComplete.showDialogForMultipleMatches", &prefBool);
m_bShowCompletionPicker = prefBool;
PREF_RegisterCallback("mailnews.reuse_thread_window", cbMsgPrefs, (void *) 0);
PREF_RegisterCallback("mailnews.reuse_message_window", cbMsgPrefs, (void *) 1);
PREF_RegisterCallback("mailnews.message_in_thread_window", cbMsgPrefs, (void *) 2);
// The BE should probably be handling most of these
PREF_RegisterCallback("mail.directory", cbMsgPrefs, (void *) 3);
PREF_RegisterCallback("network.hosts.pop_server", cbMsgPrefs, (void *) 4);
PREF_RegisterCallback("news.directory", cbMsgPrefs, (void *) 5);
PREF_RegisterCallback("network.hosts.nntp_server", cbMsgPrefs, (void *) 6);
PREF_RegisterCallback("mail.identity.useremail", cbMsgPrefs, (void *) 7);
PREF_RegisterCallback("mail.identity.username", cbMsgPrefs, (void *) 8);
PREF_RegisterCallback("mail.identity.organization", cbMsgPrefs, (void *) 9);
PREF_RegisterCallback("mail.signature_file", cbMsgPrefs, (void *) 10);
PREF_RegisterCallback("mail.leave_on_server", cbMsgPrefs, (void *) 11);
PREF_RegisterCallback("network.online", cbMsgPrefs, (void *) 12);
PREF_RegisterCallback("mail.use_mapi_server", cbMsgPrefs, (void *) 13);
//autocomplete
PREF_RegisterCallback("ldap_1.autoComplete.showDialogForMultipleMatches", cbMsgPrefs, (void*) 14);
// START THE BIFF CONTEXT
CBiffCX *pCX = new CBiffCX();
m_pBiffContext = pCX->GetContext();
MSG_BiffInit(m_pBiffContext, m_pMsgPrefs);
}
void CMsgPrefs::Shutdown()
{
}
CMsgPrefs::~CMsgPrefs()
{
XP_FREEIF(m_pszUserSig);
}
BOOL CMsgPrefs::IsValid() const
{
char buffer[256];
int nLen = 255;
buffer[0] = '\0';
long prefLong = MSG_Pop3;
PREF_GetIntPref("mail.server_type",&prefLong);
if (prefLong == MSG_Imap4 &&
PREF_NOERROR == PREF_GetCharPref("network.hosts.imap_servers", buffer, &nLen))
{
if (strlen(buffer))
return TRUE;
else
return FALSE;
}
else
{
if (PREF_NOERROR == PREF_GetCharPref("mail.pop_name", buffer, &nLen))
{
if (strlen(buffer) && !m_csMailHost.IsEmpty())
return TRUE;
else
return FALSE;
}
else
return FALSE;
}
}
MSG_Master *CMsgPrefs::GetMaster()
{
// Lazy loading of the one-and-only master object for news
// * Must be lazy loaded so theApp.m_pMsgPrefs is initialized
if (!m_pMaster)
{
if (!m_pMsgPrefs)
m_pMsgPrefs = MSG_CreatePrefs();
m_pMaster = MSG_InitializeMail(m_pMsgPrefs);
}
return m_pMaster;
}
MSG_Master *CMsgPrefs::GetMasterValue()
{
return m_pMaster;
}
//////////////////////////////////////////////////////////////////////////////
// CMailNewsOutliner
CMailNewsOutliner::CMailNewsOutliner()
{
m_iSelBlock = 0;
m_bSelChanged = FALSE;
m_bExpandOrCollapse = FALSE;
m_pPane = NULL;
m_iMysticPlane = 0;
m_nCurrentSelected = -1;
}
CMailNewsOutliner::~CMailNewsOutliner()
{
}
void CMailNewsOutliner::SetPane(MSG_Pane *pane)
{
m_pPane = pane;
if (m_pPane) {
SetTotalLines( (int) MSG_GetNumLines(m_pPane));
Invalidate();
UpdateWindow();
}
}
const char *aszNotifications[] = {
"None",
"InsOrDel",
"Changed",
"Scramble",
"All"
};
void CMailNewsOutliner::MysticStuffStarting( XP_Bool asynchronous,
MSG_NOTIFY_CODE notify,
MSG_ViewIndex where,
int32 num )
{
TipHide();
if ( 0 == m_iMysticPlane++ ) {
m_bSelChanged = FALSE;
}
if ( notify == MSG_NotifyInsertOrDelete && m_bExpandOrCollapse ) {
}
}
void CMailNewsOutliner::MysticStuffFinishing( XP_Bool asynchronous,
MSG_NOTIFY_CODE notify,
MSG_ViewIndex where,
int32 num )
{
switch ( notify ) {
case MSG_NotifyNone:
break;
case MSG_NotifyAll:
ClearSelection();
m_iSelection = -1;
m_iTopLine = 0;
m_bSelChanged = TRUE;
Invalidate();
break;
case MSG_NotifyInsertOrDelete:
if ( m_bExpandOrCollapse && where > 0 && num < 0 ) {
// We're collapsing, so if our primary selection is
// in the collapsing area, we need to select the
// parent
// Assume that where - 1 is the parent
if ( m_iSelection >= (int32) where &&
m_iSelection < (int32) (where - num) ) {
m_iSelection = CASTINT(where - 1);
m_iFocus = CASTINT(where - 1);
AddSelection( m_iSelection );
m_bSelChanged = TRUE;
}
if ( m_iShiftAnchor >= (int32) where &&
m_iShiftAnchor < (int32) (where - num ) ) {
m_iShiftAnchor = CASTINT(where - 1);
}
}
if ( num < 0 ) {
m_bSelChanged |= HandleDelete( where, -num );
} else if (num > 0) {
m_bSelChanged |= HandleInsert( where, num );
} else {
m_bSelChanged = TRUE;
}
break;
case MSG_NotifyChanged:
InvalidateLines( (int) where, (int) num );
break;
case MSG_NotifyScramble:
ScrollIntoView(m_iFocus);
Invalidate();
break;
}
if ( !--m_iMysticPlane && m_pPane ) {
SetTotalLines( (int) MSG_GetNumLines( m_pPane ) );
UpdateWindow();
if (m_bSelChanged) {
m_bSelChanged = FALSE;
OnSelChanged();
}
}
}
int CMailNewsOutliner::ToggleExpansion( int iLine )
{
int32 numChanged;
m_bExpandOrCollapse = TRUE;
MSG_ToggleExpansion( m_pPane, iLine, &numChanged );
m_bExpandOrCollapse = FALSE;
m_iLastSelected = m_iSelection;
return (int) numChanged;
}
int CMailNewsOutliner::Expand( int iLine )
{
if (MSG_ExpansionDelta( m_pPane, iLine ) > 0) {
return ToggleExpansion( iLine );
}
return 0;
}
int CMailNewsOutliner::Collapse( int iLine )
{
if (MSG_ExpansionDelta( m_pPane, iLine ) < 0) {
return ToggleExpansion( iLine );
}
return 0;
}
BEGIN_MESSAGE_MAP( CMailNewsOutliner, CMSelectOutliner )
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
END_MESSAGE_MAP()
BOOL CMailNewsOutliner::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
if ( (nHitTest == HTCLIENT) && (m_iSelBlock > 0)) {
::SetCursor( ::LoadCursor( NULL, IDC_WAIT ) );
return TRUE;
}
return CMSelectOutliner::OnSetCursor( pWnd, nHitTest, message );
}
void CMailNewsOutliner::OnLButtonDown( UINT nFlags, CPoint point )
{
if (m_iSelBlock <= 0)
COutliner::OnLButtonDown(nFlags, point);
else
MessageBeep((UINT) -1);
}
void CMailNewsOutliner::OnRButtonDown( UINT nFlags, CPoint point )
{
if (m_iSelBlock <= 0)
COutliner::OnRButtonDown(nFlags, point);
else
MessageBeep((UINT) -1);
}
void CMailNewsOutliner::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
if (m_iSelBlock <= 0)
COutliner::OnKeyDown(nChar, nRepCnt, nFlags);
else
MessageBeep((UINT) -1);
}
void CMailNewsOutliner::OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags )
{
if (m_iSelection != m_iLastSelected) {
if (m_iIndicesCount == 1) {
COutliner::OnKeyUp(nChar, nRepCnt, nFlags);
} else {
int flags = 0;
if (GetKeyState(VK_SHIFT)&0x8000)
flags |= MK_SHIFT;
if (GetKeyState(VK_CONTROL)&0x8000)
flags |= MK_CONTROL;
SelectItem(m_iSelection, OUTLINER_TIMER, flags);
}
}
}
//////////////////////////////////////////////////////////////////////////////
// CFolderOutliner
#define DOUBLE_CLICK_TIMER 9999
CFolderOutliner::CFolderOutliner ( )
{
m_pUnkUserImage = NULL;
ApiApiPtr(api);
m_pUnkUserImage = api->CreateClassInstance(
APICLASS_IMAGEMAP,NULL,(APISIGNATURE)IDB_MAILNEWS);
m_pUnkUserImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIUserImage);
ASSERT(m_pIUserImage);
if (!m_pIUserImage->GetResourceID())
m_pIUserImage->Initialize(IDB_MAILNEWS,16,16);
m_pszExtraText = new _TCHAR[EXTRATEXT_SIZE];
m_pMysticStuff = NULL;
m_pAncestor = NULL;
m_uTimer = 0;
m_dwPrevTime = 0;
m_bDoubleClicked = FALSE;
m_b3PaneParent = FALSE;
m_bRButtonDown = FALSE;
}
CFolderOutliner::~CFolderOutliner ( )
{
if (m_pUnkUserImage) {
if (m_pIUserImage)
m_pUnkUserImage->Release();
}
delete [] m_pszExtraText;
delete [] m_pMysticStuff;
}
void CFolderOutliner::MysticStuffStarting( XP_Bool asynchronous,
MSG_NOTIFY_CODE notify,
MSG_ViewIndex where,
int32 num )
{
CMailNewsOutliner::MysticStuffStarting( asynchronous, notify,
where, num );
if ( notify == MSG_NotifyScramble && m_pPane ) {
MSG_ViewIndex *indices;
int i, count;
GetSelection(indices, count);
m_pMysticStuff = new MSG_FolderInfo*[count];
for (i = 0; i < count; i++) {
m_pMysticStuff[i] = MSG_GetFolderInfo(m_pPane, indices[i]);
}
m_MysticFocus = MSG_GetFolderInfo( m_pPane, m_iFocus );
m_MysticSelection = MSG_GetFolderInfo( m_pPane, m_iSelection );
}
}
void CFolderOutliner::MysticStuffFinishing( XP_Bool asynchronous,
MSG_NOTIFY_CODE notify,
MSG_ViewIndex where,
int32 num )
{
if ( notify == MSG_NotifyScramble && m_pPane ) {
MSG_ViewIndex *indices;
int i, count;
GetSelection(indices, count);
ClearSelection();
for ( i = 0; i < count; i++ ) {
int index = (int) MSG_GetFolderIndex(m_pPane, m_pMysticStuff[i]);
if ( index != MSG_VIEWINDEXNONE ) {
AddSelection(index);
} else {
m_bSelChanged = TRUE;
}
}
delete [] m_pMysticStuff;
m_pMysticStuff = NULL;
if ( m_MysticSelection == NULL ) {
m_iSelection = -1;
} else {
int iSelection = (int) MSG_GetFolderIndex(m_pPane, m_MysticSelection);
if (iSelection == -1 ) {
iSelection = GetTotalLines() > 0 ? 0 : -1;
if (iSelection != -1)
AddSelection( iSelection );
}
m_iSelection = iSelection;
}
if ( m_MysticFocus == NULL ) {
m_iFocus = m_iSelection;
} else {
int iFocus = (int) MSG_GetFolderIndex(m_pPane, m_MysticFocus);
if ( iFocus == -1 ) {
iFocus = m_iSelection > 0 ? m_iSelection : 0;
}
m_iFocus = iFocus;
}
m_iShiftAnchor = m_iFocus;
}
CMailNewsOutliner::MysticStuffFinishing( asynchronous, notify,
where, num );
}
// Tree Info stuff
int CFolderOutliner::GetDepth( int iLine )
{
MSG_FolderLine folderLine;
MSG_GetFolderLineByIndex( m_pPane, (MSG_ViewIndex) iLine, 1, &folderLine );
return folderLine.level - 1;
}
int CFolderOutliner::GetNumChildren( int iLine )
{
MSG_FolderLine folderLine;
MSG_GetFolderLineByIndex( m_pPane, (MSG_ViewIndex) iLine, 1, &folderLine );
return folderLine.numChildren;
}
BOOL CFolderOutliner::IsCollapsed( int iLine )
{
MSG_FolderLine folderLine;
MSG_GetFolderLineByIndex( m_pPane, (MSG_ViewIndex) iLine, 1, &folderLine );
return folderLine.flags & MSG_FOLDER_FLAG_ELIDED ? TRUE : FALSE;
}
void CFolderOutliner::PropertyMenu ( int iSel, UINT flags )
{
HMENU hmenu = CreatePopupMenu();
if ( !hmenu )
return;
MSG_ViewIndex *indices;
int count;
GetSelection( indices, count );
if ( iSel < m_iTotalLines && count == 1 ) {
MSG_FolderLine folderLine;
MSG_GetFolderLineByIndex( m_pPane, indices[0], 1, &folderLine );
BOOL bReuse = g_MsgPrefs.m_bThreadReuse;
if (GetKeyState(VK_MENU) & 0x8000)
bReuse = !bReuse;
if ( folderLine.flags & MSG_FOLDER_FLAG_MAIL ) {
if (folderLine.level > 1) {
if (bReuse) {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERREUSE, szLoadString( IDS_POPUP_OPENFOLDER ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERNEW, szLoadString( IDS_POPUP_OPENFOLDERNEWWINDOW ) );
} else {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERNEW, szLoadString( IDS_POPUP_OPENFOLDERNEWWINDOW ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERREUSE, szLoadString( IDS_POPUP_OPENFOLDER ) );
}
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_FILE_NEWFOLDER, szLoadString( IDS_POPUP_NEWSUBFOLDER ) );
::AppendMenu( hmenu, MF_STRING, ID_EDIT_DELETEFOLDER, szLoadString( IDS_POPUP_DELETEFOLDER ) );
::AppendMenu( hmenu, MF_STRING, ID_FOLDER_RENAME, szLoadString( IDS_POPUP_RENAMEFOLDER ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_COMPRESSTHISFOLDER, szLoadString( IDS_POPUP_COMPRESSFOLDER ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_FILE_NEWMESSAGE, szLoadString( IDS_POPUP_NEWMESSAGE ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_EDIT_SEARCH, szLoadString( IDS_POPUP_SEARCH ) );
::AppendMenu( hmenu, MF_STRING, ID_VIEW_PROPERTIES, szLoadString( IDS_POPUP_FOLDERPROP ) );
} else {
::AppendMenu( hmenu, MF_STRING, ID_FILE_NEWFOLDER, szLoadString( IDS_POPUP_NEWFOLDER ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_UPDATECOUNTS, szLoadString( IDS_POPUP_UPDATEMESSAGECOUNT ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_EDIT_SEARCH, szLoadString( IDS_POPUP_SEARCH ) );
::AppendMenu( hmenu, MF_STRING, ID_VIEW_PROPERTIES, szLoadString( IDS_POPUP_MAILSERVERPROP) );
}
} else if ( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ) {
BOOL bReuse = g_MsgPrefs.m_bThreadReuse;
if (bReuse) {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERREUSE, szLoadString( IDS_POPUP_OPENNEWSGROUP ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERNEW, szLoadString( IDS_POPUP_OPENNEWSGROUPNEWWINDOW ) );
} else {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERNEW, szLoadString( IDS_POPUP_OPENNEWSGROUPNEWWINDOW ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENFOLDERREUSE, szLoadString( IDS_POPUP_OPENNEWSGROUP ) );
}
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_FILE_NEWMESSAGE, szLoadString( IDS_POPUP_NEWMESSAGE ) );
::AppendMenu( hmenu, MF_STRING, ID_MESSAGE_MARKALLREAD, szLoadString( IDS_POPUP_MARKNEWSGROUPREAD ) );
::AppendMenu( hmenu, MF_STRING, ID_POPUP_DELETEFOLDER, szLoadString( IDS_POPUP_REMOVENEWSGROUP ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_EDIT_SEARCH, szLoadString( IDS_POPUP_SEARCH ) );
::AppendMenu( hmenu, MF_STRING, ID_VIEW_PROPERTIES, szLoadString( IDS_POPUP_NEWSGROUPPROP ) );
} else if ( folderLine.flags & MSG_FOLDER_FLAG_NEWS_HOST ) {
::AppendMenu( hmenu, MF_STRING, ID_FILE_SUBSCRIBE, szLoadString( IDS_POPUP_JOINNEWSGROUP ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_UPDATECOUNTS, szLoadString( IDS_POPUP_UPDATEMESSAGECOUNT ) );
::AppendMenu( hmenu, MF_STRING, ID_POPUP_DELETEFOLDER, szLoadString( IDS_POPUP_REMOVENEWSHOST ) );
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
::AppendMenu( hmenu, MF_STRING, ID_EDIT_SEARCH, szLoadString( IDS_POPUP_SEARCH ) );
::AppendMenu( hmenu, MF_STRING, ID_VIEW_PROPERTIES, szLoadString( IDS_POPUP_NEWSHOSTPROP) );
}
}
// Track the popup now.
POINT pt = m_ptHit;
ClientToScreen(&pt);
::TrackPopupMenu( hmenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0,
GetParentFrame()->GetSafeHwnd(), NULL);
VERIFY(::DestroyMenu( hmenu ));
}
DROPEFFECT CFolderOutliner::DropSelect( int iLineNo, COleDataObject *pDataObject )
{
DROPEFFECT res = DROPEFFECT_NONE;
MSG_DragEffect requireEffect = MSG_Default_Drag;
MSG_DragEffect effect = MSG_Drag_Not_Allowed;
HGLOBAL hContent = NULL;
MailNewsDragData *pDragData = NULL;
if ((GetKeyState(VK_SHIFT) & 0x8000) && (GetKeyState(VK_CONTROL) & 0x8000))
requireEffect = MSG_Default_Drag;
else if (GetKeyState(VK_SHIFT) & 0x8000)
requireEffect = MSG_Require_Move;
else if (GetKeyState(VK_CONTROL) & 0x8000)
requireEffect = MSG_Require_Copy;
// The commented out code has the effect of always doing a move, if we get called
// with the same iLineNo as last time!
// if (iLineNo != m_iDragSelection)
{
if ( m_iDragSelection != -1 )
InvalidateLine (m_iDragSelection);
m_iDragSelection = -1;
MSG_FolderLine folderLine;
if (MSG_GetFolderLineByIndex( m_pPane, (MSG_ViewIndex) iLineNo, 1, &folderLine ))
{
if ( pDataObject->IsDataAvailable( m_cfMessages ) )
{
hContent = pDataObject->GetGlobalData (m_cfMessages);
pDragData = (MailNewsDragData *) GlobalLock(hContent);
effect = MSG_DragMessagesIntoFolderStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
folderLine.id, requireEffect);
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
else if ( pDataObject->IsDataAvailable( m_cfFolders ) )
{
hContent = pDataObject->GetGlobalData (m_cfFolders);
pDragData = (MailNewsDragData *) GlobalLock(hContent);
effect = MSG_DragFoldersIntoStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
folderLine.id, requireEffect);
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
else if ( pDataObject->IsDataAvailable( m_cfSearchMessages ) )
{
hContent = pDataObject->GetGlobalData (m_cfSearchMessages);
pDragData = (MailNewsDragData *) GlobalLock(hContent);
effect = MSG_DragMessagesIntoFolderStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
folderLine.id, requireEffect);
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
if (MSG_Drag_Not_Allowed != effect)
{
InvalidateLine (iLineNo);
m_iDragSelection = iLineNo;
if (effect == MSG_Require_Copy)
res = DROPEFFECT_COPY;
else
res = DROPEFFECT_MOVE;
}
}
}
// else
// res = DROPEFFECT_MOVE;
return res;
}
void CFolderOutliner::AcceptDrop( int iLineNo, COleDataObject *pDataObject,
DROPEFFECT dropEffect )
{
if (iLineNo != -1) {
MSG_FolderInfo *pFolder = MSG_GetFolderInfo(m_pPane,iLineNo);
ASSERT(pFolder);
MSG_DragEffect requireEffect = MSG_Default_Drag;
if (dropEffect & DROPEFFECT_MOVE)
requireEffect = MSG_Require_Move;
else if (dropEffect & DROPEFFECT_COPY)
requireEffect = MSG_Require_Copy;
if ( pDataObject->IsDataAvailable( m_cfMessages ) && pFolder )
{
HGLOBAL hContent = pDataObject->GetGlobalData (m_cfMessages);
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock(hContent);
MSG_DragEffect effect = MSG_DragMessagesIntoFolderStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
pFolder, requireEffect);
LPUNKNOWN pUnk = (LPUNKNOWN) MSG_GetFEData( pDragData->m_pane );
if (pUnk) {
LPMSGLIST pInterface = NULL;
pUnk->QueryInterface( IID_IMsgList, (LPVOID *) &pInterface );
if ( pInterface ) {
switch (effect) {
case MSG_Require_Move:
pInterface->MoveMessagesInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
break;
case MSG_Require_Copy:
pInterface->CopyMessagesInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
break;
default:
ASSERT(0);
break;
}
pInterface->Release();
}
}
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
if ( pDataObject->IsDataAvailable( m_cfSearchMessages ) && pFolder )
{
HGLOBAL hContent = pDataObject->GetGlobalData (m_cfSearchMessages);
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock(hContent);
MSG_DragEffect effect = MSG_DragMessagesIntoFolderStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
pFolder, requireEffect);
LPUNKNOWN pUnk = (LPUNKNOWN) MSG_GetFEData( pDragData->m_pane );
if (pUnk) {
LPMSGLIST pInterface = NULL;
pUnk->QueryInterface( IID_IMsgList, (LPVOID *) &pInterface );
if ( pInterface ) {
switch (effect) {
case MSG_Require_Move:
pInterface->MoveMessagesInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
break;
case MSG_Require_Copy:
pInterface->CopyMessagesInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
break;
default:
ASSERT(0);
break;
}
pInterface->Release();
}
}
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
if ( pDataObject->IsDataAvailable( m_cfFolders ) && pFolder )
{
HGLOBAL hContent = pDataObject->GetGlobalData (m_cfFolders);
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock(hContent);
MSG_DragEffect effect = MSG_DragFoldersIntoStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
pFolder, MSG_Default_Drag);
if (effect == MSG_Require_Copy || effect == MSG_Require_Move)
{
MSG_MoveFoldersInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
if (IsParent3PaneFrame())
{
C3PaneMailFrame* pFrame = C3PaneMailFrame::FindFrame(pFolder);
if (pFrame)
pFrame->ActivateFrame();
((C3PaneMailFrame*)GetParentFrame())->BlockFolderSelection (TRUE);
}
}
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
}
}
COleDataSource * CFolderOutliner::GetDataSource(void)
{
MSG_ViewIndex *indices;
int count;
GetSelection(indices, count);
HANDLE hContent = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,sizeof(MailNewsDragData));
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock (hContent);
pDragData->m_pane = m_pPane;
pDragData->m_indices = indices;
pDragData->m_count = count;
GlobalUnlock(hContent);
COleDataSource * pDataSource = new COleDataSource;
pDataSource->CacheGlobalData(m_cfFolders,hContent);
if ( count == 1 ) {
MSG_FolderLine folderLine;
MSG_GetFolderLineByIndex( m_pPane, indices[0], 1, &folderLine );
URL_Struct *url = MSG_ConstructUrlForFolder( m_pPane, folderLine.id );
if ( url ) {
const char *name = (folderLine.prettyName && folderLine.prettyName[0]) ?
folderLine.prettyName : folderLine.name;
RDFGLOBAL_DragTitleAndURL( pDataSource, name, url->address );
NET_FreeURLStruct( url );
}
}
return pDataSource;
}
void CFolderOutliner::InitializeClipFormats(void)
{
m_cfMessages = (CLIPFORMAT)RegisterClipboardFormat(NETSCAPE_MESSAGE_FORMAT);
m_cfFolders = (CLIPFORMAT)RegisterClipboardFormat(NETSCAPE_FOLDER_FORMAT);
m_cfSearchMessages = (CLIPFORMAT)RegisterClipboardFormat(NETSCAPE_SEARCH_FORMAT);
}
CLIPFORMAT * CFolderOutliner::GetClipFormatList(void)
{
static CLIPFORMAT cfFormatList[4];
cfFormatList[0] = m_cfMessages;
cfFormatList[1] = m_cfFolders;
cfFormatList[2] = m_cfSearchMessages;
cfFormatList[3] = 0;
return cfFormatList;
}
int CFolderOutliner::TranslateIcon (void * pData)
{
ASSERT(pData);
MSG_FolderLine * pFolder = (MSG_FolderLine*)pData;
BOOL bOpen = pFolder->numChildren <= 0 ||
pFolder->flags & MSG_FOLDER_FLAG_ELIDED ? FALSE : TRUE;
return WFE_MSGTranslateFolderIcon( pFolder->level, pFolder->flags, bOpen );
}
int CFolderOutliner::TranslateIconFolder (void * pData)
{
ASSERT(pData);
MSG_FolderLine * pFolder = (MSG_FolderLine*)pData;
if (pFolder->numChildren > 0) {
if (pFolder->flags & MSG_FOLDER_FLAG_ELIDED) {
return(OUTLINER_CLOSEDFOLDER);
} else {
return(OUTLINER_OPENFOLDER);
}
}
return (OUTLINER_ITEM);
}
void * CFolderOutliner::AcquireLineData ( int line )
{
delete [] m_pAncestor;
m_pAncestor = NULL;
m_pszExtraText[ 0 ] = '\0';
if ( line >= m_iTotalLines)
return NULL;
if ( !MSG_GetFolderLineByIndex(m_pPane, line, 1, &m_FolderLine ))
return NULL;
return &m_FolderLine;
}
void CFolderOutliner::GetTreeInfo ( int line, uint32 * pFlags, int * pDepth,
OutlinerAncestorInfo ** pAncestor )
{
delete [] m_pAncestor;
m_pAncestor = NULL;
if (pAncestor) {
if ( m_FolderLine.level > 0 ) {
m_pAncestor = new OutlinerAncestorInfo[m_FolderLine.level];
} else {
m_pAncestor = new OutlinerAncestorInfo[1];
}
int i = m_FolderLine.level - 1;
int idx = line + 1;
while ( i > 0 ) {
int level;
if ( idx < m_iTotalLines ) {
level = MSG_GetFolderLevelByIndex( m_pPane, idx );
if ( (level - 1) == i ) {
m_pAncestor[i].has_prev = TRUE;
m_pAncestor[i].has_next = TRUE;
i--;
idx++;
} else if ( (level - 1) < i ) {
m_pAncestor[i].has_prev = FALSE;
m_pAncestor[i].has_next = FALSE;
i--;
} else {
idx++;
}
} else {
m_pAncestor[i].has_prev = FALSE;
m_pAncestor[i].has_next = FALSE;
i--;
}
}
m_pAncestor[0].has_prev = FALSE;
m_pAncestor[0].has_next = FALSE;
*pAncestor = m_pAncestor;
}
if ( pFlags ) *pFlags = m_FolderLine.flags;
if ( pDepth ) *pDepth = m_FolderLine.level - 1;
}
void CFolderOutliner::ReleaseLineData ( void * )
{
delete [] m_pAncestor;
m_pAncestor = NULL;
}
int CFolderOutliner::OnCreate(LPCREATESTRUCT lpcs)
{
m_b3PaneParent = GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame));
return CMailNewsOutliner::OnCreate(lpcs);
}
void CFolderOutliner::OnDestroy()
{
if (m_uTimer)
{
KillTimer(m_uTimer);
m_uTimer = 0;
}
CMailNewsOutliner::OnDestroy();
}
void CFolderOutliner::OnTimer(UINT nIDEvent)
{
if (m_uTimer == nIDEvent)
{
if (m_bDoubleClicked)
{
m_bDoubleClicked = FALSE;
KillTimer(m_uTimer);
m_uTimer = 0;
}
else
{
UINT delta = GetTickCount() - m_dwPrevTime;
if (delta > GetDoubleClickTime())
{ // single click
m_bSelChanged = FALSE;
if (!m_iSelBlock)
GetParentFrame()->SendMessage(WM_COMMAND,
ID_FOLDER_SELECT, 0);
KillTimer(m_uTimer);
m_uTimer = 0;
}
}
m_bLButtonDown = FALSE;
}
else
CMailNewsOutliner::OnTimer(nIDEvent);
}
void CFolderOutliner::OnSelChanged()
{
if (IsParent3PaneFrame())
{
if (m_bRButtonDown)
{
((C3PaneMailFrame*)GetParentFrame())->BlankOutRightPanes();
return;
}
SetCurrentSelected(m_iLastSelected);
BOOL bControlKeydown = ((GetKeyState(VK_CONTROL) & 0x8000) && m_bLButtonDown);
if (!bControlKeydown && m_bLButtonDown && m_uTimer == 0 && !m_bDoubleClicked)
{
m_dwPrevTime = GetTickCount();
UINT uElapse = GetDoubleClickTime() / 5;
m_uTimer = SetTimer(DOUBLE_CLICK_TIMER, uElapse, NULL);
return;
}
}
m_bSelChanged = FALSE;
if (!m_iSelBlock)
GetParentFrame()->SendMessage(WM_COMMAND, ID_FOLDER_SELECT, 0);
}
void CFolderOutliner::OnSelDblClk()
{
if (m_bLButtonDown && m_uTimer != 0)
m_bDoubleClicked = TRUE;
MSG_FolderLine folderLine;
if (MSG_GetFolderLineByIndex(m_pPane, m_iFocus, 1, &folderLine)) {
if (folderLine.level < 2) {
DoToggleExpansion(m_iFocus);
}
}
GetParentFrame()->SendMessage(WM_COMMAND, ID_FILE_OPENFOLDER, 0);
}
HFONT CFolderOutliner::GetLineFont ( void *pLineData )
{
MSG_FolderLine *pFolderLine = (MSG_FolderLine *) pLineData;
if (((pFolderLine->deepUnseen > 0) && (pFolderLine->flags & MSG_FOLDER_FLAG_ELIDED)) ||
(pFolderLine->unseen > 0) ||
(pFolderLine->level < 2) )
return m_hBoldFont;
else
return m_hRegFont;
}
LPCTSTR CFolderOutliner::GetColumnText( UINT iColumn, void * pLineData )
{
m_pszExtraText[0] = '\0';
LPCTSTR name;
switch ( iColumn )
{
case ID_COLUMN_FOLDER:
name = (LPCTSTR) m_FolderLine.prettyName;
if ( !name || !name[0] )
name = m_FolderLine.name;
return name;
case ID_COLUMN_UNREAD:
if( m_FolderLine.unseen > 0 )
sprintf( m_pszExtraText, "%ld", m_FolderLine.unseen );
else if (m_FolderLine.unseen < 0)
sprintf( m_pszExtraText, "???" );
return m_pszExtraText;
case ID_COLUMN_COUNT:
if( m_FolderLine.total > 0 )
sprintf( m_pszExtraText, "%ld", m_FolderLine.total );
else if(m_FolderLine.total < 0)
sprintf( m_pszExtraText, "???" );
return m_pszExtraText;
}
return m_pszExtraText;
}
LPCTSTR CFolderOutliner::GetColumnTip( UINT iColumn, void * pLineData )
{
switch ( iColumn ) {
case ID_COLUMN_UNREAD:
if ( m_FolderLine.deepUnseen != m_FolderLine.unseen ) {
if( m_FolderLine.unseen > 0 ) {
sprintf( m_pszExtraText, "(%ld) %ld",
m_FolderLine.deepUnseen, m_FolderLine.unseen );
return m_pszExtraText;
} else if (m_FolderLine.unseen == 0) {
sprintf( m_pszExtraText, "(%ld)", m_FolderLine.deepUnseen );
return m_pszExtraText;
}
}
break;
case ID_COLUMN_COUNT:
if ( m_FolderLine.deepTotal != m_FolderLine.total ) {
if( m_FolderLine.total > 0 ) {
sprintf( m_pszExtraText, "(%ld) %ld",
m_FolderLine.deepTotal, m_FolderLine.total );
return m_pszExtraText;
} else if (m_FolderLine.total == 0) {
sprintf( m_pszExtraText, "(%ld)", m_FolderLine.deepTotal );
return m_pszExtraText;
}
}
break;
}
return NULL;
}
void CFolderOutliner::OnSetFocus(CWnd* pOldWnd)
{
C3PaneMailFrame* pParent = (C3PaneMailFrame*)GetParentFrame();
CMailNewsOutliner::OnSetFocus(pOldWnd);
if (IsParent3PaneFrame())
pParent->SetFocusWindow(this);
}
void CFolderOutliner::OnRButtonDown (UINT nFlags, CPoint point)
{
m_bRButtonDown = TRUE;
CMailNewsOutliner::OnRButtonDown (nFlags, point);
}
void CFolderOutliner::OnRButtonUp(UINT nFlags, CPoint point)
{
CMailNewsOutliner::OnRButtonUp(nFlags, point);
m_bRButtonDown = FALSE;
if (IsParent3PaneFrame())
((C3PaneMailFrame*)GetParentFrame())->CheckForChangeFocus();
}
BEGIN_MESSAGE_MAP(CFolderOutliner, CMailNewsOutliner)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_SETFOCUS()
ON_WM_DESTROY()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////////
// CMessageOutliner
CMessageOutliner::CMessageOutliner ( )
{
m_pszExtraText = new _TCHAR[EXTRATEXT_SIZE];
m_pAncestor = NULL;
m_bNews = FALSE;
m_bDrafts = FALSE;
m_uTimer = 0;
m_dwPrevTime = 0;
m_bDoubleClicked = FALSE;
m_pUnkUserImage = NULL;
ApiApiPtr(api);
m_pUnkUserImage = api->CreateClassInstance(
APICLASS_IMAGEMAP,NULL,(APISIGNATURE)IDB_MAILNEWS);
m_pUnkUserImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIUserImage);
ASSERT(m_pIUserImage);
if (!m_pIUserImage->GetResourceID())
m_pIUserImage->Initialize(IDB_MAILNEWS,16,16);
m_pMysticStuff = NULL;
}
CMessageOutliner::~CMessageOutliner ( )
{
if (m_pUnkUserImage) {
if (m_pIUserImage)
m_pUnkUserImage->Release();
}
delete [] m_pszExtraText;
delete [] m_pMysticStuff;
}
void CMessageOutliner::MysticStuffStarting( XP_Bool asynchronous,
MSG_NOTIFY_CODE notify,
MSG_ViewIndex where,
int32 num )
{
CMailNewsOutliner::MysticStuffStarting( asynchronous, notify,
where, num);
if ( notify == MSG_NotifyScramble ) {
MSG_ViewIndex *indices;
int i, count;
GetSelection(indices, count);
m_pMysticStuff = new MessageKey[count];
for (i = 0; i < count; i++) {
m_pMysticStuff[i] = MSG_GetMessageKey(m_pPane, indices[i]);
}
m_MysticFocus = MSG_MESSAGEKEYNONE;
m_MysticSelection = MSG_MESSAGEKEYNONE;
if ( m_iSelection != -1 && m_iSelection < m_iTotalLines) {
m_MysticSelection = MSG_GetMessageKey( m_pPane, m_iSelection );
}
if ( m_iFocus != -1 && m_iFocus < m_iTotalLines) {
m_MysticFocus = MSG_GetMessageKey( m_pPane, m_iFocus );
}
}
}
void CMessageOutliner::MysticStuffFinishing( XP_Bool asynchronous,
MSG_NOTIFY_CODE notify,
MSG_ViewIndex where,
int32 num )
{
if ( notify == MSG_NotifyScramble ) {
MSG_ViewIndex *indices;
int i, count;
GetSelection(indices, count);
ClearSelection();
for ( i = 0; i < count; i++ ) {
MSG_ViewIndex index = MSG_GetMessageIndexForKey(m_pPane, m_pMysticStuff[i], TRUE);
if ( index != MSG_VIEWINDEXNONE ) {
AddSelection(index);
} else {
m_bSelChanged = TRUE;
}
}
delete [] m_pMysticStuff;
m_pMysticStuff = NULL;
if ( m_MysticSelection == MSG_MESSAGEKEYNONE ) {
m_iSelection = -1;
} else {
int iSelection = CASTINT(MSG_GetMessageIndexForKey(m_pPane, m_MysticSelection, TRUE));
if (iSelection == -1 ) {
iSelection = MSG_GetNumLines( m_pPane ) > 0 ? 0 : -1;
if (iSelection != -1)
AddSelection( iSelection );
}
m_iSelection = iSelection;
}
if ( m_MysticFocus == MSG_MESSAGEKEYNONE ) {
m_iFocus = m_iSelection;
} else {
int iFocus = CASTINT(MSG_GetMessageIndexForKey(m_pPane, m_MysticFocus, TRUE));
if ( iFocus == -1 ) {
iFocus = m_iSelection > 0 ? m_iSelection : 0;
}
m_iFocus = iFocus;
}
m_iShiftAnchor = m_iFocus;
}
if ( notify == MSG_NotifyAll ) {
MSG_FolderInfo *folderInfo = MSG_GetCurFolder( m_pPane );
MSG_FolderLine folderLine;
MSG_GetFolderLineById( WFE_MSGGetMaster(),
folderInfo, &folderLine );
if ( m_bNews ) {
SaveXPPrefs("news.thread_columns_win");
} else {
SaveXPPrefs("mail.thread_columns_win");
}
m_bNews = folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ? TRUE : FALSE;
m_bDrafts = folderLine.flags & MSG_FOLDER_FLAG_DRAFTS ? TRUE : FALSE;
if( m_bNews ) {
LoadXPPrefs("news.thread_columns_win");
} else {
LoadXPPrefs("mail.thread_columns_win");
}
}
CMailNewsOutliner::MysticStuffFinishing( asynchronous, notify,
where, num);
}
// Tree Info stuff
int CMessageOutliner::GetDepth( int iLine )
{
MSG_MessageLine messageLine;
MSG_GetThreadLineByIndex( m_pPane, (MSG_ViewIndex) iLine, 1, &messageLine );
return messageLine.level - 1;
}
int CMessageOutliner::GetNumChildren( int iLine )
{
MSG_MessageLine messageLine;
MSG_GetThreadLineByIndex( m_pPane, (MSG_ViewIndex) iLine, 1, &messageLine );
return messageLine.numChildren;
}
int CMessageOutliner::GetParentIndex( int iLine )
{
MessageKey key = MSG_GetMessageKey( m_pPane, (MSG_ViewIndex) iLine );
return CASTINT(MSG_ThreadIndexOfMsg( m_pPane, key ));
}
BOOL CMessageOutliner::IsCollapsed( int iLine )
{
MSG_MessageLine messageLine;
MSG_GetThreadLineByIndex( m_pPane, (MSG_ViewIndex) iLine, 1, &messageLine );
return messageLine.flags & MSG_FLAG_ELIDED ? TRUE : FALSE;
}
void CMessageOutliner::SelectAllMessages()
{
for (int i = GetTotalLines() - 1; i >= 0; i--)
Expand(i);
}
int CMessageOutliner::ExpandAll( int iLine )
{
MSG_ViewIndex viewIndex = (MSG_ViewIndex) iLine;
int32 numLines = GetTotalLines();
MSG_Command(m_pPane, MSG_ExpandAll, &viewIndex, 1);
ScrollIntoView(m_iFocus);
return GetTotalLines() - numLines;
}
int CMessageOutliner::CollapseAll( int iLine )
{
MSG_ViewIndex viewIndex = (MSG_ViewIndex) iLine;
int32 numLines = GetTotalLines();
MSG_Command(m_pPane, MSG_CollapseAll, &viewIndex, 1);
ScrollIntoView(m_iFocus);
return numLines - GetTotalLines();
}
void CMessageOutliner::SelectThread( int iLine, UINT flags )
{
if ( MSG_GetToggleStatus( m_pPane, MSG_SortByThread, NULL, 0) != MSG_Checked )
return;
MysticStuffStarting( FALSE, MSG_NotifyNone, 0, 0 );
theApp.DoWaitCursor(1);
m_bSelChanged = TRUE;
MessageKey *keys;
MSG_ViewIndex *indices;
int i, count;
if ( iLine >= 0 ) {
if (!(flags & MK_CONTROL )) {
ClearSelection();
}
InvalidateLine(m_iFocus);
m_iFocus = m_iSelection = iLine;
InvalidateLine(m_iFocus);
if ( flags & MK_SHIFT ) {
GetSelection( indices, count );
if ( count <= 0 )
return;
keys = new MessageKey[count];
for ( i = 0; i < count; i++ ) {
keys[ i ] = MSG_GetMessageKey( m_pPane, indices[ i ] );
}
} else {
count = 1;
keys = new MessageKey[1];
keys[0] = MSG_GetMessageKey( m_pPane, (MSG_ViewIndex) iLine );
}
} else {
GetSelection( indices, count );
if ( count <= 0 )
return;
keys = new MessageKey[count];
for ( i = 0; i < count; i++ ) {
keys[ i ] = MSG_GetMessageKey( m_pPane, indices[ i ] );
}
ClearSelection();
}
for ( i = 0; i < count; i++ ) {
MSG_ViewIndex index = MSG_ThreadIndexOfMsg( m_pPane, keys[ i ] );
int delta = CASTINT(MSG_ExpansionDelta( m_pPane, index ));
if ( delta > 0) {
MSG_ToggleExpansion( m_pPane, index, NULL );
} else {
delta = -delta;
}
SelectRange( index, index + delta );
}
delete [] keys;
theApp.DoWaitCursor(-1);
MysticStuffFinishing( FALSE, MSG_NotifyNone, 0, 0 );
}
void CMessageOutliner::SelectFlagged()
{
MSG_MessageLine messageLine;
ClearSelection();
for (int i = 0; i < m_iTotalLines; i++ ) {
if ( MSG_GetThreadLineByIndex( m_pPane, i, 1, &messageLine ) ) {
if ( messageLine.flags & MSG_FLAG_MARKED ) {
AddSelection(i);
}
}
}
OnSelChanged();
}
void CMessageOutliner::EnsureFlagsVisible()
{
int iPos = GetColumnPos(ID_COLUMN_MARK);
int iVis = CASTINT(GetVisibleColumns());
if (iPos >= iVis) {
SetColumnPos(ID_COLUMN_MARK, iVis);
SetVisibleColumns(CASTUINT(iVis + 1));
RECT rc;
GetClientRect(&rc);
OnSize(0, rc.right, rc.bottom);
Invalidate();
GetParent()->Invalidate();
}
}
void CMessageOutliner::PropertyMenu ( int iSel, UINT flags )
{
HMENU hmenu = CreatePopupMenu();
if ( !hmenu )
return;
if ( iSel < m_iTotalLines ) {
if (!m_bDrafts) {
BOOL bReuse = g_MsgPrefs.m_bMessageReuse;
if (GetKeyState(VK_MENU) & 0x8000)
bReuse = !bReuse;
if (bReuse) {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENMESSAGEREUSE, szLoadString( IDS_POPUP_OPENMESSAGE ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENMESSAGENEW, szLoadString( IDS_POPUP_OPENMESSAGENEWWINDOW ) );
} else {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENMESSAGENEW, szLoadString( IDS_POPUP_OPENMESSAGENEWWINDOW ) );
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENMESSAGEREUSE, szLoadString( IDS_POPUP_OPENMESSAGE ) );
}
} else {
::AppendMenu( hmenu, MF_STRING, ID_FILE_OPENMESSAGE, szLoadString( IDS_POPUP_OPENMESSAGE ) );
}
::AppendMenu( hmenu, MF_SEPARATOR, 0, NULL );
//
WFE_MSGBuildMessagePopup( hmenu, m_bNews, TRUE, MSG_GetContext(m_pPane) );
}
// Track the popup now.
POINT pt = m_ptHit;
ClientToScreen(&pt);
::TrackPopupMenu( hmenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0,
GetParentFrame()->GetSafeHwnd(), NULL);
// Cleanup
VERIFY(::DestroyMenu( hmenu ));
}
COleDataSource * CMessageOutliner::GetDataSource(void)
{
MSG_ViewIndex *indices;
int count;
GetSelection( indices, count );
HANDLE hContent = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE,sizeof(MailNewsDragData));
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock (hContent);
pDragData->m_pane = m_pPane;
pDragData->m_indices = indices;
pDragData->m_count = count;
GlobalUnlock(hContent);
COleDataSource * pDataSource = new COleDataSource;
pDataSource->CacheGlobalData(m_cfMessages,hContent);
if ( count == 1 ) {
MSG_MessageLine messageLine;
MSG_GetThreadLineByIndex( m_pPane, indices[0], 1, &messageLine );
URL_Struct *url = MSG_ConstructUrlForMessage( m_pPane, messageLine.messageKey );
if ( url ) {
RDFGLOBAL_DragTitleAndURL( pDataSource, messageLine.subject, url->address );
NET_FreeURLStruct( url );
}
}
return pDataSource;
}
void CMessageOutliner::InitializeClipFormats(void)
{
m_cfMessages = (CLIPFORMAT)RegisterClipboardFormat(NETSCAPE_MESSAGE_FORMAT);
}
CLIPFORMAT * CMessageOutliner::GetClipFormatList(void)
{
static CLIPFORMAT cfFormatList[2];
cfFormatList[0] = m_cfMessages;
cfFormatList[1] = 0;
return cfFormatList;
}
DROPEFFECT CMessageOutliner::DropSelect( int iLineNo, COleDataObject *pDataObject )
{
DROPEFFECT res = DROPEFFECT_NONE;
if ( !m_bNews && pDataObject->IsDataAvailable( m_cfMessages ) )
{
MSG_FolderInfo *pFolderInfo = MSG_GetCurFolder( m_pPane );
HGLOBAL hContent = pDataObject->GetGlobalData (m_cfMessages);
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock(hContent);
MSG_DragEffect requireEffect = MSG_Default_Drag;
if ((GetKeyState(VK_SHIFT) & 0x8000) && (GetKeyState(VK_CONTROL) & 0x8000))
requireEffect = MSG_Default_Drag;
else if (GetKeyState(VK_SHIFT) & 0x8000)
requireEffect = MSG_Require_Move;
else if (GetKeyState(VK_CONTROL) & 0x8000)
requireEffect = MSG_Require_Copy;
MSG_DragEffect effect = MSG_DragMessagesIntoFolderStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
pFolderInfo, requireEffect);
if (effect == MSG_Require_Copy)
res = DROPEFFECT_COPY;
else
res = DROPEFFECT_MOVE;
GlobalUnlock (hContent); //do we have to GlobalFree it too?
}
return res;
}
void CMessageOutliner::AcceptDrop( int iLineNo, COleDataObject *pDataObject,
DROPEFFECT dropEffect )
{
if ( !m_bNews ) {
MSG_FolderInfo *pFolder = MSG_GetCurFolder( m_pPane );
ASSERT(pFolder);
if ( pDataObject->IsDataAvailable( m_cfMessages ) && pFolder ) {
HGLOBAL hContent = pDataObject->GetGlobalData (m_cfMessages);
MailNewsDragData *pDragData = (MailNewsDragData *) GlobalLock(hContent);
MSG_DragEffect requireEffect = MSG_Default_Drag;
if (dropEffect & DROPEFFECT_MOVE)
requireEffect = MSG_Require_Move;
else if (dropEffect & DROPEFFECT_COPY)
requireEffect = MSG_Require_Copy;
MSG_DragEffect effect = MSG_DragMessagesIntoFolderStatus
(pDragData->m_pane, pDragData->m_indices, pDragData->m_count,
pFolder, requireEffect);
// need to code this way to make it work
LPUNKNOWN pUnk = (LPUNKNOWN) MSG_GetFEData( pDragData->m_pane );
if (pUnk) {
LPMSGLIST pInterface = NULL;
pUnk->QueryInterface( IID_IMsgList, (LPVOID *) &pInterface );
if ( pInterface ) {
switch (effect ) {
case MSG_Require_Move:
pInterface->MoveMessagesInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
break;
case MSG_Require_Copy:
pInterface->CopyMessagesInto( pDragData->m_pane, pDragData->m_indices,
pDragData->m_count, pFolder);
break;
default: //do nothing
break;
}
}
}
GlobalUnlock(hContent); //do we have to GlobalFree it too?
}
}
}
BOOL CMessageOutliner::RenderData( UINT iColumn, CRect &rect, CDC &dc, LPCTSTR text )
{
switch ( iColumn )
{
case ID_COLUMN_THREAD:
if ((m_MessageLine.level == 0 && m_MessageLine.numChildren > 0) ||
(m_MessageLine.flags & (MSG_FLAG_WATCHED|MSG_FLAG_IGNORED))) {
int idxImage[] = { IDX_THREADCLOSED,
IDX_THREADOPEN,
IDX_THREADCLOSEDNEW,
IDX_THREADOPENNEW,
IDX_THREADWATCHED,
IDX_THREADWATCHED,
IDX_THREADWATCHEDNEW,
IDX_THREADWATCHEDNEW,
IDX_THREADIGNOREDCLOSED,
IDX_THREADIGNOREDOPEN,
IDX_THREADIGNOREDCLOSED,
IDX_THREADIGNOREDOPEN };
int idx = 0;
idx += m_MessageLine.flags & MSG_FLAG_ELIDED ? 0 : 1;
idx += m_MessageLine.numNewChildren ? 2 : 0;
idx += m_MessageLine.flags & MSG_FLAG_WATCHED ? 4 : 0;
idx += m_MessageLine.flags & MSG_FLAG_IGNORED ? 8 : 0;
m_pIUserImage->DrawImage ( idxImage[idx],
rect.left + ( ( rect.Width ( ) - 16 ) / 2 ), rect.top, &dc, FALSE );
}
return TRUE;
case ID_COLUMN_MARK:
{
int idxImage = m_MessageLine.flags & MSG_FLAG_MARKED ?
IDX_MARKED : IDX_READ;
m_pIUserImage->DrawImage ( idxImage,
rect.left + ( ( rect.Width ( ) - 16 ) / 2 ),
rect.top, &dc, FALSE );
}
return TRUE;
case ID_COLUMN_READ:
if (!(m_MessageLine.flags & MSG_FLAG_EXPIRED)) {
int idxImage;
if (m_MessageLine.flags & MSG_FLAG_READ)
idxImage = IDX_READ;
else
idxImage = IDX_UNREAD;
m_pIUserImage->DrawImage ( idxImage,
rect.left + ( ( rect.Width ( ) - 16 ) / 2 ), rect.top, &dc, FALSE );
}
return TRUE;
case ID_COLUMN_PRIORITY:
{
CRect rectText(rect);
rectText.left += COL_LEFT_MARGIN;
rectText.right -= COL_LEFT_MARGIN;
COLORREF colorPriority[] = { RGB(0x00,0x00,0x00),
RGB(0x00,0x00,0x00),
RGB(0xaa,0xaa,0xaa),
RGB(0x55,0x55,0x55),
RGB(0x00,0x00,0x00),
RGB(0x80,0x00,0x00),
RGB(0xff,0x00,0x00) };
UINT dwDTFormat = DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER;
COLORREF colorOld = dc.GetTextColor();
if ( colorOld != GetSysColor( COLOR_HIGHLIGHTTEXT )) {
dc.SetTextColor( colorPriority[ m_MessageLine.priority ] );
}
DrawColumnText( dc.m_hDC, rectText, text, CropRight, AlignLeft );
dc.SetTextColor( colorOld );
return TRUE;
}
break;
}
return FALSE;
}
int CMessageOutliner::TranslateIcon (void * pData)
{
int messageTable[] = { IDX_MAILMESSAGE, IDX_MAILNEW, IDX_MAILREAD,
IDX_MAILMSGOFFLINE, IDX_MAILMSGOFFLINE, IDX_MAILREADOFFLINE,
IDX_NEWSARTICLE, IDX_NEWSNEW, IDX_NEWSREAD,
IDX_NEWSMSGOFFLINE, IDX_NEWSMSGOFFLINE, IDX_NEWSREADOFFLINE,
IDX_DRAFT, IDX_DRAFT, IDX_DRAFT,
IDX_DRAFT, IDX_DRAFT, IDX_DRAFT };
ASSERT(pData);
MSG_MessageLine * pMessage = (MSG_MessageLine *)pData;
if (pMessage->flags & MSG_FLAG_IMAP_DELETED)
return IDX_IMAPMSGDELETED;
if (pMessage->flags & MSG_FLAG_ATTACHMENT)
return IDX_ATTACHMENTMAIL;
int idx = 0;
if (m_bNews)
idx = 6;
else if (m_bDrafts)
idx = 12;
if ( pMessage->flags & MSG_FLAG_OFFLINE )
idx += 3;
if ( pMessage->flags & MSG_FLAG_READ )
idx += 2;
else if ( pMessage->flags & MSG_FLAG_NEW )
idx += 1;
return messageTable[idx];
}
int CMessageOutliner::TranslateIconFolder (void * pData)
{
ASSERT(pData);
MSG_MessageLine * pMessage = (MSG_MessageLine *)pData;
if (pMessage->numChildren > 0) {
if (pMessage->flags & MSG_FLAG_ELIDED) {
return ( OUTLINER_CLOSEDFOLDER );
} else {
return ( OUTLINER_OPENFOLDER );
}
} else {
return (OUTLINER_ITEM);
}
}
BOOL CMessageOutliner::ColumnCommand ( int iColumn, int iLine )
{
MSG_ViewIndex indices[1];
indices[0] = iLine;
switch ( iColumn )
{
case ID_COLUMN_THREAD:
if ( MSG_GetToggleStatus( m_pPane, MSG_SortByThread, NULL, 0) == MSG_Checked ) {
SelectThread( iLine );
SetCapture();//~~~
return TRUE;
} else {
return FALSE;
}
case ID_COLUMN_READ:
if (!(m_MessageLine.flags & MSG_FLAG_EXPIRED))
MSG_Command(m_pPane, MSG_ToggleMessageRead, indices, 1);
return TRUE;
case ID_COLUMN_MARK:
{
MSG_MessageLine messageLine;
MSG_ViewIndex index = iLine;
MSG_GetThreadLineByIndex( m_pPane, index, 1, &messageLine );
MSG_Command( m_pPane,
( messageLine.flags & MSG_FLAG_MARKED) ?
MSG_UnmarkMessages : MSG_MarkMessages,
&index, 1 );
return TRUE;
}
}
return FALSE;
}
void * CMessageOutliner::AcquireLineData ( int line )
{
if ( line >= m_iTotalLines)
return NULL;
if ( !MSG_GetThreadLineByIndex(m_pPane, line, 1, &m_MessageLine ) )
return NULL;
return &m_MessageLine;
}
void CMessageOutliner::GetTreeInfo ( int iLine, uint32 * pFlags, int * pDepth,
OutlinerAncestorInfo ** pAncestor )
{
delete [] m_pAncestor;
m_pAncestor = NULL;
if ( pAncestor ) {
m_pAncestor = new OutlinerAncestorInfo[m_MessageLine.level + 1];
int i = m_MessageLine.level;
int idx = iLine + 1;
while ( i > 0 ) {
if ( idx < m_iTotalLines ) {
int level = MSG_GetThreadLevelByIndex( m_pPane, idx );
if ( level == i ) {
m_pAncestor[i].has_prev = TRUE;
m_pAncestor[i].has_next = TRUE;
i--;
idx++;
} else if ( level < i ) {
m_pAncestor[i].has_prev = FALSE;
m_pAncestor[i].has_next = FALSE;
i--;
} else {
idx++;
}
} else {
m_pAncestor[i].has_prev = FALSE;
m_pAncestor[i].has_next = FALSE;
i--;
}
}
m_pAncestor[0].has_prev = FALSE;
m_pAncestor[0].has_next = FALSE;
*pAncestor = m_pAncestor;
}
if ( pFlags ) *pFlags = m_MessageLine.flags;
if ( pDepth ) *pDepth = m_MessageLine.level;
}
HFONT CMessageOutliner::GetLineFont ( void * )
{
if ( m_MessageLine.flags & MSG_FLAG_EXPIRED )
return m_hRegFont;
return (!(m_MessageLine.flags & MSG_FLAG_READ) ? m_hBoldFont : m_hRegFont);
}
void CMessageOutliner::ReleaseLineData ( void * )
{
delete [] m_pAncestor;
m_pAncestor = NULL;
}
LPCTSTR CMessageOutliner::GetColumnText ( UINT iColumn, void * pLineData )
{
LPTSTR buf; // temporary buffer for mail header conversion (I18N)
m_pszExtraText[ 0 ] = _T('\0');
m_pszExtraText[ EXTRATEXT_SIZE - 1 ] = _T('\0');
switch ( iColumn )
{
case ID_COLUMN_FROM:
{
buf = IntlDecodeMimePartIIStr(m_MessageLine.author, INTL_DocToWinCharSetID(m_iCSID), FALSE);
if (buf)
{
_tcsncpy(m_pszExtraText, buf, EXTRATEXT_SIZE - 1);
XP_FREE(buf);
return m_pszExtraText;
}
return m_MessageLine.author;
}
case ID_COLUMN_SUBJECT:
{
CString cs = _T("");
if ( m_MessageLine.flags & MSG_FLAG_HAS_RE ) {
cs.LoadString(IDS_MAIL_RE);
}
_tcscpy ( m_pszExtraText, cs );
buf = IntlDecodeMimePartIIStr(m_MessageLine.subject, INTL_DocToWinCharSetID(m_iCSID), FALSE);
if (buf) {
_tcsncat ( m_pszExtraText, buf,
EXTRATEXT_SIZE - cs.GetLength() - 1);
XP_FREE(buf);
} else {
_tcsncat ( m_pszExtraText, m_MessageLine.subject,
EXTRATEXT_SIZE - cs.GetLength() - 1);
}
return m_pszExtraText;
}
case ID_COLUMN_DATE:
{
if ( m_MessageLine.flags & MSG_FLAG_EXPIRED )
return _T("");
_tcscpy ( m_pszExtraText, MSG_FormatDate(m_pPane,m_MessageLine.date));
return m_pszExtraText;
}
case ID_COLUMN_PRIORITY:
if ( m_MessageLine.priority != MSG_NoPriority &&
m_MessageLine.priority != MSG_PriorityNotSet &&
m_MessageLine.priority != MSG_NormalPriority) {
MSG_GetPriorityName( m_MessageLine.priority, m_pszExtraText, MSG_FLAG_EXPIRED);
}
return m_pszExtraText;
case ID_COLUMN_STATUS:
if (m_MessageLine.flags & MSG_FLAG_NEW) {
MSG_GetStatusName( MSG_FLAG_NEW,
m_pszExtraText, EXTRATEXT_SIZE);
return m_pszExtraText;
}
if ( m_MessageLine.flags & MSG_FLAG_REPLIED &&
m_MessageLine.flags & MSG_FLAG_FORWARDED ) {
MSG_GetStatusName( MSG_FLAG_REPLIED|MSG_FLAG_FORWARDED,
m_pszExtraText, EXTRATEXT_SIZE);
return m_pszExtraText;
}
else if ( m_MessageLine.flags & MSG_FLAG_FORWARDED ) {
MSG_GetStatusName( MSG_FLAG_FORWARDED,
m_pszExtraText, EXTRATEXT_SIZE);
return m_pszExtraText;
}
else if ( m_MessageLine.flags & MSG_FLAG_REPLIED ) {
MSG_GetStatusName( MSG_FLAG_REPLIED,
m_pszExtraText, EXTRATEXT_SIZE);
return m_pszExtraText;
}
break;
case ID_COLUMN_LENGTH:
if (m_bNews) {
_stprintf( m_pszExtraText, _T("%d"), (int) m_MessageLine.messageLines );
} else {
_TCHAR cSuffix = _T(' ');
int32 iSize = m_MessageLine.messageLines;
if ( iSize > 1L<<30 ) {
iSize /= 1L<<30;
cSuffix = _T('G');
} else if ( iSize > 1L<<20 ) {
iSize /= 1L<<20;
cSuffix = _T('M');
} else if ( iSize > 1L<<10 ) {
iSize /= 1L<<10;
cSuffix = _T('K');
} else {
iSize = 1;
cSuffix = _T('K');
}
_stprintf( m_pszExtraText, _T("%d%cB"), (int) iSize, cSuffix );
}
return m_pszExtraText;
case ID_COLUMN_UNREAD:
if (m_MessageLine.numNewChildren) {
_stprintf( m_pszExtraText, _T("%d"), (int) m_MessageLine.numNewChildren );
return m_pszExtraText;
}
break;
case ID_COLUMN_COUNT:
if (m_MessageLine.numChildren) {
_stprintf( m_pszExtraText, _T("%d"), (int) m_MessageLine.numChildren + 1 );
return m_pszExtraText;
}
break;
}
return ("");
}
void CMessageOutliner::OnDestroy()
{
if (m_uTimer)
{
KillTimer(m_uTimer);
m_uTimer = 0;
}
CMailNewsOutliner::OnDestroy();
}
void CMessageOutliner::OnTimer(UINT nIDEvent)
{
if (m_uTimer == nIDEvent)
{
if (m_bDoubleClicked)
{
m_bDoubleClicked = FALSE;
KillTimer(m_uTimer);
m_uTimer = 0;
}
else
{
UINT delta = GetTickCount() - m_dwPrevTime;
if (delta > GetDoubleClickTime())
{ // single click
m_bSelChanged = FALSE;
if (GetCurrentSelected() != m_iSelection)
{
if (!m_iSelBlock)
GetParentFrame()->PostMessage(WM_COMMAND, ID_MESSAGE_SELECT, 0);
}
KillTimer(m_uTimer);
m_uTimer = 0;
}
}
m_bLButtonDown = FALSE;
}
else
CMailNewsOutliner::OnTimer(nIDEvent);
}
void CMessageOutliner::OnSelChanged()
{
if (((C3PaneMailFrame*)GetParentFrame())->MessageViewClosed())
{
m_bSelChanged = FALSE;
if (!m_iSelBlock)
GetParentFrame()->PostMessage(WM_COMMAND, ID_MESSAGE_SELECT, 0);
}
else
{
BOOL bControlKeydown = ((GetKeyState(VK_CONTROL) & 0x8000) && m_bLButtonDown);
if (!bControlKeydown)
SetCurrentSelected(m_iLastSelected);
if (!bControlKeydown && m_bLButtonDown && m_uTimer == 0 && !m_bDoubleClicked)
{
m_dwPrevTime = GetTickCount();
UINT uElapse = GetDoubleClickTime() / 5;
m_uTimer = SetTimer(DOUBLE_CLICK_TIMER, uElapse, NULL);
}
else
{
if (!m_bDoubleClicked)
{
m_bSelChanged = FALSE;
if (!m_iSelBlock)
GetParentFrame()->PostMessage(WM_COMMAND, ID_MESSAGE_SELECT, 0);
}
}
}
}
void CMessageOutliner::OnSelDblClk()
{
if (m_bLButtonDown && m_uTimer != 0)
m_bDoubleClicked = TRUE;
GetParentFrame()->PostMessage(WM_COMMAND, ID_FILE_OPENMESSAGE, 0);
}
void CMessageOutliner::OnSetFocus(CWnd* pOldWnd)
{
C3PaneMailFrame* pParent = (C3PaneMailFrame*)GetParentFrame();
CMailNewsOutliner::OnSetFocus(pOldWnd);
pParent->SetFocusWindow(this);
}
BEGIN_MESSAGE_MAP(CMessageOutliner, CMailNewsOutliner)
ON_WM_TIMER()
ON_WM_SETFOCUS()
ON_WM_DESTROY()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFolderOutlinerParent
CFolderOutlinerParent::CFolderOutlinerParent()
{
m_pUnkUserImage = NULL;
ApiApiPtr(api);
m_pUnkUserImage = api->CreateClassInstance(
APICLASS_IMAGEMAP,NULL,(APISIGNATURE)IDB_MAILCOL);
m_pUnkUserImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIUserImage);
ASSERT(m_pIUserImage);
if (!m_pIUserImage->GetResourceID())
m_pIUserImage->Initialize(IDB_MAILCOL,16,16);
}
CFolderOutlinerParent::~CFolderOutlinerParent()
{
if (m_pUnkUserImage) {
if (m_pIUserImage)
m_pUnkUserImage->Release();
}
}
COutliner * CFolderOutlinerParent::GetOutliner ( void )
{
return new CFolderOutliner;
}
typedef struct COLUMNDESC {
UINT idCol;
UINT idTitle;
int nWidth;
BOOL bButton;
Column_t styleColumn;
CropType_t styleCrop;
AlignType_t styleAlign;
} ColumnDesc_t;
static ColumnDesc_t aidFolderColumns[] =
{ { ID_COLUMN_FOLDER, IDS_MAIL_NAME, 6000, FALSE, ColumnVariable, CropRight, AlignLeft },
{ ID_COLUMN_UNREAD, IDS_MAIL_UNREAD, 2000, FALSE, ColumnVariable, CropRight, AlignRight },
{ ID_COLUMN_COUNT, IDS_MAIL_TOTAL, 2000, FALSE, ColumnVariable, CropRight, AlignRight } };
void CFolderOutlinerParent::CreateColumns ( void )
{
ColumnDesc_t *pColumns;
int nColumns;
int i;
nColumns = sizeof( aidFolderColumns ) / sizeof ( ColumnDesc_t );
pColumns = aidFolderColumns;
CString cs;
for ( i = 0; i < nColumns; i++ ) {
int nMin = pColumns[i].styleColumn == ColumnFixed ? 20 : pColumns[i].nWidth;
int nDefault = pColumns[i].nWidth;
if ( pColumns[i].idTitle ) {
cs.LoadString(pColumns[i].idTitle);
} else {
cs = _T("");
}
m_pOutliner->AddColumn ( cs,
pColumns[i].idCol,
nMin, 0,
pColumns[i].styleColumn,
nDefault,
pColumns[i].bButton,
pColumns[i].styleCrop,
pColumns[i].styleAlign );
}
m_pOutliner->SetImageColumn( ID_COLUMN_FOLDER );
if (((CFolderOutliner*)m_pOutliner)->IsParent3PaneFrame())
m_pOutliner->LoadXPPrefs("mailnews.3Pane_folder_columns_win");
else
m_pOutliner->LoadXPPrefs("mailnews.folder_columns_win");
}
BEGIN_MESSAGE_MAP(CFolderOutlinerParent,COutlinerParent)
ON_WM_DESTROY()
END_MESSAGE_MAP()
void CFolderOutlinerParent::OnDestroy()
{
if (((CFolderOutliner*)m_pOutliner)->IsParent3PaneFrame())
m_pOutliner->SaveXPPrefs("mailnews.3Pane_folder_columns_win");
else
m_pOutliner->SaveXPPrefs( "mailnews.folder_columns_win" );
COutlinerParent::OnDestroy();
}
/////////////////////////////////////////////////////////////////////////////
// CMessageOutlinerParent
CMessageOutlinerParent::CMessageOutlinerParent()
{
m_pUnkUserImage = NULL;
ApiApiPtr(api);
m_pUnkUserImage = api->CreateClassInstance(
APICLASS_IMAGEMAP,NULL,(APISIGNATURE)IDB_MAILCOL);
m_pUnkUserImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIUserImage);
ASSERT(m_pIUserImage);
if (!m_pIUserImage->GetResourceID())
m_pIUserImage->Initialize(IDB_MAILCOL,16,16);
}
CMessageOutlinerParent::~CMessageOutlinerParent()
{
if (m_pUnkUserImage) {
if (m_pIUserImage)
m_pUnkUserImage->Release();
}
}
BOOL CMessageOutlinerParent::RenderData ( int idColumn, CRect & rect, CDC &dc, LPCTSTR text )
{
MSG_Pane *pPane = ((CMailNewsOutliner *) m_pOutliner)->GetPane();
ASSERT(pPane);
MSG_COMMAND_CHECK_STATE sortType = MSG_Unchecked;
switch (idColumn) {
case ID_COLUMN_READ:
case ID_COLUMN_THREAD:
case ID_COLUMN_MARK:
{
int idxImage;
switch (idColumn) {
case ID_COLUMN_READ:
idxImage = IDX_MAILUNREAD;
break;
case ID_COLUMN_THREAD:
if (MSG_GetToggleStatus(pPane, MSG_SortByThread, NULL, 0) == MSG_Checked) {
idxImage = IDX_THREAD;
} else {
idxImage = IDX_UNTHREAD;
}
break;
case ID_COLUMN_MARK:
idxImage = IDX_MAILMARKED;
break;
}
m_pIUserImage->DrawTransImage( idxImage,
(rect.left + rect.right + 1) / 2 - 8,
(rect.top + rect.bottom + 1) / 2 - 8, &dc );
}
return TRUE;
case ID_COLUMN_DATE:
sortType = MSG_GetToggleStatus(pPane, MSG_SortByDate, NULL, 0);
break;
case ID_COLUMN_SUBJECT:
sortType = MSG_GetToggleStatus(pPane, MSG_SortBySubject, NULL, 0);
break;
case ID_COLUMN_FROM:
sortType = MSG_GetToggleStatus(pPane, MSG_SortBySender, NULL, 0);
break;
case ID_COLUMN_PRIORITY:
sortType = MSG_GetToggleStatus(pPane, MSG_SortByPriority, NULL, 0);
break;
case ID_COLUMN_STATUS:
sortType = MSG_GetToggleStatus(pPane, MSG_SortByStatus, NULL, 0);
break;
case ID_COLUMN_LENGTH:
sortType = MSG_GetToggleStatus(pPane, MSG_SortBySize, NULL, 0);
break;
default:
return FALSE;
}
UINT dwDTFormat = DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER;
CString csTitle = text;
if ( MSG_DisplayingRecipients( pPane ) && idColumn == ID_COLUMN_FROM ) {
csTitle.LoadString( IDS_MAIL_RECIPIENT );
}
if ( idColumn == ID_COLUMN_LENGTH ) {
dwDTFormat |= DT_RIGHT;
if (!((CMessageOutliner *)m_pOutliner)->IsNews())
csTitle.LoadString( IDS_SIZE );
}
RECT rectText = rect;
rectText.left += COL_LEFT_MARGIN;
rectText.right -= COL_LEFT_MARGIN + 1;
if (sortType == MSG_Checked) {
rectText.right -= 14;
int idxImage;
if (MSG_GetToggleStatus( pPane,MSG_SortBackward, NULL, 0) == MSG_Checked )
idxImage = IDX_SORTINDICATORUP;
else
idxImage = IDX_SORTINDICATORDOWN;
m_pIImage->DrawTransImage( idxImage,
rectText.right + 4,
(rect.top + rect.bottom) / 2 - 4,
&dc );
}
WFE_DrawTextEx( 0, dc.m_hDC, (LPTSTR) (LPCTSTR) csTitle, -1,
&rectText, dwDTFormat, WFE_DT_CROPRIGHT );
return TRUE;
}
COutliner * CMessageOutlinerParent::GetOutliner ( void )
{
return new CMessageOutliner;
}
static ColumnDesc_t aidMessageColumns[] =
{ { ID_COLUMN_THREAD, 0, 24, TRUE, ColumnFixed, CropRight, AlignLeft },
{ ID_COLUMN_SUBJECT, IDS_MAIL_SUBJECT, 2500, TRUE, ColumnVariable, CropRight, AlignLeft },
{ ID_COLUMN_READ, 0, 24, TRUE, ColumnFixed, CropRight, AlignLeft },
{ ID_COLUMN_FROM, IDS_MAIL_SENDER, 2500, TRUE, ColumnVariable, CropRight, AlignLeft },
{ ID_COLUMN_DATE, IDS_MAIL_DATE, 1500, TRUE, ColumnVariable, CropRight, AlignLeft },
{ ID_COLUMN_PRIORITY, IDS_MAIL_PRIORITY, 1000, TRUE, ColumnVariable, CropRight, AlignLeft },
{ ID_COLUMN_MARK, 0, 24, TRUE, ColumnFixed, CropRight, AlignLeft },
{ ID_COLUMN_STATUS, IDS_MAIL_STATUS, 750, TRUE, ColumnVariable, CropRight, AlignLeft },
{ ID_COLUMN_LENGTH, IDS_MAIL_LENGTH, 750, TRUE, ColumnVariable, CropRight, AlignRight },
{ ID_COLUMN_UNREAD, IDS_MAIL_UNREAD, 500, FALSE, ColumnVariable, CropRight, AlignRight },
{ ID_COLUMN_COUNT, IDS_MAIL_TOTAL, 500, FALSE, ColumnVariable, CropRight, AlignRight } };
void CMessageOutlinerParent::CreateColumns ( void )
{
ColumnDesc_t *pColumns;
int nColumns;
int i;
nColumns = sizeof( aidMessageColumns ) / sizeof ( ColumnDesc_t );
pColumns = aidMessageColumns;
CString cs;
for ( i = 0; i < nColumns; i++ ) {
int nMin = pColumns[i].styleColumn == ColumnFixed ? 20 : pColumns[i].nWidth;
int nDefault = pColumns[i].nWidth;
if ( pColumns[i].idTitle ) {
cs.LoadString(pColumns[i].idTitle);
} else {
cs = _T("");
}
m_pOutliner->AddColumn ( cs,
pColumns[i].idCol,
nMin, 0,
pColumns[i].styleColumn,
nDefault,
pColumns[i].bButton,
pColumns[i].styleCrop,
pColumns[i].styleAlign );
}
m_pOutliner->SetVisibleColumns( 6 );
m_pOutliner->SetImageColumn( ID_COLUMN_SUBJECT );
if ( ((CMessageOutliner *) m_pOutliner)->IsNews() ) {
m_pOutliner->LoadXPPrefs("news.thread_columns_win");
} else {
m_pOutliner->LoadXPPrefs("mail.thread_columns_win");
}
}
BOOL CMessageOutlinerParent::ColumnCommand ( int nColumn )
{
UINT iCommand = 0;
switch ( nColumn ) {
case ID_COLUMN_FROM:
iCommand = ID_SORT_BYSENDER;
break;
case ID_COLUMN_SUBJECT:
iCommand = ID_SORT_BYSUBJECT;
break;
case ID_COLUMN_DATE:
iCommand = ID_SORT_BYDATE;
break;
case ID_COLUMN_THREAD:
iCommand = ID_SORT_BYTHREAD;
break;
case ID_COLUMN_PRIORITY:
iCommand = ID_SORT_BYPRIORITY;
break;
case ID_COLUMN_STATUS:
iCommand = ID_SORT_BYSTATUS;
break;
case ID_COLUMN_LENGTH:
iCommand = ID_SORT_BYSIZE;
break;
case ID_COLUMN_MARK:
iCommand = ID_SORT_BYFLAG;
break;
case ID_COLUMN_READ:
iCommand = ID_SORT_BYUNREAD;
break;
}
if ( iCommand ) {
SetCursor ( theApp.LoadStandardCursor ( IDC_WAIT ) );
GetParentFrame()->SendMessage(WM_COMMAND, iCommand, 0 );
SetCursor ( theApp.LoadStandardCursor ( IDC_ARROW ) );
}
return 0;
}
BEGIN_MESSAGE_MAP(CMessageOutlinerParent,COutlinerParent)
ON_WM_DESTROY()
END_MESSAGE_MAP()
void CMessageOutlinerParent::OnDestroy()
{
if ( ((CMessageOutliner *) m_pOutliner)->IsNews() )
m_pOutliner->SaveXPPrefs("news.thread_columns_win");
else
m_pOutliner->SaveXPPrefs("mail.thread_columns_win");
COutlinerParent::OnDestroy();
}
//////////////////////////////////////////////////////////////////////////////
// CMarkReadDateDlg
BOOL CMarkReadDateDlg::OnInitDialog( )
{
BOOL res = CDialog::OnInitDialog();
wndDateTo.SubclassDlgItem(IDC_STATIC1, this);
CTime timeTmp = CTime::GetCurrentTime();
wndDateTo.SetDate( timeTmp );
return res;
}
void CMarkReadDateDlg::OnOK()
{
wndDateTo.GetDate(dateTo);
CDialog::OnOK();
}
/////////////////////////////////////////////////////////////////////////////
// C function shared by CMailFolderHelper and preference
extern "C" void HelperInitFonts( HDC hdc , HFONT *phFont, HFONT *phBoldFont)
{
uint16 csid = INTL_CharSetNameToID(INTL_ResourceCharSet());
LOGFONT lf;
memset(&lf,0,sizeof(LOGFONT));
lf.lfPitchAndFamily = FF_SWISS;
lf.lfCharSet = IntlGetLfCharset( csid );
if ( csid == CS_LATIN1 )
_tcscpy( lf.lfFaceName, "MS Sans Serif" );
else
_tcscpy( lf.lfFaceName, IntlGetUIPropFaceName( csid ) );
lf.lfHeight = -MulDiv( 9, ::GetDeviceCaps( hdc, LOGPIXELSY ), 72);
*phFont = theApp.CreateAppFont( lf );
lf.lfWeight = 700;
*phBoldFont = theApp.CreateAppFont( lf );
}
extern "C" void HelperDoMeasureItem( HWND hWnd, LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
lpMeasureItemStruct->itemHeight = 16;
}
extern "C" void HelperDoDrawItem
( HWND hWnd, LPDRAWITEMSTRUCT lpDrawItemStruct, HFONT *phFont, HFONT *phBoldFont,
MSG_Master *pMaster, BOOL bStaticCtl, int iInitialDepth, LPIMAGEMAP pIImageMap,
BOOL bNoPrettyName)
{
HDC hDC = lpDrawItemStruct->hDC;
RECT rcItem = lpDrawItemStruct->rcItem;
RECT rcTemp = rcItem;
RECT rcText;
DWORD dwItemData = lpDrawItemStruct->itemData;
HBRUSH hBrushWindow = ::CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
HBRUSH hBrushHigh = ::CreateSolidBrush( GetSysColor( COLOR_HIGHLIGHT ) );
HBRUSH hBrushFill = NULL;
if ( !*phFont ) {
HelperInitFonts( hDC, phFont, phBoldFont);
}
HFONT hOldFont = NULL;
if ( *phFont ) {
hOldFont = (HFONT) ::SelectObject( hDC, *phFont );
}
if ( lpDrawItemStruct->itemState & ODS_SELECTED ) {
hBrushFill = hBrushHigh;
::SetBkColor( hDC, GetSysColor( COLOR_HIGHLIGHT ) );
::SetTextColor( hDC, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
} else {
hBrushFill = hBrushWindow;
::SetBkColor( hDC, GetSysColor( COLOR_WINDOW ) );
::SetTextColor( hDC, GetSysColor( COLOR_WINDOWTEXT ) );
}
VERIFY(::FillRect( hDC, &rcItem, hBrushWindow ));
if ( lpDrawItemStruct->itemID != -1 && dwItemData ) {
MSG_FolderInfo *folderInfo = (MSG_FolderInfo *) dwItemData;
MSG_FolderLine folderLine;
MSG_GetFolderLineById( pMaster, folderInfo, &folderLine);
int idxImage = WFE_MSGTranslateFolderIcon( folderLine.level,
folderLine.flags,
folderLine.numChildren );
if ( *phBoldFont && folderLine.unseen > 0 ) {
::SelectObject( hDC, *phBoldFont );
}
int iIndent = 4;
BOOL bStatic = FALSE;
#ifdef _WIN32
if ( sysInfo.m_bWin4 )
bStatic = ( lpDrawItemStruct->itemState & ODS_COMBOBOXEDIT ) ? TRUE : FALSE;
else
#endif
bStatic = bStaticCtl;
if (!bStatic)
iIndent += (folderLine.level - iInitialDepth) * 8;
pIImageMap->DrawImage( idxImage, iIndent, rcItem.top, hDC, FALSE );
LPCTSTR name;
if (bNoPrettyName)
name = folderLine.name;
else
{
name = (LPCTSTR) folderLine.prettyName;
if ( !name || !name[0] )
name = folderLine.name;
}
::DrawText( hDC, name, -1, &rcTemp, DT_SINGLELINE|DT_CALCRECT|DT_NOPREFIX );
int iWidth = rcTemp.right - rcTemp.left;
rcTemp = rcItem;
rcText = rcItem;
rcTemp.left = iIndent + 20;
rcTemp.right = rcTemp.left + iWidth + 4;
if (rcTemp.right > rcItem.right)
rcTemp.right = rcItem.right;
VERIFY(::FillRect( hDC, &rcTemp, hBrushFill ));
rcText.left = rcTemp.left + 2;
rcText.right = rcTemp.right - 2;
::DrawText( hDC, name, -1, &rcText, DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX );
if ( lpDrawItemStruct->itemAction & ODA_FOCUS &&
lpDrawItemStruct->itemState & ODS_SELECTED ) {
::DrawFocusRect( hDC, &rcTemp );
}
}
if ( hBrushHigh )
VERIFY( ::DeleteObject( hBrushHigh ));
if ( hBrushWindow )
VERIFY( ::DeleteObject( hBrushWindow ));
if ( hOldFont )
::SelectObject( hDC, hOldFont );
}
extern "C" void HelperSubPopulate
( HWND hWnd, int *pIndex, MSG_FolderInfo *folder, MSG_Master *pMaster,
UINT nAddString, UINT nSetItemData)
{
int32 iLines = MSG_GetFolderChildren (pMaster, folder, NULL, 0);
MSG_FolderInfo **ppFolderInfo = new MSG_FolderInfo *[iLines];
ASSERT(ppFolderInfo);
if (ppFolderInfo)
{
MSG_GetFolderChildren (pMaster, folder, ppFolderInfo, iLines);
for (int i = 0; i < iLines; i++)
{
MSG_FolderLine folderLine;
if (MSG_GetFolderLineById (pMaster, ppFolderInfo[i], &folderLine)) {
if ( !(folderLine.flags & MSG_FOLDER_FLAG_CATEGORY) ||
(folderLine.flags & MSG_FOLDER_FLAG_CAT_CONTAINER)) {
SendMessage( hWnd, nAddString, (WPARAM) 0, (LPARAM) folderLine.name );
SendMessage( hWnd, nSetItemData, (WPARAM) *pIndex, (LPARAM) folderLine.id );
(*pIndex)++;
if ( folderLine.numChildren > 0 ) {
HelperSubPopulate( hWnd, pIndex, folderLine.id ,pMaster, nAddString, nSetItemData);
}
}
}
}
delete [] ppFolderInfo;
}
}
extern "C" int HelperPopulate
( HWND hWnd, MSG_Master *master, MSG_FolderInfo *mailRoot, MSG_Master **hMaster,
UINT nResetContent, int* piInitialDepth, UINT nAddString, UINT nSetItemData)
{
*hMaster = master;
int index = 0;
*piInitialDepth = 1;
SendMessage( hWnd, nResetContent, (WPARAM) 0, (LPARAM) 0 );
if ( mailRoot ) {
MSG_FolderLine folderLine;
MSG_GetFolderLineById( master, mailRoot, &folderLine );
*piInitialDepth = folderLine.level;
}
HelperSubPopulate( hWnd, &index, mailRoot, master, nAddString, nSetItemData);
return 1;
}
/////////////////////////////////////////////////////////////////////////////
// CMailFolderCombo, CMailFolderList
CMailFolderHelper::CMailFolderHelper( UINT nAddString, UINT nSetItemData,
UINT nResetContent)
{
m_bStaticCtl = FALSE;
m_hFont = NULL;
m_hBoldFont = NULL;
m_nAddString = nAddString;
m_nSetItemData = nSetItemData;
m_nResetContent = nResetContent;
ApiApiPtr(api);
m_pIImageUnk = api->CreateClassInstance(APICLASS_IMAGEMAP);
ASSERT(m_pIImageUnk);
if (m_pIImageUnk) {
m_pIImageUnk->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIImageMap);
ASSERT(m_pIImageMap);
m_pIImageMap->Initialize(IDB_MAILNEWS,16,16);
}
}
CMailFolderHelper::~CMailFolderHelper()
{
if (m_pIImageUnk && m_pIImageMap ) {
m_pIImageUnk->Release();
}
if (m_hFont)
theApp.ReleaseAppFont(m_hFont);
if (m_hBoldFont)
theApp.ReleaseAppFont(m_hBoldFont);
}
void CMailFolderHelper::InitFonts( HDC hdc )
{
::HelperInitFonts(hdc, &m_hFont, &m_hBoldFont);
}
void CMailFolderHelper::DoMeasureItem( HWND hWnd, LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
::HelperDoMeasureItem( hWnd, lpMeasureItemStruct );
}
void CMailFolderHelper::DoDrawItem( HWND hWnd, LPDRAWITEMSTRUCT lpDrawItemStruct, BOOL bNoPrettyName)
{
::HelperDoDrawItem( hWnd, lpDrawItemStruct, &m_hFont, &m_hBoldFont,
m_pMaster, m_bStaticCtl, m_iInitialDepth, m_pIImageMap, bNoPrettyName);
}
void CMailFolderHelper::SubPopulate( HWND hWnd, int &index, MSG_FolderInfo *folder )
{
HelperSubPopulate( hWnd, &index, folder, m_pMaster, m_nAddString, m_nSetItemData);
}
int CMailFolderHelper::Populate( HWND hWnd, MSG_Master *master, MSG_FolderInfo *mailRoot )
{
return HelperPopulate( hWnd, master, mailRoot, &m_pMaster, m_nResetContent,
&m_iInitialDepth, m_nAddString, m_nSetItemData);
}
int CMailFolderHelper::PopulateMailServer( HWND hWnd, MSG_Master *master, BOOL bRoots)
{
m_pMaster = master;
int index = 0;
m_iInitialDepth = 1;
SendMessage( hWnd, m_nResetContent, (WPARAM) 0, (LPARAM) 0 );
int32 iLines = MSG_GetFolderChildren (m_pMaster, NULL, NULL, 0);
MSG_FolderInfo **ppFolderInfo = new MSG_FolderInfo *[iLines];
ASSERT(ppFolderInfo);
if (ppFolderInfo)
{
MSG_GetFolderChildren (m_pMaster, NULL, ppFolderInfo, iLines);
for (int i = 0; i < iLines; i++)
{
MSG_FolderLine folderLine;
if (MSG_GetFolderLineById (m_pMaster, ppFolderInfo[i], &folderLine)) {
if ( folderLine.flags & MSG_FOLDER_FLAG_MAIL ) {
if ( bRoots ) {
SendMessage( hWnd, m_nAddString, (WPARAM) 0, (LPARAM) folderLine.name );
SendMessage( hWnd, m_nSetItemData, (WPARAM) index, (LPARAM) folderLine.id );
index++;
}
}
}
}
delete [] ppFolderInfo;
}
return 1;
}
int CMailFolderHelper::PopulateMail( HWND hWnd, MSG_Master *master, BOOL bRoots)
{
m_pMaster = master;
int index = 0;
m_iInitialDepth = 1;
SendMessage( hWnd, m_nResetContent, (WPARAM) 0, (LPARAM) 0 );
int32 iLines = MSG_GetFolderChildren (m_pMaster, NULL, NULL, 0);
MSG_FolderInfo **ppFolderInfo = new MSG_FolderInfo *[iLines];
ASSERT(ppFolderInfo);
if (ppFolderInfo)
{
MSG_GetFolderChildren (m_pMaster, NULL, ppFolderInfo, iLines);
for (int i = 0; i < iLines; i++)
{
MSG_FolderLine folderLine;
if (MSG_GetFolderLineById (m_pMaster, ppFolderInfo[i], &folderLine)) {
if ( folderLine.flags & MSG_FOLDER_FLAG_MAIL ) {
if ( bRoots ) {
SendMessage( hWnd, m_nAddString, (WPARAM) 0, (LPARAM) folderLine.name );
SendMessage( hWnd, m_nSetItemData, (WPARAM) index, (LPARAM) folderLine.id );
index++;
}
if ( folderLine.numChildren > 0 ) {
SubPopulate( hWnd, index, ppFolderInfo[i] );
}
}
}
}
delete [] ppFolderInfo;
}
return 1;
}
int CMailFolderHelper::PopulateNews( HWND hWnd, MSG_Master *master, BOOL bRoots )
{
m_pMaster = master;
int index = 0;
m_iInitialDepth = 1;
SendMessage( hWnd, m_nResetContent, (WPARAM) 0, (LPARAM) 0 );
int32 iLines = MSG_GetFolderChildren (m_pMaster, NULL, NULL, 0);
MSG_FolderInfo **ppFolderInfo = new MSG_FolderInfo *[iLines];
ASSERT(ppFolderInfo);
if (ppFolderInfo)
{
MSG_GetFolderChildren (m_pMaster, NULL, ppFolderInfo, iLines);
for (int i = 0; i < iLines; i++)
{
MSG_FolderLine folderLine;
if (MSG_GetFolderLineById (m_pMaster, ppFolderInfo[i], &folderLine)) {
if ( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ||
folderLine.flags & MSG_FOLDER_FLAG_NEWS_HOST)
{
if ( bRoots ) {
SendMessage( hWnd, m_nAddString, (WPARAM) 0, (LPARAM) folderLine.name );
SendMessage( hWnd, m_nSetItemData, (WPARAM) index, (LPARAM) folderLine.id );
index++;
}
if ( folderLine.numChildren > 0 ) {
SubPopulate( hWnd, index, ppFolderInfo[i] );
}
}
}
}
delete ppFolderInfo;
}
return 1;
}
#define NAV_BUTTONWIDTH 24
#define NAV_BUTTONHEIGHT 16
CNavCombo::CNavCombo()
{
m_bFirst = TRUE;
m_hFont = NULL;
m_hBigFont = NULL;
}
CNavCombo::~CNavCombo()
{
}
void CNavCombo::SetFont( CFont *pFont, CFont *pBigFont )
{
m_hFont = (HFONT) pFont->m_hObject;
m_hBigFont = (HFONT) pBigFont->m_hObject;
CMailFolderCombo::SetFont(pFont);
}
void CNavCombo::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
BOOL bStatic = FALSE;
#ifdef _WIN32
if ( sysInfo.m_bWin4 )
bStatic = ( lpDrawItemStruct->itemState & ODS_COMBOBOXEDIT ) ? TRUE : FALSE;
else
#endif
bStatic = m_bStaticCtl;
if ( bStatic ) {
HDC hdc = lpDrawItemStruct->hDC;
RECT rect = lpDrawItemStruct->rcItem;
COLORREF oldText;
COLORREF oldBk;
if ( lpDrawItemStruct->itemState & ODS_SELECTED ) {
oldText = ::SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
oldBk = ::SetBkColor( hdc, GetSysColor(COLOR_HIGHLIGHT));
} else {
oldText = ::SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) );
oldBk = ::SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
}
HFONT hOldFont = (HFONT) ::SelectObject( hdc, m_hBigFont );
MSG_FolderInfo *itemData = (MSG_FolderInfo *) lpDrawItemStruct->itemData;
if ( (lpDrawItemStruct->itemID != (UINT) -1) && itemData ) {
MSG_FolderLine folderLine;
MSG_GetFolderLineById( m_pMaster, itemData, &folderLine);
rect.left += 4;
LPCTSTR name = (LPCTSTR) folderLine.prettyName;
if ( !name || !name[0] )
name = folderLine.name;
CIntlWin::DrawText( 0, hdc, (LPSTR) name, -1, &rect,
DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX );
}
if ( hOldFont )
::SelectObject( hdc, hOldFont );
::SetTextColor( hdc, oldText );
::SetBkColor(hdc, oldText);
} else {
CMailFolderCombo::DrawItem( lpDrawItemStruct );
}
}
BEGIN_MESSAGE_MAP( CNavCombo, CMailFolderCombo )
ON_WM_CTLCOLOR()
ON_WM_PAINT()
END_MESSAGE_MAP()
void CNavCombo::OnPaint()
{
m_bStaticCtl = TRUE;
CMailFolderCombo::OnPaint();
m_bFirst = TRUE;
}
HBRUSH CNavCombo::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor )
{
if (nCtlColor == CTLCOLOR_LISTBOX) {
if (m_bFirst) {
RECT rcParent;
GetWindowRect( &rcParent );
pWnd->GetWindowRect(&m_rcList);
m_bFirst = FALSE;
int height = m_rcList.bottom - m_rcList.top;
if ( (rcParent.bottom + height) > GetSystemMetrics( SM_CYFULLSCREEN ) ) {
height = GetSystemMetrics( SM_CYFULLSCREEN ) - rcParent.bottom;
}
pWnd->MoveWindow( m_rcList.left, rcParent.bottom,
m_rcList.right - m_rcList.left, height );
}
}
m_bStaticCtl = (nCtlColor == CTLCOLOR_EDIT);
return CMailFolderCombo::OnCtlColor( pDC, pWnd, nCtlColor );
}
///////////////////////////////////////////////////////////////////////
// CLinkDropSource
class CLinkDropSource: public COleDropSource
{
protected:
virtual SCODE GiveFeedback( DROPEFFECT dropEffect );
};
SCODE CLinkDropSource::GiveFeedback( DROPEFFECT dropEffect )
{
if ( !(dropEffect & (DROPEFFECT_COPY|DROPEFFECT_MOVE)) ) {
return COleDropSource::GiveFeedback( dropEffect );
} else {
::SetCursor( ::LoadCursor( AfxGetResourceHandle(),
MAKEINTRESOURCE( dropEffect & DROPEFFECT_COPY ?
IDC_LINK_COPY : IDC_LINK_MOVE ) ) );
return NOERROR;
}
}
///////////////////////////////////////////////////////////////////////
// CMailInfoBar
CMailInfoBar::CMailInfoBar()
{
m_bEraseBackground = TRUE;
m_idxImage = 0;
m_pUnkImage = NULL;
ApiApiPtr(api);
m_pUnkImage = api->CreateClassInstance( APICLASS_IMAGEMAP,
NULL,
(APISIGNATURE)IDB_MAILNEWS);
m_pUnkImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIImage);
ASSERT(m_pIImage);
if (!m_pIImage->GetResourceID())
m_pIImage->Initialize(IDB_MAILNEWS,16,16);
m_hbmBanner = NULL;
m_hFont = NULL;
m_hBoldFont = NULL;
m_hIntlFont = NULL;
m_hBoldIntlFont = NULL;
}
CMailInfoBar::~CMailInfoBar()
{
if (m_pUnkImage) {
if (m_pIImage)
m_pUnkImage->Release();
}
if (m_hbmBanner)
VERIFY(::DeleteObject( m_hbmBanner ));
if (m_hFont) {
theApp.ReleaseAppFont(m_hFont);
}
if (m_hBoldFont) {
theApp.ReleaseAppFont(m_hBoldFont);
}
if (m_hIntlFont) {
theApp.ReleaseAppFont(m_hIntlFont);
}
if (m_hBoldIntlFont) {
theApp.ReleaseAppFont(m_hBoldIntlFont);
}
}
void CMailInfoBar::SetCSID( int csid )
{
if (m_hFont) {
theApp.ReleaseAppFont(m_hFont);
}
if (m_hBoldFont) {
theApp.ReleaseAppFont(m_hBoldFont);
}
if (m_hIntlFont) {
theApp.ReleaseAppFont(m_hIntlFont);
}
if (m_hBoldIntlFont) {
theApp.ReleaseAppFont(m_hBoldIntlFont);
}
CClientDC dc(this);
m_iCSID = csid;
int16 defCSID = INTL_CharSetNameToID(INTL_ResourceCharSet());
LOGFONT lf;
memset( &lf, 0, sizeof(LOGFONT) );
lf.lfPitchAndFamily = FF_SWISS;
lf.lfCharSet = IntlGetLfCharset(defCSID);
if (defCSID == CS_LATIN1)
_tcscpy(lf.lfFaceName, "MS Sans Serif");
else
_tcscpy(lf.lfFaceName, IntlGetUIPropFaceName(defCSID));
lf.lfHeight = -MulDiv( 9, dc.GetDeviceCaps(LOGPIXELSY), 72 );
lf.lfWeight = 0;
m_hFont = theApp.CreateAppFont( lf );
lf.lfHeight = -MulDiv( 10, dc.GetDeviceCaps(LOGPIXELSY), 72 );
lf.lfWeight = 700;
m_hBoldFont = theApp.CreateAppFont( lf );
lf.lfCharSet = IntlGetLfCharset(csid);
if (csid == CS_LATIN1)
_tcscpy(lf.lfFaceName, "MS Sans Serif");
else
_tcscpy(lf.lfFaceName, IntlGetUIPropFaceName(csid));
lf.lfHeight = -MulDiv( 9, dc.GetDeviceCaps(LOGPIXELSY), 72 );
lf.lfWeight = 0;
m_hIntlFont = theApp.CreateAppFont( lf );
lf.lfHeight = -MulDiv( 10, dc.GetDeviceCaps(LOGPIXELSY), 72 );
lf.lfWeight = 700;
m_hBoldIntlFont = theApp.CreateAppFont( lf );
Invalidate();
}
BOOL CMailInfoBar::Create( CWnd *pWnd, MSG_Pane *pPane )
{
m_pPane = pPane;
ASSERT( pWnd && pWnd->IsKindOf( RUNTIME_CLASS(CFrameWnd) ));
DWORD dwStyle = WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|CBRS_TOP;
UINT nID = AFX_IDW_CONTROLBAR_FIRST + 0x7e;
LPCTSTR lpszClass = AfxRegisterWndClass( 0, ::LoadCursor( NULL, IDC_ARROW) );
#ifdef _WIN32
m_dwStyle = dwStyle;
#endif
BOOL res = CControlBar::Create( lpszClass, _T("InfoBar"), dwStyle,
CRect(0,0,0,0), pWnd, nID);
if (res) {
SetCSID( INTL_DefaultWinCharSetID(0) );
#ifndef _WIN32
m_sizeFixedLayout = CalcFixedLayout(TRUE, TRUE);
#endif
}
return res;
}
void CMailInfoBar::OnUpdateCmdUI( CFrameWnd* pTarget, BOOL bDisableIfNoHndler )
{
}
CSize CMailInfoBar::CalcFixedLayout( BOOL bStretch, BOOL bHorz )
{
ASSERT( bHorz ); // No vertical, No way
HDC hDC = ::GetDC( m_hWnd );
HFONT hOldFont = (HFONT) ::SelectObject( hDC, m_hBoldFont);
TEXTMETRIC tm;
GetTextMetrics( hDC, &tm);
::SelectObject( hDC, hOldFont );
::ReleaseDC( m_hWnd, hDC );
int iHeight = (tm.tmHeight > 20 ? tm.tmHeight : 20 ) + 4;
return CSize( 32767, iHeight );
}
BOOL CMailInfoBar::PreTranslateMessage( MSG *pMsg )
{
if (pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
m_wndToolTip.RelayEvent( pMsg );
return CControlBar::PreTranslateMessage( pMsg );
}
void CMailInfoBar::PaintBackground( HDC hDC )
{
RECT rect;
GetClientRect( &rect );
::FillRect( hDC, &rect, sysInfo.m_hbrBtnFace );
}
void CMailInfoBar::DrawInfoText( int iCSID, HDC hDC, LPCSTR lpszText, LPRECT lpRect )
{
WFE_DrawTextEx( iCSID, hDC, (LPSTR) lpszText, -1, lpRect,
DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX,
WFE_DT_CROPRIGHT );
}
void CMailInfoBar::DrawInfoText( HDC hDC, LPCSTR lpszText, LPRECT lpRect )
{
int16 resCsid = INTL_CharSetNameToID(INTL_ResourceCharSet());
DrawInfoText( resCsid, hDC, lpszText, lpRect );
}
void CMailInfoBar::MeasureInfoText( int iCSID, HDC hDC, LPCSTR lpszText, LPRECT lpRect )
{
CIntlWin::DrawText( iCSID, hDC, (LPSTR) lpszText, -1, lpRect, DT_LEFT|DT_SINGLELINE|DT_CALCRECT );
}
void CMailInfoBar::MeasureInfoText( HDC hDC, LPCSTR lpszText, LPRECT lpRect )
{
int16 resCsid = INTL_CharSetNameToID(INTL_ResourceCharSet());
MeasureInfoText( resCsid, hDC, lpszText, lpRect );
}
void CMailInfoBar::DragProxie()
{
}
BEGIN_MESSAGE_MAP( CMailInfoBar, CControlBar )
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SHOWWINDOW()
ON_WM_ERASEBKGND()
ON_WM_SETCURSOR()
END_MESSAGE_MAP()
int CMailInfoBar::OnCreate(LPCREATESTRUCT lpcs)
{
int res = CControlBar::OnCreate(lpcs);
if (res != -1) {
m_wndToolTip.Create(this, TTS_ALWAYSTIP);
m_wndToolTip.Activate(TRUE);
}
return res;
}
void CMailInfoBar::OnLButtonDown( UINT nFlags, CPoint point )
{
RECT rect;
GetClientRect(&rect);
rect.right = 22;
if (PtInRect(&rect, point)) {
DragProxie();
}
else{
// Send this message to the customizable toolbar for dragging
MapWindowPoints(GetParent(), &point, 1);
GetParent()->SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
}
}
void CMailInfoBar::OnLButtonUp( UINT nFlags, CPoint point )
{
RECT rect;
GetClientRect(&rect);
rect.right = 22;
if (!PtInRect(&rect, point)) {
// Send this message to the customizable toolbar for dragging
MapWindowPoints(GetParent(), &point, 1);
GetParent()->SendMessage(WM_LBUTTONUP, nFlags, MAKELPARAM(point.x, point.y));
}
}
void CMailInfoBar::OnMouseMove( UINT nFlags, CPoint point )
{
RECT rect;
GetClientRect(&rect);
rect.right = 22;
if (!PtInRect(&rect, point)) {
// Send this message to the customizable toolbar for dragging
MapWindowPoints(GetParent(), &point, 1);
GetParent()->SendMessage(WM_MOUSEMOVE, nFlags, MAKELPARAM(point.x, point.y));
}
}
void CMailInfoBar::OnShowWindow( BOOL bShow, UINT nStatus )
{
m_bEraseBackground |= bShow;
}
BOOL CMailInfoBar::OnEraseBkgnd( CDC* pDC )
{
if ( m_bEraseBackground ) {
PaintBackground( pDC->m_hDC );
m_bEraseBackground = FALSE;
}
return TRUE;
}
BOOL CMailInfoBar::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
POINT pt;
RECT rect;
GetWindowRect(&rect);
if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
rect.left += 30;
rect.right = rect.left + 22;
GetCursorPos( &pt );
if ( nHitTest == HTCLIENT && ::PtInRect( &rect, pt ) ) {
::SetCursor( ::LoadCursor( AfxGetResourceHandle(), MAKEINTRESOURCE(IDC_HANDOPEN) ) );
return TRUE;
}
return CControlBar::OnSetCursor( pWnd, nHitTest, message );
}
/////////////////////////////////////////////////////////////////////
//
// CContainerInfoBar
//
// Info Bar for the Folder Window
void CContainerInfoBar::Update()
{
LPCSTR szUser = FE_UsersFullName();
if ( szUser ) {
m_csBanner.Format( szLoadString( IDS_MAIL_MYCONTAINERS ), szUser);
} else {
m_csBanner.LoadString(IDS_MAIL_CONTAINERS);
}
}
void CContainerInfoBar::DragProxie()
{
URL_Struct *url = MSG_ConstructUrlForPane( m_pPane );
if ( url ) {
COleDataSource *pDataSource = new COleDataSource;
RDFGLOBAL_DragTitleAndURL( pDataSource, m_csBanner, url->address );
COleDropSource *pDropSource = new CLinkDropSource;
DROPEFFECT res = pDataSource->DoDragDrop( DROPEFFECT_COPY|DROPEFFECT_LINK|
DROPEFFECT_MOVE|DROPEFFECT_SCROLL,
CRect( 0, 0, 0, 0),
pDropSource );
pDataSource->Empty();
delete pDataSource;
delete pDropSource;
NET_FreeURLStruct( url );
}
}
BEGIN_MESSAGE_MAP( CContainerInfoBar, CMailInfoBar )
ON_WM_CREATE()
ON_WM_PAINT()
END_MESSAGE_MAP()
int CContainerInfoBar::OnCreate(LPCREATESTRUCT lpcs)
{
int res = CMailInfoBar::OnCreate(lpcs);
if (res != -1) {
RECT rect;
SetRectEmpty(&rect);
m_wndToolTip.AddTool(this, IDS_PROXIE_FOLDERS, &rect, IDS_PROXIE_FOLDERS);
}
return res;
}
void CContainerInfoBar::OnPaint( )
{
CPaintDC dc(this);
CRect rect;
GetClientRect( &rect );
PaintBackground( dc.m_hDC );
m_pIImage->DrawTransImage( IDX_COLLECTION,
2,
rect.bottom / 2 - 8,
&dc );
RECT rcTool;
::SetRect(&rcTool, 2, rect.bottom / 2 - 8, 18, rect.bottom / 2 + 8);
m_wndToolTip.SetToolRect(this, IDS_PROXIE_FOLDERS, &rcTool);
int oldMode = dc.SetBkMode( TRANSPARENT );
HFONT hOldFont = (HFONT) dc.SelectObject( m_hBoldFont );
int iWidth = rect.right - rect.left;
rect.left += 22;
DrawInfoText( dc.m_hDC, m_csBanner, &rect );
dc.SetBkMode( oldMode );
dc.SelectObject( hOldFont );
}
///////////////////////////////////////////////////////////////////////
//
// CFolderInfoBar
//
// Info Bar for the Thread Window
CFolderInfoBar::CFolderInfoBar()
{
m_folderOld = NULL;
}
CFolderInfoBar::~CFolderInfoBar()
{
}
void CFolderInfoBar::SetCSID( int csid )
{
CMailInfoBar::SetCSID( csid );
m_wndNavButton.SetFont( CFont::FromHandle( m_hFont ), CFont::FromHandle( m_hBoldFont ) );
}
void CFolderInfoBar::Update()
{
if (m_pPane) {
MSG_FolderLine folderLine;
MSG_FolderInfo *folderInfo = NULL;
if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
if (((C3PaneMailFrame*)GetParentFrame())->GetSelectedFolder(&folderLine))
folderInfo = folderLine.id;
}
if (!folderInfo)
folderInfo = MSG_GetCurFolder( m_pPane );
if (folderInfo) {
MSG_GetFolderLineById( WFE_MSGGetMaster(), folderInfo, &folderLine );
if (folderLine.flags & MSG_FOLDER_FLAG_CATEGORY) {
folderInfo = MSG_GetCategoryContainerForCategory(folderInfo);
MSG_GetFolderLineById( WFE_MSGGetMaster(), folderInfo, &folderLine );
}
if ( folderInfo != m_folderOld ) {
m_wndNavButton.Populate( WFE_MSGGetMaster(), NULL );
m_wndNavButton.SetCurSel(0);
for ( int i = 0; i < m_wndNavButton.GetCount(); i++ ) {
if ( (MSG_FolderInfo *) m_wndNavButton.GetItemData(i) == folderInfo ) {
m_wndNavButton.SetCurSel(i);
break;
}
}
}
m_csFolderName = folderLine.prettyName && folderLine.prettyName[0] ?
folderLine.prettyName : folderLine.name;
if (folderLine.flags & MSG_FOLDER_FLAG_CATEGORY) {
if (folderLine.deepUnseen >= 0) {
m_csFolderCounts.Format(szLoadString(IDS_FOLDERCOUNTS),
(int32) folderLine.deepTotal,
(int32) folderLine.deepUnseen);
} else {
m_csFolderCounts.LoadString(IDS_FOLDERUNKNOWNCOUNTS);
}
} else {
if (folderLine.unseen >= 0) {
m_csFolderCounts.Format(szLoadString(IDS_FOLDERCOUNTS),
(int32) folderLine.total,
(int32) folderLine.unseen);
} else {
m_csFolderCounts.LoadString(IDS_FOLDERUNKNOWNCOUNTS);
}
}
m_idxImage = WFE_MSGTranslateFolderIcon( folderLine.level,
folderLine.flags,
FALSE );
m_folderOld = folderInfo;
} else {
m_csFolderName = "";
m_csFolderCounts = "";
}
}
Invalidate();
UpdateWindow();
}
void CFolderInfoBar::DragProxie()
{
URL_Struct *url = MSG_ConstructUrlForPane( m_pPane );
if ( url ) {
COleDataSource *pDataSource = new COleDataSource;
RDFGLOBAL_DragTitleAndURL( pDataSource, m_csFolderName, url->address );
COleDropSource *pDropSource = new CLinkDropSource;
DROPEFFECT res = pDataSource->DoDragDrop( DROPEFFECT_COPY|DROPEFFECT_LINK|
DROPEFFECT_MOVE|DROPEFFECT_SCROLL,
CRect( 0, 0, 0, 0),
pDropSource );
pDataSource->Empty();
delete pDataSource;
delete pDropSource;
NET_FreeURLStruct( url );
}
}
BEGIN_MESSAGE_MAP( CFolderInfoBar, CMailInfoBar )
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
ON_CBN_DROPDOWN(101, OnDropDown)
ON_CBN_SELENDOK(101, OnCloseUp)
ON_BN_CLICKED(102, OnContainer )
ON_COMMAND( ID_BUTTON_CONTAINER, OnContainer )
END_MESSAGE_MAP()
int CFolderInfoBar::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
int res = CMailInfoBar::OnCreate( lpCreateStruct );
if ( res != -1 ) {
DWORD dwStyle = 0;
dwStyle = WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_OWNERDRAWFIXED|CBS_DROPDOWNLIST;
m_wndNavButton.Create( dwStyle, CRect(22,3,250,480), this, 101 );
CString csFull, csLabel, csTip, csStatus;
WFE_ParseButtonString( ID_NAVIGATE_CONTAINER, csStatus, csTip, csLabel );
m_wndBackButton.Create( this, FALSE, CSize(20,20), CSize(20,20),
csLabel, csTip, csStatus,
IDB_BACK, 0, CSize(16,16),
ID_BUTTON_CONTAINER, 0, 0 );
m_wndBackButton.SetActionMessageOwner(this);
RECT rect;
SetRectEmpty(&rect);
m_wndToolTip.AddTool(this, IDS_PROXIE_FOLDERS, &rect, IDS_PROXIE_FOLDERS);
}
return res;
}
void CFolderInfoBar::OnSize( UINT nType, int cx, int cy )
{
if ( nType != SIZE_MINIMIZED ) {
m_wndBackButton.MoveWindow( cx - 22, 3, 22, cy - 6 );
}
}
void CFolderInfoBar::OnDropDown()
{
// Folder Structure might have changed, rebuild.
m_wndNavButton.Populate( WFE_MSGGetMaster(), NULL );
m_wndNavButton.SetCurSel(0);
for ( int i = 0; i < m_wndNavButton.GetCount(); i++ ) {
if ( (MSG_FolderInfo *) m_wndNavButton.GetItemData(i) == m_folderOld ) {
m_wndNavButton.SetCurSel(i);
break;
}
}
}
void CFolderInfoBar::OnCloseUp()
{
int iCurSel = m_wndNavButton.GetCurSel();
m_wndNavButton.m_bFirst = TRUE;
MSG_FolderInfo *folderInfo = (MSG_FolderInfo *) m_wndNavButton.GetItemData(iCurSel);
MSG_FolderLine folderLine;
if ( m_folderOld != folderInfo ) {
CMsgListFrame* pFrame = C3PaneMailFrame::FindFrame( folderInfo );
if ( pFrame ) {
pFrame->ActivateFrame();
} else {
if ( !MSG_GetFolderLineById( WFE_MSGGetMaster(), folderInfo, &folderLine ) ) {
ASSERT(0); // Shouldn't happen
return;
}
// User selected a folder
pFrame = (CMsgListFrame *) GetParentFrame();
ASSERT(pFrame && pFrame->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)));
if (pFrame->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
// bounce focus back to frame
((C3PaneMailFrame*)pFrame)->UpdateFolderPane(folderInfo);
pFrame->SetFocus();
return;
}
else
{
if ( folderLine.level > 1 )
CFolderFrame::Open( folderInfo );
}
}
// Since we didn't change, reselect our folder
m_wndNavButton.SetCurSel(0);
for ( int i = 0; i < m_wndNavButton.GetCount(); i++ ) {
if ( (MSG_FolderInfo *) m_wndNavButton.GetItemData(i) == m_folderOld ) {
m_wndNavButton.SetCurSel(i);
break;
}
}
}
}
void CFolderInfoBar::OnContainer()
{
GetParentFrame()->PostMessage( WM_COMMAND, (WPARAM) ID_NAVIGATE_CONTAINER );
}
void CFolderInfoBar::OnPaint( )
{
CPaintDC dc(this);
CRect rect;
GetClientRect( &rect );
PaintBackground( dc.m_hDC );
m_pIImage->DrawTransImage( m_idxImage,
2,
rect.bottom / 2 - 8,
&dc );
RECT rcTool;
::SetRect(&rcTool, 2, rect.bottom / 2 - 8, 18, rect.bottom / 2 + 8);
m_wndToolTip.SetToolRect(this, IDS_PROXIE_FOLDERS, &rcTool);
int oldMode = dc.SetBkMode( TRANSPARENT );
HFONT hOldFont = (HFONT) dc.SelectObject( m_hBoldFont );
dc.SelectObject( m_hFont );
RECT rcText;
MeasureInfoText( dc.m_hDC, m_csFolderCounts, &rcText);
int iCountsWidth = rcText.right - rcText.left;
rect.left = rect.right - iCountsWidth - 32;
rect.right -= 32;
DrawInfoText( dc.m_hDC, m_csFolderCounts, &rect );
dc.SetBkMode( oldMode );
dc.SelectObject( hOldFont );
m_wndNavButton.UpdateWindow();
}
///////////////////////////////////////////////////////////////////////
//
// CMessageInfoBar
//
// Info Bar for the Message Window
CMessageInfoBar::CMessageInfoBar()
{
m_csFolderTip = "";
m_csFolderStatus = "";
}
CMessageInfoBar::~CMessageInfoBar()
{
}
void CMessageInfoBar::SetCSID( int csid )
{
CMailInfoBar::SetCSID( csid );
Update();
}
void CMessageInfoBar::Update()
{
if (m_pPane) {
MSG_FolderInfo *folderInfo;
MessageKey key;
MSG_ViewIndex index;
MSG_GetCurMessage( m_pPane, &folderInfo, &key, &index);
if (folderInfo) {
MSG_FolderLine folderLine;
MSG_GetFolderLineById( WFE_MSGGetMaster(), folderInfo, &folderLine );
m_idxImage = folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ?
IDX_NEWSARTICLE :
IDX_MAILREAD;
m_csFolderTip = folderLine.name;
m_csFolderStatus.Format(szLoadString(IDS_OPEN_STRING), folderLine.name);
} else {
m_idxImage = 0;
}
if ( key != MSG_MESSAGEKEYNONE ) {
LPTSTR buf;
MSG_MessageLine messageLine;
MSG_GetThreadLineById( m_pPane, key, &messageLine );
buf = IntlDecodeMimePartIIStr( messageLine.subject, INTL_DocToWinCharSetID(m_iCSID), FALSE );
if ( buf ) {
m_csMessageName = buf;
XP_FREE(buf);
} else {
m_csMessageName = messageLine.subject;
}
buf = IntlDecodeMimePartIIStr( messageLine.author, INTL_DocToWinCharSetID(m_iCSID), FALSE );
if ( buf ) {
m_csMessageAuthor = buf;
XP_FREE(buf);
} else {
m_csMessageAuthor = messageLine.author;
}
} else {
m_csMessageName = "";
m_csMessageAuthor = "";
}
}
Invalidate();
}
void CMessageInfoBar::DragProxie()
{
URL_Struct *url = MSG_ConstructUrlForPane( m_pPane );
if ( url ) {
COleDataSource *pDataSource = new COleDataSource;
RDFGLOBAL_DragTitleAndURL( pDataSource, m_csMessageName, url->address );
COleDropSource *pDropSource = new CLinkDropSource;
DROPEFFECT res = pDataSource->DoDragDrop( DROPEFFECT_COPY|DROPEFFECT_LINK|
DROPEFFECT_MOVE|DROPEFFECT_SCROLL,
CRect( 0, 0, 0, 0),
pDropSource );
pDataSource->Empty();
delete pDataSource;
delete pDropSource;
NET_FreeURLStruct( url );
}
}
BEGIN_MESSAGE_MAP( CMessageInfoBar, CMailInfoBar )
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
ON_BN_CLICKED( 102, OnContainer )
ON_COMMAND( ID_BUTTON_CONTAINER, OnContainer )
END_MESSAGE_MAP()
int CMessageInfoBar::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
int res = CMailInfoBar::OnCreate( lpCreateStruct );
if ( res != -1 ) {
CString csFull, csLabel, csTip, csStatus;
WFE_ParseButtonString( ID_NAVIGATE_MSGCONTAINER, csStatus, csTip, csLabel );
m_wndBackButton.Create( this, FALSE, CSize(20,20), CSize(20,20),
csLabel, csTip, csStatus,
IDB_BACK, 0, CSize(16,16),
ID_BUTTON_CONTAINER, 0, TB_DYNAMIC_TOOLTIP );
m_wndBackButton.SetActionMessageOwner(this);
RECT rect;
SetRectEmpty(&rect);
m_wndToolTip.AddTool(this, IDS_PROXIE_FOLDERS, &rect, IDS_PROXIE_FOLDERS);
}
return res;
}
void CMessageInfoBar::OnSize( UINT nType, int cx, int cy )
{
if ( nType != SIZE_MINIMIZED ) {
m_wndBackButton.MoveWindow( cx - 22, 3, 22, cy - 6 );
}
}
void CMessageInfoBar::OnPaint( )
{
CPaintDC dc(this);
CRect rect;
GetClientRect( &rect );
PaintBackground( dc.m_hDC );
m_pIImage->DrawTransImage( m_idxImage,
2,
rect.bottom / 2 - 8,
&dc );
RECT rcTool;
::SetRect(&rcTool, 2, rect.bottom / 2 - 8, 18, rect.bottom / 2 + 8);
m_wndToolTip.SetToolRect(this, IDS_PROXIE_FOLDERS, &rcTool);
int oldMode = dc.SetBkMode( TRANSPARENT );
HFONT hOldFont = (HFONT) dc.SelectObject( m_hBoldIntlFont );
int iWidth = rect.right - rect.left;
rect.left += 22;
rect.right = 22 + iWidth / 2;
DrawInfoText( m_iCSID, dc.m_hDC, m_csMessageName, &rect );
dc.SelectObject( m_hIntlFont );
rect.left = rect.right;
rect.right = iWidth;
DrawInfoText( m_iCSID, dc.m_hDC, m_csMessageAuthor, &rect );
dc.SetBkMode( oldMode );
dc.SelectObject( hOldFont );
}
void CMessageInfoBar::OnContainer()
{
GetParentFrame()->PostMessage( WM_COMMAND, (WPARAM) ID_NAVIGATE_CONTAINER );
}
///////////////////////////////////////////////////////////////////////