📄 idemailaddress.pas
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 10153: IdEMailAddress.pas
{
{ Rev 1.0 2002.11.12 10:37:40 PM czhower
}
unit IdEMailAddress;
{
ToDo: look into alterations required for TIdEMailAddressItem.GetText.
}
{
2001-Aug-30 - Jim Gunkel
- Fixed bugs that would occur with group names containing spaces (box test 19)
and content being located after the email address (box test 33)
2001-Jul-11 - Allen O'Neill
- Added hack to not allow recipient entries being added that are blank
2001-Jul-11 - Allen O'Neill
- Added hack to accomodate a PERIOD (#46) in an email address - this whole area needs to be looked at.
2001-Feb-03 - Peter Mee
- Overhauled TIdEMailAddressItem.GetText to support non-standard textual
elements.
2001-Jan-29 - Peter Mee
- Overhauled TIdEMailAddressList.SetEMailAddresses to support comments
and escaped characters and to ignore groups.
2001-Jan-28 - Peter Mee
- Overhauled TIdEMailAddressItem.SetText to support comments and escaped
characters.
2000-Jun-10 - J. Peter Mugaas
- started this unit to facilitate some Indy work including the
TIdEMailAddressItem and TIdEMailAddressList classes
- The GetText and SetText were originally the ToArpa and FromArpa functions in
the TIdMessage component}
interface
uses
Classes,
IdException;
type
EIdEmailParseError = class(EIdException);
TIdEMailAddressItem = class (TCollectionItem)
protected
FAddress : String;
FName : String;
Function GetText : String;
Procedure SetText(AText : String);
function ConvertAddress : String;
public
procedure Assign(Source: TPersistent); override;
published
{This is the E-Mail address itself }
property Address: string read FAddress write FAddress;
{This is the person's name} {Do not Localize}
property Name: string read FName write FName;
{This is the combined person's name and E-Mail address} {Do not Localize}
property Text: String read GetText write SetText;
end;
TIdEMailAddressList = class (TOwnedCollection)
protected
function GetItem ( Index: Integer ) : TIdEMailAddressItem;
procedure SetItem ( Index: Integer; const Value: TIdEMailAddressItem );
function GetEMailAddresses : String;
procedure SetEMailAddresses( AList : String);
public
constructor Create ( AOwner : TPersistent ); reintroduce;
{This returns formatted list of formated
addresses including the names from the collection }
procedure FillTStrings(AStrings : TStrings);
function Add: TIdEMailAddressItem;
property Items [ Index: Integer ] : TIdEMailAddressItem read GetItem write SetItem; default;
{This is a comma separated list of formated
addresses including the names from the collection }
property EMailAddresses : String read GetEMailAddresses
write SetEMailAddresses;
end;
implementation
uses
IdGlobal,
IdResourceStrings,
SysUtils;
const
// This is actually the ATEXT without the '"' and space characters... {Do not Localize}
IETF_ATEXT: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' {Do not Localize}
+ '1234567890!#$%&''*+-/=?_`{}|~'; {Do not Localize}
// ATEXT without the '"' {Do not Localize}
IETF_ATEXT_SPACE: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' {Do not Localize}
+ '1234567890!#$%&''*+-/=?_`{}|~ '; {Do not Localize}
IETF_QUOTABLE: string = '\"'; {Do not Localize}
// Three functions for easier manipulating of strings.
// Don't know of any system functions to perform these actions. {Do not Localize}
// If there aren't & someone can find an optimised way of performing {Do not Localize}
// then please implement...
function FindFirstOf(AFind, AText: string): Integer;
var
nCount, nPos: Integer;
begin
Result := 0;
for nCount := 1 to Length(AFind) do begin
nPos := IndyPos(AFind[nCount], AText);
if nPos > 0 then begin
if Result = 0 then begin
Result := nPos;
end else if Result > nPos then begin
Result := nPos;
end;
end;
end;
end;
function FindFirstNotOf(AFind, AText : String) : Integer;
var
i : Integer;
begin
result := 0;
if length(AFind) = 0 then
begin
result := 1;
exit;
end;
if length(AText) = 0 then
begin
exit;
end;
for i := 1 to length(AText) do
begin
if IndyPos(AText[i], AFind) = 0 then
begin
result := i;
exit;
end;
end;
end;
function TrimAllOf(ATrim, AText : String) : String;
begin
while Length(AText) > 0 do
begin
if Pos(AText[1], ATrim) > 0 then
begin
System.Delete(AText, 1, 1);
end else break;
end;
while Length(AText) > 0 do begin
if Pos(AText[length(AText)], ATrim) > 0 then
begin
System.Delete(AText, Length(AText), 1);
end else break;
end;
result := AText;
end;
{ TIdEMailAddressItem }
procedure TIdEMailAddressItem.Assign(Source: TPersistent);
var Addr : TIdEMailAddressItem;
begin
if ClassType <> Source.ClassType then
begin
inherited
end
else
begin
Addr := TIdEMailAddressItem(Source);
Address := Addr.Address;
Name := Addr.Name;
end;
end;
function TIdEMailAddressItem.ConvertAddress : String;
var
i : Integer;
domainPart, tempAddress, localPart : String;
begin
if length(FAddress) = 0 then
begin
if Length(FName) > 0 then
begin
result := '<>'; {Do not Localize}
end else
begin
result := ''; {Do not Localize}
end;
exit;
end;
// First work backwards to the @ sign.
for i := length(FAddress) downto 1 do
begin
if FAddress[i] = '@' then {Do not Localize}
begin
domainPart := Copy(FAddress, i, length(FAddress));
tempAddress := Copy(FAddress, 1, i - 1);
break;
end;
end;
i := FindFirstNotOf(IETF_ATEXT, tempAddress);
if (i = 0) or (tempAddress[i] = #46) then //hack to accomodate periods in emailaddress
// if i = 0 then
begin
if length(FName) > 0 then
begin
result := '<' + tempAddress + domainPart + '>'; {Do not Localize}
end else
begin
result := tempAddress + domainPart;
end;
end else
begin
localPart := '"'; {Do not Localize}
while i > 0 do
begin
localPart := localPart + Copy(tempAddress, 1, i - 1);
if IndyPos(tempAddress[i], IETF_QUOTABLE) > 0 then
begin
localPart := localPart + '\'; {Do not Localize}
end;
localPart := localPart + tempAddress[i];
tempAddress := Copy(tempAddress, i + 1, length(tempAddress));
i := FindFirstNotOf(IETF_ATEXT, tempAddress);
end;
result := '<' + localPart + tempAddress + '"' + domainPart + '>'; {Do not Localize}
end;
end;
function TIdEMailAddressItem.GetText: String;
var
i : Integer;
tempName, resName : String;
begin
if ( Length ( FName ) > 0 ) and ( UpperCase ( FAddress ) <> FName ) then
begin
i := FindFirstNotOf(IETF_ATEXT_SPACE, FName);
if i > 0 then
begin
// Need to quote the FName.
resName := '"' + Copy(FName, 1, i - 1); {Do not Localize}
if IndyPos(FName[i], IETF_QUOTABLE) > 0 then
begin
resName := resName + '\'; {Do not Localize}
end;
resName := resName + FName[i];
tempName := Copy(FName, i + 1, length(FName));
while length(tempName) <> 0 do
begin
i := FindFirstNotOf(IETF_ATEXT_SPACE, tempName);
if i = 0 then
begin
Result := resName + tempName + '" ' + ConvertAddress; {Do not Localize}
exit;
end;
resName := resName + Copy(tempName, 1, i-1);
if IndyPos(tempName[i], IETF_QUOTABLE) > 0 then
begin
resName := resName + '\'; {Do not Localize}
end;
resName := resName + tempName[i];
tempName := Copy(tempName, i + 1, length(tempName));
end;
Result := resName + '" ' + ConvertAddress; {Do not Localize}
end else
begin
Result := FName + ' ' + ConvertAddress; {Do not Localize}
end;
end // if
else
begin
Result := ConvertAddress;
end; // else .. if
end;
procedure TIdEMailAddressItem.SetText(AText: String);
var
nFirst,
nBracketCount : Integer;
bInAddress,
bAddressInLT,
bAfterAt,
bInQuote : Boolean;
begin
FAddress := ''; {Do not Localize}
FName := ''; {Do not Localize}
AText := Trim(AText);
if Length(AText) = 0 then exit;
// Find the first known character type.
nFirst := FindFirstOf('("< @' + TAB, AText); {Do not Localize}
if nFirst <> 0 then
begin
nBracketCount := 0;
bInAddress := False;
bAddressInLT := False;
bInQuote := False;
bAfterAt := False;
repeat
case AText[nFirst] of
' ', TAB : {Do not Localize}
begin
if nFirst = 1 then
begin
System.Delete(AText, 1, 1);
end else
begin
// Only valid if in a name not contained in quotes - keep the space.
if bAfterAt then begin
FAddress := FAddress + Trim(Copy(AText, 1, nFirst - 1));
end else begin
FName := FName + Copy(AText, 1, nFirst);
end;
AText := Copy(AText, nFirst + 1, Length(AText));
end;
end;
'(' : {Do not Localize}
begin
Inc(nBracketCount);
if (nFirst > 1) then
begin
// There's at least one character to the name {Do not Localize}
if bInAddress then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -