Trsek Commander - Substitute of Norton Commander, pascal

Delphi & Pascal (česká wiki)
Přejít na: navigace, hledání
Category: Source in Pascal
tc.pngProgram: Tc.pas
File exe: Tc.exe
need: Main.pasMouse.pasT_wind.pas

The purpose of this program is to substitute Norton Commander. It has had a great beginning and this program is a result. However, as it is with other similar projects, this one couldn't move at one point. At present it is possible to view the files in the window which can be enlarged or moved voluntarily by a mouse.
{ MAIN.PAS                  Copyright (c) TrSek alias Zdeno Sekerak }
{ Cast kodu ktora sa prilinkuje k programu Tc.pas                   }
{                                                                   }
{ Datum:28.07.1996                            http://www.trsek.com  }
 
{ Zarovnava na nulu cislo ak je jedno ciferne 3->03 }
function No0(w : Word) : String;
var s:String;
begin
  Str(w:0,s);
  if Ord(s[0])=1 then s:='0'+s;
  No0:=s;
end;
 
{ vyrobi potrebny pocet medzier }
function nothing(poc:byte):string;
var noth:string;
begin
 noth:='';
 for poc:=poc downto 1 do noth:=noth+' ';
 nothing:=noth;
end;
 
{ Vyrobi vsetky pismena velke }
function UUpCase(noth:string):string;
var i:byte;
begin
 for i:=1 to ord(noth[0]) do noth[i]:=UpCase(noth[i]);
 UUpCase:=noth;
end;
 
{ je aktivny CTRL }
function ctrl_akt:boolean;
begin
 if (mem[0:$417] and 4) > 0 then ctrl_akt:=true
                            else ctrl_akt:=false;
end;
 
{ je aktivny ALT }
function alt_akt:boolean;
begin
 if (mem[0:$417] and 8) > 0 then alt_akt:=true
                            else alt_akt:=false;
end;
 
{ Vypise na obrazovku text znaky s poziciou x,y }
{ attr-atribut textu }
procedure writexy(x,y,attr:byte;znaky:string);
var i:byte;
begin
 for i:=1 to ord(znaky[0]) do
     obr^.znak_attr[y+1,x+i]:=(attr shl 8)+ord(znaky[i]);
end;
 
procedure konv_sub(meno_kon:pointer;atr:byte); { ak je subor prekonvertuje }
var meno:^string;                              { na male pismena }
    i:byte;
begin
 meno:=meno_kon;
 if (atr and $10)=0 then
    for i:=1 to ord(meno^[0]) do
        if (meno^[i] in ['A'..'Z']) then meno^[i]:=chr(ord(meno^[i])+32);
end;
 
{ presunie medzi strukturov DTA a zozanmom }
 
procedure presun(DTA:t_DTA;var subor:t_subor);
var i,y:byte;
begin
  subor.atr:=DTA.atr;           { atribut }
  subor.cas:=DTA.cas;           { neformatovany cas }
  subor.datum:=DTA.datum;       { neformatovany datum }
  subor.size:=DTA.size;         { velkost }
  subor.meno_kon:='';
  for i:=1 to 12 do subor.meno_kon:=subor.meno_kon+' ';
  i:=1;y:=10;                   { meno.koncovka }
  while (not(DTA.meno_kon[i] in [#0,#46]) and (i<13)) do begin
        subor.meno_kon[i]:=DTA.meno_kon[i];
        inc(i);
       end;
 
  if (DTA.meno_kon[i]<>#0) then begin
     inc(i);
     while (not(ord(DTA.meno_kon[i]) in [0]) and (i<13)) do begin
           subor.meno_kon[y]:=DTA.meno_kon[i];
           inc(i);inc(y);
          end;
    end;                                            { toto sa mi vobec nepaci }
  if (DTA.meno_kon[1]='.') then subor.meno_kon:='..          ';
  konv_sub(@subor.meno_kon,subor.atr);
end;
 
{ Aby som nemal 2xkrat tu istu rutinu v napl_f }
 
function t_findnext(cesta:string):byte;
var Reg:Registers;
begin
 Reg.AH:=$4f;           { zisti dalsi subor rutina DOS 21 4f }
 Reg.DS:=Seg(cesta);    { Segment ofset cesty }
 Reg.DX:=Ofs(cesta)+1;
 Intr($21,Reg);
 t_findnext:=Reg.AX;
end;
 
{ odstran medzeri z retazca }
function no_space(rret:string):string;
var ret:string;
begin
 ret:=rret;
 while (pos(' ',ret)>0) do delete(ret,pos(' ',ret),1);
 no_space:=ret;
end;
 
{ uprav cestu odstran posledne lomitku atd. }
 
procedure t_getdir(var cesta:string);
begin
 cesta:=no_space(cesta);
 {$I-}
 chdir(cesta);
 {$I+}
 getdir(0,cesta);
 if (cesta[ord(cesta[0])]='\') then cesta[0]:=chr(ord(cesta[0])-1);
end;
 
{ uvolni pamat po suboroch }
procedure uvolni_f(subor:pointer);
var p_subor,d_subor:^t_subor;
begin
 if (subor<>NIL) then begin
    p_subor:=subor;
    while (p_subor^.zani<>p_subor) do p_subor:=p_subor^.zani;
 
    while (p_subor^.pred<>p_subor) do begin
          d_subor:=p_subor;
          p_subor:=p_subor^.pred;
          FreeMem(d_subor, SizeOf(t_subor));
         end;
    FreeMem(p_subor, SizeOf(t_subor));
    okno.subor:=NIL;
   end;
end;
 
{ naplni obojsmerny zoznam menami suborov a vrati smernik na prvy z nich }
{ dir adresar bez posledneho \ filter napr. *.* Attr=ake atributy }
{ do poc vrati kolko ich nasiel }
 
function napln_f(filter:string;Attr:word;var poc:integer):pointer;
var Reg:Registers;
    cesta:string;
    DTA:t_DTA;
    p_subor,d_subor:^t_subor;    { pomocne pre presuny }
    pp:pointer;
begin
 uvolni_f(okno.subor);
 t_getdir(okno.cesta);
 Reg.AH:=$1a;           { nastav DTA rutina DOS 21 1a }
 Reg.DS:=Seg(DTA);
 Reg.DX:=Ofs(DTA);
 Intr($21,Reg);
 
 Reg.AH:=$4e;           { zisti prvy subor rutina DOS 21 4e }
 cesta:=okno.cesta+'\'+filter+chr(0);
 Reg.DS:=Seg(cesta);    { Segment ofset cesty }
 Reg.DX:=Ofs(cesta)+1;
 Reg.CX:=Attr;
 Intr($21,Reg);
 
 Reg.AX:=t_findnext(cesta);
 GetMem(p_subor, SizeOf(t_subor));      { vyrob prvy .. }
 presun(DTA,p_subor^);
 p_subor^.pred:=p_subor;                { predtym bolo NIL }
 p_subor^.zani:=p_subor;                { predtym bolo NIL }
 napln_f:=p_subor;
 poc:=0;                                { toto mozno bude neskor vadit }
 pp:=p_subor;
 okno.p_subor:=pp;
 okno.k_subor:=pp;
 
 while (Reg.AX=0) do begin
     Reg.AX:=t_findnext(cesta);
     if (Reg.AX=0) then begin
        GetMem(d_subor, SizeOf(t_subor));  { vyrob zoznam obojsmerny }
        d_subor^.pred:=p_subor;
        d_subor^.zani:=d_subor;            { predtym bolo NIL }
        p_subor^.zani:=d_subor;
        p_subor:=d_subor;
        p_subor^.oznac:=false;
        presun(DTA,p_subor^);
        inc(poc);
       end;
   end;
 okno.l_subor:=d_subor^.zani;
end;
 
{ zarovnaj retazec na potrebny pocet znakov }
function zarovnaj(ret:string;kolko:byte):string;
begin
 if (ord(ret[0])>kolko) then ret[0]:=chr(kolko);
 if (ord(ret[0])<kolko) then ret:=ret+nothing(kolko-ord(ret[0]));
 zarovnaj:=ret;
end;
 
{ orezava vypis do okna }
procedure twritexy(x,y,attr:integer;ret:string);
begin
 if (x<okno.xd) then
  if ((x+ord(ret[0]))>=okno.xd) then writexy(x,y,attr,zarovnaj(ret,okno.xd-x-1))
                               else writexy(x,y,attr,ret);
end;
 
{ vyznac pole posobnosti okna }
procedure kde_text_okno(m_okno:pointer);
var x,y:integer;
    okno:^t_okno;
begin
 okno:=m_okno;
 for x:=1 to 80 do                      { znuluj ostatne }
     for y:=1 to 25 do uziv_obr[x,y]:=0;
 
 for x:=okno^.xh+1 to okno^.xd-1 do               { toto je vnutro okna }
     for y:=okno^.yh+2 to okno^.yd-3 do uziv_obr[x,y]:=okno^.c_okna+144;
 
 for i:=okno^.xh to okno^.xd-2 do begin
   uziv_obr[i+1,okno^.yh]:=okno^.c_okna+16;         { horny riadok }
   uziv_obr[i+1,okno^.yh+1]:=okno^.c_okna+128;      { sipka hore }
   uziv_obr[i+1,okno^.yd]:=okno^.c_okna+80;         { dolny riadok }
   uziv_obr[i+1,okno^.yd-2]:=okno^.c_okna+160;      { sipka dole }
   uziv_obr[i+1,okno^.yd-1]:=okno^.c_okna+176;      { PSP + info file }
  end;
 
 for i:=okno^.yh to okno^.yd-2 do begin
   uziv_obr[okno^.xh,i+1]:=okno^.c_okna+112;       { lavy okraj }
   uziv_obr[okno^.xd,i+1]:=okno^.c_okna+48;        { pravy okraj }
  end;
 
 uziv_obr[okno^.xh,okno^.yh]:=okno^.c_okna;           { lavy horny }
 uziv_obr[okno^.xh,okno^.yd]:=okno^.c_okna+96;        { lavy dolny  }
 uziv_obr[okno^.xd,okno^.yh]:=okno^.c_okna+32;        { pravy horny }
 uziv_obr[okno^.xd,okno^.yd]:=okno^.c_okna+64;        { pravy dolny }
end;
 
 
{ vykresli textove okno }
procedure text_okno(o_full:t_full);
var fi,i,p:integer;
begin
 if (o_full=full) then
    okno.pocx:=trunc((okno.xd-okno.xh-2)/39)
   else
    okno.pocx:=trunc((okno.xd-okno.xh-2)/13);
 
 okno.pocy:=okno.yd-okno.yh-4;
 okno.poccel:=(okno.pocx+1)*okno.pocy;
 
 for i:=okno.xh to okno.xd-2 do begin
   writexy(i,okno.yh-1,okno.attr,'Í');
   writexy(i,okno.yd-1,okno.attr,'Í');
   uziv_obr[i+1,okno.yh]:=okno.c_okna+16;         { horny riadok }
   uziv_obr[i+1,okno.yd]:=okno.c_okna+80;         { dolny riadok }
   if (o_full in [brief,full]) then begin         { ak to nie je obycajne okno }
      writexy(i,okno.yd-3,okno.attr,'Ä');
      uziv_obr[i+1,okno.yh+1]:=okno.c_okna+128;      { sipka hore }
      uziv_obr[i+1,okno.yd-2]:=okno.c_okna+160;      { sipka dole }
      uziv_obr[i+1,okno.yd-1]:=okno.c_okna+176;      { PSP + info file }
     end;
  end;
 
 for i:=okno.yh to okno.yd-2 do begin
   writexy(okno.xh-1,i,okno.attr,'ş');
   writexy(okno.xd-1,i,okno.attr,'ş');
   uziv_obr[okno.xh,i+1]:=okno.c_okna+112;       { lavy okraj }
   uziv_obr[okno.xd,i+1]:=okno.c_okna+48;        { pravy okraj }
   if (i<okno.yd-3) then begin
      if (o_full=brief) then
         for p:=1 to okno.pocx do
             writexy(okno.xh+p*13-1,i,okno.attr,'ł');
      if (o_full=full) then
         for p:=0 to okno.pocx do
             for fi:=1 to po_full do
             twritexy(okno.xh+p*39+ro_full[fi],i,okno.attr,'ł');
     end;
  end;
 
 writexy(okno.xh-1,okno.yh-1,okno.attr,'É');
 writexy(okno.xh-1,okno.yd-1,okno.attr,'Č');
 writexy(okno.xd-1,okno.yh-1,okno.attr,'ť');
 writexy(okno.xd-1,okno.yd-1,okno.attr,'ź');
 
 uziv_obr[okno.xh,okno.yh]:=okno.c_okna;           { lavy horny }
 uziv_obr[okno.xh,okno.yd]:=okno.c_okna+96;        { lavy dolny  }
 uziv_obr[okno.xd,okno.yh]:=okno.c_okna+32;        { pravy horny }
 uziv_obr[okno.xd,okno.yd]:=okno.c_okna+64;        { pravy dolny }
 
 if (o_full=brief) then begin                   { pre brief }
    for p:=1 to okno.pocx do begin
        writexy(okno.xh+p*13-1,okno.yd-3,okno.attr,'Á');
        writexy(okno.xh+p*13-1,okno.yh-1,okno.attr,'Ń');
       end;
    for p:=1 to okno.pocx+1 do
        twritexy(okno.xh+p*13-13,okno.yh,okno.attr,'    Name    ');
   end;
 
 if (o_full=full) then begin                                    { pre full }
    for p:=0 to okno.pocx do
        for fi:=1 to po_full do begin
            twritexy(okno.xh+p*39+ro_full[fi],okno.yd-3,okno.attr,'Á');
            twritexy(okno.xh+p*39+ro_full[fi],okno.yh-1,okno.attr,'Ń');
           end;
    for p:=0 to okno.pocx do
        for fi:=1 to po_full do
            twritexy(okno.xh+p*39+mo_full[fi],okno.yh,okno.attr,okno_fm[fi]);
   end;
end;
 
function t_istr(cislo:longint;p_zar:byte): string;
var p_str:string;
begin
 str(cislo:p_zar,p_str);
 t_istr:=p_str;
end;
 
 
{ Vypis cas na poziciu kurzora }
procedure timexy(x,y:byte);
var h, m, s, hund : Word;
begin
 GetTime(h,m,s,hund);
 writexy(x,y,d_attr,No0(h)+':'+No0(m)+':'+No0(s));
end;
 
{ vypisuje cestu do predposledneho riadku }
procedure disp_path(cesta:string);
begin
 writexy(0,24,d_attr,zarovnaj(cesta,79));
end;
 
{ vypisuje cestu do nadpisu okna }
procedure path_okno(cesta:string);
begin
 cesta:=' '+cesta+'\ ';
 if (okno.xd-okno.xh)<8 then cesta:=cesta[2]+':';
 if (ord(cesta[0])>(okno.xd-okno.xh)) then cesta:=cesta[2]+':\..'+ copy(cesta,ord(cesta[0])-okno.xd+okno.xh+6,80);
 writexy(okno.xh+trunc((okno.xd-okno.xh-ord(cesta[0]))/2),okno.yh-1,d_attr,cesta);
end;
 
{ zo suboru vyrob riadok nazov velkost datum cas }
function disp(subor:pointer;mznak:char):string;
var k_subor:^t_subor;
    ret:string;
begin
 k_subor:=subor;
 if (k_subor^.atr and $10)=$10 then ret:=chr(16)+'SUB--DIR'+chr(17)
                               else ret:=t_istr(k_subor^.size,10);
 disp:=k_subor^.meno_kon+mznak+ret+mznak+
      No0(k_subor^.datum and $1f)+'.'+No0((k_subor^.datum and $1e0) shr 5)+'.'+No0((k_subor^.datum shr 9)+80)+mznak+
      No0((k_subor^.cas and $f800) shr 11)+':'+No0((k_subor^.cas and $7e0) shr 5)+mznak;
end;
 
{ vypise do okna subor full/brief }
procedure writexy_s(xh,x,y,d_attr:byte;o_full:t_full;subor:pointer);
var po_subor:^t_subor;
    ret:string;
    fi:byte;
begin
 if (subor=NIL) then
    if (o_full=full) then begin
                      ret:=nothing(38);
                      for fi:=1 to po_full do ret[ro_full[fi]+1]:='ł';
                      twritexy(xh+x*39,y,d_attr,ret)
                      end
                     else twritexy(xh+x*13,y,d_attr,nothing(12))
   else begin
    po_subor:=subor;
    if (o_full=full) then twritexy(xh+x*39,y,d_attr,disp(po_subor,'ł'))
                     else twritexy(xh+x*13,y,d_attr,po_subor^.meno_kon);
   end;
end;
 
{ vypise do okna potrebne subory }
procedure vypis_o(subor:pointer;k_subor:string;var kurx,kury:byte);
var po_subor:^t_subor;
    pp:pointer;
    i,x,y:integer;
begin
 i:=1;x:=0;y:=1;
 kurx:=0;kury:=1;
 po_subor:=subor;
 writexy_s(okno.xh,0,okno.yh+i,d_attr,okno.o_full,po_subor);
 while ( (po_subor^.zani<>po_subor) and (i<okno.poccel) ) do begin
        inc(i);inc(y);
        if (y>okno.pocy) then begin
            y:=1;inc(x);
           end;
        po_subor:=po_subor^.zani;
                                 { ak sa nasiel pri vypise }
        if (po_subor^.meno_kon=k_subor) then
           begin
            kurx:=x;kury:=y;
            pp:=po_subor;            { somarina, lebo Addr neviem rozchodit }
            okno.k_subor:=pp;
           end;
        writexy_s(okno.xh,x,okno.yh+y,d_attr,okno.o_full,po_subor);
       end;
 
 while (i<okno.poccel) do begin
        inc(i);inc(y);
        if (y>okno.pocy) then begin
            y:=1;inc(x);
           end;
        writexy_s(okno.xh,x,okno.yh+y,d_attr,okno.o_full,NIL);
       end;
 
 
 if (kurx=0) and (kury=1) then okno.k_subor:=subor;
 disp_path(okno.cesta);
 path_okno(okno.cesta);
end;
 
{ simuluje sipku hore }
procedure si_hore(var kurx,kury:byte);
begin
 dec(kury);
 if (kury<1) then begin
    kury:=1;
    if (kurx>0) then begin dec(kurx);kury:=okno.pocy;end
                else okno.p_subor:=okno.p_subor^.pred;
   end;
 okno.k_subor:=okno.k_subor^.pred;
end;
 
{ simuluje sipku dole }
procedure si_dole(var kurx,kury:byte);
begin
 inc(kury);
 if (okno.k_subor^.zani=okno.k_subor) then dec(kury);
    if (kury>okno.pocy) then begin
    kury:=okno.pocy;
    if (kurx<okno.pocx) then begin inc(kurx);kury:=1;end
                        else okno.p_subor:=okno.p_subor^.zani;
   end;
 okno.k_subor:=okno.k_subor^.zani;
end;
 
{ pri tahani mysou meni velkost okna }
procedure men_okno(ako:byte);
var x,y,but:byte;
    bla:byte;
begin
 repeat
  get_mouse(x,y,but);
 
  if (x<okno.xh) and (x>0) and (ako in [0,6,7]) then begin   { vlavo pohni }
      move_leri(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna,true);
      dec(okno.xh);dec(okno.xd);
     end;
 
  if (x>okno.xh) and (okno.xd<80) and (ako in [0,6,7]) then begin { vpravo pohni }
      move_leri(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna,false);
      inc(okno.xh);inc(okno.xd);
     end;
 
  if (y<okno.yh) and (y>0) and (ako in [0,1,2]) then begin   { hore pohni }
      move_updo(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna,true);
      dec(okno.yh);dec(okno.yd);
     end;
 
  if (y>okno.yh) and (okno.yd<23) and (ako in [0,1,2]) then begin { dole pohni }
      move_updo(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna,false);
      inc(okno.yh);inc(okno.yd);
     end;
 
  if (x<okno.xd) and (okno.xd>okno.xh+4) and (ako in [2,3,4]) then begin  { vlavo zmens }
      size_left(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna);
      dec(okno.xd);
      text_okno(okno.o_full);
      vypis_o(okno.p_subor,okno.k_subor^.meno_kon,bla,bla);
     end;
 
  if (x>okno.xd) and (okno.xd<80) and (ako in [2,3,4]) then begin { vpravo zvacsi }
      size_right(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna);
      inc(okno.xd);
      text_okno(okno.o_full);
      vypis_o(okno.p_subor,okno.k_subor^.meno_kon,bla,bla);
     end;
 
  if (y<okno.yd) and (okno.yd>okno.yh+5) and (ako in [4,5,6]) then begin  { hore zmensi }
      size_up(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna);
      dec(okno.yd);
      text_okno(okno.o_full);
      vypis_o(okno.p_subor,okno.k_subor^.meno_kon,bla,bla);
     end;
 
  if (y>okno.yd) and (okno.yd<23) and (ako in [4,5,6]) then begin { dole zvasci }
      size_down(okno.xh,okno.xd,okno.yh,okno.yd,okno.pole_okna);
      inc(okno.yd);
      text_okno(okno.o_full);
      vypis_o(okno.p_subor,okno.k_subor^.meno_kon,bla,bla);
     end;
 
until (but<>1);
kde_text_okno(@okno);
end;
 
{ prehodi poradie dvoch suborov }
procedure change_sub(t_prvy,t_druh:pointer);
var prvy,druh,tret:^t_subor;
    pom:pointer;
begin                                    
 prvy:=t_prvy;druh:=t_druh;
 
 pom:=prvy^.zani;
 prvy^.zani:=druh^.zani;
 druh^.zani:=pom;
 tret:=druh^.zani;
 tret^.pred:=druh;
                                               { ak je na konci pola }
 if (prvy^.zani=druh) then begin        
                            prvy^.zani:=prvy;
                            pom:=prvy;
                            okno.l_subor:=pom;
                           end
                      else begin
                            tret:=prvy^.zani;
                            tret^.pred:=prvy;
                           end;
 
 pom:=prvy^.pred;
 prvy^.pred:=druh^.pred;
 druh^.pred:=pom;                              
 tret:=prvy^.pred;
 tret^.zani:=prvy;                             { ak je na zaciatku pola }
 if (druh^.pred=prvy) then begin
                           druh^.pred:=druh;
                           okno.subor:=druh;
                          end
                     else begin
                           tret:=druh^.pred;
                           tret^.zani:=druh;
                          end;
end;
 
{ nevyhovuje/vyhovuje podmienka sortovania ??? }
function podmienka(prvy,druh:t_subor;ako:byte):boolean;
begin
 podmienka:=false;
 if prvy.meno_kon[1]<>'.' then
 case ako of
 
  1:if prvy.meno_kon>druh.meno_kon then podmienka:=true;
 
  2:if prvy.meno_kon>druh.meno_kon then podmienka:=true;
 
  3:if prvy.datum>druh.datum then podmienka:=true
       else
        if (prvy.datum=druh.datum) and (prvy.cas>druh.cas) then
            podmienka:=true;
 
  4:if prvy.size>druh.size then podmienka:=true;
 
 
  5:if prvy.meno_kon<druh.meno_kon then podmienka:=true;
 
  6:if prvy.meno_kon<druh.meno_kon then podmienka:=true;
 
  7:if prvy.datum<druh.datum then podmienka:=true
       else
        if (prvy.datum=druh.datum) and (prvy.cas<druh.cas) then
            podmienka:=true;
 
  8:if prvy.size<druh.size then podmienka:=true;
 
 end;
end;
 
{ usporiada subory }
procedure sortuj(ako:byte);
var prvy,druh,etal:^t_subor;
    h, m, s, hund : Word;
begin
 if okno.sort in [2,6] then begin
    prvy:=okno.subor;
    while (prvy^.zani<>prvy) do begin
       prvy^.meno_kon:=copy(prvy^.meno_kon,10,3)+copy(prvy^.meno_kon,1,9);
       prvy:=prvy^.zani;
      end;
    prvy^.meno_kon:=copy(prvy^.meno_kon,10,3)+copy(prvy^.meno_kon,1,9);
   end;
 
 prvy:=okno.subor;
 if (prvy^.meno_kon[1]='.') or (prvy^.meno_kon[4]='.') then prvy:=prvy^.zani;
 druh:=prvy;
 
 while (druh^.zani<>druh) do begin
  etal:=druh;
  prvy:=druh;
  while (prvy^.zani<>prvy) do begin
     prvy:=prvy^.zani;
     if ( ((etal^.atr and $10)<>$10) and ((prvy^.atr and $10)=$10))  then
         etal:=prvy
       else
        if podmienka(etal^,prvy^,ako) and
           ((etal^.atr and $10)=(prvy^.atr and $10)) then
           etal:=prvy;
     end;
  if (druh<>etal) then begin
      change_sub(druh,etal);
      druh:=etal^.zani;
     end
    else druh:=druh^.zani;
 end;
 
 if okno.sort in [2,6] then begin
    prvy:=okno.subor;
    while (prvy^.zani<>prvy) do begin
       prvy^.meno_kon:=copy(prvy^.meno_kon,4,9)+copy(prvy^.meno_kon,1,3);
       prvy:=prvy^.zani;
      end;
    prvy^.meno_kon:=copy(prvy^.meno_kon,4,9)+copy(prvy^.meno_kon,1,3);
   end;
end;