📄 umsgview.pas
字号:
begin
item := Sender.GetNodeData(Node);
if Column = 0 then CellText := item.from
else
if Column = 1 then begin
try
if Assigned(item.smsData) then begin
if Assigned(item.smsData.BusinessCard) then
CellText := WideFormat(_('Business Card [%s]'),[GetvCardFullName(item.smsData.BusinessCard)])
else begin
CellText := FlattenText(item.smsData.Text);
if item.smsData.IsLong then CellText := CellText + ' (...)'; // do not localize
end;
end;
except
item.smsData := nil;
end;
{
if IsLongSMSNode(Node) then
CellText := FlattenText(GetNodeLongText(node))
else
CellText := FlattenText(item.msg);
}
end
else
if Column in [2,3] then CellText := #32 // span columns doesnt take effect
else
if Column = 4 then begin
try
if (Assigned(item.smsData) and (item.smsData.TimeStamp > 0)) then begin
if isToday(item.smsData.TimeStamp) then CellText := TimeToStr(item.smsData.TimeStamp)
else CellText := DateTimeToStr(item.smsData.TimeStamp)
end
else CellText := _('(not available)');
except
item.smsData := nil;
end;
end;
end;
procedure TfrmMsgView.ListMsgHeaderClick(Sender: TVTHeader;
Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
if Column = Sender.SortColumn then begin
if Sender.SortDirection = sdDescending then
Sender.SortDirection := sdAscending
else
Sender.SortDirection := sdDescending;
end
else
Sender.SortColumn := Column;
end;
procedure TfrmMsgView.RenderListView(sl: TStringList);
const
Sem: boolean = False;
var
i,j: Integer;
isNumber: boolean;
item: PListData;
Node: PVirtualNode;
dbfixed: boolean;
md: TFmaMessageData;
test: DWord;
begin
if Sem then exit;
Sem := True;
{ Clear view }
DoCloseDetails;
dbfixed := False;
SearchName := '';
SearchMode := smAll;
edSearchFor.Text := '';
edSearchForExit(nil);
FIsRendered := False;
lblFiltered.Visible := False;
{ Fill list }
try
if sl.Count <> 0 then NoItemsPanel.Visible := False;
if sl.Count > 99 then begin // show a message to user on large folder
Form1.Status(_('Building messages list, please wait...'),False);
Animate1.Top := ListMsg.Top + (ListMsg.Height - Animate1.Height) div 2 + 32;
Animate1.Color := ColorToRGB(clWindow);
Animate1.Visible := ListMsg.Height > 128;
Animate1.Active := Animate1.Visible;
if Animate1.Visible then NoItemsPanel.Visible := False;
end;
{ Clear view }
MemoMsgBody.Clear;//ADD
FCustomImage := True; //Force image reload
IsCustomImage := False;
ListMsg.BeginUpdate;
ListMsg.Clear;
ListMsg.EndUpdate;
Update;
{ Build message list }
ListMsg.BeginUpdate;
try
ListMsg.NodeDataSize := sizeof(TListData);
{ process DB }
if sl <> FRendered then
FRendered := nil;
FRenderCanceled := False;
i := 0;
test := GetTickCount;
while i < sl.Count do begin
if FRenderCanceled then break;
md := TFmaMessageData(sl.Objects[i]);
if md = nil then begin
Inc(i);
continue;
end;
Node := ListMsg.AddChild(nil);
try
item := ListMsg.GetNodeData(Node);
item.smsData := md;
// Check if smsData.From is number (can be alpha string)
isNumber := item.smsData.From = '';
for j := 1 to Length(item.smsData.From) do
if IsDelimiter('+0123456789', item.smsData.From, j) then begin
isNumber := True;
break;
end;
if isNumber then
item.from := Form1.ContactNumberByTel(item.smsData.From)
else
item.from := item.smsData.From;
item.sender := Form1.ExtractContact(item.from);
item.stateindex := md.MsgIndex; // index
if md.Location = mlME then begin // ME
item.ImageIndex := 14;
end
else if md.Location = mlSM then begin // SM
item.ImageIndex := 15;
end
else { if md.Location = mlPC then } begin // PC
if md.IsOutgoing then item.ImageIndex := 17
else item.ImageIndex := 16;
end;
// Direction Bit
if md.IsOutgoing then begin
if md.ReportRequested and not md.IsDelivered then
DoFindDeliveryReport(md);
end;
// Long SMS? - show only first SMS message
if (md.IsLong) and (not md.IsLongFirst) then begin
ListMsg.IsVisible[Node] := False;
if md.IsNew then begin
{ Don't set non-first Long SMS part as new flag }
md.IsNew := False;
if FindCmdLineSwitch('FIXDB') then begin
md.IsNew := False;
Log.AddMessageFmt(_('Database: Removed new message flag (DB Index: %d)'), [i], lsInformation);
dbfixed := True;
end;
end;
end;
if i mod 8 = 0 then begin
Application.ProcessMessages;
if Application.Terminated then break;
end;
except
ListMsg.DeleteNode(Node);
Log.AddMessageFmt(_('Database: Error loading data (DB Index %d)'), [i], lsError);
if FindCmdLineSwitch('FIXDB') then begin
sl[i] := '';
Log.AddMessageFmt(_('Database: Removed incorrect data (DB Index: %d)'), [i], lsInformation);
dbfixed := True;
end;
end;
Inc(i);
end;
{ All done }
FRendered := sl;
Log.AddMessageFmt('Rendering messages took: %d ms', [GetTickCount - test], lsDebug);
finally
Animate1.Visible := False;
Animate1.Active := False;
ListMsg.Sort(nil, ListMsg.Header.SortColumn, ListMsg.Header.SortDirection);
ListMsg.EndUpdate;
UpdatePropertiesStatus;
{
i := 0;
Node := ListMsg.GetFirstVisible;
while Assigned(Node) do begin
Inc(i);
Node := ListMsg.GetNextVisible(Node);
end;
}
i := ListMsg.VisibleCount;
Form1.Status(WideFormat(_('%d %s'),[i,ngettext('message','messages',i)]),False);
end;
finally
Sem := False;
NoItemsPanel.Visible := ListMsg.ChildCount[nil] = 0;
if dbfixed then
Form1.UpdateNewMessagesCounter(Form1.ExplorerNew.FocusedNode);
FIsRendered := True;
end;
end;
procedure TfrmMsgView.DoShowDetails(Node: PVirtualNode);
var
curr: PVirtualNode;
item: PListData;
sms: TSMS;
sl: TTntStringList;
i: Integer;
begin
if Assigned(Node) then begin
item := ListMsg.GetNodeData(node);
if item <> nil then begin
{ Create details dialog if needed }
if not Assigned(frmDetail) then frmDetail := TfrmDetail.Create(Self);
frmDetail.SMS := item.smsData;
if item.smsData.Location = mlME then // ME
frmDetail.edLocation.Text := _('FMA and Phone')
else
if item.smsData.Location = mlSM then // SM
frmDetail.edLocation.Text := _('FMA and SIM card')
else
{if item.smsData.Location = mlPC then} // PC
frmDetail.edLocation.Text := _('FMA only');
if IsLongSMSNode(node) then begin
{ Add full long SMS text, since it can't be obtained from PDU }
frmDetail.memoText.Text := GetNodeLongText(node);
sl := TTntStringList.Create;
sms := TSMS.Create;
try
{ Refill PDU memo with all Long SMS PDUs }
frmDetail.memoPDU.Clear;
GetNodeLongList(node,sl);
for i := 0 to sl.Count-1 do begin
frmDetail.memoPDU.Lines.Add(WideFormat(_('SMS Number: %d'),[i+1]));
curr := PVirtualNode(sl.Objects[i]);
if Assigned(curr) then begin
item := ListMsg.GetNodeData(curr);
sms.PDU := item.smsData.PDU;
if sms.IsOutgoing then
frmDetail.memoPDU.Lines.Add(WideFormat(_('Message Type: %s'),
['SMS SUBMIT'])) // do not localize
else
frmDetail.memoPDU.Lines.Add(WideFormat(_('Message Type: %s'),
['SMS DELIVER'])); // do not localize
frmDetail.memoPDU.Lines.Add(sLineBreak + item.smsData.PDU + sLineBreak);
end
else
frmDetail.memoPDU.Lines.Add(sLineBreak + _('Message part is missing.') + sLineBreak);
end;
finally
sms.Free;
sl.Free;
end;
end;
frmDetail.Show;
end;
end;
end;
procedure TfrmMsgView.Properties1Click(Sender: TObject);
var
Node :PVirtualNode;
begin
if Form1.ExplorerNew.FocusedNode = Form1.FNodeMsgDrafts then // just in case
exit;
Node := ListMsg.FocusedNode;
if Assigned(Node) then begin
Timer1.Enabled := False;
Timer1.Interval := 100;
Timer1.Enabled := True;
DoShowDetails(Node);
end;
end;
procedure TfrmMsgView.ExportList(FileType:Integer; Filename: WideString);
var
node: PVirtualNode;
item: PListData;
sl: TStringList;
wl: TTntStringList;
t: WideString;
s,ss,str: String;
i: Integer;
begin
if FileType <> 1 then begin
if MessageDlgW(_('FMA could Import only CSV message exports. Do you still want to continue exporting?'),
mtConfirmation, MB_YESNO or MB_DEFBUTTON2) <> ID_YES then
exit;
end;
case FileType of
1:begin//CSV
sl := TStringList.Create;
try
{ Write export header }
ss := '"Subject","Body","From: (Name)","From: (Address)","From: (Type)",'+ // do not localize
'"To: (Name)","To: (Address)","To: (Type)",'+ // do not localize
'"Fma Date","Fma State","Fma PDU","Fma IsNew"'; // do not localize
sl.add(ss);
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;
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;
for i := 0 to wl.Count-1 do begin
item := GetNodeData(PVirtualNode(wl.Objects[i]));
{ NOTE: every item should be quoted!!! Import depends on it }
ss := '"SMS","' + WideStringToUTF8String(Tnt_WideStringReplace(item.smsData.Text, '"', '""', [rfReplaceAll])) + '",'; // do not localize
s := item.smsData.From;
t := Form1.ExtractContact(item.from);
if item.smsData.IsOutgoing then begin // outgoing message
ss := ss + '"(Outgoing)","' + WideStringToUTF8String(item.from) + '","PHONE",'; // do not localize
ss := ss + '"' + WideStringToUTF8String(t) + '","' + s + '","PHONE",'; // do not localize
end
else begin
ss := ss + '"' + WideStringToUTF8String(t) + '","' + s + '","PHONE",'; // do not localize
ss := ss + '"(Incoming)","' + WideStringToUTF8String(item.from) + '","PHONE",'; // do not localize
end;
if item.smsData.TimeStamp > 0 then ss := ss + '"' + DateTimeToStr(item.smsData.TimeStamp) + '",'
else ss := ss + '"",';
ss := ss + '"' + IntToStr(item.stateindex) + '","' + item.smsData.PDU + '","' + IntToStr(byte(item.smsData.IsNew)) + '"';
sl.add(ss);
end;
finally
wl.Free;
end;
end;
except
end;
node := GetNext(node);
until node = nil;
end;
{ Write export body }
sl.SaveToFile(FileName);
finally
sl.Free;
end;
end;
2:begin//XML
sl := TStringList.Create;
try
sl.Add('<?xml version="1.0" encoding="utf-8" ?>'); // do not localize
sl.Add('<fma_messages>'); // do not localize
with ListMsg do begin
node := GetFirst;
repeat
try
if Selected[node] then begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -