{$I-,F+,O+,X+}
unit FMClip;

interface

uses FileMngr;

procedure ClipCopyPrim(FManager: PPanel);
procedure ClipPastePrim(FManager: PPanel; Unselect: Boolean);

implementation

uses Objects, Drivers, Views, App, PanelRec, Swaps, ClipPrim, FindFile,
  FMAbort, BBSStuff, EditMsg, RevPos, LFN, Keyboard, TPString, Commands,
  Defaults;

procedure ClipCopyPrim(FManager: PPanel);
var
  I, SaveCount, MaxLen: Integer;
  SR: PPanelRec;
  PS: PFilesBBSRec;
  S, C: String;

procedure GetCopyStr;
var
  B: Byte;
begin
  with FManager^ do
  if (Status = stFull) and (Options and ofFilesBBS <> 0) and
     (Settings and seLongNames = 0) then
  begin
    PS := FilesBBS^.At(I);
    if (PS = nil) or (PS^.Text = nil) then C := ''
    else C := PS^.Text^;
    AddNameExt('', SR, S);
    lGetShortFileName(S, S);
    S := JustFileName(S);
    UpcaseSt(S);
    if BBSSpaces = 0 then B := Length(S) + 1
    else B := BBSWrapPos;
    PadSt(S, B);
    S := S + C;
  end
  else
  begin
    GetRecStr(SR, S);
    if InArchive then S := System.Copy(
      S, Length(Archiver^.ArcName^) + 2, 255);
  end;
end;

begin
  with FManager^ do
  begin
    if DiskClipStream = nil then Exit;
    DrawFMClipCopyStatus;
    if (Status >= stInfo) or
       ((SelCount > 0) and (Settings and seIgnoreSelection = 0)) then
    begin
      SetExpandClipAreaFlag;
      MaxLen := 0;
      SaveCount := ClipLines^.Count;
      if Status >= stInfo then for I := 0 to Dirinfo^.Count - 1 do
      begin
	PS := Dirinfo^.At(I);
	if PS = nil then S := ''
	else S := DelChar('|', PString(PS)^);
	PutClipLine(S);
	if not MarkColumns or (Length(S) > MaxLen) then
	  MaxLen := Length(S);
	if ClipOverflow then Break;
	if (KbdStatus = 1) and FMAbortAction then Break;
      end
      else for I := 0 to List^.Count - 1 do
      begin
	SR := List^.At(I);
	if SR^.Selected then
	begin
	  GetCopyStr;
	  PutClipLine(S);
	  if not MarkColumns or (Length(S) > MaxLen) then
	    MaxLen := Length(S);
	  if ClipOverflow then Break;
	end;
	if (KbdStatus = 1) and FMAbortAction then Break;
      end;
      SetOrExpandClipArea(SaveCount, MaxLen + 1);
      Message(Desktop, evBroadcast, cmUpdateViews, nil);
    end
    else
    begin
      I := Focused;
      SR := List^.At(I);
      GetCopyStr;
      Message(Application, evBroadcast, cmCopy, @S);
    end;
  end;
end;

procedure ClipPastePrim(FManager: PPanel; Unselect: Boolean);
var
  B: Byte;
  I, N: Integer;
  P: PPanelRec;
  E: TEvent;
  S: String;

procedure ScanLine;
begin
  B := 1;
  repeat
    TrimSt(S);
    if S = '' then Exit;
    while (B <= Length(S)) and (S[B] <> ' ') do Inc(B);
    N := 0;
    repeat
      FManager^.FindByName(Copy(S, 1, B - 1), N);
      if N = -1 then Break;
      with FManager^ do
      begin
	P := List^.At(N);
	if P^.Attr and $10 = 0 then SetSelect(P, not Unselect);
      end;
      Inc(N);
    until False;
    System.Delete(S, 1, B);
  until False;
end;

begin
  with FManager^ do
  begin
    if (DiskClipStream = nil) or not ClipAreaSelected or
       (Status > stTree) or (List^.Count = 0) then Exit;
    if PPanelWindow(Owner)^.State and sfSearching <> 0 then
    begin
      GetClipLine(ClipArea^.KB, S);
      for I := 1 to Length(S) do
      begin
	E.What := evKeyDown;
	E.CharCode := S[I];
	N := SearchPos;
	HandleEvent(E);
	if N = SearchPos then Exit;
      end;
      Exit;
    end;
    if Status = stTree then Exit;
    DrawStatusLine('Searching for the selected file names.');
    Message(Desktop, evBroadcast, cmUpdateViews, nil);
    for I := ClipArea^.KB to ClipArea^.KK do
    begin
      GetClipLine(I, S);
      ScanLine;
      if (KbdStatus = 1) and FMAbortAction then Break;
    end;
    FocusItem(Focused);
  end;
end;

end.