IdMessage.pas 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10251: IdMessage.pas
  11. {
  12. { Rev 1.13 6/9/04 5:38:06 PM RLebeau
  13. { Updated ClearHeader() to clear the MsgId and UID properties.
  14. {
  15. { Updated SetUseNowForDate() to support AValue being set to False
  16. }
  17. {
  18. { Rev 1.12 2/3/04 11:58:26 AM RLebeau
  19. { Updated TIdMessageParts.CountParts() to use the TIdMessagePart.ContentId
  20. { property instead of ExtraHeaders.Values['Content-Id']
  21. }
  22. {
  23. { Rev 1.11 1/15/04 7:39:10 PM RLebeau
  24. { Updated GenerateHeader() to remove support for the BBCList property
  25. }
  26. {
  27. { Rev 1.10 1/7/04 10:51:32 PM RLebeau
  28. { Bug fix for various TIdMessage properties that were not previously using
  29. { setter methods correctly.
  30. }
  31. {
  32. { Rev 1.9 10/17/03 11:49:18 AM RLebeau
  33. { Added ContentID property to TIdMessagePart
  34. {
  35. { Updated TIdText.Assign() and TIdAttachment.Assign() to copy all available
  36. { header values rather than select ones.
  37. }
  38. {
  39. { Rev 1.8 9/28/03 1:29:40 PM RLebeau
  40. { Updated GenerateHeader() and ProcessHeader() to support the BBCList property
  41. }
  42. {
  43. { Rev 1.7 2003.07.03 11:52:08 AM czhower
  44. { DeleteTempFiles addition.
  45. { Fix of old property IsTempFile, changed to DeleteTempFile so as not to change
  46. { broken but old functionality that could otherwise cause data loss.
  47. }
  48. {
  49. { Rev 1.6 02/07/2003 7:07:14 PM ANeillans
  50. { Fix AV in SaveToStream (fix was posted on Indy-Dev-Public)
  51. }
  52. {
  53. Rev 1.5 6/17/2003 2:07:08 AM DSiders
  54. Modified TIdMessage.SaveToStream to call Connect / Disconnect for the message
  55. client. Required due to the new Active property in TIdIOHandler.
  56. }
  57. {
  58. { Rev 1.4 2003.06.15 3:00:32 PM czhower
  59. { -Fixed IdIOHandlerStream to function as originally designed and needed.
  60. { -Change ReadStream, WriteStream to Input/Output to be consistent with other
  61. { areas.
  62. }
  63. {
  64. Rev 1.3 1/27/2003 10:04:52 PM DSiders
  65. Corrected error setting file stream permissions in LoadFromFile. Bug Report
  66. 649502.
  67. }
  68. {
  69. { Rev 1.2 27/1/2003 2:33:16 PM SGrobety
  70. { Only issue X-Priority header if priority is <> mpNormal
  71. }
  72. {
  73. { Rev 1.1 09/12/2002 18:23:14 ANeillans
  74. { Removed X-Library Line
  75. }
  76. {
  77. { Rev 1.0 2002.11.12 10:45:26 PM czhower
  78. }
  79. {//////////////////////////////////////////////////////////////////
  80. 2001-Jul-11 Hadi Hariri
  81. TODO: Make checks for encoding and content-type later on.
  82. TODO: Add TIdHTML, TIdRelated
  83. TODO: CountParts on the fly
  84. TODO: Merge Encoding and AttachmentEncoding
  85. TODO: Make encoding plugable
  86. TODO: Clean up ISO header coding
  87. /////////////////////////////////////////////////////////////////}
  88. unit IdMessage;
  89. {
  90. 2002-12-09 Andrew Neillans
  91. Removed X-Library Line
  92. 2001-12-27 Andrew P.Rybin
  93. Custom InitializeISO, ExtractCharSet
  94. 2001-Oct-29 Don Siders
  95. Added EIdMessageCannotLoad exception.
  96. Added RSIdMessageCannotLoad constant.
  97. Added TIdMessage.LoadFromStream.
  98. Modified TIdMessage.LoadFromFile to call LoadFromStream.
  99. Added TIdMessage.SaveToStream.
  100. Modified TIdMessage.SaveToFile to call SaveToStream.
  101. Modified TIdMessage.GenerateHeader to include headers received but not used in properties.
  102. 2001-Sep-14 Andrew Neillans
  103. Added LoadFromFile Header only
  104. 2001-Sep-12 Johannes Berg
  105. Fixed upper/lowercase in uses clause for Kylix
  106. 2001-Aug-09 Allen O'Neill
  107. Added line to check for valid charset value before adding second ';' after content-type boundry
  108. 2001-Aug-07 Allen O'Neill
  109. Added SaveToFile & LoadFromFile ... Doychin fixed
  110. 2001-Jul-11 Hadi Hariri
  111. Added Encoding for both MIME and UU.
  112. 2000-Jul-25 Hadi Hariri
  113. - Added support for MBCS
  114. 2000-Jun-10 Pete Mee
  115. - Fixed some minor but annoying bugs.
  116. 2000-May-06 Pete Mee
  117. - Added coder support directly into TIdMessage.
  118. }
  119. { TODO : Moved Decode/Encode out and will add later,. Maybe TIdMessageEncode, Decode?? }
  120. { TODO : Support any header in TMessagePart }
  121. { DESIGN NOTE: The TIdMessage has an fBody which should only ever be the
  122. raw message. TIdMessage.fBody is only raw if TIdMessage.fIsEncoded = true
  123. The component parts are thus possibly made up of the following
  124. order of TMessagePart entries:
  125. MP[0] : Possible prologue text (fBoundary is '')
  126. MP[0 or 1 - depending on prologue existence] :
  127. fBoundary = boundary parameter from Content-Type
  128. MP[next...] : various parts with or without fBoundary = ''
  129. MP[MP.Count - 1] : Possible epilogue text (fBoundary is '')
  130. }
  131. { DESIGN NOTE: If TMessagePart.fIsEncoded = True, then TMessagePart.fBody
  132. is the encoded raw message part. Otherwise, it is the (decoded) text.
  133. }
  134. interface
  135. uses
  136. Classes,
  137. IdBaseComponent, IdException, IdEMailAddress, IdHeaderList,
  138. IdCoderHeader, SysUtils;
  139. type
  140. TIdMessagePriority = (mpHighest, mpHigh, mpNormal, mpLow, mpLowest);
  141. const
  142. ID_MSG_NODECODE = False;
  143. ID_MSG_USENOWFORDATE = True;
  144. ID_MSG_PRIORITY = mpNormal;
  145. type
  146. TOnGetMessagePartStream = procedure(AStream: TStream) of object;
  147. TIdMIMEBoundary = class
  148. protected
  149. FBoundaryList: TStrings;
  150. FNewBoundary: Boolean;
  151. function GetBoundary: string;
  152. public
  153. constructor Create;
  154. destructor Destroy; override;
  155. class function FindBoundary(AContentType: string): string;
  156. procedure Push(ABoundary: string);
  157. procedure Pop;
  158. procedure Clear;
  159. property Boundary: string read GetBoundary;
  160. property NewBoundary: Boolean read FNewBoundary write FNewBoundary;
  161. end;
  162. TIdMessageFlags =
  163. ( mfAnswered, //Message has been answered.
  164. mfFlagged, //Message is "flagged" for urgent/special attention.
  165. mfDeleted, //Message is "deleted" for removal by later EXPUNGE.
  166. mfDraft, //Message has not completed composition (marked as a draft).
  167. mfSeen, //Message has been read.
  168. mfRecent ); //Message is "recently" arrived in this mailbox.
  169. TIdMessageFlagsSet = set of TIdMessageFlags;
  170. TIdMessagePart = class(TCollectionItem)
  171. protected
  172. FBoundary: string;
  173. FBoundaryBegin: Boolean;
  174. FBoundaryEnd: Boolean;
  175. FContentMD5: string;
  176. FContentID: string;
  177. FContentTransfer: string;
  178. FContentType: string;
  179. FEndBoundary: string;
  180. FExtraHeaders: TIdHeaderList;
  181. FHeaders: TIdHeaderList;
  182. FIsEncoded: Boolean;
  183. FOnGetMessagePartStream: TOnGetMessagePartStream;
  184. FStoredPathName: TFileName;
  185. //
  186. function GetContentID: string;
  187. function GetContentType: string;
  188. function GetContentTransfer: string;
  189. procedure SetContentID(const AValue: string);
  190. procedure SetContentType(const AValue: string);
  191. procedure SetContentTransfer(const AValue: string);
  192. procedure SetExtraHeaders(const AValue: TIdHeaderList);
  193. procedure SetHeaders(const AValue: TIdHeaderList);
  194. public
  195. constructor Create(Collection: TCollection); override;
  196. destructor Destroy; override;
  197. procedure Assign(Source: TPersistent); override;
  198. //
  199. property Boundary : String read FBoundary write FBoundary;
  200. property BoundaryBegin : Boolean read FBoundaryBegin write FBoundaryBegin;
  201. property BoundaryEnd : Boolean read FBoundaryEnd write FBoundaryEnd;
  202. property IsEncoded : Boolean read fIsEncoded;
  203. property OnGetMessagePartStream: TOnGetMessagePartStream read FOnGetMessagePartStream
  204. write FOnGetMessagePartStream;
  205. property StoredPathName: TFileName read FStoredPathName write FStoredPathName;
  206. property Headers: TIdHeaderList read FHeaders write SetHeaders;
  207. published
  208. property ContentID: string read GetContentID write SetContentID;
  209. property ContentTransfer: string read GetContentTransfer write SetContentTransfer;
  210. property ContentType: string read GetContentType write SetContentType;
  211. property ExtraHeaders: TIdHeaderList read FExtraHeaders write SetExtraHeaders;
  212. end;
  213. TIdMessagePartClass = class of TIdMessagePart;
  214. TIdMessageParts = class;
  215. TIdAttachment = class(TIdMessagePart)
  216. protected
  217. FContentDisposition: string;
  218. FDeleteTempFile: boolean;
  219. FFileName: TFileName;
  220. //
  221. function GetContentDisposition: string;
  222. procedure SetContentDisposition(const AValue: string);
  223. public
  224. procedure Assign(Source: TPersistent); override;
  225. constructor Create(Collection: TIdMessageParts; const AFileName: TFileName = ''); reintroduce;
  226. destructor Destroy; override;
  227. procedure Encode(ADest: TStream);
  228. function SaveToFile(const AFileName: TFileName): Boolean;
  229. //
  230. property ContentDisposition: string read GetContentDisposition write SetContentDisposition;
  231. property DeleteTempFile: Boolean read FDeleteTempFile write FDeleteTempFile;
  232. property FileName: TFileName read FFileName write FFileName;
  233. end;
  234. TIdText = class(TIdMessagePart)
  235. protected
  236. FBody: TStrings;
  237. //
  238. procedure SetBody(const AStrs : TStrings);
  239. public
  240. constructor Create(Collection: TIdMessageParts; ABody: TStrings = nil); reintroduce;
  241. destructor Destroy; override;
  242. procedure Assign(Source: TPersistent); override;
  243. //
  244. property Body: TStrings read FBody write SetBody;
  245. end;
  246. TIdMessageParts = class(TOwnedCollection)
  247. protected
  248. FAttachmentEncoding: string;
  249. FAttachmentCount: integer;
  250. FMessageEncoderInfo: TObject;
  251. FRelatedPartCount: integer;
  252. FTextPartCount: integer;
  253. //
  254. function GetItem(Index: Integer): TIdMessagePart;
  255. procedure SetAttachmentEncoding(const AValue: string);
  256. procedure SetItem(Index: Integer; const AValue: TIdMessagePart);
  257. public
  258. function Add: TIdMessagePart;
  259. procedure CountParts;
  260. constructor Create(AOwner: TPersistent); reintroduce;
  261. //
  262. property AttachmentCount: integer read FAttachmentCount;
  263. property AttachmentEncoding: string read FAttachmentEncoding write SetAttachmentEncoding;
  264. property Items[Index: Integer]: TIdMessagePart read GetItem write SetItem; default;
  265. property MessageEncoderInfo: TObject read FMessageEncoderInfo;
  266. property RelatedPartCount: integer read FRelatedPartCount;
  267. property TextPartCount: integer read FTextPartCount;
  268. end;
  269. TIdMessageEncoding = (meMIME, meUU);
  270. TIdInitializeIsoEvent = procedure (var VTransferHeader: TTransfer; var VHeaderEncoding: Char;
  271. var VCharSet: string) of object;
  272. TIdMessage = class(TIdBaseComponent)
  273. protected
  274. FBccList: TIdEmailAddressList;
  275. FBody: TStrings;
  276. FCharSet: string;
  277. FCcList: TIdEmailAddressList;
  278. FContentType: string;
  279. FContentTransferEncoding: string;
  280. FContentDisposition: string;
  281. FDate: TDateTime;
  282. FDeleteTempFiles: Boolean;
  283. FIsEncoded : Boolean;
  284. FExtraHeaders: TIdHeaderList;
  285. FEncoding: TIdMessageEncoding;
  286. FFlags: TIdMessageFlagsSet;
  287. FFrom: TIdEmailAddressItem;
  288. FHeaders: TIdHeaderList;
  289. FMessageParts: TIdMessageParts;
  290. FMIMEBoundary: TIdMIMEBoundary;
  291. FMsgId: string;
  292. FNewsGroups: TStrings;
  293. FNoEncode: Boolean;
  294. FNoDecode: Boolean;
  295. FOnInitializeISO: TIdInitializeISOEvent;
  296. FOrganization: string;
  297. FPriority: TIdMessagePriority;
  298. FSubject: string;
  299. FReceiptRecipient: TIdEmailAddressItem;
  300. FRecipients: TIdEmailAddressList;
  301. FReferences: string;
  302. FReplyTo: TIdEmailAddressList;
  303. FSender: TIdEMailAddressItem;
  304. FUID: String;
  305. FXProgram: string;
  306. //
  307. procedure DoInitializeISO(var VTransferHeader: TTransfer; var VHeaderEncoding: Char; var VCharSet: string); virtual;
  308. function GetAttachmentEncoding: string;
  309. procedure SetAttachmentEncoding(const AValue: string);
  310. procedure SetBccList(const AValue: TIdEmailAddressList);
  311. procedure SetBody(const AValue: TStrings);
  312. procedure SetCCList(const AValue: TIdEmailAddressList);
  313. procedure SetEncoding(const AValue: TIdMessageEncoding);
  314. procedure SetExtraHeaders(const AValue: TIdHeaderList);
  315. procedure SetFrom(const AValue: TIdEmailAddressItem);
  316. procedure SetHeaders(const AValue: TIdHeaderList);
  317. procedure SetNewsGroups(const AValue: TStrings);
  318. procedure SetReceiptRecipient(const AValue: TIdEmailAddressItem);
  319. procedure SetRecipients(const AValue: TIdEmailAddressList);
  320. procedure SetReplyTo(const AValue: TIdEmailAddressList);
  321. procedure SetSender(const AValue: TIdEmailAddressItem);
  322. procedure SetUseNowForDate(const AValue: Boolean);
  323. public
  324. constructor Create(AOwner: TComponent); override;
  325. destructor Destroy; override;
  326. procedure AddHeader(const AValue: string);
  327. procedure Clear; virtual;
  328. procedure ClearBody;
  329. procedure ClearHeader;
  330. function GenerateHeader: TIdHeaderList;
  331. function GetUseNowForDate: Boolean;
  332. // 2001-Oct-29 Don Siders
  333. procedure LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean = False);
  334. procedure LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean = False);
  335. procedure ProcessHeaders;
  336. // 2001-Oct-29 Don Siders
  337. procedure SaveToFile(const AFileName : string; const AHeadersOnly: Boolean = False);
  338. procedure SaveToStream(AStream: TStream; const AHeadersOnly: Boolean = False);
  339. //
  340. property Flags: TIdMessageFlagsSet read FFlags write FFlags;
  341. property IsEncoded : Boolean read fIsEncoded write fIsEncoded;
  342. property MsgId: string read FMsgId write FMsgId;
  343. property Headers: TIdHeaderList read FHeaders write SetHeaders;
  344. property MessageParts: TIdMessageParts read FMessageParts;
  345. property MIMEBoundary: TIdMIMEBoundary read FMIMEBoundary write FMIMEBoundary;
  346. property UID: String read FUID write FUID;
  347. published
  348. //TODO: Make a property editor which drops down the registered coder types
  349. property AttachmentEncoding: string read GetAttachmentEncoding write SetAttachmentEncoding;
  350. property Body: TStrings read FBody write SetBody;
  351. property BccList: TIdEmailAddressList read FBccList write SetBccList;
  352. property CharSet: string read FCharSet write FCharSet;
  353. property CCList: TIdEmailAddressList read FCcList write SetCcList;
  354. property ContentType: string read FContentType write FContentType;
  355. property ContentTransferEncoding: string read FContentTransferEncoding
  356. write FContentTransferEncoding;
  357. property ContentDisposition: string read FContentDisposition write FContentDisposition;
  358. property Date: TDateTime read FDate write FDate;
  359. property DeleteTempFiles: Boolean read FDeleteTempFiles
  360. write FDeleteTempFiles;
  361. property Encoding: TIdMessageEncoding read FEncoding write SetEncoding;
  362. property ExtraHeaders: TIdHeaderList read FExtraHeaders write SetExtraHeaders;
  363. property From: TIdEmailAddressItem read FFrom write SetFrom;
  364. property NewsGroups: TStrings read FNewsGroups write SetNewsGroups;
  365. property NoEncode: Boolean read FNoEncode write FNoEncode default ID_MSG_NODECODE;
  366. property NoDecode: Boolean read FNoDecode write FNoDecode default ID_MSG_NODECODE;
  367. property Organization: string read FOrganization write FOrganization;
  368. property Priority: TIdMessagePriority read FPriority write FPriority default ID_MSG_PRIORITY;
  369. property ReceiptRecipient: TIdEmailAddressItem read FReceiptRecipient write SetReceiptRecipient;
  370. property Recipients: TIdEmailAddressList read FRecipients write SetRecipients;
  371. property References: string read FReferences write FReferences;
  372. property ReplyTo: TIdEmailAddressList read FReplyTo write SetReplyTo;
  373. property Subject: string read FSubject write FSubject;
  374. property Sender: TIdEmailAddressItem read FSender write SetSender;
  375. property UseNowForDate: Boolean read GetUseNowForDate write SetUseNowForDate default ID_MSG_USENOWFORDATE;
  376. // Events
  377. property OnInitializeISO: TIdInitializeIsoEvent read FOnInitializeISO write FOnInitializeISO;
  378. End;
  379. TIdMessageEvent = procedure(ASender : TComponent; var AMsg : TIdMessage) of object;
  380. TIdStringMessageEvent = procedure(ASender : TComponent; const AString : String; var AMsg : TIdMessage) of object;
  381. EIdMessageException = class(EIdException);
  382. EIdCanNotCreateMessagePart = class(EIdMessageException);
  383. EIdTextInvalidCount = class(EIdMessageException);
  384. // 2001-Oct-29 Don Siders
  385. EIdMessageCannotLoad = class(EIdMessageException);
  386. const
  387. // 2001-Oct-29 Don Siders
  388. // TODO: Move to IdResourceStrings.pas
  389. RSIdMessageCannotLoad = 'Cannot load message from file %s'; {Do not Localize}
  390. const
  391. MessageFlags : array [mfAnswered..mfRecent] of String =
  392. ( '\Answered', {Do not Localize} //Message has been answered.
  393. '\Flagged', {Do not Localize} //Message is "flagged" for urgent/special attention.
  394. '\Deleted', {Do not Localize} //Message is "deleted" for removal by later EXPUNGE.
  395. '\Draft', {Do not Localize} //Message has not completed composition (marked as a draft).
  396. '\Seen', {Do not Localize} //Message has been read.
  397. '\Recent' ); {Do not Localize} //Message is "recently" arrived in this mailbox.
  398. implementation
  399. uses
  400. IdMessageCoderMIME, // Here so the 'MIME' in create will always suceed
  401. IdGlobal, IdMessageCoder, IdResourceStrings, IdStream,
  402. IdMessageClient, IdIOHandlerStream, IdStrings;
  403. { TIdMIMEBoundary }
  404. procedure TIdMIMEBoundary.Clear;
  405. begin
  406. FBoundaryList.Clear;
  407. end;
  408. constructor TIdMIMEBoundary.Create;
  409. begin
  410. FBoundaryList := TStringList.Create;
  411. end;
  412. destructor TIdMIMEBoundary.Destroy;
  413. begin
  414. FBoundaryList.Free;
  415. inherited Destroy;
  416. end;
  417. class function TIdMIMEBoundary.FindBoundary(AContentType: string): string;
  418. var
  419. s: string;
  420. begin
  421. // Store in s and not Result because of Fetch semantics
  422. s := UpperCase(AContentType);
  423. Fetch(s, 'BOUNDARY='); {do not localize}
  424. if (Length(s) > 0) and (s[1] = '"') then begin {do not localize}
  425. Delete(s, 1, 1);
  426. Result := Fetch(s, '"'); {do not localize}
  427. // Should never occur, and if so bigger problems but just in case we'll try
  428. end else begin
  429. Result := s;
  430. end;
  431. end;
  432. function TIdMIMEBoundary.GetBoundary: string;
  433. begin
  434. if FBoundaryList.Count > 0 then begin
  435. Result := FBoundaryList.Strings[0];
  436. end else begin
  437. Result := '';
  438. end;
  439. end;
  440. procedure TIdMIMEBoundary.Pop;
  441. begin
  442. FBoundaryList.Delete(0);
  443. end;
  444. procedure TIdMIMEBoundary.Push(ABoundary: string);
  445. begin
  446. if (FBoundaryList.Count > 0) and (AnsiSameText(ABoundary, FBoundaryList.Strings[0])) then begin
  447. FNewBoundary := True;
  448. end else begin
  449. if Length(ABoundary) > 0 then begin
  450. FBoundaryList.Insert(0, ABoundary);
  451. FNewBoundary := False;
  452. end;
  453. end;
  454. end;
  455. { TIdMessagePart }
  456. procedure TIdMessagePart.Assign(Source: TPersistent);
  457. var
  458. mp: TIdMessagePart;
  459. begin
  460. if ClassType <> Source.ClassType then begin
  461. inherited;
  462. end else begin
  463. mp := TIdMessagePart(Source);
  464. {
  465. ContentTransfer := mp.ContentTransfer;
  466. ContentType := mp.ContentType;
  467. }
  468. Headers.Assign(mp.Headers);
  469. ExtraHeaders.Assign(mp.ExtraHeaders);
  470. end;
  471. end;
  472. constructor TIdMessagePart.Create(Collection: TCollection);
  473. begin
  474. if ClassType = TIdMessagePart then begin
  475. raise EIdCanNotCreateMessagePart.Create(RSTIdMessagePartCreate);
  476. end;
  477. inherited;
  478. FIsEncoded := False;
  479. FHeaders := TIdHeaderList.Create;
  480. FExtraHeaders := TIdHeaderList.Create;
  481. end;
  482. destructor TIdMessagePart.Destroy;
  483. begin
  484. FHeaders.Free;
  485. FExtraHeaders.Free;
  486. inherited;
  487. end;
  488. function TIdMessagePart.GetContentID: string;
  489. begin
  490. Result := Headers.Values['Content-ID']; {do not localize}
  491. end;
  492. function TIdMessagePart.GetContentTransfer: string;
  493. begin
  494. Result := Headers.Values['Content-Transfer-Encoding']; {do not localize}
  495. end;
  496. function TIdMessagePart.GetContentType: string;
  497. begin
  498. Result := Headers.Values['Content-Type']; {do not localize}
  499. end;
  500. procedure TIdMessagePart.SetContentID(const AValue: string);
  501. begin
  502. Headers.Values['Content-ID'] := AValue; {do not localize}
  503. end;
  504. procedure TIdMessagePart.SetContentTransfer(const AValue: string);
  505. begin
  506. Headers.Values['Content-Transfer-Encoding'] := AValue; {do not localize}
  507. end;
  508. procedure TIdMessagePart.SetContentType(const AValue: string);
  509. begin
  510. Headers.Values['Content-Type'] := AValue; {do not localize}
  511. end;
  512. procedure TIdMessagePart.SetExtraHeaders(const AValue: TIdHeaderList);
  513. begin
  514. FExtraHeaders.Assign(AValue);
  515. end;
  516. procedure TIdMessagePart.SetHeaders(const AValue: TIdHeaderList);
  517. begin
  518. FHeaders.Assign(AValue)
  519. end;
  520. { TIdAttachment }
  521. procedure TIdAttachment.Assign(Source: TPersistent);
  522. var
  523. mp: TIdAttachment;
  524. begin
  525. if ClassType <> Source.ClassType then begin
  526. inherited;
  527. end else begin
  528. mp := TIdAttachment(Source);
  529. {
  530. ContentTransfer := mp.ContentTransfer;
  531. ContentType := mp.ContentType;
  532. ContentDisposition := mp.ContentDisposition;
  533. }
  534. Headers.Assign(mp.Headers);
  535. ExtraHeaders.Assign(mp.ExtraHeaders);
  536. FileName := mp.FileName;
  537. end;
  538. end;
  539. constructor TIdAttachment.Create(Collection: TIdMessageParts; const AFileName: TFileName = '');
  540. begin
  541. inherited Create(Collection);
  542. FStoredPathname := AFileName;
  543. FFilename := ExtractFilename(AFilename);
  544. end;
  545. destructor TIdAttachment.Destroy;
  546. begin
  547. if DeleteTempFile then begin
  548. DeleteFile(StoredPathname);
  549. end;
  550. inherited;
  551. end;
  552. procedure TIdAttachment.Encode(ADest: TStream);
  553. begin
  554. with TIdMessageEncoderInfo(TIdMessageParts(Collection).MessageEncoderInfo).MessageEncoderClass
  555. .Create(nil) do try
  556. Filename := Self.Filename;
  557. Encode(Self.StoredPathname, ADest);
  558. finally Free; end;
  559. end;
  560. function TIdAttachment.GetContentDisposition: string;
  561. begin
  562. Result := Headers.Values['Content-Disposition']; {do not localize}
  563. end;
  564. function TIdAttachment.SaveToFile(const AFileName: TFileName): Boolean;
  565. begin
  566. Result := CopyFileTo(StoredPathname, AFileName);
  567. if not Result then begin
  568. raise EIdException.Create(RSTIdMessageErrorSavingAttachment);
  569. end;
  570. // Only if successful
  571. DeleteTempFile := True;
  572. end;
  573. procedure TIdAttachment.SetContentDisposition(const AValue: string);
  574. begin
  575. Headers.Values['Content-Disposition'] := AValue; {do not localize}
  576. end;
  577. { TIdText }
  578. procedure TIdText.Assign(Source: TPersistent);
  579. var mp : TIdText;
  580. begin
  581. if ClassType <> Source.ClassType then
  582. begin
  583. inherited;
  584. end
  585. else
  586. begin
  587. mp := TIdText(Source);
  588. {
  589. ContentTransfer := mp.ContentTransfer;
  590. ContentType := mp.ContentType;
  591. }
  592. Headers.Assign(mp.Headers);
  593. ExtraHeaders.Assign(mp.ExtraHeaders);
  594. Body.Assign(mp.Body);
  595. end;
  596. end;
  597. constructor TIdText.Create(Collection: TIdMessageParts; ABody: TStrings = nil);
  598. begin
  599. inherited Create(Collection);
  600. FBody := TStringList.Create;
  601. if ABody <> nil then begin
  602. FBody.Assign(ABody);
  603. end;
  604. end;
  605. destructor TIdText.Destroy;
  606. begin
  607. FBody.Free;
  608. inherited;
  609. end;
  610. procedure TIdText.SetBody(const AStrs: TStrings);
  611. begin
  612. FBody.Assign(AStrs);
  613. end;
  614. { TMessageParts }
  615. function TIdMessageParts.Add: TIdMessagePart;
  616. begin
  617. // This helps prevent TIdMessagePart from being added
  618. Result := nil;
  619. end;
  620. procedure TIdMessageParts.CountParts;
  621. //TODO: Make AttCount, etc maintained on the fly
  622. var
  623. i: integer;
  624. begin
  625. FAttachmentCount := 0;
  626. FRelatedPartCount := 0;
  627. FTextPartCount := 0;
  628. for i := 0 to Count - 1 do begin
  629. if Items[i] is TIdText then begin
  630. Inc(FTextPartCount)
  631. end else if Items[i] is TIdAttachment then begin
  632. if Length(Items[i].ContentId) > 0 then begin
  633. Inc(FRelatedPartCount);
  634. end;
  635. Inc(FAttachmentCount);
  636. end;
  637. end;
  638. // if TextPartCount = 1 then begin
  639. // raise EIdTextInvalidCount.Create(RSTIdTextInvalidCount);
  640. // end;
  641. end;
  642. constructor TIdMessageParts.Create(AOwner: TPersistent);
  643. begin
  644. inherited Create(AOwner, TIdMessagePart);
  645. // Must set prop and not variable so it will initialize it
  646. AttachmentEncoding := 'MIME';
  647. end;
  648. function TIdMessageParts.GetItem(Index: Integer): TIdMessagePart;
  649. begin
  650. Result := TIdMessagePart(inherited GetItem(Index));
  651. end;
  652. procedure TIdMessageParts.SetAttachmentEncoding(const AValue: string);
  653. begin
  654. FMessageEncoderInfo := TIdMessageEncoderList.ByName(AValue);
  655. FAttachmentEncoding := AValue;
  656. end;
  657. procedure TIdMessageParts.SetItem(Index: Integer; const AValue: TIdMessagePart);
  658. begin
  659. inherited SetItem(Index, AValue);
  660. end;
  661. { TIdMessage }
  662. procedure TIdMessage.AddHeader(const AValue: string);
  663. begin
  664. FHeaders.Add(AValue);
  665. end;
  666. procedure TIdMessage.Clear;
  667. begin
  668. ClearHeader;
  669. ClearBody;
  670. end;
  671. procedure TIdMessage.ClearBody;
  672. begin
  673. MessageParts.Clear;
  674. Body.Clear;
  675. end;
  676. procedure TIdMessage.ClearHeader;
  677. begin
  678. CcList.Clear;
  679. BccList.Clear;
  680. Date := 0;
  681. From.Text := '';
  682. NewsGroups.Clear;
  683. Organization := '';
  684. References := '';
  685. ReplyTo.Clear;
  686. Subject := '';
  687. Recipients.Clear;
  688. Priority := ID_MSG_PRIORITY;
  689. ReceiptRecipient.Text := '';
  690. ContentType := '';
  691. CharSet := '';
  692. ContentTransferEncoding := '';
  693. ContentDisposition := '';
  694. FSender.Text := '';
  695. Headers.Clear;
  696. ExtraHeaders.Clear;
  697. FMIMEBoundary.Clear;
  698. //UseNowForDate := ID_MSG_USENOWFORDATE;
  699. Flags := [];
  700. MsgId := '';
  701. UID := '';
  702. end;
  703. constructor TIdMessage.Create(AOwner: TComponent);
  704. begin
  705. inherited;
  706. FBody := TStringList.Create;
  707. FRecipients := TIdEmailAddressList.Create(Self);
  708. FBccList := TIdEmailAddressList.Create(Self);
  709. FCcList := TIdEmailAddressList.Create(Self);
  710. FMessageParts := TIdMessageParts.Create(Self);
  711. FNewsGroups := TStringList.Create;
  712. FHeaders := TIdHeaderList.Create;
  713. FFrom := TIdEmailAddressItem.Create(nil);
  714. FReplyTo := TIdEmailAddressList.Create(Self);
  715. FSender := TIdEmailAddressItem.Create(nil);
  716. FExtraHeaders := TIdHeaderList.Create;
  717. FReceiptRecipient := TIdEmailAddressItem.Create(nil);
  718. NoDecode := ID_MSG_NODECODE;
  719. FMIMEBoundary := TIdMIMEBoundary.Create;
  720. Clear;
  721. FEncoding := meMIME;
  722. end;
  723. destructor TIdMessage.Destroy;
  724. begin
  725. FBody.Free;
  726. FRecipients.Free;
  727. FBccList.Free;
  728. FCcList.Free;
  729. FMessageParts.Free;
  730. FNewsGroups.Free;
  731. FHeaders.Free;
  732. FExtraHeaders.Free;
  733. FFrom.Free;
  734. FReplyTo.Free;
  735. FSender.Free;
  736. FReceiptRecipient.Free;
  737. FMIMEBoundary.Free;
  738. inherited destroy;
  739. end;
  740. function TIdMessage.GenerateHeader: TIdHeaderList;
  741. var
  742. ISOCharset: string;
  743. HeaderEncoding: Char;
  744. TransferHeader: TTransfer;
  745. begin
  746. // TODO: Clean up
  747. MessageParts.CountParts;
  748. if Encoding = meMIME then begin
  749. TIdMessageEncoderInfo(MessageParts.MessageEncoderInfo).InitializeHeaders(Self);
  750. if Length(CharSet) > 0 then begin
  751. if Length(ContentType) = 0 then begin
  752. ContentType := 'charset="' + CharSet + '"';
  753. end else begin
  754. ContentType := ContentType + ';' + EOL + TAB + 'charset="' + CharSet + '"';
  755. end;
  756. end;
  757. end else begin
  758. // Check message parts
  759. with MessageParts do begin
  760. if (FRelatedPartCount > 0) or (FTextPartCount > 0) then begin
  761. raise EIdMessageException.Create(RSMsgClientInvalidEncoding);
  762. end;
  763. end;
  764. end;
  765. InitializeISO(TransferHeader, HeaderEncoding, ISOCharSet);
  766. DoInitializeISO(TransferHeader, HeaderEncoding, ISOCharSet);//APR
  767. Result := TIdHeaderList.Create;
  768. // added 2001-Oct-29 Don Siders insures use of headers received but not used in properties
  769. if (FHeaders.Count > 0) then begin
  770. Result.Assign(FHeaders);
  771. end;
  772. try
  773. with Result do
  774. begin
  775. Values['From'] := EncodeAddressItem(From, HeaderEncoding, TransferHeader, ISOCharSet); {do not localize}
  776. Values['Subject'] := EncodeHeader(Subject, [], HeaderEncoding, TransferHeader, ISOCharSet); {do not localize}
  777. Values['To'] := EncodeAddress(Recipients, HeaderEncoding, TransferHeader, ISOCharSet); {do not localize}
  778. Values['Cc'] := EncodeAddress(CCList, HeaderEncoding, TransferHeader, ISOCharSet); {do not localize}
  779. {RL: do not include BCCList here}
  780. Values['Newsgroups'] := NewsGroups.CommaText; {do not localize}
  781. if Encoding = meMIME then
  782. begin
  783. Values['Content-Type'] := ContentType; {do not localize}
  784. if MessageParts.Count > 0 then begin
  785. Values['MIME-Version'] := '1.0'; {do not localize}
  786. end;
  787. Values['Content-Transfer-Encoding'] := ContentTransferEncoding; {do not localize}
  788. end;
  789. Values['Sender'] := Sender.Text; {do not localize}
  790. Values['Reply-To'] := EncodeAddress(ReplyTo, HeaderEncoding, TransferHeader, ISOCharSet); {do not localize}
  791. Values['Organization'] := EncodeHeader(Organization, [], HeaderEncoding, TransferHeader, ISOCharSet); {do not localize}
  792. Values['Disposition-Notification-To'] := EncodeAddressItem(ReceiptRecipient, {do not localize}
  793. HeaderEncoding, TransferHeader, ISOCharSet);
  794. Values['References'] := References; {do not localize}
  795. if UseNowForDate then
  796. begin
  797. Values['Date'] := DateTimeToInternetStr(Now); {do not localize}
  798. end
  799. else begin
  800. Values['Date'] := DateTimeToInternetStr(Self.Date); {do not localize}
  801. end;
  802. // S.G. 27/1/2003: Only fill the priority header if it's different from normal
  803. if Priority <> mpNormal then
  804. Values['X-Priority'] := IntToStr(Ord(Priority) + 1); {do not localize}
  805. // Add extra headers created by UA - allows duplicates
  806. if (FExtraHeaders.Count > 0) then
  807. begin
  808. AddStrings(FExtraHeaders);
  809. end;
  810. end;
  811. except
  812. FreeAndNil(Result);
  813. raise;
  814. end;
  815. end;
  816. procedure TIdMessage.ProcessHeaders;
  817. var
  818. ABoundary: string;
  819. // Some mailers send priority as text, number or combination of both
  820. function GetMsgPriority(Priority:string): TIdMessagePriority;
  821. var
  822. s: string;
  823. Num: integer;
  824. begin
  825. // This is for Pegasus.
  826. if IndyPos('urgent', LowerCase(Priority)) <> 0 then begin {do not localize}
  827. Result := mpHigh;
  828. end else if IndyPos('non-priority', LowerCase(Priority)) <> 0 then begin {do not localize}
  829. Result := mpLow;
  830. end else begin
  831. s := Trim(Priority);
  832. s := Trim(Fetch(s, ' '));
  833. Num := StrToIntDef(s, 3);
  834. Result := TIdMessagePriority(Num - 1);
  835. end;
  836. end;
  837. procedure ExtractCharSet;
  838. var
  839. s: string;
  840. begin
  841. s := UpperCase(ContentType);
  842. Fetch(s, 'CHARSET='); {do not localize}
  843. if Copy(s, 1, 1) = '"' then begin {do not localize}
  844. Delete(s, 1, 1);
  845. FCharset := Fetch(s, '"'); {do not localize}
  846. // Sometimes its not in quotes
  847. end else begin
  848. FCharset := Fetch(s, ';');
  849. end;
  850. end;
  851. begin
  852. ContentType := Headers.Values['Content-Type']; {do not localize}
  853. ExtractCharSet;
  854. ContentTransferEncoding := Headers.Values['Content-Transfer-Encoding']; {do not localize}
  855. ContentDisposition := Headers.Values['Content-Disposition'];
  856. Subject := DecodeHeader(Headers.Values['Subject']); {do not localize}
  857. From.Text := DecodeHeader(Headers.Values['From']); {do not localize}
  858. MsgId := Headers.Values['Message-Id']; {do not localize}
  859. CommaSeparatedToStringList(Newsgroups, Headers.Values['Newsgroups']); {do not localize}
  860. Recipients.EMailAddresses := DecodeHeader(Headers.Values['To']); {do not localize}
  861. CCList.EMailAddresses := DecodeHeader(Headers.Values['Cc']); {do not localize}
  862. {RL: Added support for BCCList...}
  863. BCCList.EMailAddresses := DecodeHeader(Headers.Values['Bcc']); {do not localize}
  864. Organization := Headers.Values['Organization']; {do not localize}
  865. ReceiptRecipient.Text := Headers.Values['Disposition-Notification-To']; {do not localize}
  866. if Length(ReceiptRecipient.Text) = 0 then begin
  867. ReceiptRecipient.Text := Headers.Values['Return-Receipt-To']; {do not localize}
  868. end;
  869. References := Headers.Values['References']; {do not localize}
  870. ReplyTo.EmailAddresses := Headers.Values['Reply-To']; {do not localize}
  871. Date := GMTToLocalDateTime(Headers.Values['Date']); {do not localize}
  872. Sender.Text := Headers.Values['Sender']; {do not localize}
  873. if Length(Headers.Values['Priority']) = 0 then begin {do not localize}
  874. Priority := GetMsgPriority(Headers.Values['X-Priority']) {do not localize}
  875. end else begin
  876. Priority := GetMsgPriority(Headers.Values['Priority']); {do not localize}
  877. end;
  878. ABoundary := MIMEBoundary.FindBoundary(ContentType);
  879. MIMEBoundary.Push(ABoundary);
  880. end;
  881. function TIdMessage.GetUseNowForDate: Boolean;
  882. begin
  883. Result := (FDate = 0);
  884. end;
  885. procedure TIdMessage.SetUseNowForDate(const AValue: Boolean);
  886. begin
  887. if GetUseNowForDate <> AValue then begin
  888. if AValue then begin
  889. FDate := 0;
  890. end else begin
  891. FDate := Now;
  892. end;
  893. end;
  894. end;
  895. procedure TIdMessage.SetAttachmentEncoding(const AValue: string);
  896. begin
  897. MessageParts.AttachmentEncoding := AValue;
  898. end;
  899. function TIdMessage.GetAttachmentEncoding: string;
  900. begin
  901. Result := MessageParts.AttachmentEncoding;
  902. end;
  903. procedure TIdMessage.SetEncoding(const AValue: TIdMessageEncoding);
  904. begin
  905. FEncoding := AValue;
  906. if AValue = meMIME then begin
  907. AttachmentEncoding := 'MIME';
  908. end else begin
  909. AttachmentEncoding := 'UUE';
  910. end;
  911. end;
  912. { procedure TIdMessage.LoadFromFile(const AFileName: string; const AHeaderOnly: Boolean = False);
  913. var
  914. LMsgClient : TIdMessageClient;
  915. begin
  916. LMsgClient := TIdMessageClient.Create(self);
  917. try
  918. LMsgClient.ProcessMessage(Self, AFileName, AHeaderOnly);
  919. finally
  920. FreeAndNil(LMsgClient);
  921. end;
  922. end; }
  923. { procedure TIdMessage.SaveToFile(AFileName: string);
  924. var
  925. LMsgClient : TIdMessageClient;
  926. LS : TFileStream;
  927. IOHandler : TIdIOHandlerStream;
  928. begin
  929. if FileExists(AFileName) then begin
  930. DeleteFile(AFileName);
  931. end;
  932. LS := TFileStream.create(AFileName, fmCreate);
  933. IOHandler := TIdIOHandlerStream.Create(nil);
  934. IOHandler.StreamType := stWrite;
  935. IOHandler.WriteStream := LS;
  936. try
  937. LMsgClient := TIdMessageClient.Create(nil);
  938. LMsgClient.IOHandler := IOHandler;
  939. LMsgClient.OpenWriteBuffer(32768);
  940. LMsgClient.SendMsg(Self);
  941. LMsgClient.WriteLn('.');
  942. LMsgClient.CloseWriteBuffer;
  943. finally
  944. FreeAndNil(LMsgClient);
  945. IOHandler.WriteStream.Free;
  946. FreeAndNil(IOHandler);
  947. end;
  948. end; }
  949. procedure TIdMessage.LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean = False);
  950. var
  951. vStream: TFileStream;
  952. begin
  953. if (not FileExists(AFilename)) then
  954. begin
  955. raise EIdMessageCannotLoad.CreateFmt(RSIdMessageCannotLoad, [AFilename]);
  956. end;
  957. vStream := TFileStream.Create(AFilename, fmOpenRead or fmShareDenyWrite);
  958. try
  959. LoadFromStream(vStream, AHeadersOnly);
  960. finally
  961. vStream.Free;
  962. end;
  963. end;
  964. procedure TIdMessage.LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean = False);
  965. var
  966. vMsgClient : TIdMessageClient;
  967. begin
  968. // clear message properties, headers before loading
  969. Clear;
  970. vMsgClient := TIdMessageClient.Create(nil);
  971. try
  972. vMsgClient.ProcessMessage(Self, AStream, AHeadersOnly);
  973. finally
  974. FreeAndNil(vMsgClient);
  975. end;
  976. end;
  977. procedure TIdMessage.SaveToFile(const AFileName: string; const AHeadersOnly: Boolean = False);
  978. var
  979. vStream : TFileStream;
  980. begin
  981. if FileExists(AFileName) then
  982. begin
  983. DeleteFile(AFileName);
  984. end;
  985. vStream := TFileStream.create(AFileName, fmCreate);
  986. try
  987. SaveToStream(vStream, AHeadersOnly);
  988. finally
  989. vStream.Free;
  990. end;
  991. end;
  992. // TODO: Override TIdMessageClient.SendMsg to provide socket, stream, and file
  993. // versions like TIdMessageClient.ProcessMessage?
  994. procedure TIdMessage.SaveToStream(AStream: TStream;
  995. const AHeadersOnly: Boolean = False);
  996. var
  997. LMsgClient: TIdMessageClient;
  998. LIOHS: TIdIOHandlerStream;
  999. begin
  1000. LMsgClient := TIdMessageClient.Create(nil);
  1001. try
  1002. LIOHS := TIdIOHandlerStream.Create(nil);
  1003. try
  1004. LIOHS.FreeStreams := False;
  1005. LIOHS.OutputStream := AStream;
  1006. LMsgClient.IOHandler := LIOHS;
  1007. LMsgClient.OpenWriteBuffer(32768);
  1008. {
  1009. ds - the following is required with new Active property in IOHandler.
  1010. Without Connect, IOHandler.Open is never called and a false
  1011. ConnectionClosedGracefully is raised when trying to write to the
  1012. Output stream. This uses the same logic as used in
  1013. TIdMessageClient.ProcessMessage.
  1014. For stream IOHandlers, perhaps Open could be called in Create just like
  1015. Close is called in the Destroy.
  1016. }
  1017. LMsgClient.Connect;
  1018. try
  1019. LMsgClient.SendMsg(Self, AHeadersOnly);
  1020. // Add the end of message marker when body is included
  1021. if AHeadersOnly = False then
  1022. begin
  1023. LMsgClient.WriteLn('.');
  1024. end;
  1025. finally
  1026. LMsgClient.CloseWriteBuffer;
  1027. {
  1028. ds - the following is required with new Active property in IOHandler.
  1029. }
  1030. LMsgClient.Disconnect;
  1031. end;
  1032. finally
  1033. FreeAndNil(LIOHS);
  1034. end;
  1035. finally
  1036. FreeAndNil(LMsgClient);
  1037. end;
  1038. end;
  1039. procedure TIdMessage.SetBody(const AValue: TStrings);
  1040. begin
  1041. FBody.Assign(AValue);
  1042. end;
  1043. procedure TIdMessage.SetBccList(const AValue: TIdEmailAddressList);
  1044. begin
  1045. FBccList.Assign(AValue);
  1046. end;
  1047. procedure TIdMessage.SetCCList(const AValue: TIdEmailAddressList);
  1048. begin
  1049. FCcList.Assign(AValue);
  1050. end;
  1051. procedure TIdMessage.SetExtraHeaders(const AValue: TIdHeaderList);
  1052. begin
  1053. FExtraHeaders.Assign(AValue);
  1054. end;
  1055. procedure TIdMessage.SetFrom(const AValue: TIdEmailAddressItem);
  1056. begin
  1057. FFrom.Assign(AValue);
  1058. end;
  1059. procedure TIdMessage.SetHeaders(const AValue: TIdHeaderList);
  1060. begin
  1061. FHeaders.Assign(AValue);
  1062. end;
  1063. procedure TIdMessage.SetNewsGroups(const AValue: TStrings);
  1064. begin
  1065. FNewsgroups.Assign(AValue);
  1066. end;
  1067. procedure TIdMessage.SetReceiptRecipient(const AValue: TIdEmailAddressItem);
  1068. begin
  1069. FReceiptRecipient.Assign(AValue);
  1070. end;
  1071. procedure TIdMessage.SetRecipients(const AValue: TIdEmailAddressList);
  1072. begin
  1073. FRecipients.Assign(AValue);
  1074. end;
  1075. procedure TIdMessage.SetReplyTo(const AValue: TIdEmailAddressList);
  1076. begin
  1077. FReplyTo.Assign(AValue);
  1078. end;
  1079. procedure TIdMessage.SetSender(const AValue: TIdEmailAddressItem);
  1080. begin
  1081. FSender.Assign(AValue);
  1082. end;
  1083. procedure TIdMessage.DoInitializeISO(var VTransferHeader: TTransfer;
  1084. var VHeaderEncoding: Char; var VCharSet: string);
  1085. Begin
  1086. if Assigned(FOnInitializeISO) then FOnInitializeISO(VTransferHeader, VHeaderEncoding, VCharSet);//APR
  1087. End;//
  1088. initialization
  1089. RegisterClasses([TIdAttachment, TIdText]);
  1090. end.