Browse Source

[*] the fake (!) TOKENS.PAS still contained the typo bug
FSplit(,n,d,e) (correctly FSplit(,d,n,e))
[*] CodeComplete had a very ugly bug - coordinates were document-relative
(instead of being screen-relative)
[*] TResourceStream didn't count the size of the resource names when
determining the file size and this could lead to the last resources not
loaded correctly


[+] Ctrl-Enter in editor now tries to open the file at cursor
[+] CodeComplete option added to Options|Environment|Editor
[+] user interface for managing CodeComplete implemented
[+] user interface for CodeTemplates implemented
[+] CodeComplete wordlist and CodeTemplates stored in desktop file
[+] help topic size no longer limited to 64KB when compiled with FPC

michael 25 years ago
parent
commit
682acf3bd8
6 changed files with 810 additions and 111 deletions
  1. 242 5
      ide/text/fpcodcmp.pas
  2. 404 31
      ide/text/fpcodtmp.pas
  3. 20 3
      ide/text/fpmhelp.inc
  4. 32 3
      ide/text/fpstring.pas
  5. 83 65
      ide/text/whlpview.pas
  6. 29 4
      ide/text/wresourc.pas

+ 242 - 5
ide/text/fpcodcmp.pas

@@ -2,20 +2,52 @@ unit FPCodCmp; { CodeComplete }
 
 interface
 
-uses Objects,
-     WUtils;
+uses Objects,Drivers,
+     WUtils,WViews;
 
-const CodeCompleteWords : PTextCollection = nil;
+type
+     PCodeCompleteWordList = ^TCodeCompleteWordList;
+     TCodeCompleteWordList = object(TTextCollection)
+     end;
+
+    PCodeCompleteDialog = ^TCodeCompleteDialog;
+    TCodeCompleteDialog = object(TCenterDialog)
+      constructor Init;
+      function    Execute: Word; virtual;
+      procedure   HandleEvent(var Event: TEvent); virtual;
+    private
+      CodeCompleteLB : PAdvancedListBox;
+      procedure Add;
+      procedure Edit;
+      procedure Delete;
+    end;
 
 function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
 
 procedure InitCodeComplete;
+function  LoadCodeComplete(var S: TStream): boolean;
+function  StoreCodeComplete(var S: TStream): boolean;
 procedure DoneCodeComplete;
 
+const CodeCompleteWords : PCodeCompleteWordList = nil;
+
+procedure RegisterCodeComplete;
+
 implementation
 
-uses WEditor,
-     FPViews;
+uses Commands,Views,Dialogs,MsgBox,
+     WEditor,
+     FPConst,FPString,FPViews;
+
+{$ifndef NOOBJREG}
+const
+  RCodeCompleteWordList: TStreamRec = (
+     ObjType: 14401;
+     VmtLink: Ofs(TypeOf(TCodeCompleteWordList)^);
+     Load:    @TCodeCompleteWordList.Load;
+     Store:   @TCodeCompleteWordList.Store
+  );
+{$endif}
 
 function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
 var OK: boolean;
@@ -50,10 +82,215 @@ begin
   }
 end;
 
+function LoadCodeComplete(var S: TStream): boolean;
+var C: PCodeCompleteWordList;
+    OK: boolean;
+begin
+  New(C, Load(S));
+  OK:=Assigned(C) and (S.Status=stOk);
+  if OK then
+    begin
+      if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
+      CodeCompleteWords:=C;
+    end
+  else
+    if Assigned(C) then
+      Dispose(C, Done);
+  LoadCodeComplete:=OK;
+end;
+
+function StoreCodeComplete(var S: TStream): boolean;
+var OK: boolean;
+begin
+  OK:=Assigned(CodeCompleteWords);
+  if OK then
+  begin
+    CodeCompleteWords^.Store(S);
+    OK:=OK and (S.Status=stOK);
+  end;
+  StoreCodeComplete:=OK;
+end;
+
 procedure DoneCodeComplete;
 begin
   if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
   CodeCompleteWords:=nil;
 end;
 
+constructor TCodeCompleteDialog.Init;
+var R,R2,R3: TRect;
+    SB: PScrollBar;
+begin
+  R.Assign(0,0,46,16);
+  inherited Init(R,'CodeComplete');
+
+  GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
+  R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
+  New(SB, Init(R2)); Insert(SB);
+  New(CodeCompleteLB, Init(R,1,SB));
+  Insert(CodeCompleteLB);
+  R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
+  Insert(New(PLabel, Init(R2, '~K~eywords', CodeCompleteLB)));
+
+  R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
+  Insert(New(PButton, Init(R, 'O~K~', cmOK, bfNormal)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, '~E~dit', cmEditItem, bfDefault)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, '~N~ew', cmAddItem, bfNormal)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, '~D~elete', cmDeleteItem, bfNormal)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
+  SelectNext(false);
+end;
+
+procedure TCodeCompleteDialog.HandleEvent(var Event: TEvent);
+var DontClear: boolean;
+begin
+  case Event.What of
+    evKeyDown :
+      begin
+        DontClear:=false;
+        case Event.KeyCode of
+          kbIns  :
+            Message(@Self,evCommand,cmAddItem,nil);
+          kbDel  :
+            Message(@Self,evCommand,cmDeleteItem,nil);
+        else DontClear:=true;
+        end;
+        if DontClear=false then ClearEvent(Event);
+      end;
+    evBroadcast :
+      case Event.Command of
+        cmListItemSelected :
+          if Event.InfoPtr=pointer(CodeCompleteLB) then
+            Message(@Self,evCommand,cmEditItem,nil);
+      end;
+    evCommand :
+      begin
+        DontClear:=false;
+        case Event.Command of
+          cmAddItem    : Add;
+          cmDeleteItem : Delete;
+          cmEditItem   : Edit;
+        else DontClear:=true;
+        end;
+        if DontClear=false then ClearEvent(Event);
+      end;
+  end;
+  inherited HandleEvent(Event);
+end;
+
+function TCodeCompleteDialog.Execute: Word;
+var R: word;
+    C: PCodeCompleteWordList;
+    I: integer;
+    S1,S2,S3: string;
+    W: word;
+begin
+  New(C, Init(10,20));
+  if Assigned(CodeCompleteWords) then
+  for I:=0 to CodeCompleteWords^.Count-1 do
+    C^.Insert(NewStr(GetStr(CodeCompleteWords^.At(I))));
+  CodeCompleteLB^.NewList(C);
+  R:=inherited Execute;
+  if R=cmOK then
+    begin
+      if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
+      CodeCompleteWords:=C;
+    end
+  else
+    Dispose(C, Done);
+  Execute:=R;
+end;
+
+procedure TCodeCompleteDialog.Add;
+var IC: boolean;
+    S: string;
+    P: PString;
+    Cmd: word;
+    CanExit: boolean;
+    I: sw_integer;
+begin
+  IC:=CodeCompleteLB^.Range=0;
+  if IC=false then
+    S:=GetStr(CodeCompleteLB^.List^.At(CodeCompleteLB^.Focused))
+  else
+    S:='';
+
+  repeat
+    Cmd:=InputBox(dialog_codecomplete_add,label_codecomplete_add_keyword,S,255);
+    CanExit:=Cmd<>cmOK;
+    if CanExit=false then
+      begin
+        CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,I)=false;
+        if CanExit=false then
+          ErrorBox('"'+S+'" is already in the list',nil);
+      end;
+  until CanExit;
+
+  if Cmd=cmOK then
+    begin
+      P:=NewStr(S);
+      with CodeCompleteLB^ do
+      begin
+        List^.Insert(P);
+        SetRange(List^.Count);
+        SetFocusedItem(P);
+      end;
+      ReDraw;
+    end;
+end;
+
+procedure TCodeCompleteDialog.Edit;
+var S: string;
+    I,T: sw_integer;
+    Cmd: word;
+    CanExit: boolean;
+    P: PString;
+begin
+  if CodeCompleteLB^.Range=0 then Exit;
+  I:=CodeCompleteLB^.Focused;
+  S:=GetStr(CodeCompleteLB^.List^.At(I));
+  repeat
+    Cmd:=InputBox(dialog_codecomplete_edit,label_codecomplete_edit_keyword,S,255);
+    CanExit:=Cmd<>cmOK;
+    if CanExit=false then
+      begin
+        CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,T)=false;
+        CanExit:=CanExit or (T=I);
+        if CanExit=false then
+          ErrorBox('"'+S+'" is already in the list',nil);
+      end;
+  until CanExit;
+
+  if Cmd=cmOK then
+    begin
+      P:=NewStr(S);
+      with CodeCompleteLB^ do
+      begin
+        List^.AtFree(I);
+        List^.Insert(P);
+        SetFocusedItem(P);
+      end;
+      ReDraw;
+    end;
+end;
+
+procedure TCodeCompleteDialog.Delete;
+begin
+  if CodeCompleteLB^.Range=0 then Exit;
+  CodeCompleteLB^.List^.AtFree(CodeCompleteLB^.Focused);
+  CodeCompleteLB^.SetRange(CodeCompleteLB^.List^.Count);
+  ReDraw;
+end;
+
+procedure RegisterCodeComplete;
+begin
+{$ifndef NOOBJREG}
+  RegisterType(RCodeCompleteWordList);
+{$endif}
+end;
+
 END.

+ 404 - 31
ide/text/fpcodtmp.pas

@@ -2,8 +2,9 @@ unit FPCodTmp; { Code Templates }
 
 interface
 
-uses Objects,
-     WUtils;
+uses Objects,Drivers,Dialogs,
+     WUtils,WViews,WEditor,
+     FPViews;
 
 type
     PCodeTemplate = ^TCodeTemplate;
@@ -11,6 +12,12 @@ type
       constructor Init(const AShortCut: string; AText: PUnsortedStringCollection);
       function    GetShortCut: string;
       procedure   GetText(AList: PUnsortedStringCollection);
+      procedure   SetShortCut(const AShortCut: string);
+      procedure   SetText(AList: PUnsortedStringCollection);
+      procedure   GetParams(var AShortCut: string; Lines: PUnsortedStringCollection);
+      procedure   SetParams(const AShortCut: string; Lines: PUnsortedStringCollection);
+      constructor Load(var S: TStream);
+      procedure   Store(var S: TStream);
       destructor  Done; virtual;
     private
       ShortCut: PString;
@@ -23,15 +30,67 @@ type
       function SearchByShortCut(const ShortCut: string): PCodeTemplate; virtual;
     end;
 
+    PCodeTemplateListBox = ^TCodeTemplateListBox;
+    TCodeTemplateListBox = object(TAdvancedListBox)
+      function GetText(Item,MaxLen: Sw_Integer): String; virtual;
+    end;
+
+    PCodeTemplateDialog = ^TCodeTemplateDialog;
+    TCodeTemplateDialog = object(TCenterDialog)
+      constructor Init(const ATitle: string; ATemplate: PCodeTemplate);
+      function    Execute: Word; virtual;
+    private
+      Template   : PCodeTemplate;
+      ShortcutIL : PInputLine;
+      CodeMemo   : PFPCodeMemo;
+    end;
+
+    PCodeTemplatesDialog = ^TCodeTemplatesDialog;
+    TCodeTemplatesDialog = object(TCenterDialog)
+      constructor Init;
+      function    Execute: Word; virtual;
+      procedure   HandleEvent(var Event: TEvent); virtual;
+    private
+      CodeTemplatesLB : PCodeTemplateListBox;
+      TemplateViewer  : PFPCodeMemo;
+      procedure Add;
+      procedure Edit;
+      procedure Delete;
+      procedure Update;
+    end;
+
 const CodeTemplates : PCodeTemplateCollection = nil;
 
 function FPTranslateCodeTemplate(const Shortcut: string; ALines: PUnsortedStringCollection): boolean;
 
 procedure InitCodeTemplates;
+function  LoadCodeTemplates(var S: TStream): boolean;
+function  StoreCodeTemplates(var S: TStream): boolean;
 procedure DoneCodeTemplates;
 
+procedure RegisterCodeTemplates;
+
 implementation
 
+uses Commands,Views,MsgBox,App,
+     FPConst,FPString;
+
+{$ifndef NOOBJREG}
+const
+  RCodeTemplate: TStreamRec = (
+     ObjType: 14501;
+     VmtLink: Ofs(TypeOf(TCodeTemplate)^);
+     Load:    @TCodeTemplate.Load;
+     Store:   @TCodeTemplate.Store
+  );
+  RCodeTemplateCollection: TStreamRec = (
+     ObjType: 14502;
+     VmtLink: Ofs(TypeOf(TCodeTemplateCollection)^);
+     Load:    @TCodeTemplateCollection.Load;
+     Store:   @TCodeTemplateCollection.Store
+  );
+{$endif}
+
 constructor TCodeTemplate.Init(const AShortCut: string; AText: PUnsortedStringCollection);
 procedure CopyIt(P: PString); {$ifndef FPC}far;{$endif}
 begin
@@ -40,9 +99,7 @@ end;
 begin
   inherited Init;
   ShortCut:=NewStr(AShortCut);
-  New(Text, Init(10,10));
-  if Assigned(AText) then
-  AText^.ForEach(@CopyIt);
+  SetText(AText);
 end;
 
 function TCodeTemplate.GetShortCut: string;
@@ -56,8 +113,44 @@ begin
   AList^.Insert(NewStr(GetStr(P)));
 end;
 begin
-  if Assigned(AList) then
-  Text^.ForEach(@CopyIt);
+  if Assigned(AList) and Assigned(Text) then
+    Text^.ForEach(@CopyIt);
+end;
+
+procedure TCodeTemplate.SetShortCut(const AShortCut: string);
+begin
+  if Assigned(ShortCut) then DisposeStr(ShortCut);
+  ShortCut:=NewStr(AShortCut);
+end;
+
+procedure TCodeTemplate.SetText(AList: PUnsortedStringCollection);
+begin
+  if Assigned(Text) then Dispose(Text, Done);
+  New(Text, CreateFrom(AList));
+end;
+
+procedure TCodeTemplate.GetParams(var AShortCut: string; Lines: PUnsortedStringCollection);
+begin
+  AShortCut:=GetShortCut;
+  GetText(Lines);
+end;
+
+procedure TCodeTemplate.SetParams(const AShortCut: string; Lines: PUnsortedStringCollection);
+begin
+  SetShortCut(AShortCut);
+  SetText(Lines);
+end;
+
+constructor TCodeTemplate.Load(var S: TStream);
+begin
+  ShortCut:=S.ReadStr;
+  New(Text, Load(S));
+end;
+
+procedure TCodeTemplate.Store(var S: TStream);
+begin
+  S.WriteStr(ShortCut);
+  Text^.Store(S);
 end;
 
 destructor TCodeTemplate.Done;
@@ -105,30 +198,6 @@ begin
     if OK then
       P^.GetText(ALines);
   end;
-{$ifdef GABOR}
-  {
-    this is for testing purposes only. once the user front-end for defining
-    CodeTemplates is implemented, this can be removed - Gabor
-  }
-  if (OK=false) and (UpCaseStr(ShortCut)='CASES') then
-  begin
-    OK:=true;
-    ALines^.Insert(NewStr('case  of'));
-    ALines^.Insert(NewStr('  : ;'));
-    ALines^.Insert(NewStr('  : ;'));
-    ALines^.Insert(NewStr('end;'));
-  end else
-  if (OK=false) and (UpCaseStr(ShortCut)='CASEE') then
-  begin
-    OK:=true;
-    ALines^.Insert(NewStr('case  of'));
-    ALines^.Insert(NewStr('  : ;'));
-    ALines^.Insert(NewStr('  : ;'));
-    ALines^.Insert(NewStr('else ;'));
-    ALines^.Insert(NewStr('end;'));
-  end else
-  ;
-{$endif}
   FPTranslateCodeTemplate:=OK;
 end;
 
@@ -139,10 +208,314 @@ begin
   New(CodeTemplates, Init(10,10));
 end;
 
+function LoadCodeTemplates(var S: TStream): boolean;
+var C: PCodeTemplateCollection;
+    OK: boolean;
+begin
+  New(C, Load(S));
+  OK:=Assigned(C) and (S.Status=stOk);
+  if OK then
+    begin
+      if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
+      CodeTemplates:=C;
+    end
+  else
+    if Assigned(C) then
+      Dispose(C, Done);
+  LoadCodeTemplates:=OK;
+end;
+
+function StoreCodeTemplates(var S: TStream): boolean;
+var OK: boolean;
+begin
+  OK:=Assigned(CodeTemplates);
+  if OK then
+  begin
+    CodeTemplates^.Store(S);
+    OK:=OK and (S.Status=stOK);
+  end;
+  StoreCodeTemplates:=OK;
+end;
+
 procedure DoneCodeTemplates;
 begin
   if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
   CodeTemplates:=nil;
 end;
 
+function TCodeTemplateListBox.GetText(Item,MaxLen: Sw_Integer): String;
+var P: PCodeTemplate;
+begin
+  P:=List^.At(Item);
+  GetText:=P^.GetShortCut;
+end;
+
+constructor TCodeTemplateDialog.Init(const ATitle: string; ATemplate: PCodeTemplate);
+var R,R2,R3: TRect;
+    Items: PSItem;
+    I,KeyCount: sw_integer;
+begin
+  R.Assign(0,0,52,15);
+  inherited Init(R,ATitle);
+  Template:=ATemplate;
+
+  GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
+  Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+46;
+  New(ShortCutIL, Init(R, 128)); Insert(ShortcutIL);
+  R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~S~hortcut', ShortcutIL)));
+  R.Move(0,3); R.B.Y:=R.A.Y+8;
+  New(CodeMemo, Init(R, nil,nil,nil,4096)); Insert(CodeMemo);
+  R2.Copy(R); R2.Move(-1,-1); R2.B.Y:=R2.A.Y+1; Insert(New(PLabel, Init(R2, '~T~emplate content', CodeMemo)));
+
+  InsertButtons(@Self);
+
+  ShortcutIL^.Select;
+end;
+
+function TCodeTemplateDialog.Execute: Word;
+var R: word;
+    S: string;
+    L: PUnsortedStringCollection;
+    W: word;
+begin
+  New(L, Init(10,10));
+  S:=Template^.GetShortCut;
+  Template^.GetText(L);
+  ShortcutIL^.SetData(S);
+  CodeMemo^.SetContent(L);
+  R:=inherited Execute;
+  if R=cmOK then
+  begin
+    L^.FreeAll;
+    ShortcutIL^.GetData(S);
+    CodeMemo^.GetContent(L);
+    Template^.SetShortcut(S);
+    Template^.SetText(L);
+  end;
+  Execute:=R;
+end;
+
+constructor TCodeTemplatesDialog.Init;
+var R,R2,R3: TRect;
+    SB: PScrollBar;
+begin
+  R.Assign(0,0,46,20);
+  inherited Init(R,'CodeTemplates');
+
+  GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R.B.Y:=R.A.Y+10;
+  R3.Copy(R); Dec(R.B.X,12);
+  R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
+  New(SB, Init(R2)); Insert(SB);
+  New(CodeTemplatesLB, Init(R,1,SB));
+  Insert(CodeTemplatesLB);
+  R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
+  Insert(New(PLabel, Init(R2, '~T~emplates', CodeTemplatesLB)));
+
+  GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y,12);
+  R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
+  New(SB, Init(R2)); Insert(SB);
+  New(TemplateViewer, Init(R,nil,SB,nil,4096));
+  with TemplateViewer^ do
+  begin
+    IsReadOnly:=true;
+    AlwaysShowScrollBars:=true;
+  end;
+  Insert(TemplateViewer);
+
+  R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
+  Insert(New(PButton, Init(R, 'O~K~', cmOK, bfNormal)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, '~E~dit', cmEditItem, bfDefault)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, '~N~ew', cmAddItem, bfNormal)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, '~D~elete', cmDeleteItem, bfNormal)));
+  R.Move(0,2);
+  Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
+  SelectNext(false);
+end;
+
+procedure TCodeTemplatesDialog.Update;
+var C: PUnsortedStringCollection;
+begin
+  if CodeTemplatesLB^.Range=0 then C:=nil else
+    C:=PCodeTemplate(CodeTemplatesLB^.GetFocusedItem)^.Text;
+  TemplateViewer^.SetContent(C);
+  ReDraw;
+end;
+
+procedure TCodeTemplatesDialog.HandleEvent(var Event: TEvent);
+var DontClear: boolean;
+begin
+  case Event.What of
+    evKeyDown :
+      begin
+        DontClear:=false;
+        case Event.KeyCode of
+          kbIns  :
+            Message(@Self,evCommand,cmAddItem,nil);
+          kbDel  :
+            Message(@Self,evCommand,cmDeleteItem,nil);
+        else DontClear:=true;
+        end;
+        if DontClear=false then ClearEvent(Event);
+      end;
+    evBroadcast :
+      case Event.Command of
+        cmListItemSelected :
+          if Event.InfoPtr=pointer(CodeTemplatesLB) then
+            Message(@Self,evCommand,cmEditItem,nil);
+        cmListFocusChanged :
+          if Event.InfoPtr=pointer(CodeTemplatesLB) then
+            Message(@Self,evBroadcast,cmUpdate,nil);
+        cmUpdate :
+          Update;
+      end;
+    evCommand :
+      begin
+        DontClear:=false;
+        case Event.Command of
+          cmAddItem    : Add;
+          cmDeleteItem : Delete;
+          cmEditItem   : Edit;
+        else DontClear:=true;
+        end;
+        if DontClear=false then ClearEvent(Event);
+      end;
+  end;
+  inherited HandleEvent(Event);
+end;
+
+function TCodeTemplatesDialog.Execute: Word;
+var R: word;
+    P: PCodeTemplate;
+    C: PCodeTemplateCollection;
+    L: PUnsortedStringCollection;
+    I: integer;
+    S1,S2,S3: string;
+    W: word;
+begin
+  New(C, Init(10,20));
+  if Assigned(CodeTemplates) then
+  for I:=0 to CodeTemplates^.Count-1 do
+    begin
+      P:=CodeTemplates^.At(I);
+      New(L, Init(10,50));
+      P^.GetText(L);
+      C^.Insert(New(PCodeTemplate, Init(P^.GetShortCut,L)));
+      Dispose(L, Done);
+    end;
+  CodeTemplatesLB^.NewList(C);
+  Update;
+  R:=inherited Execute;
+  if R=cmOK then
+    begin
+      if Assigned(CodeTemplates) then Dispose(CodeTemplates, Done);
+      CodeTemplates:=C;
+    end
+  else
+    Dispose(C, Done);
+  Execute:=R;
+end;
+
+procedure TCodeTemplatesDialog.Add;
+var P,P2: PCodeTemplate;
+    IC: boolean;
+    S: string;
+    L: PUnsortedStringCollection;
+    I: sw_integer;
+    W: word;
+    Cmd: word;
+    CanExit: boolean;
+begin
+  New(L, Init(10,10));
+  IC:=CodeTemplatesLB^.Range=0;
+  if IC=false then
+    begin
+      P:=CodeTemplatesLB^.List^.At(CodeTemplatesLB^.Focused);
+      P^.GetParams(S,L);
+    end
+  else
+    begin
+      S:='';
+    end;
+  New(P, Init(S,L));
+  repeat
+    Cmd:=Application^.ExecuteDialog(New(PCodeTemplateDialog, Init('New template',P)), nil);
+    CanExit:=(Cmd<>cmOK);
+    if CanExit=false then
+      begin
+        P2:=PCodeTemplateCollection(CodeTemplatesLB^.List)^.SearchByShortCut(P^.GetShortCut);
+        CanExit:=(Assigned(P2)=false);
+        if CanExit=false then
+          ErrorBox('A template named "'+P^.GetShortCut+'" is already in the list',nil);
+      end;
+  until CanExit;
+  if Cmd=cmOK then
+    begin
+      CodeTemplatesLB^.List^.Insert(P);
+      CodeTemplatesLB^.SetRange(CodeTemplatesLB^.List^.Count);
+      CodeTemplatesLB^.SetFocusedItem(P);
+      Update;
+    end
+  else
+    Dispose(P, Done);
+  Dispose(L, Done);
+end;
+
+procedure TCodeTemplatesDialog.Edit;
+var P,O,P2: PCodeTemplate;
+    I: sw_integer;
+    S: string;
+    L: PUnsortedStringCollection;
+    Cmd: word;
+    CanExit: boolean;
+begin
+  if CodeTemplatesLB^.Range=0 then Exit;
+  New(L, Init(10,10));
+  I:=CodeTemplatesLB^.Focused;
+  O:=CodeTemplatesLB^.List^.At(I);
+  O^.GetParams(S,L);
+  P:=New(PCodeTemplate, Init(S, L));
+  repeat
+    Cmd:=Application^.ExecuteDialog(New(PCodeTemplateDialog, Init('Modify template',P)), nil);
+    CanExit:=(Cmd<>cmOK);
+    if CanExit=false then
+      begin
+        P2:=PCodeTemplateCollection(CodeTemplatesLB^.List)^.SearchByShortCut(P^.GetShortCut);
+        CanExit:=(Assigned(P2)=false) or (CodeTemplatesLB^.List^.IndexOf(P2)=I);
+        if CanExit=false then
+          ErrorBox('A template named "'+P^.GetShortCut+'" is already in the list',nil);
+      end;
+  until CanExit;
+  if Cmd=cmOK then
+    begin
+      with CodeTemplatesLB^ do
+      begin
+        List^.AtFree(I); O:=nil;
+        List^.Insert(P);
+        SetFocusedItem(P);
+      end;
+      Update;
+    end;
+  Dispose(L, Done);
+end;
+
+procedure TCodeTemplatesDialog.Delete;
+begin
+  if CodeTemplatesLB^.Range=0 then Exit;
+  CodeTemplatesLB^.List^.AtFree(CodeTemplatesLB^.Focused);
+  CodeTemplatesLB^.SetRange(CodeTemplatesLB^.List^.Count);
+  Update;
+end;
+
+
+procedure RegisterCodeTemplates;
+begin
+{$ifndef NOOBJREG}
+  RegisterType(RCodeTemplate);
+  RegisterType(RCodeTemplateCollection);
+{$endif}
+end;
+
 END.

+ 20 - 3
ide/text/fpmhelp.inc

@@ -44,7 +44,7 @@ end;
 type
     PHelpFileListBox = ^THelpFileListBox;
     THelpFileListBox = object(TListBox)
-      function GetText(Item: Integer; MaxLen: Integer): String; virtual;
+      function GetText(Item: sw_Integer; MaxLen: sw_Integer): String; virtual;
     end;
 
     PHelpFilesDialog = ^THelpFilesDialog;
@@ -57,7 +57,7 @@ type
       C : PUnsortedStringCollection;
     end;
 
-function THelpFileListBox.GetText(Item: Integer; MaxLen: Integer): String;
+function THelpFileListBox.GetText(Item: sw_Integer; MaxLen: sw_Integer): String;
 var S: string;
     P: integer;
 begin
@@ -190,7 +190,24 @@ end;
 
 {
   $Log$
-  Revision 1.7  1999-05-22 13:44:31  peter
+  Revision 1.8  2000-02-07 08:29:13  michael
+  [*] the fake (!) TOKENS.PAS still contained the typo bug
+       FSplit(,n,d,e) (correctly FSplit(,d,n,e))
+  [*] CodeComplete had a very ugly bug - coordinates were document-relative
+      (instead of being screen-relative)
+  [*] TResourceStream didn't count the size of the resource names when
+      determining the file size and this could lead to the last resources not
+      loaded correctly
+
+
+  [+] Ctrl-Enter in editor now tries to open the file at cursor
+  [+] CodeComplete option added to Options|Environment|Editor
+  [+] user interface for managing CodeComplete implemented
+  [+] user interface for CodeTemplates implemented
+  [+] CodeComplete wordlist and CodeTemplates stored in desktop file
+  [+] help topic size no longer limited to 64KB when compiled with FPC
+
+  Revision 1.7  1999/05/22 13:44:31  peter
     * fixed couple of bugs
 
   Revision 1.6  1999/03/01 15:41:56  peter

+ 32 - 3
ide/text/fpstring.pas

@@ -13,7 +13,8 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  **********************************************************************}
-{$mode objfpc}
+{$i globdir.inc}
+{$ifdef USERESSTRINGS}{$mode objfpc}{$endif}
 unit fpstring;
 
   interface
@@ -21,7 +22,7 @@ unit fpstring;
     uses
        fpconst;
 
-{$ifdef FPC}
+{$ifdef USERESSTRINGS}
     resourcestring
 {$else}
     const
@@ -110,6 +111,8 @@ unit fpstring;
       menu_options_env       = '~E~nvironment';
       menu_options_env_preferences = '~P~references...';
       menu_options_env_editor= '~E~ditor...';
+      menu_options_env_codecomplete = 'Code~C~omplete...';
+      menu_options_env_codetemplates = 'Code~T~emplates...';
       menu_options_env_desktop = '~D~esktop...';
       menu_options_env_mouse = '~M~ouse...';
       menu_options_env_startup = '~S~tartup...';
@@ -181,6 +184,15 @@ unit fpstring;
       menu_key_help_topicsearch = 'Ctrl+F1';
       menu_key_help_prevtopic= 'Alt+F1';
 
+      dialog_codecomplete_add = 'Add new keyword';
+      label_codecomplete_add_keyword = 'Keyword';
+
+      dialog_codecomplete_edit = 'Edit keyword';
+      label_codecomplete_edit_keyword = 'Keyword';
+
+      dialog_codetemplates_add = 'Add new template';
+      dialog_codetemplates_edit = 'Edit template';
+
       { status line entries }
       status_help            = '~F1~ Help';
       status_help_on_help    = '~F1~ Help on help';
@@ -210,7 +222,24 @@ unit fpstring;
 end.
 {
   $Log$
-  Revision 1.1  2000-01-23 21:25:17  florian
+  Revision 1.2  2000-02-07 08:29:13  michael
+  [*] the fake (!) TOKENS.PAS still contained the typo bug
+       FSplit(,n,d,e) (correctly FSplit(,d,n,e))
+  [*] CodeComplete had a very ugly bug - coordinates were document-relative
+      (instead of being screen-relative)
+  [*] TResourceStream didn't count the size of the resource names when
+      determining the file size and this could lead to the last resources not
+      loaded correctly
+
+
+  [+] Ctrl-Enter in editor now tries to open the file at cursor
+  [+] CodeComplete option added to Options|Environment|Editor
+  [+] user interface for managing CodeComplete implemented
+  [+] user interface for CodeTemplates implemented
+  [+] CodeComplete wordlist and CodeTemplates stored in desktop file
+  [+] help topic size no longer limited to 64KB when compiled with FPC
+
+  Revision 1.1  2000/01/23 21:25:17  florian
     + start of internationalization support
 
 }

+ 83 - 65
ide/text/whlpview.pas

@@ -57,7 +57,7 @@ type
       PHelpKeyword = ^THelpKeyword;
       THelpKeyword = record
         KWord    : PString;
-        Index    : integer;
+        Index    : sw_integer;
       end;
 
       PLinkCollection = ^TLinkCollection;
@@ -72,9 +72,9 @@ type
 
       PKeywordCollection = ^TKeywordCollection;
       TKeywordCollection = object({TSorted}TCollection)
-        function  At(Index: Integer): PHelpKeyword;
+        function  At(Index: sw_Integer): PHelpKeyword;
         procedure FreeItem(Item: Pointer); virtual;
-        function  Compare(Key1, Key2: Pointer): Integer; virtual;
+        function  Compare(Key1, Key2: Pointer): sw_Integer; virtual;
       end;
 
 {      TSearchRelation = (srEqual,srGreater,srLess,srGreatEqu,srLessEqu);
@@ -91,19 +91,19 @@ type
         Links: PLinkCollection;
         ColorAreas: PColorAreaCollection;
         constructor Init(ATopic: PTopic);
-        procedure   SetParams(AMargin, AWidth: integer); virtual;
+        procedure   SetParams(AMargin, AWidth: sw_integer); virtual;
         function    GetLineCount: sw_integer; virtual;
         function    GetLineText(Line: sw_integer): string; virtual;
-        function    GetLinkCount: integer; virtual;
-        procedure   GetLinkBounds(Index: integer; var R: TRect); virtual;
-        function    GetLinkFileID(Index: integer): word; virtual;
-        function    GetLinkContext(Index: integer): THelpCtx; virtual;
-        function    GetColorAreaCount: integer; virtual;
-        procedure   GetColorAreaBounds(Index: integer; var R: TRect); virtual;
-        function    GetColorAreaColor(Index: integer): word; virtual;
+        function    GetLinkCount: sw_integer; virtual;
+        procedure   GetLinkBounds(Index: sw_integer; var R: TRect); virtual;
+        function    GetLinkFileID(Index: sw_integer): word; virtual;
+        function    GetLinkContext(Index: sw_integer): THelpCtx; virtual;
+        function    GetColorAreaCount: sw_integer; virtual;
+        procedure   GetColorAreaBounds(Index: sw_integer; var R: TRect); virtual;
+        function    GetColorAreaColor(Index: sw_integer): word; virtual;
         destructor  Done; virtual;
       private
-        Width,Margin: integer;
+        Width,Margin: sw_integer;
         StockItem: boolean;
         procedure  ReBuild;
       end;
@@ -112,15 +112,15 @@ type
         Context_     : THelpCtx;
         Delta_       : TPoint;
         CurPos_      : TPoint;
-        CurLink_     : integer;
+        CurLink_     : sw_integer;
         FileID_      : word;
       end;
 
       PHelpViewer = ^THelpViewer;
       THelpViewer = object(TEditor)
-        Margin: integer;
+        Margin: sw_integer;
         HelpTopic: PHelpTopic;
-        CurLink: integer;
+        CurLink: sw_integer;
         constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
         procedure   ChangeBounds(var Bounds: TRect); virtual;
         procedure   Draw; virtual;
@@ -128,20 +128,20 @@ type
         procedure   SetCurPtr(X,Y: sw_integer); virtual;
         function    GetLineCount: sw_integer; virtual;
         function    GetLineText(Line: sw_integer): string; virtual;
-        function    GetLinkCount: integer; virtual;
-        procedure   GetLinkBounds(Index: integer; var R: TRect); virtual;
-        function    GetLinkFileID(Index: integer): word; virtual;
-        function    GetLinkContext(Index: integer): THelpCtx; virtual;
-        function    GetLinkText(Index: integer): string; virtual;
-        function    GetColorAreaCount: integer; virtual;
-        procedure   GetColorAreaBounds(Index: integer; var R: TRect); virtual;
-        function    GetColorAreaColor(Index: integer): word; virtual;
+        function    GetLinkCount: sw_integer; virtual;
+        procedure   GetLinkBounds(Index: sw_integer; var R: TRect); virtual;
+        function    GetLinkFileID(Index: sw_integer): word; virtual;
+        function    GetLinkContext(Index: sw_integer): THelpCtx; virtual;
+        function    GetLinkText(Index: sw_integer): string; virtual;
+        function    GetColorAreaCount: sw_integer; virtual;
+        procedure   GetColorAreaBounds(Index: sw_integer; var R: TRect); virtual;
+        function    GetColorAreaColor(Index: sw_integer): word; virtual;
         procedure   SelectNextLink(ANext: boolean); virtual;
         procedure   SwitchToIndex; virtual;
         procedure   SwitchToTopic(SourceFileID: word; Context: THelpCtx); virtual;
         procedure   SetTopic(Topic: PTopic); virtual;
-        procedure   SetCurLink(Link: integer); virtual;
-        procedure   SelectLink(Index: integer); virtual;
+        procedure   SetCurLink(Link: sw_integer); virtual;
+        procedure   SelectLink(Index: sw_integer); virtual;
         procedure   PrevTopic; virtual;
         procedure   RenderTopic; virtual;
         procedure   Lookup(S: string); virtual;
@@ -187,7 +187,8 @@ type
 implementation
 
 uses
-  Video;
+  Video,
+  WViews;
 
 const CommentColor = Blue;
 
@@ -218,7 +219,7 @@ begin
   if P<>nil then Dispose(P);
 end;
 
-function NewKeyword(Index: integer; KWord: string): PHelpKeyword;
+function NewKeyword(Index: sw_integer; KWord: string): PHelpKeyword;
 var P: PHelpKeyword;
 begin
   New(P); FillChar(P^, SizeOf(P^), 0);
@@ -245,7 +246,7 @@ begin
   if Item<>nil then DisposeColorArea(Item);
 end;
 
-function TKeywordCollection.At(Index: Integer): PHelpKeyword;
+function TKeywordCollection.At(Index: sw_Integer): PHelpKeyword;
 begin
   At:=inherited At(Index);
 end;
@@ -255,8 +256,8 @@ begin
   if Item<>nil then DisposeKeyword(Item);
 end;
 
-function TKeywordCollection.Compare(Key1, Key2: Pointer): Integer;
-var R: integer;
+function TKeywordCollection.Compare(Key1, Key2: Pointer): sw_Integer;
+var R: sw_integer;
     K1: PHelpKeyword absolute Key1;
     K2: PHelpKeyword absolute Key2;
     S1,S2: string;
@@ -268,9 +269,9 @@ begin
   Compare:=R;
 end;
 
-{function TAdvancedStringCollection.SearchItem(Key: pointer; Rel: TSearchRelation; var Index: integer): boolean;
+{function TAdvancedStringCollection.SearchItem(Key: pointer; Rel: TSearchRelation; var Index: sw_integer): boolean;
 var
-  L, H, I, C: Integer;
+  L, H, I, C: sw_Integer;
 const resSmaller = -1; resEqual = 0; resGreater = 1;
 begin
   Index:=-1;
@@ -311,7 +312,7 @@ begin
   New(Lines, Init(100,100)); New(Links, Init(50,50)); New(ColorAreas, Init(50,50));
 end;
 
-procedure THelpTopic.SetParams(AMargin, AWidth: integer);
+procedure THelpTopic.SetParams(AMargin, AWidth: sw_integer);
 begin
   if Width<>AWidth then
   begin
@@ -321,16 +322,16 @@ begin
 end;
 
 procedure THelpTopic.ReBuild;
-var TextPos,LinkNo: word;
+var TextPos,LinkNo: sw_word;
     Line,CurWord: string;
     C: char;
     InLink,InColorArea: boolean;
     LinkStart,LinkEnd,ColorAreaStart,ColorAreaEnd: TPoint;
     CurPos: TPoint;
-    ZeroLevel: integer;
-    LineStart,NextLineStart: integer;
+    ZeroLevel: sw_integer;
+    LineStart,NextLineStart: sw_integer;
     LineAlign : (laLeft,laCenter,laRight);
-    FirstLink,LastLink: integer;
+    FirstLink,LastLink: sw_integer;
 procedure ClearLine;
 begin
   Line:='';
@@ -338,7 +339,7 @@ end;
 procedure AddWord(TheWord: string); forward;
 procedure NextLine;
 var P: sw_integer;
-    I,Delta: integer;
+    I,Delta: sw_integer;
 begin
   Line:=CharStr(' ',Margin)+Line;
   repeat
@@ -487,45 +488,45 @@ begin
   GetLineText:=S;
 end;
 
-function THelpTopic.GetLinkCount: integer;
+function THelpTopic.GetLinkCount: sw_integer;
 begin
   GetLinkCount:=Links^.Count;
 end;
 
-procedure THelpTopic.GetLinkBounds(Index: integer; var R: TRect);
+procedure THelpTopic.GetLinkBounds(Index: sw_integer; var R: TRect);
 var P: PHelpLink;
 begin
   P:=Links^.At(Index);
   R:=P^.Bounds;
 end;
 
-function THelpTopic.GetLinkFileID(Index: integer): word;
+function THelpTopic.GetLinkFileID(Index: sw_integer): word;
 var P: PHelpLink;
 begin
   P:=Links^.At(Index);
   GetLinkFileID:=P^.FileID;
 end;
 
-function THelpTopic.GetLinkContext(Index: integer): THelpCtx;
+function THelpTopic.GetLinkContext(Index: sw_integer): THelpCtx;
 var P: PHelpLink;
 begin
   P:=Links^.At(Index);
   GetLinkContext:=P^.Context;
 end;
 
-function THelpTopic.GetColorAreaCount: integer;
+function THelpTopic.GetColorAreaCount: sw_integer;
 begin
   GetColorAreaCount:=ColorAreas^.Count;
 end;
 
-procedure THelpTopic.GetColorAreaBounds(Index: integer; var R: TRect);
+procedure THelpTopic.GetColorAreaBounds(Index: sw_integer; var R: TRect);
 var P: PHelpColorArea;
 begin
   P:=ColorAreas^.At(Index);
   R:=P^.Bounds;
 end;
 
-function THelpTopic.GetColorAreaColor(Index: integer): word;
+function THelpTopic.GetColorAreaColor(Index: sw_integer): word;
 var P: PHelpColorArea;
 begin
   P:=ColorAreas^.At(Index);
@@ -579,7 +580,7 @@ begin
 end;
 
 procedure THelpViewer.SetCurPtr(X,Y: sw_integer);
-var OldCurLink,I: integer;
+var OldCurLink,I: sw_integer;
     OldPos,P: TPoint;
     R: TRect;
 begin
@@ -600,7 +601,7 @@ begin
 end;
 
 function THelpViewer.GetLineCount: sw_integer;
-var Count: integer;
+var Count: sw_integer;
 begin
   if HelpTopic=nil then Count:=0 else Count:=HelpTopic^.GetLineCount;
   GetLineCount:=Count;
@@ -613,32 +614,32 @@ begin
   GetLineText:=S;
 end;
 
-function THelpViewer.GetLinkCount: integer;
-var Count: integer;
+function THelpViewer.GetLinkCount: sw_integer;
+var Count: sw_integer;
 begin
   if HelpTopic=nil then Count:=0 else Count:=HelpTopic^.GetLinkCount;
   GetLinkCount:=Count;
 end;
 
-procedure THelpViewer.GetLinkBounds(Index: integer; var R: TRect);
+procedure THelpViewer.GetLinkBounds(Index: sw_integer; var R: TRect);
 begin
   HelpTopic^.GetLinkBounds(Index,R);
 end;
 
-function THelpViewer.GetLinkFileID(Index: integer): word;
+function THelpViewer.GetLinkFileID(Index: sw_integer): word;
 begin
   GetLinkFileID:=HelpTopic^.GetLinkFileID(Index);
 end;
 
-function THelpViewer.GetLinkContext(Index: integer): THelpCtx;
+function THelpViewer.GetLinkContext(Index: sw_integer): THelpCtx;
 begin
   GetLinkContext:=HelpTopic^.GetLinkContext(Index);
 end;
 
-function THelpViewer.GetLinkText(Index: integer): string;
+function THelpViewer.GetLinkText(Index: sw_integer): string;
 var S: string;
     R: TRect;
-    Y,StartX,EndX: integer;
+    Y,StartX,EndX: sw_integer;
 begin
   S:=''; GetLinkBounds(Index,R);
   Y:=R.A.Y;
@@ -652,25 +653,25 @@ begin
   GetLinkText:=S;
 end;
 
-function THelpViewer.GetColorAreaCount: integer;
-var Count: integer;
+function THelpViewer.GetColorAreaCount: sw_integer;
+var Count: sw_integer;
 begin
   if HelpTopic=nil then Count:=0 else Count:=HelpTopic^.GetColorAreaCount;
   GetColorAreaCount:=Count;
 end;
 
-procedure THelpViewer.GetColorAreaBounds(Index: integer; var R: TRect);
+procedure THelpViewer.GetColorAreaBounds(Index: sw_integer; var R: TRect);
 begin
   HelpTopic^.GetColorAreaBounds(Index,R);
 end;
 
-function THelpViewer.GetColorAreaColor(Index: integer): word;
+function THelpViewer.GetColorAreaColor(Index: sw_integer): word;
 begin
   GetColorAreaColor:=HelpTopic^.GetColorAreaColor(Index);
 end;
 
 procedure THelpViewer.SelectNextLink(ANext: boolean);
-var I,Link: integer;
+var I,Link: sw_integer;
     R: TRect;
 begin
   if HelpTopic=nil then Exit;
@@ -694,7 +695,7 @@ begin
   SetCurLink(Link);
 end;
 
-procedure THelpViewer.SetCurLink(Link: integer);
+procedure THelpViewer.SetCurLink(Link: sw_integer);
 var R: TRect;
 begin
   if Link<>-1 then
@@ -797,7 +798,7 @@ begin
 end;
 
 procedure THelpViewer.BuildTopicWordList;
-var I: integer;
+var I: sw_integer;
 begin
   WordList^.FreeAll;
   for I:=0 to GetLinkCount-1 do
@@ -861,7 +862,7 @@ begin
   InLookup:=false;
 end;
 
-procedure THelpViewer.SelectLink(Index: integer);
+procedure THelpViewer.SelectLink(Index: sw_integer);
 var ID: word;
     Ctx: THelpCtx;
 begin
@@ -940,8 +941,8 @@ procedure THelpViewer.Draw;
 var NormalColor, LinkColor,
     SelectColor, SelectionColor: word;
     B: TDrawBuffer;
-    DX,DY,X,Y,I,MinX,MaxX,ScreenX: integer;
-    LastLinkDrawn,LastColorAreaDrawn: integer;
+    DX,DY,X,Y,I,MinX,MaxX,ScreenX: sw_integer;
+    LastLinkDrawn,LastColorAreaDrawn: sw_integer;
     S: string;
     R: TRect;
 {$ifndef EDITORS}
@@ -1138,7 +1139,24 @@ end;
 END.
 {
   $Log$
-  Revision 1.10  1999-08-16 18:25:31  peter
+  Revision 1.11  2000-02-07 08:29:13  michael
+  [*] the fake (!) TOKENS.PAS still contained the typo bug
+       FSplit(,n,d,e) (correctly FSplit(,d,n,e))
+  [*] CodeComplete had a very ugly bug - coordinates were document-relative
+      (instead of being screen-relative)
+  [*] TResourceStream didn't count the size of the resource names when
+      determining the file size and this could lead to the last resources not
+      loaded correctly
+
+
+  [+] Ctrl-Enter in editor now tries to open the file at cursor
+  [+] CodeComplete option added to Options|Environment|Editor
+  [+] user interface for managing CodeComplete implemented
+  [+] user interface for CodeTemplates implemented
+  [+] CodeComplete wordlist and CodeTemplates stored in desktop file
+  [+] help topic size no longer limited to 64KB when compiled with FPC
+
+  Revision 1.10  1999/08/16 18:25:31  peter
     * Adjusting the selection when the editor didn't contain any line.
     * Reserved word recognition redesigned, but this didn't affect the overall
       syntax highlight speed remarkably (at least not on my Amd-K6/350).

+ 29 - 4
ide/text/wresourc.pas

@@ -676,20 +676,29 @@ function TResourceFile.CalcSizes(IncludeHeaders, UpdatePosData: boolean): longin
 var RH  : TResourceHeader;
     REH : TResourceEntryHeader;
     Size: longint;
+    NamesSize: longint;
 procedure AddResourceEntrySize(P: PResourceEntry); {$ifndef FPC}far;{$endif}
 begin
   if UpdatePosData then P^.DataOfs:=Size;
   P^.BuildHeader(REH);
   Inc(Size,REH.DataLen);
 end;
+procedure AddResourceSize(P: PResource); {$ifndef FPC}far;{$endif}
+var RH: TResourceHeader;
+begin
+  P^.BuildHeader(RH);
+  Inc(NamesSize,RH.NameLen);
+end;
 begin
-  Size:=0;
+  Size:=0; NamesSize:=0;
   Inc(Size,SizeOf(Header)); { this is on start so we always include it }
   ForEachResourceEntry(@AddResourceEntrySize);
   if IncludeHeaders then
     begin
+      ForEachResource(@AddResourceSize);
       Inc(Size,SizeOf(RH)*Resources^.Count);
       Inc(Size,SizeOf(REH)*Entries^.Count);
+      Inc(Size,NamesSize);
     end;
   CalcSizes:=Size;
 end;
@@ -747,8 +756,7 @@ destructor TResourceFile.Done;
 begin
   Flush;
   inherited Done;
-  if assigned(S) then dispose(S,Done);
-  S:=nil;
+{  if assigned(S) then dispose(S,Done); S:=nil;}
   if Resources<>nil then Dispose(Resources, Done); Resources:=nil;
   if Entries<>nil then
     begin Entries^.DeleteAll; Dispose(Entries, Done); Entries:=nil; end;
@@ -783,7 +791,24 @@ end;
 END.
 {
   $Log$
-  Revision 1.7  1999-09-07 09:26:26  pierre
+  Revision 1.8  2000-02-07 08:29:14  michael
+  [*] the fake (!) TOKENS.PAS still contained the typo bug
+       FSplit(,n,d,e) (correctly FSplit(,d,n,e))
+  [*] CodeComplete had a very ugly bug - coordinates were document-relative
+      (instead of being screen-relative)
+  [*] TResourceStream didn't count the size of the resource names when
+      determining the file size and this could lead to the last resources not
+      loaded correctly
+
+
+  [+] Ctrl-Enter in editor now tries to open the file at cursor
+  [+] CodeComplete option added to Options|Environment|Editor
+  [+] user interface for managing CodeComplete implemented
+  [+] user interface for CodeTemplates implemented
+  [+] CodeComplete wordlist and CodeTemplates stored in desktop file
+  [+] help topic size no longer limited to 64KB when compiled with FPC
+
+  Revision 1.7  1999/09/07 09:26:26  pierre
    * E^.DataLen=-1 sets OK to false in TResourceFile.ReadSourceEntryToStream
 
   Revision 1.6  1999/08/03 20:22:44  peter