📄 umsgview.pas
字号:
SortDirection := TSortDirection(StrToInt(GetFirstToken(s)));
if SortColumn in [2,3] then SortColumn := 4;
for i := 0 to Columns.Count-1 do begin
Columns[i].Width := StrToInt(GetFirstToken(s));
Columns[i].Position := StrToInt(GetFirstToken(s));
end;
end;
except
end;
Picture1Click(nil);
Commands1Click(nil);
end;
procedure TfrmMsgView.ListMsgHeaderMouseUp(Sender: TVTHeader;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FormStorage1SavePlacement(nil);
end;
function TfrmMsgView.CanModifyReadStatus: boolean;
var EData: PFmaExplorerNode;
begin
EData := Form1.ExplorerNew.GetNodeData(Form1.ExplorerNew.FocusedNode);
Result := Assigned(EData) and
(EData.StateIndex and FmaMessagesRootMask = FmaMessagesRootFlag) and
(Form1.ExplorerNew.FocusedNode <> Form1.FNodeMsgOutbox) and (Form1.ExplorerNew.FocusedNode <> Form1.FNodeMsgDrafts);
end;
procedure TfrmMsgView.DownloadSMS1Click(Sender: TObject);
begin
{ Obsolete
if MessageDlgW(_('Local messages will be replaced with a fresh copy from the phone.'+
sLinebreak+sLinebreak+
'Any local changes will be lost. Do you wish to continue?'),
mtConfirmation, MB_YESNO or MB_DEFBUTTON2) = ID_YES then
}
Form1.ActionConnectionDownload.Execute;
end;
procedure TfrmMsgView.ListMsgIncrementalSearch(Sender: TBaseVirtualTree;
Node: PVirtualNode; const SearchText: WideString; var Result: Integer);
var
Data: PListData;
Text: WideString;
begin
Data := ListMsg.GetNodeData(Node);
Text := Copy(Data.from,1,Length(SearchText));
Result := WideCompareText(SearchText,Text);
end;
procedure TfrmMsgView.Commands1Click(Sender: TObject);
begin
tbCommands.Visible := Commands1.Checked;
end;
procedure TfrmMsgView.Picture1Click(Sender: TObject);
begin
ImagePanel.Visible := Picture1.Checked;
end;
function TfrmMsgView.IsRendered(const sl: TStrings): boolean;
begin
{ Do we have rendered data from currently selected Eplorer node? }
Result := (ListMsg.ChildCount[nil] <> 0) and (FRendered = sl) and Assigned(sl) and (edSearchFor.Text = '');
end;
procedure TfrmMsgView.DoMarkMessages(AsRead, SelectedOnly: Boolean);
var
node,curr: PVirtualNode;
item: PListData;
wl : TTntStringList;
i: Integer;
begin
{ do not mark as read/unread messages stored in Outbox or Drafts }
if CanModifyReadStatus then begin
node := ListMsg.GetFirst;
while Assigned(node) do begin
if not SelectedOnly or ListMsg.Selected[node] then begin
{ Skip Long SMS entries except for the first one }
item := ListMsg.GetNodeData(node);
if (item.smsData.IsLong) and (not item.smsData.IsLongFirst) then begin
node := ListMsg.GetNext(node);
Continue;
end;
wl := TTntStringList.Create;
try
{ Break long SMS into several parts in order to process each PDU-s.
If it's regular SMS, then emulate a Long SMS with one member (PDU) }
if not item.smsData.IsLong then
wl.AddObject(item.smsData.Text,Pointer(node))
else
GetNodeLongList(node,wl);
for i := 0 to wl.Count-1 do begin
curr := PVirtualNode(wl.Objects[i]);
if Assigned(curr) then begin
item := ListMsg.GetNodeData(curr);
item.smsData.IsNew := not AsRead;
{ Do not mark long SMS entries as Unread, except the first one }
if not AsRead then break;
end;
end;
finally
wl.Free;
end;
end;
node := ListMsg.GetNext(node);
end;
ListMsg.Repaint;
end;
ResetAutoMarkAsReadTimer;
Form1.UpdateNewMessagesCounter(Form1.ExplorerNew.FocusedNode);
end;
procedure TfrmMsgView.MarkAllRead1Click(Sender: TObject);
begin
DoMarkMessages(True,False);
end;
procedure TfrmMsgView.SearchForMessages(what: WideString);
var
Node: PVirtualNode;
Item: PListData;
md,mn: string;
mt,ms: WideString;
EmptySearch: boolean;
begin
what := WideUpperCase(what);
EmptySearch := what = '';
Timer2.Enabled := False; // cancel search timer
try
ListMsg.BeginUpdate;
DeselectAll;
node := ListMsg.GetFirst;
while Assigned(node) do begin
Item := ListMsg.GetNodeData(Node);
if (item.smsData.IsLong) and (not item.smsData.IsLongFirst) then begin
node := ListMsg.GetNext(node);
Continue;
end;
{ Get message info }
if item.smsData.IsLong then mt := GetNodeLongText(Node) else mt := item.smsData.Text;
mt := WideUpperCase(mt); // message text (for both short or long SMS message)
md := UpperCase(DateTimeToStr(item.smsData.TimeStamp)); // sent or received date
ms := WideUpperCase(item.sender); // message sender's name (no number!)
mn := UpperCase(item.smsData.From); // sender's number only (no name!)
{ Apply search filter }
case FSearchMode of
smSender:
ListMsg.IsVisible[Node] := EmptySearch or (Pos(what,ms) <> 0);
smFrom:
ListMsg.IsVisible[Node] := EmptySearch or (Pos(what,ms) <> 0) or (Pos(what,mn) <> 0);
smAll:
ListMsg.IsVisible[Node] := EmptySearch or (Pos(what,mt) <> 0) or // text
(Pos(what,ms) <> 0) or (Pos(what,mn) <> 0) or // sender and number
(Pos(what,md) <> 0); // message date
smText:
ListMsg.IsVisible[Node] := EmptySearch or (Pos(what,mt) <> 0);
smDate:
ListMsg.IsVisible[Node] := EmptySearch or (Pos(what,md) <> 0);
end;
node := ListMsg.GetNext(node);
end;
finally
ListMsg.EndUpdate;
lblFiltered.Visible := not EmptySearch;
end;
end;
procedure TfrmMsgView.DeselectAll;
begin
ListMsg.BeginUpdate;
try
ListMsg.ClearSelection;
finally
ListMsg.EndUpdate;
end;
end;
procedure TfrmMsgView.ListMsgClick(Sender: TObject);
var
item: PListData;
mouse: TPoint;
hit: THitInfo;
b: boolean;
begin
if ListMsg.SelectedCount = 1 then begin
GetCursorPos(mouse);
mouse := ListMsg.ScreenToClient(mouse);
ListMsg.GetHitTestInfoAt(mouse.X, mouse.Y, True, hit);
if hit.HitColumn = 2 then
if Assigned(hit.HitNode) then begin
item := ListMsg.GetNodeData(hit.HitNode);
b := item.smsData.IsNew;
Screen.Cursor := crAppStart;
try
Timer1.Enabled := false;
DoMarkMessages(b);
Timer1.Enabled := false;
ListMsg.RepaintNode(ListMsg.GetFirstSelected);
finally
Screen.Cursor := crDefault;
end;
end;
end;
end;
procedure TfrmMsgView.ListMsgPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
var
item: PListData;
begin
item := Sender.GetNodeData(Node);
if Assigned(item) and Assigned(item.smsData) then
if item.smsData.IsNew then
TargetCanvas.Font.Style := [fsBold]
else
TargetCanvas.Font.Style := [];
end;
procedure TfrmMsgView.edSearchForKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_RETURN then begin
Key := 0;
if Timer2.Enabled then SearchForMessages(edSearchFor.Text);
end
else
if Key = VK_ESCAPE then begin
Key := 0;
if edSearchFor.Text <> '' then begin
edSearchFor.Text := '';
SearchForMessages('');
end;
end;
end;
procedure TfrmMsgView.edSearchForKeyPress(Sender: TObject; var Key: Char);
begin
if Key in [#13,#27] then Key := #0; // disables beep sound on enter and escape
end;
procedure TfrmMsgView.edSearchForChange(Sender: TObject);
begin
Timer2.Enabled := False;
Timer2.Enabled := edSearchFor.ParentFont;
end;
procedure TfrmMsgView.Timer2Timer(Sender: TObject);
begin
SearchForMessages(edSearchFor.Text);
end;
procedure TfrmMsgView.Search1Click(Sender: TObject);
begin
edSearchFor.Text := '';
edSearchForExit(nil);
SearchPanel.Visible := True;
if Visible then
if ListMsg.Focused then
edSearchFor.SetFocus
else
ListMsg.SetFocus;
end;
procedure TfrmMsgView.SendToPhone1Click(Sender: TObject);
begin
WriteSMS('ME'); // do not localize
Form1.Status(_('Messages sent to Phone'));
end;
procedure TfrmMsgView.SendToSIM1Click(Sender: TObject);
begin
WriteSMS('SM'); // do not localize
Form1.Status(_('Messages sent to SIM card'));
end;
procedure TfrmMsgView.SendfromPhone1Click(Sender: TObject);
begin
WriteSMS('ME',2); // do not localize
Form1.Status(_('Drafts sent to Phone'));
end;
procedure TfrmMsgView.DoShowPreview(Node: PVirtualNode);
const
LastImage: string = '';
var
item: PListData;
sms: TSMS;
UDHI: String;
pos, octet, {posTemp,} udhil: Integer;
Description: String;
contact: PContactData;
s: WideString;
//SL: TWideStringList;
//i: Integer;
vcardcontact: TContactData;
begin
IsCustomImage := False;
if Node = nil then begin
MemoMsgBody.Clear;
exit;
end;
item := ListMsg.GetNodeData(Node);
if Assigned(item.smsData.BusinessCard) then begin
vCard2Contact(item.smsData.BusinessCard,@vcardcontact);
GetContactDetails(@vcardcontact,MemoMsgBody.Lines);
exit;
end;
sms := TSMS.Create;//ADD
try
//posTemp := 0;
MemoMsgBody.Text := item.smsData.Text;// + inttostr(length(item.msg));
MemoMsgBody.DefAttributes.Color := clWindowText;
MemoMsgBody.DefAttributes.Size := 10;
sms.PDU := item.smsData.PDU; //ADD
sms.Text; // Decode all PDU fields
{ try to load contact personalized image and maintain a cache }
s := Form1.LookupContact(item.smsData.From);
if Form1.IsIrmcSyncEnabled and Form1.frmSyncPhonebook.FindContact(s,contact) then begin
s := GetContactPictureFile(contact);
if s <> '' then
try
{ cache loaded image name }
if not IsCustomImage or (s <> LastImage) then begin
{ Use uGlobal function }
LoadBitmap32FromFile(s,SelImage.Bitmap);
IsCustomImage := True;
LastImage := s;
end;
except
IsCustomImage := False;
end
else
IsCustomImage := False;
end
else
IsCustomImage := False;
{ show message info }
//item.msg := sms.Text;
if sms.IsUDH then begin
UDHI := sms.UDHI;
udhil := StrToInt('$' + copy(UDHI, 1, 2));
//ANALIZE UDHI
UDHI := Copy(UDHI, 3, length(UDHI));
//pos := 1;
repeat
//Get the octet for type
octet := StrToInt('$' + Copy(UDHI, 1, 2));
UDHI := Copy(UDHI, 3, length(UDHI));
case octet of
0,8:begin //SMS CONCATENATION
pos := StrToInt('$' + Copy(UDHI, 1, 2)) + 1;
if octet = 0 then begin
Description := Description + _('[LONG SMS - REFID:') + IntToStr(StrToInt('$' + Copy(UDHI, 3, 2)));
Description := Description + _(' - COUNT:') + IntToStr(StrToInt('$' + Copy(UDHI, 5, 2))) + ']';
end
else begin
Description := Description + _('[LONG SMS - REFID:') + IntToStr(StrToInt('$' + Copy(UDHI, 3, 4)));
Description := Description + _(' - COUNT:') + IntToStr(StrToInt('$' + Copy(UDHI, 7, 2))) + ']';
end;
UDHI := Copy(UDHI, pos*2+1, length(UDHI));
MemoMsgBody.Clear;
(*
SL := TWideStringList.Create;
try
SL.Text := GetNodeLongText(Node);
for i := 0 to SL.Count - 1 do begin
{
// Show different parts in different colors
if i mod 2 = 0 then
MemoMsgBody.SelAttributes.Color := clHotLight
els
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -