⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umsgview.pas

📁 FMA is a free1 powerful phone editing tool allowing users to easily manage all of the personal data
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        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 + -