gecko-dev/cmd/winfe/nsadrnam.cpp

508 строки
12 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.
*/
// NSAdrNam.cpp : implementation file
//
#include "stdafx.h"
#include "nsadrlst.h"
#include "nsadrnam.h"
#include "addrbook.h"
#include "addrfrm.h" //only need for #ifdef MOZ_NEWADDR
#include "wfemsg.h"
/////////////////////////////////////////////////////////////////////////////
// CNSAddressNameEditField
CNSAddressNameEditField::CNSAddressNameEditField(CNSAddressList *pParentAddressList)
{
m_pIAddressParent = NULL;
m_bNameCompletion = FALSE;
m_bAttemptNameCompletion = TRUE;
#ifdef MOZ_NEWADDR
m_bSetTimerForCompletion = TRUE;
#else
m_bSetTimerForCompletion = FALSE;
#endif
m_uTypedownClock = 0;
m_pParentAddressList = pParentAddressList;
}
CNSAddressNameEditField::~CNSAddressNameEditField()
{
}
BOOL CNSAddressNameEditField::Create( CWnd *pParent, MWContext *pContext )
{
return CGenericEdit::Create(ES_MULTILINE|ES_WANTRETURN|ES_LEFT|ES_AUTOHSCROLL, CRect(0,0,0,0), pParent, (UINT)IDC_STATIC );
}
static BOOL replaceNewLineWithSpace(LPSTR szString, LPSTR szSource)
{
BOOL bRet = FALSE;
int iLength = strlen(szSource);
for(int i = 0, j = 0; i < iLength; i++)
{
if((szSource[i] == '\n') || (szSource[i] == '\r') || (szSource[i] == '\t'))
{
bRet = TRUE;
szString[j] = ' ';
}
else
szString[j] = szSource[i];
if((j >= 0) && (szString[j - 1] == ' ') && (szString[j] == ' '))
continue;
j++;
}
szString[j] = '\0';
return bRet;
}
void CNSAddressNameEditField::Paste()
{
if(!IsClipboardFormatAvailable(CF_TEXT))
{
CGenericEdit::Paste();
return;
}
if(!OpenClipboard())
{
CGenericEdit::Paste();
return;
}
LPSTR psz = (LPSTR)GetClipboardData(CF_TEXT);
if(psz == NULL)
{
CloseClipboard();
CGenericEdit::Paste();
return;
}
// copy clipboard content for modification
HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, strlen(psz) + 1);
LPVOID pData = GlobalLock(hData);
strcpy((LPSTR)pData, psz);
if(!replaceNewLineWithSpace((LPSTR)pData, psz))
{
// no modification made
GlobalUnlock(hData);
GlobalFree(hData);
CloseClipboard();
CGenericEdit::Paste();
return;
}
// backup a copy of clipboard content
HGLOBAL hBackup = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, strlen(psz) + 1);
LPVOID pBackup = GlobalLock(hBackup);
strcpy((LPSTR)pBackup, psz);
GlobalUnlock(hData);
SetClipboardData(CF_TEXT, hData);
LPSTR pszNew = (LPSTR)GetClipboardData(CF_TEXT);
CGenericEdit::Paste();
// restore clipboard content
GlobalUnlock(hBackup);
SetClipboardData(CF_TEXT, hBackup);
GlobalFree(hData);
// we don't free hBackup -- see description of SetClipboardData(...)
CloseClipboard();
}
BEGIN_MESSAGE_MAP(CNSAddressNameEditField, CGenericEdit)
//{{AFX_MSG_MAP(CNSAddressNameEditField)
ON_WM_KILLFOCUS()
ON_WM_TIMER ()
ON_WM_CHAR()
ON_WM_CREATE()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNSAddressNameEditField message handlers
BOOL CNSAddressNameEditField::PreTranslateMessage( MSG* pMsg )
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == 'v' || pMsg->wParam == 'V')
{
if (GetKeyState(VK_CONTROL)&0x8000)
{
Paste();
return TRUE;
}
}
else if (pMsg->wParam == VK_INSERT)
{
if (GetKeyState(VK_SHIFT)&0x8000)
{
Paste();
return TRUE;
}
else if (GetKeyState(VK_CONTROL)&0x8000)
{
Copy();
return TRUE;
}
}
else if (pMsg->wParam == 'x' || pMsg->wParam == 'X')
{
if (GetKeyState(VK_CONTROL)&0x8000)
{
Cut();
return TRUE;
}
}
else if (pMsg->wParam == 'c' || pMsg->wParam == 'C')
{
if (GetKeyState(VK_CONTROL)&0x8000)
{
Copy();
return TRUE;
}
}
#ifdef MOZ_NEWADDR
else if(pMsg->wParam == 'j' || pMsg->wParam == 'J')
{
//check this on 16 bit
if ( ((CNSAddressList *)GetParent())->OnKeyPress( this, pMsg->wParam, pMsg->lParam & 0x1000,
pMsg->lParam & 0x10000000))
{
return TRUE;
}
}
#endif
}
return CGenericEdit::PreTranslateMessage(pMsg);
}
void CNSAddressNameEditField::OnKillFocus(CWnd * pNewWnd)
{
if (GetParent()->SendMessage(WM_NOTIFYSELECTIONCHANGE))
CGenericEdit::OnKillFocus(pNewWnd);
else
SetSel(0, -1);
}
static int howManyAmpersands(char * szString)
{
if(szString == NULL)
return 0;
int iCount = 0;
int iLength = strlen(szString);
for(int i = 0; i < iLength; i++)
{
if(szString[i] == '&')
iCount++;
}
return iCount;
}
static char * makeRightAmpersandString(char * szString, int iNumAmp)
{
if(iNumAmp <= 0)
return NULL;
int iLength = strlen(szString);
int iRightLength = iLength + iNumAmp;
char * szRightString = new char[iRightLength + 1];
if(szRightString == NULL)
return NULL;
for(int i = 0, k = 0; i < iLength; i++, k++)
{
if(szString[i] == '&')
szRightString[k++] = '&';
szRightString[k] = szString[i];
}
szRightString[iRightLength] = '\0';
return szRightString;
}
static void freeRightAmpersandString(char * szString)
{
if(szString != NULL)
delete [] szString;
}
void CNSAddressNameEditField::DrawNameCompletion()
{
if (m_pIAddressParent)
{
CString cs;
GetWindowText(cs);
char *pName = NULL;
char *pMultiple = NULL;
#ifdef MOZ_NEWADDR
AB_NameCompletionCookie *pCookie;
int nNumResults;
m_pParentAddressList->GetNameCompletionCookieInfo(&pCookie, &nNumResults);
if(nNumResults > 1)
{
pMultiple = szLoadString(IDS_MULTIPLE_MATCHES);
}
else if(pCookie && nNumResults == 1)
{
pName = AB_GetNameCompletionDisplayString(pCookie);
}
#else
pName = m_pIAddressParent->NameCompletion((char*)((const char *)cs));
#endif
CDC * pDC = GetDC();
UINT iPre = cs.GetLength();
CFont * pOldFont = pDC->SelectObject(CFont::FromHandle(m_cfTextFont));
int iPixOffset = pDC->GetTextExtent(cs,iPre).cx;
CRect rect;
GetClientRect(rect);
rect.left = iPixOffset;
if (pName)
{
m_bNameCompletion = TRUE;
COLORREF crOld = pDC->SetTextColor(RGB(150,150,150));
COLORREF crOldBk = pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
if (iPre < strlen(pName))
{
int iNumAmp = howManyAmpersands(&pName[iPre]);
if(iNumAmp == 0)
pDC->DrawText(&pName[iPre],strlen(&pName[iPre]),rect,DT_VCENTER|DT_LEFT);
else
{
char * pRightString = makeRightAmpersandString(&pName[iPre], iNumAmp);
if(pRightString != NULL)
{
pDC->DrawText(pRightString,strlen(pRightString),rect,DT_VCENTER|DT_LEFT);
freeRightAmpersandString(pRightString);
}
}
}
pDC->SetTextColor(crOld);
pDC->SetBkColor(crOldBk);
free(pName);
}
else if(pMultiple)
{
m_bNameCompletion = FALSE;
m_bNameCompletion = TRUE;
COLORREF crOld = pDC->SetTextColor(RGB(150,150,150));
COLORREF crOldBk = pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
pDC->DrawText(pMultiple,strlen(pMultiple),rect,DT_VCENTER|DT_LEFT);
pDC->SetTextColor(crOld);
pDC->SetBkColor(crOldBk);
}
else
{
m_bNameCompletion = FALSE;
InvalidateRect(rect);
}
pDC->SelectObject(pOldFont);
ReleaseDC(pDC);
}
}
#define NAME_COMPLETION_TIMER 12
#define COMPLETION_SPEED 750
void CNSAddressNameEditField::OnTimer(UINT nID)
{
if (nID == NAME_COMPLETION_TIMER) {
KillTimer(m_uTypedownClock);
m_uTypedownClock = 0;
#ifdef MOZ_NEWADDR
m_pParentAddressList->StartNameCompletion();
#else
DrawNameCompletion();
#endif
}
}
void CNSAddressNameEditField::StopNameCompletion()
{
if (m_bSetTimerForCompletion)
{
if (m_uTypedownClock) {
KillTimer(m_uTypedownClock);
}
}
}
void CNSAddressNameEditField::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags )
{
switch (nChar)
{
case VK_ESCAPE:
return;
case VK_DELETE:
break;
default:
if ( ((CNSAddressList *)GetParent())->OnKeyPress( this, nChar, nRepCnt, nFlags ) )
return;
}
CGenericEdit::OnChar( nChar, nRepCnt, nFlags );
if (m_bAttemptNameCompletion)
{
if (m_bSetTimerForCompletion)
{
if (m_uTypedownClock) {
KillTimer(m_uTypedownClock);
}
#ifdef MOZ_NEWADDR
//Also need to kill current search because it's no longer valid
m_pParentAddressList->StopNameCompletion();
#endif
m_uTypedownClock = SetTimer(NAME_COMPLETION_TIMER, COMPLETION_SPEED, NULL);
}
else
DrawNameCompletion();
}
}
int CNSAddressNameEditField::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CGenericEdit::OnCreate(lpCreateStruct) == -1)
return -1;
#ifndef MOZ_NEWADDR
uint32 count;
DIR_Server* pab = NULL;
DIR_GetPersonalAddressBook (theApp.m_directories, &pab);
if (pab) {
AB_GetEntryCount(pab, theApp.m_pABook, &count, ABTypeAll, NULL);
if (count > 1500)
m_bSetTimerForCompletion = TRUE;
}
#endif
return 0;
}
void CNSAddressNameEditField::SetCSID(int16 iCSID)
{
if(m_hWnd)
{
CDC * pdc = GetDC();
if (m_cfTextFont) {
theApp.ReleaseAppFont(m_cfTextFont);
}
LOGFONT lf;
memset(&lf,0,sizeof(LOGFONT));
lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH;
strcpy(lf.lfFaceName, IntlGetUIFixFaceName(iCSID));
lf.lfHeight = -MulDiv(NS_ADDRESSFONTSIZE,pdc->GetDeviceCaps(LOGPIXELSY),72);
lf.lfQuality = PROOF_QUALITY;
lf.lfCharSet = IntlGetLfCharset(iCSID);
m_cfTextFont = theApp.CreateAppFont( lf );
if (!(lf.lfPitchAndFamily & FIXED_PITCH))
m_bAttemptNameCompletion = FALSE;
::SendMessage(GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfTextFont, FALSE);
TEXTMETRIC tm;
pdc->GetTextMetrics(&tm);
m_iTextHeight = tm.tmHeight;
ReleaseDC(pdc);
}
}
void CNSAddressNameEditField::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar)
{
case VK_HOME:
{
int nStart, nEnd;
GetSel(nStart,nEnd);
if ((!nStart)&&(!nEnd))
((CNSAddressList *)GetParent())->OnKeyPress(this,nChar,nRepCnt,nFlags);
}
break;
case VK_END:
{
int nStart, nEnd;
GetSel(nStart,nEnd);
if (nStart == nEnd)
if (nStart == LineLength())
((CNSAddressList *)GetParent())->OnKeyPress(this,nChar,nRepCnt,nFlags);
}
break;
case VK_UP:
case VK_DOWN:
((CNSAddressList *)GetParent())->OnKeyPress(this,nChar,nRepCnt,nFlags);
break;
case VK_DELETE:
{
CString cs;
GetWindowText(cs);
if (!cs.GetLength())
{
((CNSAddressList *)GetParent())->OnKeyPress(this,nChar,nRepCnt,nFlags);
return;
}
}
break;
}
CGenericEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CNSAddressNameEditField::OnLButtonDblClk(UINT nFlags, CPoint point)
{
SetSel(0,-1);
}