📄 umsgview.pas
字号:
{ Skip Long SMS entries except for the first one }
item := GetNodeData(node);
if (item.smsData.IsLong) and (not item.smsData.IsLongFirst) then begin
node := GetNext(node);
Continue;
end;
str := '<sms>'; // do not localize
str := str + '<from>' + HTMLEncode(WideStringToUTF8String(item.from),False) + '</from>'; // do not localize
if item.smsData.IsLong then
str := str + '<msg>' + HTMLEncode(WideStringToUTF8String(GetNodeLongText(Node)),False) + '</msg>' // do not localize
else
str := str + '<msg>' + HTMLEncode(WideStringToUTF8String(item.smsData.Text),False) + '</msg>'; // do not localize
if item.smsData.TimeStamp > 0 then
str := str + '<date>' + HTMLEncode(DateTimeToStr(item.smsData.TimeStamp),False) + '</date>' // do not localize
else
str := str + '<date/>'; // do not localize
str := str + '</sms>'; // do not localize
sl.add(str);
end;
except
end;
node := GetNext(node);
until node = nil;
end;
sl.Add('</fma_messages>'); // do not localize
sl.SaveToFile(FileName);
finally
sl.Free;
end;
end;
3:begin//HTML
sl := TStringList.Create;
try
sl.Add('<html><head><meta content="text/html;charset=utf-8" http-equiv="content-type">'); // do not localize
sl.Add('<title>FMA Messages</title></head><body>'); // do not localize
sl.Add('<TABLE BORDER="1">'); // do not localize
sl.Add('<TR><TD>FROM</TD><TD>BODY</TD><TD>DATE</TD></TR>'); // do not localize
with ListMsg do begin
node := GetFirst;
repeat
try
if Selected[node] then begin
{ Skip Long SMS entries except for the first one }
item := GetNodeData(node);
if (item.smsData.IsLong) and (not item.smsData.IsLongFirst) then begin
node := GetNext(node);
Continue;
end;
str := '<TR>'; // do not localize
str := str + '<TD>' + HTMLEncode(WideStringToUTF8String(item.from),False) + '</TD>'; // do not localize
if item.smsData.IsLong then
str := str + '<TD>' + HTMLEncode(WideStringToUTF8String(GetNodeLongText(Node)),False) + '</TD>' // do not localize
else
str := str + '<TD>' + HTMLEncode(WideStringToUTF8String(item.smsData.Text),False) + '</TD>'; // do not localize
if item.smsData.TimeStamp > 0 then
str := str + '<TD>' + HTMLEncode(DateTimeToStr(item.smsData.TimeStamp),False) + '</TD>' // do not localize
else
str := str + '<TD></TD>'; // do not localize
str := str + '</TR>'; // do not localize
sl.add(str);
end;
except
end;
node := GetNext(node);
until node = nil;
end;
sl.Add('</TABLE>'); // do not localize
sl.Add('</body></html>'); // do not localize
sl.SaveToFile(FileName);
finally
sl.Free;
end;
end;
end;
end;
procedure TfrmMsgView.Copy1Click(Sender: TObject);
begin
memomsgbody.CopyToClipboard;
end;
procedure TfrmMsgView.WriteSMS(Mem: String; StoreAs: Integer);
var
State: Integer;
node,prev: PVirtualNode;
EData: PFmaExplorerNode;
item: PListData;
sl: TStringList;
wl: TTntStringList;
j: Integer;
UpdateIncoming,UpdateOutgoing: boolean;
procedure DelNodeFromDBandView;
var
index: Integer;
begin
index := sl.IndexOfObject(item.smsData);
if index <> -1 then begin
item.smsData := nil;
TFmaMessageData(sl.Objects[index]).Free;
sl.Delete(index);
if prev = ListMsg.FocusedNode then begin
MemoMsgBody.Clear;
IsCustomImage := False;
end;
ListMsg.DeleteNode(prev);
end;
end;
begin
{ By default message status will be set to 'Received unread' (StoreAs = -1) }
UpdateIncoming := False;
UpdateOutgoing := False;
ListMsg.BeginUpdate;
try
EData := Form1.ExplorerNew.GetNodeData(Form1.ExplorerNew.FocusedNode);
sl := TStringList(EData.Data);
with ListMsg do begin
node := GetFirst;
while node <> nil do begin
prev := nil;
if Selected[node] then begin
{ Skip Long SMS entries except for the first one }
item := GetNodeData(node);
if (item.smsData.IsLong) and (not item.smsData.IsLongFirst) then begin
node := GetNext(node);
Continue;
end;
wl := TTntStringList.Create;
try
{ Break long SMS into several parts in order to keep original PDU-s.
If it's regular SMS, then emulate a Long one with one member (PDU) }
if not item.smsData.IsLong then
wl.AddObject(item.smsData.Text,Pointer(node))
else
if not GetNodeLongList(node,wl) then begin
node := GetNext(node);
continue; // skip missing parts messages
end;
{ Send all message parts to phone }
for j := 0 to wl.Count-1 do begin
item := GetNodeData(PVirtualNode(wl.Objects[j]));
State := StoreAs;
if State = -1 then begin
{ State description:
0 Received unread (new) message - Default setting
1 Received read message
2 Stored unsent message (only applicable to SMs)
3 Stored sent message (only applicable to SMs) }
if item.smsData.IsOutgoing then // outgoing message
State := 3
else
State := 1;
end;
if State = -1 then State := 0;
{ Upload to phone }
if Form1.WriteSMS(Mem, item.smsData.PDU, State) then
case State of
0,1: UpdateIncoming := True;
2,3: UpdateOutgoing := True;
end
else
raise EInOutError.Create(_('Could not send message to phone (storage full?)'));
end;
{ Delete message parts from database if its not first part which will be deleted below. }
for j := 0 to wl.Count-1 do begin
prev := PVirtualNode(wl.Objects[j]);
item := GetNodeData(prev);
if prev <> node then DelNodeFromDBandView;
end;
finally
wl.Free;
end;
{ Mark node for deletion }
prev := node;
end;
node := GetNext(node);
if Assigned(prev) then begin
item := GetNodeData(prev);
DelNodeFromDBandView;
ListMsg.Repaint;
end;
end;
end;
finally
ListMsg.EndUpdate;
Form1.UpdateNewMessagesCounter(Form1.ExplorerNew.FocusedNode);
end;
{ Refresh Phone Text Folders as needed }
if UpdateIncoming then
if UpdateOutgoing then
Form1.DownloadAllMessages
else
Form1.DownloadMessages(Form1.FNodeMsgInbox)
else
if UpdateOutgoing then
Form1.DownloadMessages(Form1.FNodeMsgSent);
end;
procedure TfrmMsgView.pmListMsgPopup(Sender: TObject);
var
node: PVirtualNode;
data: PFmaExplorerNode;
item: PListData;
HasRead,HasUnread: boolean;
begin
{ check Read/Unread status }
HasRead := False;
HasUnread := False;
if CanModifyReadStatus and (ListMsg.SelectedCount <> 0) then begin
node := ListMsg.GetFirst;
Repeat
if ListMsg.Selected[node] then begin
item := ListMsg.GetNodeData(node);
if item.smsData.IsNew then HasUnread := True else HasRead := True;
if HasRead and HasUnread then break;
end;
node := ListMsg.GetNext(node);
Until node = nil;
end;
data := Form1.ExplorerNew.GetNodeData(Form1.ExplorerNew.FocusedNode);
{ Check other options }
SendMessage1.Visible := Form1.ExplorerNew.FocusedNode = Form1.FNodeMsgDrafts;
SendMessage1.Enabled := ListMsg.SelectedCount = 1;
Newmessage1.Visible := not SendMessage1.Visible;
MarkasRead1.Enabled := HasUnread;
MarkasUnread1.Enabled := HasRead;
MarkAllRead1.Enabled := CanModifyReadStatus;
DownloadSMS1.Enabled := (not Form1.FConnected or not Form1.FObex.Connected) and
((Form1.ExplorerNew.FocusedNode = Form1.FNodeMsgInbox) or (Form1.ExplorerNew.FocusedNode = Form1.FNodeMsgSent));
SendToPhone1.Enabled := not SendMessage1.Visible and Form1.FConnected and not Form1.FObex.Connected and
((Form1.ExplorerNew.FocusedNode = Form1.FNodeMsgArchive) or (data.StateIndex = FmaSMSSubFolderFlag));
SendToSIM1.Enabled := SendToPhone1.Enabled;
SendfromPhone1.Visible := SendMessage1.Visible;
SendfromPhone1.Enabled := (ListMsg.SelectedCount >= 1) and Form1.FConnected and not Form1.FObex.Connected;
SaveSearch2.Enabled := (edSearchFor.Text <> '') and edSearchFor.ParentFont;
UpdatePropertiesStatus;
end;
procedure TfrmMsgView.DeleteSelected(Ask: boolean = True);
var
i,j,index: Integer;
s,memType: String;
node,prev: PVirtualNode;
data: PFmaExplorerNode;
item: PListData;
sl: TStringList;
wl : TTntStringList;
procedure DelNodeFromView;
begin
{ If deleteing current node, clear personalization and msg preview too }
if prev = ListMsg.FocusedNode then begin
MemoMsgBody.Clear;
IsCustomImage := False;
end;
ListMsg.DeleteNode(prev);
end;
begin
if ListMsg.SelectedCount = 0 then exit;
s := WideFormat(_('Deleting %d %s.'), [ListMsg.SelectedCount,ngettext('message','messages',ListMsg.SelectedCount)]);
if Ask and (MessageDlgW(s+_(' Do you wish to continue?'), mtConfirmation, MB_YESNO or MB_DEFBUTTON2) <> ID_YES) then
exit;
Form1.Status(s+'..');
Update;
frmConnect := GetProgressDialog;
try
if Ask and Form1.CanShowProgress and (ListMsg.SelectedCount > 1) then
frmConnect.ShowProgress(Form1.FProgressLongOnly);
frmConnect.Initialize(ListMsg.SelectedCount,s);
Form1.Enabled := False; // prevent keyboard move up/down in list while deleteing
ListMsg.BeginUpdate;
try
data := Form1.ExplorerNew.GetNodeData(Form1.ExplorerNew.FocusedNode);
sl := TStringList(data.Data);
node := ListMsg.GetLast;
while node <> nil do begin
prev := nil;
if ListMsg.Selected[node] then begin
{ Skip Long SMS entries except for the first one }
item := ListMsg.GetNodeData(node);
if (not item.smsData.IsLong) or (item.smsData.IsLongFirst) then begin
wl := TTntStringList.Create;
try
{ Break long SMS into several parts in order to keep original PDU-s.
If it's regular SMS, then emulate a Long one with one member (PDU) }
if not item.smsData.IsLong then
wl.AddObject(item.smsData.Text,Pointer(node))
else
GetNodeLongList(node,wl);
{ Delete all parts of the message }
for j := 0 to wl.Count-1 do begin
prev := PVirtualNode(wl.Objects[j]);
if Assigned(prev) then begin
item := ListMsg.GetNodeData(prev);
index := item.StateIndex;
if item.smsData.Location = mlME then // ME
memType := 'ME' // do not localize
else
if item.smsData.Location = mlSM then // SM
memType := 'SM' // do not localize
else
{if item.smsData.Location = mlPC then} // PC
memType := '';
{ If deleteing from Outbox, notify and enable Chat window }
if Form1.ExplorerNew.FocusedNode = Form1.FNodeMsgOutbox then
Form1.ChatNotifyDel(item.smsData.PDU);
{ Remove message from database }
i := sl.IndexOfObject(item.smsData);
if i <> -1 then begin
if memType <> '' then begin { in phone? }
Form1.AskRequestConnection;
try
Form1.DeleteSMS(index, memType, item.smsData.PDU);
except
{ silently ignore delete failure - it means message is not in phone anyway }
end;
end;
(item.smsData).Free;
item.smsData := nil;
sl.Delete(i);
{ Delete message part from database if its not the first one.
The first part will be deleted below in DelNodeFromView call. }
if prev <> node then DelNodeFromView;
end
else begin // this should never happen
RenderListView(sl);
Exit;
end;
end;
end;
finally
wl.Free;
end;
{ Update progress }
frmConnect.IncProgress(1);
prev := node; // prev is used in DelNode
end;
end;
node := ListMsg.GetPrevious(node);
if Assigned(prev) then begin
DelNodeFromView;
if Ask then ListMsg.Repaint;
end;
end;
finally
ListMsg.EndUpdate;
NoItemsPanel.Visible := ListMsg.ChildCount[nil] = 0;
Form1.Enabled := True;
Form1.UpdateNewMessagesCounter(Form1.ExplorerNew.FocusedNode);
end;
finally
FreeProgressDialog;
end;
Form1.Status('');
end;
procedure TfrmMsgView.sbCloseSearchClick(Sender: TObject);
begin
edSearchFor.Text := '';
ListMsg.SetFocus;
SearchPanel.Visible := False;
end;
procedure TfrmMsgView.ListMsgKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = VK_RETURN) and (ListMsg.SelectedCount = 1) then
ListMsgDblClick(ListMsg);
end;
procedure TfrmMsgView.Splitter2Moved(Sender: TObject);
begin
if PreviewPanel.Height < Splitter2.MinSize then PreviewPanel.Height := Splitter2.MinSize;
end;
procedure TfrmMsgView.ListMsgChange(Sender: TBaseVirtualTree;
Node: PVirtualNode);
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -