Tom Wellige  

About Me
Home
My Blog

Favourites
Books
Drink

Open Source
Miscellaneous
CAN M3S Driver
HPShell
Web DB Editor
Open Queue

Miscellaneous
Wiki
Bookmark

My Programming Page - HPSHELL




HPSHELL

Contents of this page




EDITORS.PAS
{************************************************}
{                                                }
{   UNIT EDITORS                                 }
{   Copyright (c) 1992 Borland International     }
{   Copyright (c) 1993-98 by Tom Wellige         }
{                                                }
{   Part of HPShell                              }
{   Integrated Developing Environment            }
{   for HP48 calculators                         }
{                                                }
{   Author: Tom Wellige                          }
{   E-Mail: wellige@t-online.de                  }
{                                                }
{   These sources can be freely used as long     }
{   as their origin is stated in the             }
{   resulting program (code *and* exe)           }
{                                                }
{************************************************}

unit Editors;


[...]


procedure TEditor.ConvertText;
type
  sw = record s1, s2: word; end;
var
  Dlg : PDialog;
  R : TRect;
  P: PParser;
  Control, HScroll : PView;
  I: Word;
  Switch: sw;
  s1, s2: string;
  Pos: word;
begin
  Switch.s1:= $00; Switch.s2:= $00;

  R.Assign(0,0,47,17);
  New(Dlg, Init(R, GetString(436))); {'Text konvertieren'}

  with Dlg^ do
  begin
    Options:= Options or ofCentered;
    HelpCtx:= 41104;

    R.Assign(5, 1, 42, 12);
    Insert(New(P3D_Frame, Init(R)));

    R.Assign(13,3,34,5);
    Control := New(PRadiobuttons, Init(R,
      NewSItem(GetString(431),          {'~g~esamten Text'}
      NewSItem(GetString(432),Nil))));  {'~m~arkierten Text'}
    Insert(Control);

    R.Assign(12,2,18,3);                {'~T~ext:'}
    Insert(New(PLabel, Init(R, GetString(433), Control)));

    R.Assign(13,7,34,10);
    Control := New(PRadiobuttons, Init(R,
      NewSItem(GetString(437),          {'~P~C zu HP'}
      NewSItem(GetString(438),          {'~H~P zu PC'}
      NewSItem(GetString(439),Nil))))); {'~P~C zu PC'}
    Insert(Control);

    R.Assign(12,6,22,7);                {'~R~ichtung'}
    Insert(New(PLabel, Init(R, GetString(440), Control)));

    R.Assign(3,14,16,16);
    Control := New(PButton, Init(R, GetString(10), cmOK, bfDefault));
    Insert(Control);

    R.Assign(17,14,30,16);
    Control := New(PButton, Init(R, GetString(13), cmHelp, bfNormal));
    Insert(Control);

    R.Assign(31,14,44,16);
    Control := New(PButton, Init(R, GetString(12), cmCancel, bfNormal));
    Insert(Control);

    SelectNext(False);
  end;

  if Application^.ExecuteDialog(Dlg, @Switch) = cmOk then
  begin
    case Switch.s1 of
      $00: s1:= GetString(441);  {'gesamten Text'}
      $01: s1:= GetString(442);  {'markierten Text'}
    end;
    case Switch.s2 of
      $00: s2:= 'PC -> HP';
      $01: s2:= 'HP -> PC';
      $02: s2:= 'PC -> PC';
    end;

    P:= nil;
    ConvertDialog:= New(PConvertDlg, Init(@s1, @s2, cvManuell));
    Desktop^.Insert(ConvertDialog);

    Pos:= CurPtr;
    if Switch.s1 = $00 then SetCurPtr(BufLen, 0);

    case Switch.s1 of
      $00: P:= new(PParser, Init(@self, Switch.s2 + 4, 0, BufLen));
      $01: P:= new(PParser, Init(@self, Switch.s2 + 4, SelStart, SelEnd));
    end;

    if (Switch.s1 = $00) and (Pos <= BufLen) then
      SetCurPtr(Pos, 0);

    Desktop^.Delete(ConvertDialog);
    Dispose(ConvertDialog, Done);
    ConvertDialog:= nil;
    if Assigned(P) then Dispose(P, Done);
  end;
end;



procedure TEditor.SendText(ATitle: string; AHelpCtx: word);
var
  Dlg : PDialog;
  R : TRect;
  Control, HScroll : PView;
  I: Word;
  Switch: word;
begin
  Switch:= $00;
  R.Assign(0,0,47,12);
  Dlg:= New(PDialog, Init(R, ATitle));
  with Dlg^ do
  begin
    Options:= Options or ofCentered;
    HelpCtx:= AHelpCtx;

    R.Assign(5, 1, 42, 7);
    Insert(New(P3D_Frame, Init(R)));

    R.Assign(13,3,34,5);
    Control := New(PRadiobuttons, Init(R,
    NewSItem(GetString(431),           {'~g~esamten Text'}
    NewSItem(GetString(432),Nil))));   {'~m~arkierten Text'}
    Insert(Control);

    R.Assign(12,2,21,3);               {'~T~ext:'}
    Insert(New(PLabel, Init(R, GetString(433), Control)));

    R.Assign(3,9,16,11);
    Control := New(PButton, Init(R, GetString(10), cmOK, bfDefault));
    Insert(Control);

    R.Assign(17,9,30,11);
    Control := New(PButton, Init(R, GetString(11), cmHelp, bfNormal));
    Insert(Control);

    R.Assign(31,9,44,11);
    Control := New(PButton, Init(R, GetString(12), cmCancel, bfNormal));
    Insert(Control);

    SelectNext(False);
  end;
  if Application^.ExecuteDialog(Dlg, @Switch) = cmOk then
  begin
    with SendRec^ do
    begin
      case Switch of
        $00: begin
               Option:= 2;
               Size  := BufLen;
               Start := 0;
               Stop  := BufLen;
             end;
        $01: begin
               Option:= 1;
               Size  := SelEnd - SelStart;
               Start := SelStart;
               Stop  := SelEnd;
             end;
      end;
      Editor:= @self;
    end;
    Message(Application, evBroadCast, cmSendRecord, SendRec);
  end;
end;


procedure TEditor.Draw;
var i, s, ag, bg: word;
begin
  if DrawLine <> Delta.Y then
  begin
    DrawPtr := LineMove(DrawPtr, Delta.Y - DrawLine);
    DrawLine := Delta.Y;
  end;

  IsAString:= 0;
  IsAList:= 0;

  if (Delta.Y > 0) then
  begin
    s:= LineStart(DrawPtr)-1;
    for i:= 0 to s do
      if BufChar(i) = '"' then
        inc(IsAString)
      else
        { nur ausserhalb von Strings Ausschau nach Listen halten. }
        if (IsAString mod 2 = 0) then
        begin
          if BufChar(i) = '{' then inc(IsAList);
          if BufChar(i) = '}' then dec(IsAList);
        end;
  end;

  DrawLines(0, Size.Y, DrawPtr);
end;

procedure TEditor.DrawLines(Y, Count: Integer; LinePtr: Word);
var
  Color: Word;
  B: array[0..MaxLineLength - 1] of Word;
begin
  Color := GetColor($0201);
  while Count > 0 do
  begin
{    FormatLine(B, LinePtr, Delta.X + Size.X, Color);}
    if (Delta.X+Size.X) > (LineEnd(LinePtr)-LineStart(LinePtr)) then
      FormatLine(B, LinePtr, Delta.X + Size.X, Color) else
      FormatLine(B, LinePtr, LineEnd(LinePtr)-LineStart(LinePtr)+1, Color);

    if Displays and (not IsClipboard) then DrawDisplay(B, Y);

    if SyntaxHighlight and (not IsClipboard) then
{      if (Delta.X+Size.X) >= (LineEnd(LinePtr)-LineStart(LinePtr)) then
        DrawSyntax (B, Y, Delta.X + Size.X) else}
        DrawSyntax (B, Y, LineEnd(LinePtr)-LineStart(LinePtr));

    WriteBuf(0, Y, Size.X, 1, B[Delta.X]);
    LinePtr := NextLine(LinePtr);
    Inc(Y);
    Dec(Count);
  end;
end;


procedure TEditor.DrawDisplay(var B: array of word; Y: integer);
var
  Color, Tmp: Word;
  i: integer;

  function IsSelected(w: word): boolean;
  var Color: word;
  begin
    Color:= GetColor($0201);
    if Hi(w) = Hi(Color) then IsSelected:= true else IsSelected:= false;
  end;

  function IsDisplayLine: boolean;
  var
    d: boolean;
    Num: integer;
  begin
    d:= false;
    Y:= Delta.Y + Y;
    Num:= Y div (DisplayHight + DisplayDistance);
    if Num = 0 then
      if Y >= DisplayDistance then d:= true else d:= false
    else
      if Y >= (Num*(DisplayDistance+DisplayHight))+DisplayDistance then
        d:= true else d:= false;
    IsDisplayLine:= d;
  end;

begin
  if IsDisplayLine then
  begin
    Color:= GetColor($0304);
    for i:= 0 to DisplayLength - 1 do
      if not IsSelected(B[i]) then
      begin
        Tmp:= B[i] and $00FF;
        Tmp:= (Hi(Color)*256) + Tmp;
        B[i]:= Tmp;
      end else
      begin
        Tmp:= B[i] and $00FF;
        Tmp:= (Lo(Color)*256) + Tmp;
        B[i]:= Tmp;
      end;
  end;
end;


procedure TEditor.DrawSyntax (var B: array of word; Y: integer; MaxX: word);
var
  Pos, x1, x2: word;
  c, clrString, clrComment, clrList, clrError: word;
  s: TSyntaxString;

  function IsString(w: word): boolean;
  begin
    IsString:= (w and $0F00) = clrString;
  end;

  function IsComment(w: word): boolean;
  begin
    IsComment:= (w and $0F00) = clrComment;
  end;

  function IsList(w: word): boolean;
  begin
    IsList:= (w and $0F00) = clrList;
  end;

  procedure ScanForStrings;
  var i: word;
  begin
    for i:= 0 to MaxX do
    begin
      if Lo(B[i]) = ord('"') then
        if (IsAString mod 2 = 0) then
        begin
          inc(IsAString);            { String Anfang                      }
        end else
        begin
          B[i]:= B[i] and $F0FF;     { String beenden, " aber noch farbig }
          B[i]:= B[i] or clrString;
          inc(IsAString);
        end;
      if (IsAString mod 2 <> 0) then
      begin
        B[i]:= B[i] and $F0FF;       { String farbig darstellen           }
        B[i]:= B[i] or clrString;
      end;
    end;
  end;

  procedure ReScanForStrings;
  var i: word;
  begin
    for i:= 1 to MaxX do
      if IsString(B[i]) and IsComment(B[i-1]) then
      begin
        B[i]:= B[i] and $F0FF;
        B[i]:= B[i] or clrComment;
      end;
  end;

  procedure ScanForComments;
  var
    i: word;
    IsAComment: boolean;
  begin
    IsAComment:= false;
    for i:= 0 to Delta.X + Size.X do
    begin
      if Lo(B[i]) = ord('@') then
        if not IsString(B[i]) then
          if (not IsAComment) then
          begin
            IsAComment:= true;       { Kommentar Anfang                   }
          end else
          begin
            B[i]:= B[i] and $F0FF;   { Kommentar Ende, @ aber noch farbig }
            B[i]:= B[i] or clrComment;
            IsAComment:= false;
          end;
      if (not IsString(B[i])) and IsAComment then
      begin
        B[i]:= B[i] and $F0FF;       { Kommentar farbig darstellen        }
        B[i]:= B[i] or clrComment;
      end;
    end;
  end;

  procedure ScanForLists;

     function IsWhat(i: integer): integer;
     begin
       if i < 0 then IsWhat:= 0 else
       if i = 0 then IsWhat:= 1 else
                     IsWhat:= 2;
     end;

  var
    i: word;
  begin
    for i:= 0 to MaxX do
    begin
      if (not IsString(B[i])) and (not IsComment(B[i])) then
      begin

        case IsWhat(IsAlist) of

          0: { kleiner Null }
             begin
               if Lo(B[i]) = ord('{') then
               begin
                 B[i]:= B[i] and $00FF;
                 B[i]:= B[i] or clrError;
               end;
               if Lo(B[i]) = ord('}') then
               begin
                 B[i]:= B[i] and $00FF;
                 B[i]:= B[i] or clrError;
               end;
             end;
          1: { gleich Null }
             begin
               if Lo(B[i]) = ord('{') then
               begin
                 B[i]:= B[i] and $F0FF;
                 B[i]:= B[i] or clrList;
                 inc(IsAList);
               end;
               if Lo(B[i]) = ord('}') then
               begin
                 B[i]:= B[i] and $00FF;
                 B[i]:= B[i] or clrError;
                 dec(IsAList);
               end;
             end;
          2: { groesser Null }
             begin
               B[i]:= B[i] and $F0FF;
               B[i]:= B[i] or clrList;
               if Lo(B[i]) = ord('{') then inc(IsAList);
               if Lo(B[i]) = ord('}') then dec(IsAList);
             end;
        end;

      end;
    end;
  end;

  procedure PutColor(c, x1, x2: word);
  var i: word;
  begin
    for i:= x1 to x2 do
    begin
        B[i]:= B[i] and $F0FF;       { Keyword farbig darstellen         }
        B[i]:= B[i] or c;
      end;
  end;

  function GetWord(var Pos, x1, x2: word): TSyntaxString;
  var
    i: word;
    s: TSyntaxString;
  begin
    while IsComment(B[Pos]) or IsString(B[Pos]) or
          IsList(B[Pos]) or (Lo(B[Pos]) = ord(' ')) do inc(Pos);
    x1:= Pos;
    while (not IsComment(B[Pos]))  and
          (not IsString(B[Pos]))   and
          (not IsList(B[Pos]))     and
          (Lo(B[Pos]) <> ord(' ')) and
          (Lo(B[Pos]) <> 10)       and
          (Lo(B[Pos]) <> 13)       and
          (Pos < Delta.X+Size.X)   do inc(Pos);
    x2:= Pos-1;
    s:= '';
    if (x2 - x1) > SizeOf(TSyntaxString) then
      x1:= x2 - SizeOf(TSyntaxString);
    for i:= x1 to x2 do s:= s + chr(Lo(B[i]));
    GetWord:= s;
  end;

begin
  { Default-Werte }
  clrComment:= $0100;
  clrString := $0F00;
  clrList   := $0500;
  clrError  := $4F00;
  { Aktuelle Werte Laden }
  SyntaxList^.GetColor('@Comments',    clrComment);
  SyntaxList^.GetColor('" Strings "',  clrString);
  SyntaxList^.GetColor('{ Lists }',    clrList);

  ScanForStrings;       { Strings    }
  ScanForComments;      { Kommentare }
  ScanForLists;         { Listen }
  ReScanForStrings;     { Strings innerhalb von Kommentaren oder Listen }

  Pos := 0;
  while Pos < Delta.X+Size.X do
  begin
    s:= GetWord(Pos, x1, x2);
    if SyntaxList^.GetColor(s, c) then
      PutColor(c, x1, x2);
  end;
end;


[...]

page up


HPTRANS.PAS
{************************************************}
{                                                }
{   UNIT HPTrans   Transfer-Routinen             }
{   Copyright (c) 1994-98 by Tom Wellige         }
{                                                }
{   Part of HPShell                              }
{   Integrated Developing Environment            }
{   for HP48 calculators                         }
{                                                }
{   Author: Tom Wellige                          }
{   E-Mail: wellige@t-online.de                  }
{                                                }
{   These sources can be freely used as long     }
{   as their origin is stated in the             }
{   resulting program (code *and* exe)           }
{                                                }
{************************************************}

(* 28.04.95  Fehlermeldungen im Klartext hinzugefgt.                  *)
(* 01.05.95  Fehlermeldungen erweitert.                                *)
(* 01.05.95  CHECKIFFILESARETHERE:                                     *)
(*            - Fehler in Nummernberechnung entf.                      *)
(*            - Abfrage hinzugefgt, ob umbenannt werden soll.         *)
(* 14.05.95  Fehlerabfrage, ob w„hrend šbertragung ein Fehler aufge-   *)
(*             treten ist ( 0 < w < 256 )                              *)
(* 28.06.95  DeleteHPHeaders: Check l„uft mittels Block-Fkt., so daá   *)
(*             er unabh„ngig von der Zeilenl„nge wird -> GROBs !       *)
(*           DeleteBrqckets : Check l„uft mittels Block-Fkt., so daá   *)
(*             er unabh„ngig von der Zeilenl„nge wird -> GROBs !       *)
(* 08.12.98  MakeKermitFile: Anstelle von "*.*" bzw. "*." wird nun     *)
(*             pro Datei eine "send" Zeile eingefgt.                  *)

unit HPTrans;

{$O+,F+}

interface

uses
  Dos, Objects, Drivers, App, Views, Dialogs, MsgBox,
  MultiF, MsgObj, Tone,
  TWApp, TWMsgBox, TWWindow, TWDialog, TWGlobal, TWCommon, TWDos,
  HPGlobal, HPChars, HPProt, HPPort;

const
  kmSend          = 1;
  kmSendBinary    = 2;
  kmReceive       = 3;
  kmReceiveBinary = 4;


(* ermittelt alle Files in beliebigem Verzeichnis *)
function GetFileList(d: string): PFileNames;
(* berprft Files nach Namesregeln fr HP *)
function CheckFileNames(List: PFileNames): boolean;
(* kopiert Files in beliebiges Verzeichnis *)
function CopyFiles(List: PFileNames; d: string): boolean;
(* l”scht alle Dateien im Verzeichnis *)
function DeleteFiles(d: string): boolean;
(* Fgt mehrere Dateien zu einer zusammen *)
(* gibt FALSE und FRESULT=0 zurck, wenn Speicherfehler auftritt. *)
function MergeFiles(var List: PFileNames; FName: string): boolean;

(* berprft, ob Datei schon vorhanden ist, und benennt ggf. um *)
procedure CheckIfFilesAreThere(var List: PFileNames; d: string);


(* konvertiert Files *)
function ConvertFiles(List: PFileNames; AOption: word): boolean;
(* l”scht HP-Header aus Dateien *)
function DeleteHPHeaders(List: PFileNames): boolean;
(* l”scht Programmklammern *)
function DeleteBrackets(List: PFileNames): boolean;

(* Liefert Aufrufparameter fr externes Protokoll zurck *)
function CalcExternalParameters(p: string): string;


(* Ruft KERLITE.EXE zum Senden auf *)
procedure SendKermitProtocol(binary: boolean; List: PFileNames);
(* Ruft KERLITE.EXE zum Empfangen auf *)
function ReceiveKermitProtocol(binary: boolean): boolean;
(* Ruft externes Protokoll zum Senden auf *)
procedure SendExternalProtocol;
(* Ruft externes Protokoll zum Empfangen auf *)
function ReceiveExternalProtocol: boolean;


(* Erzeugt MSKERMIT.INI Datei fr KERLITE.EXE *)
function MakeKermitFile(Option: word; List: PFileNames): boolean;

type
  PHPInputLine = ^THPInputLine;
  THPInputLine = object(TInputLine)
    function Valid(Command: word): boolean; virtual;
  end;


implementation

type
  PWord = ^word;

(********************************************************************)
(**                     THPInputLine                               **)
(********************************************************************)

function THPInputLine.Valid(command: word): boolean;
var
  Ok: boolean;
  i: integer;
  Event: TEvent;
begin
  Ok:= true;
  if length(Data^)>0 then
    if not (command= cmCancel) then
    begin
      if not CheckObjectName(Data^) then
      begin
        Ok:= false;
        OneStringRec:= Data;
        { Der Variablenname "%s" ist nach der HP48-Namenskonvention ungltig.}
        FormatStr(ToFormatString, GetString(1312), OneStringRec);
        ErrorBox(#3+ToFormatString, nil, mfOkBeep);
        Event.What:= evCommand;
        Event.Command:= 234;  { Hilfefenster "Namengebung" }
        Application^.PutEvent(Event);
        Select;
      end;
    end;
  if Ok then valid:= inherited Valid(Command) else valid:= false;
end;



(********************************************************************)
(**               procedure SendKermitProtocol                     **)
(********************************************************************)

procedure SendKermitProtocol(binary: boolean; List: PFileNames);
var
  ok: boolean;
  s: string;
begin
  if not binary then
    ok:= MakeKermitFile(kmSend, List) else
    ok:= MakeKermitFile(kmSendBinary, List);
  if ok then
  begin
    s:= Dirs.Prog + 'kerlite';
    Message(Application, evCommand, cmCallProtocol, @s);
    if (CallReturn < 256) and (CallReturn > 0) then
         {'šbetragungsprotokoll wurde durch den Benutzer oder
           einen Fehler abgebrochen.'}
      ErrorBox(#3+GetString(1461), nil, mfOkBeep);
    FDelete(Dirs.Temp + 'MSKERMIT.INI');
  end;
end;


(********************************************************************)
(**               procedure ReceiveKermitProtocol                  **)
(********************************************************************)

function ReceiveKermitProtocol(binary: boolean): boolean;
var
  ok: boolean;
  s: string;
begin
  if not binary then
    ok:= MakeKermitFile(kmReceive, nil) else
    ok:= MakeKermitFile(kmReceiveBinary, nil);
  if ok then
  begin
    s:= Dirs.Prog + 'kerlite';
    Message(Application, evCommand, cmCallProtocol, @s);
    if (CallReturn < 256) and (CallReturn > 0) then
         {'šbetragungsprotokoll wurde durch den Benutzer oder
           einen Fehler abgebrochen.'}
      ErrorBox(#3+GetString(1461), nil, mfOkBeep);
    FDelete(Dirs.Temp + 'MSKERMIT.INI');
  end;
  ReceiveKermitProtocol:= CallReturn = 0;
end;


(********************************************************************)
(**               procedure MakeKermitFile                         **)
(********************************************************************)

function MakeKermitFile(Option: word; List: PFileNames): boolean;
var
  INI: Text;
  p: PFileRec;
  i: integer;
begin
  assign(INI, Dirs.Temp + 'MSKERMIT.INI');
  {$I-} rewrite(INI); {$I+}
  if IOresult <> 0 then
  begin
    {'Steuerdatei fr KERLITE.EXE konnte nicht erstellt werden.'}
    ErrorBox(#3+GetString(1420), nil, mfOkBeep);
    MakeKermitFile:= false;
    Exit;
  end;

  writeln(INI, '; FILE MSKERMIT.INI');
  writeln(INI, '; ');
  writeln(INI, '; Created by HPShell ' + ShellVer + ' ' + CopyRightStr);
  writeln(INI, '; ');
  writeln(INI, '; Do NOT make any changes in this file since it will be overwritten');
  writeln(INI, '; each time you start a transmission between PC and HP48 !');
  writeln(INI, '; ');
  writeln(INI);

  writeln(INI, '; Parameter');
  writeln(INI, 'set port com', ComPort.COM+1);
  case ComPort.PORT[ComPort.COM] of
    0: writeln(INI, 'set com', ComPort.COM+1, ' \x03f8 ', ComPort.IRQ[ComPort.COM]+2);
    1: writeln(INI, 'set com', ComPort.COM+1, ' \x02f8 ', ComPort.IRQ[ComPort.COM]+2);
    2: writeln(INI, 'set com', ComPort.COM+1, ' \x03e8 ', ComPort.IRQ[ComPort.COM]+2);
    3: writeln(INI, 'set com', ComPort.COM+1, ' \x02e8 ', ComPort.IRQ[ComPort.COM]+2);
  end;
  case ComPort.BAUD of
    0: writeln(INI, 'set speed 1200');
    1: writeln(INI, 'set speed 2400');
    2: writeln(INI, 'set speed 4800');
    3: writeln(INI, 'set speed 9600');
  end;
  case ComPort.PARITY of
    0: writeln(INI, 'set parity none');
    1: writeln(INI, 'set parity even');
    2: writeln(INI, 'set parity odd');
    3: writeln(INI, 'set parity space');
    4: writeln(INI, 'set parity mark');
  end;
  writeln(INI, 'set block-check 3');
  writeln(INI);

  writeln(INI, '; Prompt');
  writeln(INI, 'set prompt HPShell-Kermit>');
  writeln(INI);

  writeln(INI, '; Transmission');
  if Option in [kmSendBinary, kmReceiveBinary] then
                                writeln(INI, 'set file type binary');
  case Option of
    kmReceive, kmReceiveBinary:
      begin
        writeln(INI, 'receive');
      end;

    kmSend, kmSendBinary:
      begin
        { pro Datei eine "send" Zeile einfgen }
        for i:= 0 to List^.Count-1 do
        begin
          p:= PFileRec(List^.At(i));
          writeln(INI, 'send ' + p^.Name);
        end;
      end;
  end;
  writeln(INI);

  writeln(INI, '; Quit');
  writeln(INI, 'quit');

  close(INI);

  FCopy(Dirs.Temp + 'MSKERMIT.INI', Dirs.Prog + 'MSKERMIT.INI');

  MakeKermitFile:= true;
end;


(********************************************************************)
(**               procedure SendExternalProtocol                   **)
(********************************************************************)

procedure SendExternalProtocol;
var
  s, p: string;
  i, y: integer;
  l: PFileNames;
  r: PFileRec;
begin
  s:= CalcExternalParameters(Protocol.Field2);  (* senden *)
  if Pos('*.*', s) = 0 then
  begin
    p:= '';
    l:= GetFileList(Dirs.Temp);
    if assigned(l) then
    begin
      for i:= 0 to l^.Count-1 do
      begin
        r:= PFileRec(l^.at(i));
        y:= length(r^.Name);
        while r^.Name[y] <> '\' do dec(y);
        System.Delete(r^.Name, 1, y);
        if Pos('.', r^.Name) = 0 then r^.Name:= r^.Name + '.';
        p:= p + r^.Name + ' ';
      end;
      p:= copy(p, 1, length(p)-1);
      Dispose(l, done);
    end;
    s:= s + ' ' + p;
  end;
  Message(Application, evCommand, cmCallProtocol, @s);
  if (CallReturn < 256) and (CallReturn > 0) then
       {'šbetragungsprotokoll wurde durch den Benutzer oder
         einen Fehler abgebrochen.'}
    ErrorBox(#3+GetString(1461), nil, mfOkBeep);
end;


(********************************************************************)
(**               procedure ReceiveExternalProtocol                **)
(********************************************************************)

function ReceiveExternalProtocol: boolean;
var
  s: string;
begin
  s:= CalcExternalParameters(Protocol.Field3);  (* empfangen *)
  Message(Application, evCommand, cmCallProtocol, @s);
  if (CallReturn < 256) and (CallReturn > 0) then
       {'šbetragungsprotokoll wurde durch den Benutzer oder
         einen Fehler abgebrochen.'}
    ErrorBox(#3+GetString(1461), nil, mfOkBeep);
  ReceiveExternalProtocol:= CallReturn = 0;
end;


(********************************************************************)
(**               function CalcExternalParamters                   **)
(********************************************************************)

function CalcExternalParameters(p: string): string;
const
  BaudArray  : array[0..3] of string = ('1200','2400','4800','9600');
  ParityArray: array[0..4] of string = ('NONE','EVEN','ODD','SPACE','MARK');
  PortArray  : array[0..3] of string = ('03F8','02F8','03E8','02E8');
var
  s: string;

  procedure Replace(var s: string; old, new: string);
  var
    i: integer;
    u: string;
  begin
    u:= UpString(s);
    while Pos(old, u) <> 0 do
    begin
      i:= Pos(old, u);
      Delete(s, i, length(old));
      Insert(new, s, i);
      u:= UpString(s);
    end;
  end;

begin

  str(ComPort.COM+1, s);
  Replace(p, '#COM', s);

  s:= BaudArray[ComPort.Baud];
  Replace(p, '#BAUD', s);

  s:= ParityArray[ComPort.Parity];
  Replace(p, '#PARITY', s);

  s:= PortArray[ComPort.COM];
  Replace(p, '#PORT', s);

  str(ComPort.IRQ[ComPort.COM]+2, s);
  Replace(p, '#IRQ', s);

  CalcExternalParameters:= p
end;


(********************************************************************)
(**                function DeleteBrackets                         **)
(********************************************************************)

function DeleteBrackets(List: PFileNames): boolean;
const TempFile : string = '~DELBRAC.TMP';
type
  PBuff = ^TBuff;
  TBuff = array[1..2048] of byte;   (* BuffergrӇe 2kB ! *)

  procedure CheckBrackets(Buff: PBuff; var NumRead: word);
  var i, j: integer;
  begin
    if (chr(Buff^[1]) = '\') and (chr(Buff^[2]) = '<') and
       (chr(Buff^[3]) = '<') then
    begin
      i:= 1;
      while Buff^[i] <> 32 do inc(i);
      inc(i);
      for j:= i to NumRead do Buff^[j-i+1]:= Buff^[j];
      NumRead:= NumRead - i + 1;
    end;
  end;

var
  org, tmp  : file;
  org2, tmp2: file of char;
  i: integer;
  j,k: longint;
  b: char;
  ok: boolean;
  s, error, number: string;
  p: PFileRec;
  W: PMessageWindow;
  Buff: PBuff;
  NumRead, NumWritten: word;
begin
  ok:= false;
  FResult:= 0;
  for i:= 0 to List^.Count-1 do
  begin
    p:= PFileRec(List^.At(i));
    OneStringRec:= PString(@p^.Name);  {'Datei: %s'}
    FormatStr(s, GetString(906), OneStringRec);
    W:= New(PMessageWindow, Init('Deleting Brackets...', @s));
    Desktop^.Insert(W);

    assign(org,  p^.Name);
    assign(org2, p^.Name);
    assign(tmp,  TempFile);
    assign(tmp2, TempFile);
    {$I-} reset(org,1); {$I+}
    FResult:= IOresult;
    if FResult <> 0 then
    begin
      Number:= '1';
      str(FResult, Error);
      TwoStringRec.s1:= PString(@Number);
      TwoStringRec.s2:= PString(@Error);
         {'Fehler (%s,%s) beim Entfernen der Programmklammern.'}
      ErrorBox(#3+GetString(1063), @TwoStringRec, mfOkBeep);
    end else
    begin
      {$I-} rewrite(tmp,1); {$I+}
      FResult:= IOresult;
      if FResult<> 0 then
      begin
        Number:= '2';
        str(FResult, Error);
        TwoStringRec.s1:= PString(@Number);
        TwoStringRec.s2:= PString(@Error);
           {'Fehler (%s,%s) beim Entfernen der Programmklammern.'}
        ErrorBox(#3+GetString(1063), @TwoStringRec, mfOkBeep);
      end else
      begin
        if MaxAvail < SizeOf(Buff^) then ok:= false else
        begin
          New(Buff);
          j:= 1;
          repeat
            BlockRead(org, Buff^, SizeOf(Buff^), NumRead);
            if j = 1 then CheckBrackets(Buff, NumRead);
            BlockWrite(tmp, Buff^, NumRead, NumWritten);
            inc(j);
          until (NumRead = 0) or (NumWritten <> NumRead);
          Dispose(Buff);

          close(org);
          close(tmp);

          reset(tmp2);
          j:= filesize(tmp2)-1;
          seek(tmp2, j);
          read(tmp2, b);
          while b in [#10,#13,#32,'>','\'] do
          begin
            dec(j);
            seek(tmp2, j);
            read(tmp2, b);
          end;

          seek(tmp2, 0);
          rewrite(org2);

          for k:= 0 to j do
          begin
            read (tmp2, b);
            write(org2, b);
          end;

          close(org2);
          close(tmp2);

          ok:= FDelete(TempFile);
          if not ok then
          begin
            Number:= '3';
            str(FResult, Error);
            TwoStringRec.s1:= PString(@Number);
            TwoStringRec.s2:= PString(@Error);
               {'Fehler (%s,%s) beim Entfernen der Programmklammern.'}
            ErrorBox(#3+GetString(1063), @TwoStringRec, mfOkBeep);
          end;
        end;
      end;
    end;
    Desktop^.Delete(W);
    Dispose(W, Done);
  end;
  DeleteBrackets:= ok;
end;


(********************************************************************)
(**                function DeleteHPHeaders                        **)
(********************************************************************)

function DeleteHPHeaders(List: PFileNames): boolean;
const TempFile : string = '~DELHEAD.TMP';
type
  PBuff = ^TBuff;
  TBuff = array[1..2048] of byte;   (* BuffergrӇe 2kB ! *)

  procedure CheckHeader(Buff: PBuff; var NumRead: word);
  var i, j: integer;
  begin
    if (chr(Buff^[1]) = '%') and (chr(Buff^[2]) = '%') and
       (chr(Buff^[3]) = 'H') and (chr(Buff^[4]) = 'P') then
    begin
      i:= 1;
      while Buff^[i] <> 10 do inc(i);
      inc(i);
      for j:= i to NumRead do Buff^[j-i+1]:= Buff^[j];
      NumRead:= NumRead - i + 1;
    end;
  end;

var
  org, tmp: file;
  i, j: integer;
  ok: boolean;
  s, error, number: string;
  p: PFileRec;
  W: PMessageWindow;
  Buff: PBuff;
  NumRead, NumWritten: word;
begin
  ok:= false;
  FResult:= 0;
  for i:= 0 to List^.Count-1 do
  begin
    p:= PFileRec(List^.At(i));
    OneStringRec:= PString(@p^.Name);  {'Datei: %s'}
    FormatStr(s, GetString(906), OneStringRec);
    W:= New(PMessageWindow, Init('Deleting Header...', @s));
    Desktop^.Insert(W);

    assign(org, p^.Name);
    assign(tmp, TempFile);
    {$I-} reset(org,1); {$I+}
    FResult:= IOresult;
    if FResult <> 0 then
    begin
      Number:= '1';
      str(FResult, Error);
      TwoStringRec.s1:= PString(@Number);
      TwoStringRec.s2:= PString(@Error);
         {'Fehler (%s,%s) beim Entfernen des šbertragungsheaders.'}
      ErrorBox(#3+GetString(1061), @TwoStringRec, mfOkBeep);
    end else
    begin
      {$I-} rewrite(tmp,1); {$I+}
      FResult:= IOresult;
      if FResult<> 0 then
      begin
        Number:= '2';
        str(FResult, Error);
        TwoStringRec.s1:= PString(@Number);
        TwoStringRec.s2:= PString(@Error);
           {'Fehler (%s,%s) beim Entfernen des šbertragungsheaders.'}
        ErrorBox(#3+GetString(1061), @TwoStringRec, mfOkBeep);
      end else
      begin
        if MaxAvail < SizeOf(Buff^) then ok:= false else
        begin
          New(Buff);
          j:= 1;
          repeat
            BlockRead(org, Buff^, SizeOf(Buff^), NumRead);
            if j = 1 then CheckHeader(Buff, NumRead);
            BlockWrite(tmp, Buff^, NumRead, NumWritten);
            inc(j);
          until (NumRead = 0) or (NumWritten <> NumRead);
          Dispose(Buff);

          close(org);
          close(tmp);

          ok:= FDelete(p^.Name);
          if not ok then
          begin
            Number:= '3';
            str(FResult, Error);
            TwoStringRec.s1:= PString(@Number);
            TwoStringRec.s2:= PString(@Error);
               {'Fehler (%s,%s) beim Entfernen des šbertragungsheaders.'}
            ErrorBox(#3+GetString(1061), @TwoStringRec, mfOkBeep);
          end else
          begin
            ok:= FRename(TempFile, p^.Name);
            if not ok then
            begin
              Number:= '4';
              str(FResult, Error);
              TwoStringRec.s1:= PString(@Number);
              TwoStringRec.s2:= PString(@Error);
                 {'Fehler (%s,%s) beim Entfernen des šbertragungsheaders.'}
              ErrorBox(#3+GetString(1061), @TwoStringRec, mfOkBeep);
            end;
          end;
        end;
      end;
    end;
    Desktop^.Delete(W);
    Dispose(W, Done);
  end;
  DeleteHPHeaders:= ok;
end;


(********************************************************************)
(**                   function ConvertFiles                        **)
(********************************************************************)

function ConvertFiles(List: PFileNames; AOption: word): boolean;
var
  P: PParser;
  s, f: string;
  i: integer;
  rec: PFileRec;
begin
  for i:= 0 to List^.Count-1 do
  begin
    rec:= PFileRec(List^.At(i));
    s:= rec^.Name;
    case AOption of
      psPCtoHP, psTextPCtoHP: f:= 'PC -> HP';
      psHPtoPC, psTextHPtoPC: f:= 'HP -> PC';
    end;
    ConvertDialog:= New(PConvertDlg, Init(@s, @f, cvAutomatisch));
    Desktop^.Insert(ConvertDialog);
    P:= new(PParser, Init(@rec^.Name, AOption, 0, 0));
    Desktop^.Delete(ConvertDialog);
    Dispose(ConvertDialog, Done);
    ConvertDialog:= nil;
    if assigned(P) then Dispose(P, Done);
  end;
end;


(********************************************************************)
(**                   function GetFileList                         **)
(********************************************************************)

function GetFileList(d: string): PFileNames;
var
  p: PFileNames;
  s: SearchRec;
  r: PFileRec;

  function GetPFileRec(s: SearchRec): PFileRec;
  var r: PFileRec;
  begin
    r:= New(PFileRec);
    r^.Name:= d + s.Name;
    r^.Attr:= s.Attr;
    r^.Time:= s.Time;
    r^.Size:= s.Size;
    GetPFileRec:= r;
  end;

begin
  p:= nil;
  FindFirst(d + '*.*', Archive, s);
  if DOSError = 0 then
  begin
    p:= New(PFileNames, Init(10, 2));
    r:= GetPFileRec(s);
    p^.Insert(r);
    while DOSError = 0  do
    begin
      FindNext(s);
      if DOSError = 0 then
      begin
        r:= GetPFileRec(s);
        p^.Insert(r);
      end;
    end;
  end;
  GetFileList:= p;
end;


(********************************************************************)
(**                   function CheckFileNames                      **)
(********************************************************************)

function CheckFileNames(List: PFileNames): boolean;
var
  i    : integer;
  s, f : string;
  ok   : boolean;
  p    : PFileRec;
  FDir : DirStr;
  FName: NameStr;
  FExt : ExtStr;
begin
  ok:= true;
  if not assigned(List) then
  begin
    CheckFileNames:= false;
    exit;
  end;
  for i:= 0 to List^.Count-1 do
    if ok then
    begin
      p:= PFileRec(List^.At(i));
      FSplit(p^.Name, FDir, FName, FExt);
      if FExt = '.' then FExt:= '';
      if not CheckObjectName(FName + FExt) then
        ok:= EnterObjectName(p);
    end;
  CheckFileNames:= ok;
end;


(********************************************************************)
(**                   function CopyFiles                           **)
(********************************************************************)

function CopyFiles(List: PFileNames; d: string): boolean;
var
  i    : integer;
  ok   : boolean;
  p    : PFileRec;
  FDir : DirStr;
  FName: NameStr;
  FExt : ExtStr;
begin
  ok:= true;
  for i:= 0 to List^.Count-1 do
    if ok then
    begin
      p:= PFileRec(List^.At(i));
      FSplit(p^.Name, FDir, FName, FExt);
      ok:= FCopy(p^.Name, d + FName + FExt);
    end;
  CopyFiles:= ok;
end;


(********************************************************************)
(**                   function DeleteFiles                         **)
(********************************************************************)

function DeleteFiles(d: string): boolean;
var
  i    : integer;
  ok   : boolean;
  p    : PFileRec;
  FDir : DirStr;
  FName: NameStr;
  FExt : ExtStr;
  List: PFileNames;
begin
  ok:= true;
  List:= GetFileList(d);
  if assigned(List) then
  begin
    for i:= 0 to List^.Count-1 do
      if ok then
      begin
        p:= PFileRec(List^.At(i));
        FSplit(p^.Name, FDir, FName, FExt);
        ok:= FDelete(d + FName + FExt);
      end;
  end;
  DeleteFiles:= ok;
end;


(********************************************************************)
(**                function MergeFiles                             **)
(********************************************************************)

function MergeFiles(var List: PFileNames; FName: string): boolean;
type
  PBuff = ^TBuff;
  TBuff = array[1..8192] of byte;   (* BuffergrӇe 8kB ! *)
var
  ok: boolean;
  s, d: file;
  NumRead, NumWrite: word;
  Buff: PBuff;
  i: integer;
  p: PFileRec;
begin
  ok:= true;
  FResult:= 0;
  assign(d, FName);
  {$I-} rewrite(d, 1); {$I+}
  FResult:= IOresult;
  if FResult <> 0 then ok:= false else
  begin
    if MaxAvail < SizeOf(Buff^) then ok:= false else
    begin
      New(Buff);
      for i:= 0 to List^.Count-1 do
      begin
        assign(s, PFileRec(List^.At(i))^.Name);
        {$I-} reset(s, 1); {$I+}
        FResult:= IOresult;
        if FResult <> 0 then
        begin
          MergeFiles:= false;
          Dispose(List, Done);
          Exit;
        end;
        repeat
          BlockRead(s, Buff^, SizeOf(Buff^), NumRead);
          BlockWrite(d, Buff^, NumRead, NumWrite);
          ok:= NumRead = NumWrite;
        until (NumRead = 0) or (not ok);
        close(s);
      end;
      Dispose(Buff);
    end;
    List^.FreeAll;
    p:= New(PFileRec);
    p^.Name:= FName;
    List^.insert(p);
    close(d);
  end;
  MergeFiles:= ok;
end;


(********************************************************************)
(**                function CheckIfFilesAreThere                   **)
(********************************************************************)

procedure CheckIfFilesAreThere(var List: PFileNames; d: string);
var
  i: word;
  p: PFileRec;
  ss, dd, dest: PathStr;
  error: boolean;

  function GetName(n: PathStr): PathStr;
  var i: integer;
  begin
    i:= length(n);
    while n[i] <> '\' do dec(i);
    inc(i);
    GetName:= copy(n, i, length(n)+i+1);
  end;

  function GetPath(n: PAthStr): PathStr;
  var i: integer;
  begin
    i:= length(n);
    while n[i] <> '\' do dec(i);
    GetPath:= copy(n, 1, i);
  end;

  function IsThere(n: PathStr): boolean;
  var
    a: word;
    f: file;
  begin
    assign(f, n);
    getfattr(f, a);
    IsThere:= DosError = 0;
  end;

  function AddNum(var p: PathStr): boolean;
  var
    d: DirStr; n: NameStr; e: ExtStr;
    snum: string;
    num, code: integer;
    error: boolean;
  begin
    error:= false;
    FSplit(p, d, n, e);
    val(copy(n, length(n), 1), num, code);
    if code = 0 then
    begin
      val(copy(n, length(n)-1, 2), num, code);
      if code <> 0 then val(copy(n, length(n), 1), num, code);
    end else num:= 0;
    num:= num + 1;
    if num > 99 then error:= true else
    begin
      Str(num, snum);
      if length(n) <= ( 8 - length(snum) ) then
      begin
        if num = 1 then n:= n + snum else
          if num <= 10 then n:= copy(n, 1, length(n)-1) + snum else
            n:= copy(n, 1, length(n)-2) + snum;
      end else n:= copy(n, 1, 8 - length(snum)) + snum;
      p:= d + n + e;
    end;
    AddNum:= error;
  end;

begin
  for i:= 0 to List^.count-1 do
  begin
    error:= false;
    p:= PFileRec(List^.at(i));
    dest:= d + GetName(p^.Name);
    while (IsThere(dest)) and (not error) do error:= AddNum(dest);
    ss:= GetName(p^.Name);
    dd:= GetName(dest);
    if error then
    begin
       write(#7);
      OneStringRec:= PString(@ss);
              { 'Die Datei %s ist bereits 99 mal im Empfangsverzeichnis '+
                'vorhanden, und wird somit berschrieben.' }
      ErrorBox(#3+GetString(1434), @OneStringRec, mfOkBeep);
    end;
    if (ss <> dd) and (not error) then
    begin
      AttentionBeep;
      TwoStringRec.s1:= PString(@ss);
      TwoStringRec.s2:= PString(@dd);
      if MessageBox(#3+GetString(1435), @TwoStringRec,
                    mfConfirmation+mfYesNoCancel) = cmYes then
      begin
        FRename(p^.Name, GetPath(p^.Name) + dd);
        p^.Name:= GetPath(p^.Name) + dd;
      end;
    end;
  end;
end;

end.



page up


HPDIR.PAS
{************************************************}
{                                                }
{   UNIT HPDIR     DIR-Variablen erzeugen        }
{   Copyright (c) 1994-98 by Tom Wellige         }
{                                                }
{   Part of HPShell                              }
{   Integrated Developing Environment            }
{   for HP48 calculators                         }
{                                                }
{   Author: Tom Wellige                          }
{   E-Mail: wellige@t-online.de                  }
{                                                }
{   These sources can be freely used as long     }
{   as their origin is stated in the             }
{   resulting program (code *and* exe)           }
{                                                }
{************************************************}

(* 01.05.95  Alle Texte von GetString im Klartext hinzugefgt.       *)
(* 24.06.95  CheckItems eingefgt. Es wird nun erst der komplette    *)
(*           Baum eingelesen und anschlieáend berprft.             *)
(* 29.06.95  Nachdem HP-Dir erfolgreich erstellt wurde, wird gefragt *)
(*           ob dieses sofort zum HP gesendet werden soll.           *)
(* 25.12.95  Kommentare in ResultFile eingefuegt.                    *)
(* 20.01.96  CST Erstellung hinzugefgt.                             *)
(* 11.06.96  REGIST aus "uses" entfernt                              *)
(* 28.06.96  In WriteCST einige "writeln" eingefgt. Nun wird fr    *)
(*           jedes CST Men (6 Items) eine Zeile verwendet           *)


{$O+,F+}

unit HPDir;

interface

uses Crt, Dos, Drivers, Objects, App, Views, Dialogs, Stddlg, Msgbox,
     HPGlobal, {regist,} Tone, MultiF, Combobox,
     TWApp, TWGlobal, TWDialog, TWMsgbox, TWStddlg, TWCommon, TWDos;


type
  CreateDirRec = record
    Variable : String[8];
    SavePath : String[79];
    Order    : Word;
    DirSort  : Word;
    Comment  : Word;
  end;


  (* allgemeiner Eintrag im Verzeichnisbaum, kann also Stammverzeichnis,
     Unterverzeichnis oder auch eine Datei sein                  *)
  PItem = ^TItem;
  TItem = object(TObject)
      Name: string;
      Previous, NextFile, NextDir, NextSubDir: PItem;
  end;

  (* sucht Dateien und Verzeichnisse, und erzeugt in ResultFile
     eine HP48-Verzeichnis-Variable                              *)
  PCreateHPDir = ^TCreateHPDir;
  TCreateHPDir = object(TObject)
      StatusDlg: PDialog;
      InfoBar: PInfoBar;
      Status, Action: PView;
      StartDir, ResultFile: PathStr;
      LastHeap: pointer;
      Items: PItem;
      Order, DirSort: word;  { Order  : 0=nicht, 1=steigend, 2=fallend }
      Result: Text;          { DirSort: 0=vorne, 1= hinten             }
      NumOfFiles, NumOfDirs, NumOfWrittenFiles: word;
      Error: word;           { 0  = kein Fehler augetreten             }
                             { 1  = Fehler beim Wechseln in Verz.      }
                             { 20 = Fehler beim Erzeugen vom ResultF.  }
      Comment: boolean;      { detailierte Kommentare einfgen         }
    constructor Init(AStartDir, AResultFile: PathStr;
                     AOrder, ADirSort: word);
    destructor Done; virtual;
    procedure  InitStatusDlg;
    function   GetItems: PItem;
    function   CheckItems(p: PItem): boolean;
    function   GetResultSize: LongInt;
    function   MakeResultFile: boolean;
    procedure  DoIt;
    procedure  Update(s: string; r: boolean);
    procedure  ShowStat;
  end;

  PCreateDirDlg = ^TCreateDirDlg;
  TCreateDirDlg = object(TDialog)
      VarName : PInputLine;
      SavePath: PDirInputLine;
    constructor Init(ADosDirName: string);
    procedure HandleEvent(var Event: TEvent); virtual;
    function Valid(Command: word): boolean; virtual;
  end;

  PActionView = ^TActionView;
  TActionView = object(TView)
      Reading: boolean;
      FileName: string;
    procedure Draw; virtual;
  end;

  PStatusView = ^TStatusView;
  TStatusView = object(TView)
      P: PCreateHPDir;
    procedure Draw; virtual;
  end;

  PCSTDialog = ^TCSTDialog;
  TCSTDialog = object(TDialog)
    constructor Init;
    function Valid(Command : word): boolean; virtual;
  end;


(* ”ffnet Verzeichnis-Dlg, danach wird mittels TCreateHPDir eine
   HP-Verzeichnis-Variable angelegt                                 *)
function CreateHPDir(s: string): boolean;


const
  CST_Def : array [1..6] of string[20] = ('', '', '', '', '', '');
  LastOrder   : word    = 0;
  LastDirSort : word    = 0;
  LastSavePath: string  = '';
  LastComment : boolean = true;
  LastCST     : boolean = false;

implementation

const
  cmDefineCST           = 236;
  cmInsertChanged       = 3000;

function GetDirString(s: string; l: integer): string;
var i: integer;
begin
  if l > 3 then l:= l - 3;
  if length(s) > l then
  begin
    while length(s) > l do
    begin
      i:= 4;
      while s[i] <> '\' do inc(i);
      System.Delete(s, 4, i-3);
    end;
    System.Insert('\...', s, 3);
  end;
  GetDirString:= s;
end;


function GetName(d: string): string;
var i: integer;
begin
  i:= length(d);
  while d[i] <> '\' do dec(i);
  GetName:= copy(d, i+1, length(d)-i);
end;


(********************************************************************)
(**                        TCSTDialog                              **)
(********************************************************************)

constructor TCSTDialog.Init;
var
  R : TRect;
  Control, Control1 : PView;
begin
  R.Assign(0, 3, 45, 20);
  inherited Init(R, GetString(1346));  {'CST Vorgaben'}
  Options:= Options or ofCenterX or ofCenterY;

  R.Assign(4, 1, 41, 12);
  Insert(New(P3D_Frame, Init(R)));

  R.Assign(7, 2, 36, 3);          {'Standardwerte fr Mentasten:'}
  Insert(New(PStaticText, Init(R, GetString(1347))));

  R.Assign(16, 4, 28, 5);
  Control:= New(PInputLine, Init(R, 20));
  Insert(Control);

  R.Assign(28, 4, 31, 5);
  Control1:= New(PCombo, Init(R, PInputLine(Control), cbxNoTransfer,
    NewSItem('UPDIR',
    NewSItem('HOME',
    NewSItem('""',
    NewSItem('USR',
    NewSItem('OFF', Nil)))))));
  Insert(Control1);

  R.Assign(12, 4, 15, 5);
  Insert(New(PLabel, Init(R, '~1~:', Control)));

  R.Assign(16, 5, 28, 6);
  Control:= New(PInputLine, Init(R, 20));
  Insert(Control);

  R.Assign(28, 5, 31, 6);
  Control1:= New(PCombo, Init(R, PInputLine(Control), cbxNoTransfer,
    NewSItem('UPDIR',
    NewSItem('HOME',
    NewSItem('""',
    NewSItem('USR',
    NewSItem('OFF', Nil)))))));
  Insert(Control1);

  R.Assign(12, 5, 15, 6);
  Insert(New(PLabel, Init(R, '~2~:', Control)));

  R.Assign(16, 6, 28, 7);
  Control:= New(PInputLine, Init(R, 20));
  Insert(Control);

  R.Assign(28, 6, 31, 7);
  Control1:= New(PCombo, Init(R, PInputLine(Control), cbxNoTransfer,
    NewSItem('UPDIR',
    NewSItem('HOME',
    NewSItem('""',
    NewSItem('USR',
    NewSItem('OFF', Nil)))))));
  Insert(Control1);

  R.Assign(12, 6, 15, 7);
  Insert(New(PLabel, Init(R, '~3~:', Control)));

  R.Assign(16, 7, 28, 8);
  Control:= New(PInputLine, Init(R, 20));
  Insert(Control);

  R.Assign(28, 7, 31, 8);
  Control1:= New(PCombo, Init(R, PInputLine(Control), cbxNoTransfer,
    NewSItem('UPDIR',
    NewSItem('HOME',
    NewSItem('""',
    NewSItem('USR',
    NewSItem('OFF', Nil)))))));
  Insert(Control1);

  R.Assign(12, 7, 15, 8);
  Insert(New(PLabel, Init(R, '~4~:', Control)));

  R.Assign(16, 8, 28, 9);
  Control:= New(PInputLine, Init(R, 20));
  Insert(Control);

  R.Assign(28, 8, 31, 9);
  Control1:= New(PCombo, Init(R, PInputLine(Control), cbxNoTransfer,
    NewSItem('UPDIR',
    NewSItem('HOME',
    NewSItem('""',
    NewSItem('USR',
    NewSItem('OFF', Nil)))))));
  Insert(Control1);

  R.Assign(12, 8, 15, 9);
  Insert(New(PLabel, Init(R, '~5~:', Control)));

  R.Assign(16, 9, 28, 10);
  Control:= New(PInputLine, Init(R, 20));
  Insert(Control);

  R.Assign(28, 9, 31, 10);
  Control1:= New(PCombo, Init(R, PInputLine(Control), cbxNoTransfer,
    NewSItem('UPDIR',
    NewSItem('HOME',
    NewSItem('""',
    NewSItem('USR',
    NewSItem('OFF', Nil)))))));
  Insert(Control1);

  R.Assign(12, 9, 15, 10);
  Insert(New(PLabel, Init(R, '~6~:', Control)));

  R.Assign(2, 14, 15, 16);    {'~O~k'}
  Insert(New(PButton, Init(R, GetString(10), cmOK, bfDefault)));

  inc(R.A.X, 14); inc(R.B.X, 14); {'~H~ilfe'}
  Insert(New(PButton, Init(R, GetString(11), cmHelp, bfNormal)));

  inc(R.A.X, 14); inc(R.B.X, 14); {'~A~bbruch'}
  Insert(New(PButton, Init(R, GetString(12), cmCancel, bfNormal)));

  SelectNext(False);
end;


(********************************************************************)
(**                    function CreateHPDir                        **)
(********************************************************************)

function CreateHPDir(s: string): boolean;
var
  OrgDir, CurDir, ResultFile, v: string;
  D: PDirDlg;
  P: PCreateDirDlg;
  C: PCreateHPDir;
  Rec: CreateDirRec;
  tmp: PathStr;
begin
  GetDir(0, OrgDir);

  if s <> '' then
  begin
    if s[length(s)] = '\' then s:= copy(s, 1, length(s)-1);
    ChDir(Copy(s, 1, 2));
    ChDir(s);
  end;
                        { DOS-Verzeichnis ausw„hlen }
  D:= New(PDirDlg, Init(GetString(1300), cdHelpButton, 101));

  if assigned(D) then
  begin
    D^.HelpCtx:= 41041;
    tmp:= LastDirectory;
    if Application^.ExecuteDialog(D, nil) <> cmCancel then
    begin
      GetDir(0, CurDir);
      P:= New(PCreateDirDlg, Init(CurDir));
      if assigned(P) then
      begin
        P^.HelpCtx:= 41042;
        if LastSavePath = '' then LastSavePath:= Dirs.Dirs;
        Rec.Variable:= GetName(CurDir);
        Rec.SavePath:= LastSavePath;
        Rec.Order   := LastOrder;
        Rec.DirSort := LastDirSort;
        Rec.Comment := 0;
        if LastComment then Rec.Comment:= Rec.Comment or $01;
        if LastCST     then Rec.Comment:= Rec.Comment or $02;
        if Application^.ExecuteDialog(P, @Rec) <> cmCancel then
        begin
          LastSavePath:= Rec.SavePath;
          LastOrder   := Rec.Order;
          LastDirSort := Rec.DirSort;
          LastComment := Rec.Comment and $01 <> 0;
          LastCST     := Rec.Comment and $02 <> 0;

          C:= New(PCreateHPDir, Init(CurDir, LastSavePath + Rec.Variable,
                                     LastOrder, LastDirSort));
          Dispose(C, Done);
             {'Wollen Sie diese Verzeichnis-Variable nun ' +
              'sofort zum HP bertragen ?'}
          if MessageBox(#3+GetString(1336), nil,
                        mfConfirmation + mfYesNoCancel) = cmYes then
          begin
            v:= LastSavePath + Rec.Variable;
            Message(Application, evCommand, cmSendHPDir, @v);
          end;
        end;
      end;
    end;
    LastDirDirectory:= LastDirectory;
    LastDirectory   := tmp;
  end;

  ChDir(copy(OrgDir, 1, 2));
  ChDir(OrgDir);
end;


function TCSTDialog.Valid(Command : word): boolean;
var
  Result: boolean;
  r: array[1..6] of string[20];
begin
  if (Command = cmOk) then
  begin
    Result:= true;
    GetData(r);
    if ( r[1] <> '' ) and ( r[2] <> '' ) and ( r[3] <> '' ) and
       ( r[4] <> '' ) and ( r[5] <> '' ) and ( r[6] <> '' ) then
    begin {'Wenn Sie alle Mentasten mit Standardwerten belegen,
            bleibt kein Platz mehr fr Ihre Daten.'}
      ErrorBox(#3+GetString(1337), nil, mfOkBeep);
      Result:= false;
    end else result:= inherited Valid(Command);
  end else result:= inherited Valid(Command);
  Valid:= Result;
end;


(********************************************************************)
(**                       TCreateDirDlg                            **)
(********************************************************************)

constructor TCreateDirDlg.Init(ADosDirName: string);
var
  R: TRect;
  Control: PView;
begin
  R.Assign(0, 0, 60, 21);  { Verzeichnis-Variable erzeugen }
  inherited Init(R, GetString(1301));
  Options:= Options or ofCentered;

  R.Assign(2, 1, 58, 8);
  Insert(New(P3D_Frame, Init(R)));

  R.Assign(4, 2, 20, 3);         { DOS-Verzeichnis }
  Insert(New(PStaticText, Init(R, GetString(1302))));

  R.Assign(21, 2, 56, 3);
  Insert(New(PStaticText, Init(R, GetDirString(ADosDirName, 35))));

  R.Assign(20, 4, 30, 5);
  VarName:= New(PInputLine, Init(R, 8));
  Insert(VarName);

  R.Assign(3, 4, 20, 5);    { Variablen-Name }
  Insert(New(PLabel, Init(R, GetString(1303), VarName)));

  R.Assign(20, 6, 56, 7);
  SavePath:= New(PDirInputLine, Init(R, 79));
  Insert(SavePath);

  R.Assign(3, 6, 17, 7);    { speichern in }
  Insert(New(PLabel, Init(R, GetString(1304), SavePath)));


  R.Assign(2, 8, 58, 16);
  Insert(New(P3D_Frame, Init(R)));

  R.Assign(4, 10, 29, 13);
  Control:= New(PRadioButtons, Init(R,
    NewSItem(GetString(1305), { unsortiert }
    NewSItem(GetString(1306), { alphabet. steigend }
    NewSItem(GetString(1307), { alphabet. fallend  } Nil)))));
  Insert(Control);

  R.Assign(3, 9, 15, 10);    { Sortierung }
  Insert(New(PLabel, Init(R, GetString(1308), Control)));

  R.Assign(31, 10, 56, 12);
  Control:= New(PRadioButtons, Init(R,
    NewSItem(GetString(1309), { vorne }
    NewSItem(GetString(1310), { hinten } Nil))));
  Insert(Control);

  R.Assign(30, 9, 54, 10);   { Verzeichnisse anordnen }
  Insert(New(PLabel, Init(R, GetString(1311), Control)));

  R.Assign(31, 13, 56, 15);
  Control:= New(PMsgCheckboxes, Init(R,
    NewSItem(GetString(1338),  {'~K~ommentare einfgen'}
    NewSItem(GetString(1339),  {'~C~STs einfgen'}
       nil)), cmInsertChanged));
  Insert(Control);


  R.Assign(2, 18, 15, 20);
  Insert(New(PButton, Init(R, GetString(10), cmOK, bfDefault)));

  inc(R.A.X, 14); inc(R.B.X, 14); {'CS~T~'}
  Insert(New(PButton, Init(R, GetString(1345), cmDefineCST, bfNormal)));

  inc(R.A.X, 14); inc(R.B.X, 14);
  Insert(New(PButton, Init(R, GetString(11), cmHelp, bfNormal)));

  inc(R.A.X, 14); inc(R.B.X, 14);
  Insert(New(PButton, Init(R, GetString(12), cmCancel, bfNormal)));

  SelectNext(False);

  if LastCST then EnableCommands([cmDefineCST])
             else DisableCommands([cmDefineCST]);
end;

procedure TCreateDirDlg.HandleEvent(var Event: TEvent);
var
  w: word;
  D: PCSTDialog;
begin
  inherited HandleEvent(Event);
  case Event.What of
    evBroadCast:
      if Event.Command = cmInsertChanged then
      begin
        w:= Word(Event.InfoPtr^);
        if w and $02 <> 0 then EnableCommands([cmDefineCST])
                          else DisableCommands([cmDefineCST]);
      end;

    evCommand:
      if Event.Command = cmDefineCST then
      begin
        D:= new(PCSTDialog, Init);
        D^.HelpCtx:= 41048;
        Application^.ExecuteDialog(D, @CST_Def);
      end;
  end;
end;

function TCreateDirDlg.Valid(Command: word): boolean;
var
  d: PDialog;
  Ok: boolean;
  s, p, f: string;
  test: file;
  Event: TEvent;
begin
  Ok:= true;
  if (Command <> cmCancel) and (Command <> 0) then
  begin
    p:= SavePath^.Data^;
    f:= VarName^.Data^;
    if not CheckObjectName(f) then
    begin
      d:= PDialog(TRez.Get('Filename'));
      d^.Palette:= dpBlueDialog;
      if (TRez.Stream^.Status <> 0) or (not assigned(d)) then
        ResError('Error in resource file ' + CalcLNGFileName + '.') else
      begin
        AttentionBeep;
        d^.HelpCtx:= 20049;
        ok:= Application^.ExecuteDialog(d, nil) = cmOk;
      end;
      VarName^.Select;
      VarName^.SelectAll(true);
    end;

    if ok then
    begin
      if p[length(p)] <> '\' then p:= p + '\';
      assign(test, p + f);
      {$I-} reset(test); {$I+}
      if IOresult = 0 then
      begin
        System.close(test);
        p:= p + f;
        OneStringRec:= PString(@p);
        { Soll die existierende Datei %s berschrieben werden ? }
        FormatStr(s, GetString(1313), OneStringRec);
        if ErrorBox(#3+s, nil, mfWarning+mfBeep+mfYesNoCancel) <> cmYes then
        begin
          VarName^.Select;
          ok:= false;
        end;
      end;
    end;
  end;
  if Ok then valid:= inherited Valid(Command) else valid:= false;
end;


(********************************************************************)
(**                        TCreateHPDir                            **)
(********************************************************************)

constructor TCreateHPDir.Init(AStartDir, AResultFile: PathStr;
                      AOrder, ADirSort: word);
begin
  inherited Init;
  StartDir  := AStartDir;
  ResultFile:= AResultFile;
  Order     := AOrder;
  DirSort   := ADirSort;
  Items     := nil;
  NumOfDirs := 0;
  NumOfFiles:= 0;
  Error     := 0;
  Comment   := LastComment;

  InitStatusDlg;

  Assign(Result, ResultFile);
  Mark(LastHeap);
  DoIt;
end;


destructor TCreateHPDir.Done;
begin
  Release(LastHeap);
  if assigned(StatusDlg) then
  begin
    Desktop^.Delete(StatusDlg);
    Dispose(StatusDlg, Done);
  end;
  inherited Done;
end;


procedure TCreateHPDir.InitStatusDlg;
var
  R: TRect;
  InfoBarRec: TInfoBarRec;
  s: string;
begin
  R.Assign(0,0,52,12);            { Verzeichnis-Variable erzeugen }
  StatusDlg:= New(PDialog, Init(R, GetString(1314)));
  if assigned(StatusDlg) then
  with StatusDlg^ do
  begin
    Options:= Options or ofCentered;
    Flags:= Flags and not wfClose;

    R.Assign(3, 2, 49, 3);         { Name     : }
    Insert(New(PStaticText, Init(R, GetString(1315) +
                       GetDirString(ResultFile, 36))));
    case Order of
      0: s:= GetString(1316); { unsortiert     }
      1: s:= GetString(1317); { alph. steigend }
      2: s:= GetString(1318); { alph. fallend  }
    end;
    s:= s + ', ';
    case DirSort of
      0: s:= s + GetString(1319); { Verz. vorne  }
      1: s:= s + GetString(1320); { Verz. hinten }
    end;
    R.Assign(3, 3, 49, 4);         { Anordnung: }
    Insert(New(PStaticText, Init(R, GetString(1321) + s)));

    R.Assign(3,5,49,8);
    Status:= New(PStatusView, Init(R));
    PStatusView(Status)^.P:= @self;
    Status^.Hide;
    Insert(Status);

    R.Assign(3,5,49,6);
    Action:= New(PActionView, Init(R));
    Insert(Action);

    with InfoBarRec do
    begin
      Text1:= GetString(1322); { Bitte warten Sie... }
      Text2:= '';
      Size := 0;
    end;
    R.Assign(1,10,51,11);
    InfoBar:= New(PInfoBar, Init(R, @InfoBarRec));
    Insert(InfoBar);
  end;
  Desktop^.Insert(StatusDlg);
end;

function TCreateHPDir.GetItems: PItem;
var
  OrgDir, s: string;
  Fehler: boolean;
  First: PItem;

  r: text;

  procedure ScanDirectory(FirstDir: PItem; var Fehler: boolean);
  var
    Verz: SearchRec;
    Dir: string;
    FirstFile, NewFile, NewDir: PItem;
    First, Second: boolean;

    function CheckName(s: string): boolean;
    var i: integer;
    begin
      i:= length(s);
      while s[i] <> '\' do dec(i);
      inc(i);
      s:= copy(s, i, length(s)-i);
      CheckName:= CheckObjectName(s);
    end;

    procedure InsertFile(Item: PItem);
    var d, p: PItem;
    begin
      p:= nil;
      d:= FirstFile;
      Update(Item^.Name, true);
      case order of
       0: { unsortiert, Item wird hinten angeh„ngt }
         begin
           while assigned(d^.NextFile) do d:= d^.NextFile;
           d^.NextFile:= Item;
           Item^.Previous:= d;
         end;
       1: { Item wird alphabetisch steigend einsortiert }
         begin
           while assigned(d^.NextFile) and
                 (d^.NextFile^.Name < Item^.Name) do d:= d^.NextFile;
           if assigned(d^.NextFile) then p:= d^.NextFile;
           d^.NextFile:= Item;
           Item^.Previous:= d;
           if assigned(p) then Item^.NextFile:= p;
         end;
       2: { Item wird alphabetisch fallend einsortiert }
         begin
           while assigned(d^.NextFile) and
                 (d^.NextFile^.Name > Item^.Name) do d:= d^.NextFile;
           if assigned(d^.NextFile) then p:= d^.NextFile;
           d^.NextFile:= Item;
           Item^.Previous:= d;
           if assigned(p) then Item^.NextFile:= p;
         end;
      end;
    end;


    { Fgt NEW in die DIR-Kette ein. šberprft ob OLD gleich dem ersten
      Verzeichnis in der Kette ist, und „ndert entsprechend.}
    procedure InsertNodeBefore(Old, New: PItem);
    var p: PItem;
    begin
     if Old <> FirstDir then
      begin
        {writeln(r, 'InsertNodeBefore: Old <> FirstDir');}
        p:= Old^.Previous;
        p^.NextDir   := New;
        Old^.Previous:= New;
        New^.Previous:= p;
        New^.NextDir := Old;
      end else
      begin
        {writeln(r, 'InsertNodeBefore: Old = FirstDir');}
        FirstDir^.Previous^.NextSubDir:= New;
        New^.Previous:= FirstDir^.Previous;
        New^.NextDir := FirstDir;
        FirstDir^.Previous:= New;
        FirstDir:= New;
      end;
    end;


    { Fgt NEW in die DIR-Kette ein.}
    procedure InsertNodeAfter(Old, New: PItem);
    var p: PItem;
    begin
      {writeln(r, 'InsertNodeAfter');}
      p:= Old^.NextDir;
      if assigned(p) then p^.Previous:= New;
      Old^.NextDir:= New;
      New^.Previous:= Old;
      New^.NextDir:= p;
    end;


    procedure InsertDir(Item: PItem; var SubDir: boolean);
    var d, p: PItem;
    begin
      if SubDir then
      begin
        {writeln(r);
        writeln(r, 'FirstDir: ',FirstDir^.Name);
        writeln(r, 'Item    : ',Item^.Name);
        writeln(r, 'SubDir  : true');}
        FirstDir^.NextSubDir:= Item;
        Item^.Previous:= FirstDir;
        FirstDir:= Item;
        SubDir:= false;
        Second:= true;
      end else
      begin
        {writeln(r);
        writeln(r, 'FirstDir: ',FirstDir^.Name);
        writeln(r, 'Item    : ',Item^.Name);
        writeln(r, 'SubDir  : false');}
        p:= nil;
        d:= FirstDir;
        case order of
         0: { unsortiert, Item wird hinten angeh„ngt }
           begin
             while assigned(d^.NextDir) do d:= d^.NextDir;
             d^.NextDir:= Item;
             Item^.Previous:= d;
           end;
         1: { Item wird alphabetisch steigend einsortiert }
           begin
             while assigned(d^.NextDir) and (Item^.Name > d^.Name) do
               d:= d^.NextDir;
             if (Item^.Name < d^.Name) then InsertNodeBefore(d, Item)
                                       else InsertNodeAfter(d, Item);
           end;
         2: { Item wird alphabetisch fallend einsortiert }
           begin
             while assigned(d^.NextDir) and (Item^.Name < d^.Name) do
               d:= d^.NextDir;
             if (Item^.Name > d^.Name) then InsertNodeBefore(d, Item)
                                       else InsertNodeAfter(d, Item);
           end;
        end;
      end;
    end;

  begin
    First:= true;
    Second:= false;
    FirstFile:= FirstDir;
    FindFirst('*.*', Archive+Directory, Verz);
    while (DosError = 0) and not FEHLER do
    begin
      if Verz.Attr <> Directory then
      begin
        inc(NumOfFiles);
        NewFile      := New(PItem, Init);
        NewFile^.Name:= FExpand(Verz.Name);
        InsertFile(NewFile);
      end else
      if (Verz.Name <> '.') and (Verz.Name <> '..') then
      begin
        inc(NumOfDirs);
        NewDir      := New(PItem, Init);
        NewDir^.Name:= FExpand(Verz.Name);
        InsertDir(NewDir, First);
      end;
      if not Fehler then FindNext(Verz);
    end;
  end;

  procedure FindDirs(First: PItem; var Fehler : boolean);
  begin
    ScanDirectory(First, Fehler);
    if assigned(First^.NextSubDir) and (not Fehler) then
    begin
      First:= First^.NextSubDir;
      { das erste Verzeichnis durchsuchen }
      {$I-} ChDir(First^.Name); {$I+}
      if IOresult <> 0 then
      begin
        Fehler:= true;
        Error := 1;
        OneStringRec:= PString(@First^.Name);
        { Kann nicht nach %s wechseln. }
        ErrorBox(#3+GetString(1325), @OneStringRec, mfOkBeep);
        exit;
      end;
      FindDirs(First, Fehler);
      ChDir('..');
      { weitere Verzeichnisse durchsuchen }
      while assigned(First^.NextDir) and (not Fehler) do
      begin
        First:= First^.NextDir;
        {$I-} ChDir(First^.Name); {$I+}
        if IOresult <> 0 then
        begin
          Fehler:= true;
          Error := 1;
          OneStringRec:= PString(@First^.Name);
          { Kann nicht nach %s wechseln. }
          ErrorBox(#3+GetString(1325), @OneStringRec, mfOkBeep);
          exit;
        end;
        FindDirs(First, Fehler);
        ChDir('..');
      end;
    end;
  end;

begin
  {assign(r, 'C:\hp48s\debug.');
  rewrite(r);}
  Fehler     := false;
  First      := New(PItem, Init);
  First^.Name:= StartDir;

  GetDir(0, OrgDir);
  StartDir:= UpString(StartDir);

  { ins StartDir wechseln und suchen }
  ChDir(copy(StartDir, 1, 3));
  ChDir(StartDir);
  FindDirs(First, Fehler);

  { ins OrgDir zurck wechseln }
  ChDir(copy(OrgDir, 1, 3));
  ChDir(OrgDir);

  {close(r);}
  if Fehler then GetItems:= nil else GetItems:= First;
end;


function TCreateHPDir.CheckItems(p: PItem): boolean;
var
  ok: boolean;

  function CheckDir(p: PItem): boolean;
  var
    ok   : boolean;
    d    : PItem;
    rec  : TFileRec;
    FDir : DirStr;
    FName: NameStr;
    FExt : ExtStr;
  begin
    ok:= true;

    rec.Name:= p^.Name;
    FSplit(p^.Name, FDir, FName, FExt);
    if FExt = '.' then FExt:= '';
    if not CheckObjectName(FName + FExt) then
    begin
      ok:= EnterObjectName(PFileRec(@rec));
      if ok then p^.Name:= rec.Name;
    end;

    if (assigned(p^.NextDir)) and ok then
      ok:= CheckDir(p^.NextDir);

    if (assigned(p^.NextSubDir)) and ok then
      ok:= CheckDir(p^.NextSubDir);

    if (assigned(p^.NextFile)) and ok then
      ok:= CheckDir(p^.NextFile);

    CheckDir:= ok;
  end;

begin
  ok:= CheckDir(p);
  CheckItems:= ok;
end;


function TCreateHPDir.GetResultSize: LongInt;
var s: SearchRec;
begin
  FindFirst(ResultFile, AnyFile, s);
  if DOSError = 0 then GetResultSize:= s.Size
                  else GetResultSize:= 0;
end;

procedure TCreateHPDir.DoIt;
var
  s: string;
  Event: TEvent;
begin
  Items:= GetItems;
  if (CheckItems(Items)) and (Error = 0) then
  begin
    MakeResultFile;
    ShowStat;
  end;
end;


function TCreateHPDir.MakeResultFile: boolean;
type CFile = file of char;
var
  s : string;
  i : integer;
  Ok: boolean;
  depth: integer;
  p: PItem;
  d,m,y,dw,h,min,sec,hs: word;

  function GetTAB: string;
  var
    i: integer;
    s: string;
  begin
    s:= '';
    for i:= 1 to Depth do s:= s + ' ';
    GetTAB:= s;
  end;


  function WriteFile(var r: text; n: string): boolean;
  var
    f: CFile;
    s: string;
    c: char;
    l: longint;
    waitforlf, first: boolean;
    ferror: integer;
  begin
    Update(n, false);
    first:= true;
    waitforlf:= false;
    assign(f, n);
    {$I-} reset(f); {$I+}
    if IOresult <> 0 then
    begin
      WriteFile:= false;
      OneStringRec:= PString(@n);
      { Kann die Datei "%s" nicht ”ffnen. }
      ErrorBox(#3+GetString(1326), @OneStringRec, mfOkBeep);
      Exit;
    end;
    {$I-}
    if Comment then writeln(r, '  @ DOS File: ' + n);
    writeln(r, '  ' + GetName(n));
    ferror:= IOresult;
    for l:= 1 to filesize(f) do
      if ferror = 0 then
      begin
        read(f, c);
        if First and (c = '%') then
        begin
          First:= false;
          WaitForLF:= true;
        end else
        begin
          First:= false;
          if not WaitForLF then
          begin
            write(r, c);
            ferror:= IOresult;
          end else
            if c = #10 then WaitForLF:= false;
        end;
      end;
    write(r, #13);
    write(r, #10);
    close(f);
    {$I+}
    if ferror <> 0 then
    begin
      WriteFile:= false;
      OneStringRec:= PString(@n);
      { Fehler beim Schreiben der Datei "%s". }
      ErrorBox(#3+GetString(1327), @OneStringRec, mfOkBeep);
      exit;
    end;
    WriteFile:= true;
  end;

  function WriteCST(var r: text; p: PItem; sort: word): boolean;
  var
    i: PItem;
    k, j: integer;
    empty: boolean;

     function IsDefaultKey: boolean;
     begin
       IsDefaultKey:= CST_Def[k] <> '';
     end;

     function StillDefaultKeys: boolean;
     var
       i: integer;
       found: boolean;
     begin
       found:= false;
       for i:= k to 6 do
         if CST_Def[i] <> '' then found:= true;
       StillDefaultKeys:= found;
     end;

     procedure WriteDefaultKey;
     begin
       write(r, CST_Def[k] + ' ');
       inc(k);
       if k > 6 then
       begin
         k:= 1;
         writeln(r); write(r, '  ');
       end;
     end;

     procedure WriteCSTDir;
     begin
       i:= p^.NextSubDir;
       while assigned(i) do
       begin
         while IsDefaultKey do WriteDefaultKey;
         write(r, GetName(i^.Name) + ' ');
         empty:= false;
         inc(k);
         if k > 6 then
         begin
           k:= 1;
           writeln(r); write(r, '  ');
         end;
         i:= i^.NextDir;
       end;
     end;

  begin
    writeln(r, '  CST');
    write(r, '{ ');
    k:= 1;
    empty:= true;

    if sort = 0 then WriteCSTDir;   { Verzeichnisse vorne anordnen }

    i:= p^.NextFile;
    while assigned(i) do
    begin
      while IsDefaultKey do WriteDefaultKey;
      write(r, GetName(i^.Name) + ' ');
      empty:= false;
      inc(k);
      if k > 6 then
      begin
        k:= 1;
        writeln(r); write(r, '  ');
      end;
      i:= i^.NextFile;
    end;

    if sort <> 0 then WriteCSTDir;  { Verzeichnisse hinten anordnen }

    if empty then
    begin
      j:= k;
      while StillDefaultKeys and ( j < 7 ) do
      begin
        inc(j);
        if IsDefaultKey then WriteDefaultKey else
        begin
          write(r, '"" ');
          inc(k);
        end;
      end;
    end else
      if ( k > 1 ) then
        while StillDefaultKeys and ( k <> 1 ) do
          if IsDefaultKey then WriteDefaultKey else
          begin
            write(r, '"" ');
            inc(k);
            if k > 6 then
            begin
              k:= 1;
              writeln(r); write(r, '  ');
            end;
          end;

    writeln(r, '}');
    WriteCST:= true;
  end;

  function WriteDir(var r: text; p: PItem; sub: boolean; first: boolean): boolean;
  var
    d : PItem;
    ok: boolean;
  begin
    ok:= true;
    inc(Depth, 2);
    if Comment then writeln(r, GetTAB + '@ DOS Directory: ' + p^.Name);
    if not first then writeln(r, GetTAB + GetName(p^.Name));
    writeln(r, GetTAB + 'DIR');
    if LastCST then WriteCST(r, p, DirSort);
    if DirSort = 0 then    { Dirs werden vorne angeordnet }
    begin
      if assigned(p^.NextSubDir) then ok:= WriteDir(r, p^.NextSubDir, true, false);
      d:= p^.NextFile;
      while (assigned(d)) and ok do
      begin
        ok:= WriteFile(r, d^.Name);
        d:= d^.NextFile;
      end;
      writeln(r, GetTAB + 'END');
      dec(Depth, 2);
      d:= p^.NextDir;
      while (assigned(d)) and ok and sub do
      begin
        ok:= WriteDir(r, d, false, false);
        d:= d^.NextDir;
      end;
    end else
    begin                  { Dirs werden hinten angeordnet }
      d:= p^.NextFile;
      while (assigned(d)) and ok do
      begin
        ok:= WriteFile(r, d^.Name);
        d:= d^.NextFile;
      end;
      if assigned(p^.NextSubDir) then ok:= WriteDir(r, p^.NextSubDir, true, false);
      writeln(r, GetTAB + 'END');
      dec(Depth, 2);
      d:= p^.NextDir;
      while (assigned(d)) and ok and sub do
      begin
        ok:= WriteDir(r, d, false, false);
        d:= d^.NextDir;
      end;
    end;
    WriteDir:= ok;
  end;

  function AddZero(n: word): string;
  var s: string;
  begin
    str(n, s);
    if s[0] = #1 then s:= '0' + s;
    AddZero:= s;
  end;

begin
  ok   := true;
  Depth:= -2;

  {$I-} rewrite(Result); {$I+}
  if IOresult <> 0 then
  begin
    Error:= 20;
    MakeResultFile:= false;
    OneStringRec:= PString(@ResultFile);
    { Kann neue Datei "%s" nicht erzeugen. }
    ErrorBox(#3+GetString(1328), @OneStringRec, mfOkBeep);
    exit;
  end;

  writeln(Result, '@ *********************************');
  writeln(Result, '@ HP 48 Directory Variable');
  writeln(Result, '@ Created using HPShell V' + ShellVer);
  writeln(Result, '@ *********************************');

  if Comment then
  begin
    GetDate(y,m,d,dw);
    GetTime(h,min,sec,hs);

    writeln(Result, '@ Date   : ', AddZero(d), '.', AddZero(m), '.', AddZero(y));
    writeln(Result, '@ Time   : ', AddZero(h), ':', AddZero(min), ':', AddZero(sec));
    writeln(Result, '@ Subdirs: ', NumOfDirs);
    writeln(Result, '@ Files  : ', NumOfFiles);
    writeln(Result, '@ *********************************');
  end;
  writeln(Result, '');

  if assigned(Items) then ok:= WriteDir(Result, Items, true, true);

  close(Result);

  if (not ok) or (Error <> 0) then
  begin
    FDelete(ResultFile);
  end;

  MakeResultFile:= Ok;
end;

procedure TCreateHPDir.Update(s: string; r: boolean);
var Rec: TInfoBarRec;
begin
  if assigned(Action) then
  begin
    PActionView(Action)^.FileName:= s;
    PActionView(Action)^.Reading := r;
    Action^.DrawView;
  end;

  if not r then
  begin
    if NumOfWrittenFiles = 0 then
    begin
      Rec.Text1:= GetString(1322); { Bitte warten Sie... }
      Rec.Text2:= '';
      Rec.Size := NumOfFiles;
      Message(InfoBar, evBroadCast, cmResetInfoBar, @Rec);
    end;
    inc(NumOfWrittenFiles);
    Rec.Text1:= '';
    Rec.Text2:= '';
    Rec.Size := NumOfWrittenFiles;
    Message(InfoBar, evBroadCast, cmInfoBarRec, @Rec);
  end;
end;

procedure TCreateHPDir.ShowStat;
var Rec: TInfoBarRec;
begin
  AttentionBeep;

  StatusDlg^.Flags:= StatusDlg^.Flags or wfClose;

  if assigned(Action) then Action^.Hide;
  if assigned(Status) then Status^.Show;

  Rec.Text1:= GetString(1329); { beendet:  }
  Rec.Text2:= GetString(1330); { beliebige Taste ! }
  Rec.Size := 0;
  Message(InfoBar, evBroadCast, cmResetInfoBar, @Rec);

  StatusDlg^.Redraw;

  PTWApp(Application)^.WaitForKey;
end;


(********************************************************************)
(**                        TActionView                             **)
(********************************************************************)

procedure TActionView.Draw;
var
  Buf: TDrawBuffer;
  Color: Byte;
begin
  Color := GetColor(6);
  MoveChar(Buf, ' ', Color, Size.X);
  if reading then { lese     :  } { schreibe : }
    MoveStr(Buf, GetString(1331) + GetDirString(FileName, 36), Color) else
    MoveStr(Buf, GetString(1332) + GetDirString(FileName, 36), Color);
  WriteLine(0, 0, Size.X, 1, Buf);
end;

(********************************************************************)
(**                        TStatusView                             **)
(********************************************************************)

procedure TStatusView.Draw;
var
  Buf: TDrawBuffer;
  Color: Byte;
  s: string;
begin
  Color := GetColor(6);

  MoveChar(Buf, ' ', Color, Size.X);
  str(P^.NumOfDirs, s); { Verzeichnisse: }
  MoveStr(Buf, GetString(1333) + s, Color);
  WriteLine(0, 0, Size.X, 1, Buf);

  MoveChar(Buf, ' ', Color, Size.X);
  str(P^.NumOfFiles, s); { Dateien      : }
  MoveStr(Buf, GetString(1334) + s, Color);
  WriteLine(0, 1, Size.X, 1, Buf);

  MoveChar(Buf, ' ', Color, Size.X);
  str(P^.GetResultSize, s); { GrӇe        : }
  MoveStr(Buf, GetString(1335) + s + ' Bytes', Color);
  WriteLine(0, 2, Size.X, 1, Buf);
end;




end.

page up

This page was created using Code Colorizer -    http://www.chami.com/colorizer





Bookmark this page.
 
 

Copyright © Tom Wellige, 1995-2010
All Rights Reserved