📄 maillist.pas
字号:
(*
# (C) Copyright 2003
# Miha Vrhovnik, miha.vrhovnik@guest.arnes.si
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
# The Initial Developer of the Original Code is Miha Vrhovnik (Slovenia).
# Portions created by Miha Vrhovnik are Copyright (c)2000-2003.
# All Rights Reserved.
#==============================================================================
# Contributor(s):
#==============================================================================
# History: see whats new.txt from distribution package
#==============================================================================
*)
unit maillist;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, VirtualTrees, gnugettext, ImgList, StdCtrls, ExtCtrls, GPanel, pcre,
Menus, ActnList, account, dateUtils, defFldrs, fCompose, TB2Item, TBX,
TBXExtItems, TB2ExtItems, TB2Toolbar, TB2Dock, TB2ToolWindow;
type TGroupBy = (gbNone, gbDate);
type
TfrmMaillist = class(TForm)
lstMailList: TVirtualStringTree;
ActionList: TActionList;
actMessageNew: TAction;
actMessageReply: TAction;
actMessageReplyAll: TAction;
actMessageForward: TAction;
actMessageBounce: TAction;
actMessageRedirect: TAction;
actMessageAnnotate: TAction;
actMessageMove: TAction;
actMessageForwardAs: TAction;
actMessageMarkAsRead: TAction;
actMessageMarkAsUnread: TAction;
actMessageMarkAsReplied: TAction;
actMessageMarkAsUnreplied: TAction;
actMessageLabelReply: TAction;
actMessageLabelTrashLater: TAction;
actMessageLabelCustom3: TAction;
actMessageLabelImportant: TAction;
actMessageLabelFriend: TAction;
actMessageLabelAskLater: TAction;
actMessageLabelCompany: TAction;
actMessageLabelToDo: TAction;
actMessageLabelCustom1: TAction;
actMessageLabelCustom2: TAction;
actGroupByDate: TAction;
actGroupBySender: TAction;
actGroupBySize: TAction;
actGroupByLabel: TAction;
actGroupByPriority: TAction;
actMessageContinueEdit: TAction;
tmrMark: TTimer;
actMessageProperties: TAction;
actMessageLabelClear: TAction;
actMessageMarkAsForwarded: TAction;
actMessageMarkAsUnforwarded: TAction;
popAnnotate: TTBXPopupMenu;
popLabel: TTBXPopupMenu;
popMenu: TTBXPopupMenu;
Annotate2: TTBXItem;
Company2: TTBXItem;
Business2: TTBXItem;
Friend1: TTBXItem;
Important3: TTBXItem;
Reply3: TTBXItem;
odo2: TTBXItem;
rashlater2: TTBXItem;
Custom12: TTBXItem;
Custom22: TTBXItem;
Followup2: TTBXItem;
N5: TTBXSeparatorItem;
Clearlabel2: TTBXItem;
New1: TTBXItem;
Reply1: TTBXItem;
Replytoall1: TTBXItem;
Forward1: TTBXItem;
Forwardasattachment1: TTBXItem;
Bounce1: TTBXItem;
Redirectto1: TTBXItem;
Annotate1: TTBXItem;
Continueediting1: TTBXItem;
Delete1: TTBXItem;
N1: TTBXSeparatorItem;
Mark1: TTBXSubmenuItem;
Asread1: TTBXItem;
Asunread1: TTBXItem;
N3: TTBXSeparatorItem;
Asreplied1: TTBXItem;
Asunreplied1: TTBXItem;
N6: TTBXSeparatorItem;
Forwarded1: TTBXItem;
Unforwarded1: TTBXItem;
mnuLabelAs: TTBXSubmenuItem;
Company1: TTBXItem;
Business1: TTBXItem;
Important1: TTBXItem;
Important2: TTBXItem;
Reply2: TTBXItem;
odo1: TTBXItem;
rashlater1: TTBXItem;
Custom11: TTBXItem;
Custom21: TTBXItem;
Followup1: TTBXItem;
N4: TTBXSeparatorItem;
Clearlabel1: TTBXItem;
Groupby1: TTBXSubmenuItem;
Date1: TTBXItem;
Sender1: TTBXItem;
Size1: TTBXItem;
Label2: TTBXItem;
Priority1: TTBXItem;
N2: TTBXSeparatorItem;
Moveto1: TTBXItem;
Properties1: TTBXItem;
TBXItem1: TTBXItem;
actMessageOpen: TAction;
actMessageSave: TAction;
actMessageSaveAppend: TAction;
TBXSeparatorItem1: TTBXSeparatorItem;
TBXItem2: TTBXItem;
TBXItem3: TTBXItem;
actMessageAddSender: TAction;
TBXItem4: TTBXItem;
diSaveDialog: TSaveDialog;
TBXToolWindow1: TTBXToolWindow;
TBXToolbar1: TTBXToolbar;
lblMsg2: TLabel;
lblMsg: TLabel;
TBXEditItem2: TTBXEditItem;
TBXSeparatorItem2: TTBXSeparatorItem;
TBXComboBoxItem1: TTBXComboBoxItem;
TBXSeparatorItem3: TTBXSeparatorItem;
procedure FormCreate(Sender: TObject);
procedure lstMailListGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
procedure lstMailListMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure lstMailListInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
procedure lstMailListGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: WideString);
procedure lstMailListHeaderClick(Sender: TVTHeader;
Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
procedure lstMailListDragAllowed(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
procedure lstMailListCompareNodes(Sender: TBaseVirtualTree; Node1,
Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
procedure lstMailListChange(Sender: TBaseVirtualTree;
Node: PVirtualNode);
procedure actMessageContinueEditUpdate(Sender: TObject);
procedure actMessageContinueEditExecute(Sender: TObject);
procedure lstMailListGetPopupMenu(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; const P: TPoint;
var AskParent: Boolean; var PopupMenu: TPopupMenu);
procedure lstMailListGetImageIndex(Sender: TBaseVirtualTree;
Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
var Ghosted: Boolean; var ImageIndex: Integer);
procedure tmrMarkTimer(Sender: TObject);
procedure actMessageAnnotateExecute(Sender: TObject);
procedure lstMailListGetHint(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: WideString);
procedure lstMailListClick(Sender: TObject);
procedure actMessageLabelExecute(Sender: TObject);
procedure actMessageMarkAsReadExecute(Sender: TObject);
procedure actMessageMarkAsUnreadExecute(Sender: TObject);
procedure actMessageAnnotateUpdate(Sender: TObject);
procedure actMessageNewExecute(Sender: TObject);
procedure actMessagePropertiesExecute(Sender: TObject);
procedure actMessageNewUpdate(Sender: TObject);
procedure actMessageMarkAsUnreadUpdate(Sender: TObject);
procedure lstMailListPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType);
procedure lstMailListDblClick(Sender: TObject);
procedure actMessageReplyExecute(Sender: TObject);
procedure actMessageForwardExecute(Sender: TObject);
procedure actMessageReplyUpdate(Sender: TObject);
procedure actMessageForwardUpdate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure actGroupByDateExecute(Sender: TObject);
procedure actMessageMarkAsRepliedExecute(Sender: TObject);
procedure actMessageMarkAsUnrepliedExecute(Sender: TObject);
procedure actMessageMarkAsForwardedExecute(Sender: TObject);
procedure actMessageMarkAsUnforwardedExecute(Sender: TObject);
procedure actMessageReplyAllExecute(Sender: TObject);
procedure actMessageOpenExecute(Sender: TObject);
procedure actMessageOpenUpdate(Sender: TObject);
procedure actMessageSaveExecute(Sender: TObject);
procedure actMessageAddSenderExecute(Sender: TObject);
procedure actMessageAddSenderUpdate(Sender: TObject);
private
{ Private declarations }
FlastMsgID: Integer; //last message id
Fmbox: TMailbox;
FaccountID: Integer;
Fminimized: Boolean;
FGroubBy: TGroupBy;
FLastCompose: TfrmCompose;
procedure showGroupByDate;
procedure openMessage(Node: PVirtualNode; newWindow: Boolean = False);
procedure parseMail(Value: String; var name, email: String);
public
{ Public declarations }
procedure ShowMailbox;
procedure MoveToMailbox(destMbox: TMailbox; sameAccount: Boolean);
function actMaillistDeleteF: Boolean;
procedure actMaillistDeleteUpdate;
procedure Minimize;
procedure Restore;
procedure Clear;
property Mailbox: TMailbox read Fmbox;
property Minimized: Boolean read Fminimized write Fminimized;
property ShownMailbox: TMailbox read Fmbox;
property MailboxFromAccount: Integer read FaccountID;
property LastCompose: TfrmCompose read FLastCompose;
procedure ClearMaillist;
procedure RemoveMessageWithInternalID(msgId: Integer);
procedure ComposeWindowsChangeFont(fnt: TFont);
end;
var
frmMaillist: TfrmMaillist;
implementation
uses fMain, mailBox, fMailView, fMyInputBox, fMessageInfo, dImages,
addressBook, fContact, StrUtils, addrBk_frm;
{$R *.dfm}
//tree type data
//TmsgDescription
(*type TTreeMaillist=record
end;*)
type PTreeMaillist = ^TmsgDescription;
const imgUnread = 0;
const imgRead = 1;
const imgReplyed = 2;
const imgForwarded = 3;
const imgReFwd = 4;
const imgCached = 5;
const imgOnServer = 6;
const imgComment = 7;
const imgAttachment = 8;
const imgPriority0 = 13;
const imgPriority1 = 12;
const imgPriority2 = 11;
const imgPriority3 = 10;
const imgPriority4 = 9;
const imgMsgFlag = 14; //up to 23
//const img
procedure TfrmMaillist.FormCreate(Sender: TObject);
begin
lstMaillist.Align := alClient;
Fmbox := nil;
Fminimized := False;
FGroubBy := gbNone;
//e-mail save dialog
diSaveDialog.Filter := _('Text (*.txt)|*.txt|Html (*.html)|*.html|Full message (*.eml)|*.eml');
end;
procedure TfrmMaillist.ShowMailbox;
var tmpStr: String;
begin
ClearMaillist;
FlastMsgID := -1;
Fmbox := nil;
Fmbox := frmMailbox.getMailbox(frmMailbox.SelectedAccount, frmMailbox.SelectedMailbox);
FaccountID := frmMailbox.SelectedAccount;
if not Fmbox.Unlocked then begin
tmpStr := InputPassword(_('Password required'),
Format(_('' +
'Mailbox ''%s'' is password protected.Please write password to field below.'),
[Fmbox.MailboxName]), '', '*');
if not Fmbox.Unlock(tmpStr) then begin
MessageDlg(_('Wrong password.'), mtError, [mbOk], 0);
Exit;
end;
end;
case TMailboxType( -Fmbox.id) of
mboxUnsent, mboxUnfinished, mboxSent:
lstMaillist.Header.Columns[6].Text := _('To')
else lstMaillist.Header.Columns[6].Text := _('From')
end;
if Fmbox = nil then begin
lblMsg.Caption := _('Messages');
lblMsg2.Caption := '';
end
else begin
lblMsg.Caption := Format(_('Messages - [%s]') + ',', [Fmbox.MailboxName]);
lblMsg2.Left := lblMsg.Left + lblMsg.Width + 5;
lblMsg2.Caption := Format(_('{total: %d, unread: %d}'), [Fmbox.TotalMessageCount, Fmbox.UnreadMessageCount]);
end;
case FGroubBy of
gbNone:
lstMailList.RootNodeCount := Fmbox.TotalMessageCount;
gbDate:
ShowGroupByDate;
end;
end;
procedure TfrmMaillist.lstMailListGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
begin
NodeDataSize := sizeOf(TmsgDescription);
end;
procedure TfrmMaillist.lstMailListInitNode(Sender: TBaseVirtualTree;
ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
var d: PTreeMaillist;
begin
d := PTreeMaillist((Sender as TVirtualStringTree).GetNodeData(Node));
d.deleted := True;
if FGroubBy <> gbNone then Exit;
//find first message which is not deleted
while d.deleted do begin
Inc(FlastMsgID); //we shuldn't fall out here
//if FlastMsgID > mbox.
d^ := Fmbox.GetMessageDescription(FlastMsgID);
d.id := FlastMsgID;
end;
end;
procedure TfrmMaillist.lstMailListGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: WideString);
begin
//return each column's text
with PTreeMaillist((Sender as TVirtualStringTree).GetNodeData(Node))^ do begin
case Column of
0, 1, 2, 3, 4:
CellText := '';
5:
CellText := subject;
6:
CellText := from;
7:
CellText := DateTimeToStr(date);
8:
CellText := frmMain.SizeToString(size);
end;
end;
end;
procedure TfrmMaillist.lstMailListHeaderClick(Sender: TVTHeader;
Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
//if same column then just reverse sorting
if Sender.SortColumn = Column then begin
if Sender.SortDirection = sdAscending then
Sender.SortDirection := sdDescending
else Sender.SortDirection := sdAscending;
end
else Sender.SortColumn := Column;
end;
procedure TfrmMaillist.lstMailListDragAllowed(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
begin
Allowed := True;
end;
procedure TfrmMaillist.MoveToMailbox(destMbox: TMailbox; sameAccount: Boolean);
var i: Integer;
var msg: TMemoryStream;
var Node: PVirtualNode;
var nd: PTreeMaillist;
var markAsRead: Boolean;
begin
//move mails
Node := nil;
markAsRead := frmMailbox.Profile.Config.ReadBool(Self.Name, 'markAsRead', True);
lstMaillist.BeginUpdate;
Node := lstMaillist.GetFirstSelected;
while True do begin
nd := lstMaillist.GetNodeData(Node);
//decrement total message count
//mark as unread if moving to trash
if (destMbox.Id = -Integer(mboxTrash)) and markAsRead then
nd^.status := nd^.status + [msgRead];
msg := TMemoryStream(FMbox.GetMessageContent(nd^.id));
//move only if there is no attachment or its sameAccount
if ( not (msgAttachmentOutside in nd^.status)) or sameAccount then begin
destMbox.AddMessage(msg, nd^);
msg.Free;
FMbox.RemoveMessage(nd^.id);
if lstMailList.GetNextSelected(Node) <> nil then begin
lstMaillist.DeleteNode(Node);
Node := lstMaillist.GetFirstSelected;
end
else begin //select first after deleted
if lstMailList.GetNext(Node) <> nil then
lstMailList.Selected[lstMailList.GetNext(Node)] := True
else if lstMailList.GetPrevious(Node) <> nil then
lstMailList.Selected[lstMailList.GetPrevious(Node)] := True;
lstMaillist.DeleteNode(Node);
Break;
end;
end
else Beep;
end;
lstMaillist.EndUpdate;
frmMailbox.RefreshTotals(frmMailbox.SelectedAccount);
frmMailbox.trMailbox.Repaint;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -