Преглед на файлове

+ tools menu
+ speedsearch in symbolbrowser
* working run command

peter преди 26 години
родител
ревизия
124db68c70

+ 26 - 1
ide/fake/browcol.pas

@@ -9,6 +9,9 @@ interface
 uses
   objects;
 
+const
+    SymbolTypLen : integer=6;
+
 type
     TStoreCollection = object(TStringCollection)
       function Add(const S: string): PString;
@@ -54,11 +57,13 @@ type
     TSymbolCollection = object(TSortedCollection)
        function  At(Index: Sw_Integer): PSymbol;
        procedure Insert(Item: Pointer); virtual;
+       function  LookUp(const S: string; var Idx: sw_integer): string; virtual;
     end;
 
     TSortedSymbolCollection = object(TSymbolCollection)
       function  Compare(Key1, Key2: Pointer): Sw_Integer; virtual;
       procedure Insert(Item: Pointer); virtual;
+      function  LookUp(const S: string; var Idx: sw_integer): string; virtual;
     end;
 
     TReferenceCollection = object(TCollection)
@@ -70,6 +75,9 @@ const
   ModuleNames : PModuleNameCollection = nil;
   TypeNames   : PTypeNameCollection = nil;
 
+procedure InitBrowserCol;
+procedure DoneBrowserCol;
+
 
 implementation
 
@@ -96,6 +104,12 @@ procedure TSymbolCollection.Insert(Item: Pointer);
 begin
 end;
 
+function TSymbolCollection.LookUp(const S: string; var Idx: sw_integer): string;
+begin
+  Idx:=-1;
+  LookUp:='';
+end;
+
 
 {****************************************************************************
                                TReferenceCollection
@@ -120,6 +134,12 @@ procedure TSortedSymbolCollection.Insert(Item: Pointer);
 begin
 end;
 
+function TSortedSymbolCollection.LookUp(const S: string; var Idx: sw_integer): string;
+begin
+  Idx:=-1;
+  LookUp:='';
+end;
+
 
 {****************************************************************************
                                 TReference
@@ -227,7 +247,12 @@ begin
 end.
 {
   $Log$
-  Revision 1.1  1999-01-12 15:00:46  peter
+  Revision 1.2  1999-01-21 11:54:08  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.1  1999/01/12 15:00:46  peter
     * fake unit
 
 }

+ 8 - 1
ide/text/Makefile

@@ -62,12 +62,19 @@ endif
 # Dependencies
 #####################################################################
 
+fp$(EXEEXT): $(wildcard *.pas) $(wildcard *.inc)
+
 full:
 	make all FULL=1
 
 #
 # $Log$
-# Revision 1.2  1999-01-19 18:21:49  peter
+# Revision 1.3  1999-01-21 11:54:09  peter
+#   + tools menu
+#   + speedsearch in symbolbrowser
+#   * working run command
+#
+# Revision 1.2  1999/01/19 18:21:49  peter
 #   * Use FPCDIR and FPCMAKE environment to find makefile.fpc
 #   * better install dir setting
 #

+ 13 - 3
ide/text/fp.pas

@@ -17,7 +17,9 @@ program FP;
 
 uses
   Dos,
-  FPIni,FPViews,FPConst,FPVars,FPUtils,FPIde,FPHelp,FPSwitches,FPUsrScr;
+  BrowCol,
+  FPIni,FPViews,FPConst,FPVars,FPUtils,FPIde,FPHelp,FPSwitches,FPUsrScr,
+  FPTools;
 
 
 procedure ProcessParams(BeforeINI: boolean);
@@ -61,7 +63,7 @@ end;
 
 
 BEGIN
-  {$ifdef TP}HeapLimit:=256;{$endif}
+  {$ifdef DEV}HeapLimit:=4096;{$endif}
   writeln('þ Free Pascal IDE  Version '+VersionStr);
   StartupDir:=CompleteDir(FExpand('.'));
 
@@ -72,6 +74,7 @@ BEGIN
   InitSwitches;
   InitINIFile;
   InitUserScreen;
+  InitTools;
 
 { load old options }
   ReadINIFile;
@@ -87,13 +90,20 @@ BEGIN
   WriteSwitches(SwitchesPath);
   WriteINIFile;
 
+  DoneBrowserCol;
+  DoneTools;
   DoneUserScreen;
   DoneSwitches;
   DoneHelpFiles;
 END.
 {
   $Log$
-  Revision 1.5  1999-01-12 14:29:31  peter
+  Revision 1.6  1999-01-21 11:54:10  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.5  1999/01/12 14:29:31  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 13 - 7
ide/text/fpcompil.pas

@@ -59,7 +59,6 @@ begin
   Insert(KeyST);
   GetExtent(R); R.Grow(-1,-1); R.A.Y:=10;
   New(MsgLB, Init(R, nil, nil));
-{  MsgLB^.NewList(New(PUnsortedStringCollection, Init(100,100))); }
   Insert(MsgLB);
 end;
 
@@ -111,7 +110,7 @@ end;
 
 function CompilerStatus: boolean; {$ifndef FPC}far;{$endif}
 begin
-  SD^.Update;
+  if SD<>nil then SD^.Update;
   CompilerStatus:=false;
 end;
 
@@ -128,7 +127,8 @@ begin
   if (status.verbosity and Level)=Level then
 {$endif}
    begin
-     ProgramInfoWindow^.AddMessage(Level,S,SmartPath(status.currentmodule),status.currentline);
+     ProgramInfoWindow^.AddMessage(Level,S,status.currentsourcepath+status.currentsource,status.currentline);
+     if SD<>nil then
      SD^.MsgLB^.AddItem(New(PCompilerMessage, Init(Level, S, SmartPath(status.currentmodule),status.currentline)));
    end;
 end;
@@ -137,7 +137,7 @@ function GetExePath: string;
 var Path: string;
     I: integer;
 begin
-  Path:='.\';
+  Path:='.'+DirSep;
   if DirectorySwitches<>nil then
     with DirectorySwitches^ do
     for I:=0 to ItemCount-1 do
@@ -186,8 +186,8 @@ begin
       FileName:=P^.Editor^.FileName;
     end;
   WriteSwitches(SwitchesPath);
-  MainFile:=FExpand(FileName);
-  EXEFile:=GetEXEPath+NameAndExtOf(MainFile);
+  MainFile:=FixFileName(FExpand(FileName));
+  EXEFile:=FixFileName(GetEXEPath+NameOf(MainFile)+ExeExt);
 { Reset }
   CtrlBreakHit:=false;
 { Show Program Info }
@@ -227,12 +227,18 @@ begin
 
 {  if (WasVisible=false) and (status.errorcount=0) then
    ProgramInfoWindow^.Hide;}
+  Message(Application,evCommand,cmUpdate,nil);
 end;
 
 end.
 {
   $Log$
-  Revision 1.6  1999-01-15 16:12:43  peter
+  Revision 1.7  1999-01-21 11:54:11  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.6  1999/01/15 16:12:43  peter
     * fixed crash after compile
 
   Revision 1.5  1999/01/14 21:42:19  peter

+ 20 - 11
ide/text/fpconst.pas

@@ -23,6 +23,7 @@ const
      VersionStr           = '0.9';
 
      MaxRecentFileCount   = 5;
+     MaxToolCount         = 16;
 
      ININame              = 'fp.ini';
      SwitchesName         = 'fp.cfg';
@@ -34,6 +35,7 @@ const
 
      { Main menu submenu indexes }
      menuFile             = 0;
+     menuTools            = 6;
 
      { MouseAction constants }
      acNone               = 0;
@@ -77,13 +79,15 @@ const
 
      cmSearchWindow      = 1500;
      cmUpdate            = 1600;
-     cmSourceWindowClosing = 1601;
-     cmDeleteWnd         = 1602;
-     cmLocalMenu         = 1603;
-     cmCalculatorPaste   = 1604;
-     cmAddTPH            = 1605;
-     cmDeleteTPH         = 1606;
-     cmMsgClear          = 1607;
+     cmSourceWndClosing  = 1601;
+     cmLocalMenu         = 1602;
+     cmCalculatorPaste   = 1603;
+     cmMsgClear          = 1604;
+     cmUpdateTools       = 1605;
+
+     cmAddItem           = 1620;
+     cmEditItem          = 1621;
+     cmDeleteItem        = 1622;
 
      cmUserScreen        = 1650;
      cmUserScreenWindow  = 1651;
@@ -108,7 +112,7 @@ const
      cmOpenINI           = 2011;
      cmSaveINI           = 2012;
      cmSaveAsINI         = 2013;
-     cmSetSwitchesMode   = 2014;
+     cmSwitchesMode      = 2014;
 
      cmHelpContents      = 2100;
      cmHelpIndex         = 2101;
@@ -162,7 +166,7 @@ const
      hcSaveINI           = hcShift+cmSaveINI;
      hcSaveAsINI         = hcShift+cmSaveAsINI;
      hcCalculator        = hcShift+cmCalculator;
-     hcSetSwitchesMode   = hcShift+cmSetSwitchesMode;
+     hcSwitchesMode      = hcShift+cmSwitchesMode;
      hcAbout             = hcShift+cmAbout;
 
      hcSystemMenu        = 9000;
@@ -248,7 +252,7 @@ const
          { CSourceWindow }
 {167-182}#$17#$1F#$1A#$31#$31#$1E#$71#$1F#$00#$00#$00#$00#$00#$00#$00#$00 + { 1-16}
 {183-198}#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00 + {17-32}
-{199-214}#$1E#$1F#$17#$1F#$1E#$1B#$13#$1A#$1E#$71#$3F#$1F#$1C#$13#$1F#$4E + {33-48}
+{199-214}#$1E#$1F#$17#$1F#$1E#$1B#$13#$1A#$1E#$71#$3F#$30#$1C#$13#$1F#$4E + {33-48}
          { CBrowserWindow }
 {215-   }#$31#$3F#$3A#$31#$31#$31#$71#$1F#$31#$2F#$3E#$3F ;
 
@@ -257,7 +261,12 @@ implementation
 END.
 {
   $Log$
-  Revision 1.5  1999-01-12 14:29:33  peter
+  Revision 1.6  1999-01-21 11:54:12  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.5  1999/01/12 14:29:33  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 19 - 3
ide/text/fphelp.pas

@@ -36,6 +36,7 @@ type
 procedure Help(FileID, Context: word; Modal: boolean);
 procedure HelpIndex(Keyword: string);
 procedure HelpTopicSearch(Editor: PEditor);
+procedure HelpTopic(S: string);
 
 procedure InitHelpSystem;
 procedure DoneHelpSystem;
@@ -139,8 +140,12 @@ begin
 
     hcToolsMenu     : S:='User installed tools';
     hcCalculator    : S:='Show calculator';
+    hcToolsBase..
+    hcToolsBase+MaxToolCount
+                    : S:='User installed tool';
 
     hcOptionsMenu   : S:='Setting for compiler, editor, mouse, etc.';
+    hcSwitchesMode  : S:='Select settings for normal, debug or release version';
     hcCompiler      : S:='Set default compiler directives and conditional defines';
     hcMemorySizes   : S:='Set default stack and heap sizes for generated programs';
     hcLinker        : S:='Set linker options';
@@ -248,12 +253,18 @@ begin
 end;
 
 procedure HelpTopicSearch(Editor: PEditor);
+var S: string;
+begin
+  if Editor=nil then S:='' else
+  S:=GetEditorCurWord(Editor);
+  HelpTopic(S);
+end;
+
+procedure HelpTopic(S: string);
 var FileID, Ctx: word;
-    S: string;
 var Found: boolean;
 begin
   CheckHelpSystem;
-  S:=GetEditorCurWord(Editor);
   PushStatus(strLocatingTopic);
   Found:=HelpFacility^.TopicSearch(S,FileID,Ctx);
   PopStatus;
@@ -317,7 +328,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.3  1999-01-04 11:49:44  peter
+  Revision 1.4  1999-01-21 11:54:13  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.3  1999/01/04 11:49:44  peter
    * 'Use tab characters' now works correctly
    + Syntax highlight now acts on File|Save As...
    + Added a new class to syntax highlight: 'hex numbers'.

+ 105 - 33
ide/text/fpide.pas

@@ -46,15 +46,18 @@ type
       procedure Target;
       procedure PrimaryFile_;
       procedure ClearPrimary;
+      procedure ShowScreenWindow;
       procedure ShowUserScreen;
       procedure Information;
       procedure Calculator;
+      procedure ExecuteTool(Idx: integer);
       procedure SetSwitchesMode;
       procedure Compiler;
       procedure MemorySizes;
       procedure Linker;
       procedure Debugger;
       procedure Directories;
+      procedure Tools;
       procedure EditorOptions(Editor: PEditor);
       procedure Mouse;
       procedure Colors;
@@ -62,7 +65,6 @@ type
       procedure SaveINI;
       procedure SaveAsINI;
       procedure CloseAll;
-      procedure ShowScreenWindow;
       procedure WindowList;
       procedure HelpContents;
       procedure HelpHelpIndex;
@@ -71,6 +73,8 @@ type
       procedure HelpUsingHelp;
       procedure HelpFiles;
       procedure About;
+    private
+      procedure DoExecute(ProgramPath, Params: string; IsDOSShell: boolean);
     private
       procedure AddRecentFile(AFileName: string; CurX, CurY: integer);
       function  SearchRecentFile(AFileName: string): integer;
@@ -81,6 +85,7 @@ type
       procedure UpdatePrimaryFile;
       procedure UpdateINIFile;
       procedure UpdateRecentFileList;
+      procedure UpdateTools;
     end;
 
 
@@ -95,7 +100,7 @@ uses
   Systems,BrowCol,
   WHelp,WHlpView,WINI,
   FPConst,FPVars,FPUtils,FPSwitches,FPIni,FPIntf,FPCompile,FPHelp,
-  FPTemplt,FPCalc,FPUsrScr,FPSymbol;
+  FPTemplt,FPCalc,FPUsrScr,FPSymbol,FPTools;
 
 
 function IDEUseSyntaxHighlight(Editor: PFileEditor): boolean; {$ifndef FPC}far;{$endif}
@@ -112,7 +117,6 @@ begin
   New(CalcWindow, Init); CalcWindow^.Hide;
   Desktop^.Insert(CalcWindow);
   New(ProgramInfoWindow, Init); ProgramInfoWindow^.Hide; Desktop^.Insert(ProgramInfoWindow);
-  New(UserScreenWindow, Init(UserScreen)); UserScreenWindow^.Hide; Desktop^.Insert(UserScreenWindow);
   Message(@Self,evBroadcast,cmUpdate,nil);
   InitTemplates;
   CurDirChanged;
@@ -161,9 +165,7 @@ begin
     NewSubMenu('~R~un',hcRunMenu, NewMenu(
       NewItem('~R~un','Ctrl+F9', kbCtrlF9, cmRun, hcRun,
       NewItem('P~a~rameters...','', kbNoKey, cmParameters, hcParameters,
-      NewLine(
-      NewItem('~U~ser screen','Alt+F5', kbAltF5, cmUserScreen, hcUserScreen,
-      nil))))),
+      nil))),
     NewSubMenu('~C~ompile',hcCompileMenu, NewMenu(
       NewItem('~C~ompile','Alt+F9', kbAltF9, cmCompile, hcCompile,
       NewItem('~M~ake','F9', kbF9, cmMake, hcMake,
@@ -176,15 +178,15 @@ begin
       NewItem('~I~nformation...','', kbNoKey, cmInformation, hcInformation,
       nil)))))))))),
     NewSubMenu('~D~ebug', hcDebugMenu, NewMenu(
+      NewItem('~O~utput','', kbNoKey, cmUserScreenWindow, hcUserScreenWindow,
       NewItem('~U~ser screen','Alt+F5', kbAltF5, cmUserScreen, hcUserScreen,
-      nil)),
+      nil))),
     NewSubMenu('~T~ools', hcToolsMenu, NewMenu(
       NewItem('~M~essages', '', kbNoKey, cmToolsMessages, hcToolsMessages,
-      NewLine(
       NewItem('~C~alculator', '', kbNoKey, cmCalculator, hcCalculator,
-      nil)))),
+      nil))),
     NewSubMenu('~O~ptions', hcOptionsMenu, NewMenu(
-      NewItem('Mode~.~..','', kbNoKey, cmSetSwitchesMode, hcSetSwitchesMode,
+      NewItem('Mode~.~..','', kbNoKey, cmSwitchesMode, hcSwitchesMode,
       NewItem('~C~ompiler...','', kbNoKey, cmCompiler, hcCompiler,
       NewItem('~M~emory sizes...','', kbNoKey, cmMemorySizes, hcMemorySizes,
       NewItem('~L~inker...','', kbNoKey, cmLinker, hcLinker,
@@ -216,9 +218,8 @@ begin
       NewItem('~C~lose','Alt+F3', kbAltF3, cmClose, hcClose,
       NewLine(
       NewItem('~L~ist...','Alt+0', kbAlt0, cmWindowList, hcWindowList,
-      NewItem('~U~ser screen window','', kbNoKey, cmUserScreenWindow, hcUserScreenWindow,
       NewItem('~R~efresh display','', kbNoKey, cmUpdate, hcUpdate,
-      nil)))))))))))))),
+      nil))))))))))))),
     NewSubMenu('~H~elp', hcHelpMenu, NewMenu(
       NewItem('~C~ontents','', kbNoKey, cmHelpContents, hcHelpContents,
       NewItem('~I~ndex','Shift+F1', kbShiftF1, cmHelpIndex, hcHelpIndex,
@@ -321,12 +322,13 @@ begin
            { -- Debug menu -- }
              cmUserScreen    : ShowUserScreen;
            { -- Options menu -- }
-             cmSetSwitchesMode : SetSwitchesMode;
+             cmSwitchesMode  : SetSwitchesMode;
              cmCompiler      : Compiler;
              cmMemorySizes   : MemorySizes;
              cmLinker        : Linker;
              cmDebugger      : Debugger;
              cmDirectories   : Directories;
+             cmTools         : Tools;
              cmEditor        : EditorOptions(nil);
              cmEditorOptions : EditorOptions(Event.InfoPtr);
              cmMouse         : Mouse;
@@ -336,6 +338,9 @@ begin
              cmSaveAsINI     : SaveAsINI;
            { -- Tools menu -- }
              cmCalculator    : Calculator;
+             cmToolsBase+1..
+             cmToolsBase+MaxToolCount
+                             : ExecuteTool(Event.Command-cmToolsBase);
            { -- Window menu -- }
              cmCloseAll      : CloseAll;
              cmWindowList    : WindowList;
@@ -354,9 +359,11 @@ begin
          end;
        evBroadcast :
          case Event.Command of
+           cmUpdateTools :
+             UpdateTools;
            cmUpdate              :
              Update;
-           cmSourceWindowClosing :
+           cmSourceWndClosing :
              with PSourceWindow(Event.InfoPtr)^ do
                if Editor^.FileName<>'' then
                   AddRecentFile(Editor^.FileName,Editor^.CurPos.X,Editor^.CurPos.Y);
@@ -365,15 +372,54 @@ begin
   inherited HandleEvent(Event);
 end;
 
+procedure TIDEApp.DoExecute(ProgramPath, Params: string; IsDosShell: boolean);
+begin
+  if UserScreen=nil then
+   begin
+     ErrorBox('Sorry, user screen not available.',nil);
+     Exit;
+   end;
+
+  DoneSysError;
+  DoneEvents;
+  DoneMouse;
+  DoneScreen;
+  DoneDosMem;
+
+  if Assigned(UserScreen) then
+    UserScreen^.SwitchTo;
+
+  if IsDOSShell then
+    WriteShellMsg;
+
+  SwapVectors;
+  Exec(GetEnv('COMSPEC'),'/C '+ProgramPath+' '+Params);
+  SwapVectors;
+
+  if Assigned(UserScreen) then
+    UserScreen^.SwitchBack;
+
+  InitDosMem;
+  InitScreen;
+  InitMouse;
+  InitEvents;
+  InitSysError;
+  Redraw;
+  CurDirChanged;
+  Message(Application,evBroadcast,cmUpdate,nil);
+  UpdateScreen(true);
+end;
+
 procedure TIDEApp.Update;
 begin
   SetCmdState([cmSaveAll],IsThereAnyEditor);
   SetCmdState([cmCloseAll,cmTile,cmCascade,cmWindowList],IsThereAnyWindow);
-  SetCmdState([cmFindProcedure,cmObjects,cmModules,cmGlobals{,cmInformation}],{SymbolInfoLoaded}true);
+  SetCmdState([cmFindProcedure,cmObjects,cmModules,cmGlobals{,cmInformation}],IsSymbolInfoAvailable);
   UpdatePrimaryFile;
   UpdateINIFile;
   Message(MenuBar,evBroadcast,cmUpdate,nil);
   UpdateRecentFileList;
+  UpdateTools;
   Message(Application,evBroadcast,cmCommandSetChanged,nil);
 end;
 
@@ -440,25 +486,46 @@ begin
   end;
 end;
 
+procedure TIDEApp.UpdateTools;
+var P: PMenuItem;
+    ID,I: word;
+    ToolsMenu: PMenuItem;
+    S1,S2,S3: string;
+    W: word;
+begin
+  ID:=cmToolsBase;
+  ToolsMenu:=SearchSubMenu(MenuBar^.Menu,menuTools);
+  repeat
+    P:=GetMenuItemBefore(ToolsMenu^.SubMenu,nil);
+    if (P<>nil) then
+    begin
+      if (cmToolsBase<P^.Command) and (P^.Command<=cmToolsBase+MaxToolCount) then
+        begin
+          RemoveMenuItem(ToolsMenu^.SubMenu,P);
+          if ToolsMenu^.SubMenu^.Default=P then
+            ToolsMenu^.SubMenu^.Default:=ToolsMenu^.SubMenu^.Items;
+        end
+      else
+        P:=nil;
+    end;
+  until P=nil;
+  P:=GetMenuItemBefore(ToolsMenu^.SubMenu,nil);
+  if (P<>nil) and IsSeparator(P) then
+     RemoveMenuItem(ToolsMenu^.SubMenu,P);
+
+  if GetToolCount>0 then
+     AppendMenuItem(ToolsMenu^.SubMenu,NewLine(nil));
+  for I:=1 to GetToolCount do
+  begin
+    GetToolParams(I-1,S1,S2,S3,W);
+    P:=NewItem(S1,KillTilde(GetHotKeyName(W)),W,cmToolsBase+I,hcToolsBase+I,nil);
+    AppendMenuItem(ToolsMenu^.SubMenu,P);
+  end;
+end;
+
 procedure TIDEApp.DosShell;
 begin
-  DoneSysError;
-  DoneEvents;
-  DoneVideo;
-  DoneDosMem;
-  if UserScreen<>nil then UserScreen^.SwitchTo;
-  WriteShellMsg;
-  SwapVectors;
-  Exec(GetEnv('COMSPEC'), '');
-  SwapVectors;
-  if UserScreen<>nil then UserScreen^.SwitchBack;
-  InitDosMem;
-  InitVideo;
-  InitEvents;
-  InitSysError;
-  Redraw;
-  CurDirChanged;
-  Message(Application,evBroadcast,cmUpdate,nil);
+  DoExecute(GetEnv('COMSPEC'), '', true);
 end;
 
 {$I FPMFILE.INC}
@@ -529,7 +596,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.2  1999-01-14 21:42:20  peter
+  Revision 1.3  1999-01-21 11:54:14  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.2  1999/01/14 21:42:20  peter
     * source tracking from Gabor
 
   Revision 1.1  1999/01/12 14:29:34  peter

+ 39 - 3
ide/text/fpini.pas

@@ -36,7 +36,7 @@ implementation
 uses
   Dos,Objects,Drivers,
   WINI,{$ifndef EDITORS}WEditor{$else}Editors{$endif},
-  FPConst,FPVars,FPIntf;
+  FPConst,FPVars,FPIntf,FPTools;
 
 const
   { INI file sections }
@@ -49,6 +49,7 @@ const
   secHighlight       = 'Highlight';
   secMouse           = 'Mouse';
   secSearch          = 'Search';
+  secTools           = 'Tools';
 
   { INI file tags }
   ieRecentFile       = 'RecentFile';
@@ -64,6 +65,10 @@ const
   ieAltClickAction   = 'AltClickAction';
   ieCtrlClickAction  = 'CtrlClickAction';
   ieFindFlags        = 'FindFlags';
+  ieToolName         = 'Title';
+  ieToolProgram      = 'Program';
+  ieToolParams       = 'Params';
+  ieToolHotKey       = 'HotKey';
 
 procedure InitINIFile;
 var S: string;
@@ -117,9 +122,10 @@ end;
 
 function ReadINIFile: boolean;
 var INIFile: PINIFile;
-    S,PS: string;
+    S,PS,S1,S2,S3: string;
     I,P: integer;
     OK: boolean;
+    W: word;
 begin
   OK:=ExistsFile(INIPath);
   if OK then
@@ -158,6 +164,16 @@ begin
   MouseReverse:=boolean(INIFile^.GetIntEntry(secMouse,ieReverseButtons,byte(MouseReverse)));
   AltMouseAction:=INIFile^.GetIntEntry(secMouse,ieAltClickAction,AltMouseAction);
   CtrlMouseAction:=INIFile^.GetIntEntry(secMouse,ieCtrlClickAction,CtrlMouseAction);
+  for I:=1 to MaxToolCount do
+    begin
+      S:=IntToStr(I);
+      S1:=INIFile^.GetEntry(secTools,ieToolName+S,'');
+      if S1='' then Break; { !!! }
+      S2:=INIFile^.GetEntry(secTools,ieToolProgram+S,'');
+      S3:=INIFile^.GetEntry(secTools,ieToolParams+S,'');
+      W:=Max(0,Min(65535,INIFile^.GetIntEntry(secTools,ieToolHotKey+S,0)));
+      AddTool(S1,S2,S3,W);
+    end;
   S:=AppPalette;
   PS:=StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_1_40',PaletteToStr(copy(S,1,40))));
   PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_41_80',PaletteToStr(copy(S,41,40))));
@@ -174,6 +190,8 @@ end;
 function WriteINIFile: boolean;
 var INIFile: PINIFile;
     S: string;
+    S1,S2,S3: string;
+    W: word;
     I: integer;
     OK: boolean;
 procedure ConcatName(P: PString); {$ifndef FPC}far;{$endif}
@@ -206,6 +224,19 @@ begin
   INIFile^.SetIntEntry(secMouse,ieAltClickAction,AltMouseAction);
   INIFile^.SetIntEntry(secMouse,ieCtrlClickAction,CtrlMouseAction);
   INIFile^.SetIntEntry(secSearch,ieFindFlags,FindFlags);
+  INIFile^.DeleteSection(secTools);
+  for I:=1 to GetToolCount do
+    begin
+      S:=IntToStr(I);
+      GetToolParams(I-1,S1,S2,S3,W);
+      if S1<>'' then S1:='"'+S1+'"';
+      if S2<>'' then S2:='"'+S2+'"';
+      if S3<>'' then S3:='"'+S3+'"';
+      INIFile^.SetEntry(secTools,ieToolName+S,S1);
+      INIFile^.SetEntry(secTools,ieToolProgram+S,S2);
+      INIFile^.SetEntry(secTools,ieToolParams+S,S3);
+      INIFile^.SetIntEntry(secTools,ieToolHotKey+S,W);
+    end;
   if AppPalette<>CIDEAppColor then
   begin
     { this has a bug. if a different palette has been read on startup, and
@@ -227,7 +258,12 @@ end;
 end.
 {
   $Log$
-  Revision 1.4  1999-01-04 11:49:45  peter
+  Revision 1.5  1999-01-21 11:54:15  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.4  1999/01/04 11:49:45  peter
    * 'Use tab characters' now works correctly
    + Syntax highlight now acts on File|Save As...
    + Added a new class to syntax highlight: 'hex numbers'.

+ 16 - 1
ide/text/fpmdebug.inc

@@ -14,6 +14,16 @@
 
  **********************************************************************}
 
+procedure TIDEApp.ShowScreenWindow;
+begin
+  if UserScreenWindow=nil then
+    begin
+     New(UserScreenWindow, Init(UserScreen, SearchFreeWindowNo));
+     Desktop^.Insert(UserScreenWindow);
+    end;
+  UserScreenWindow^.MakeFirst;
+end;
+
 procedure TIDEApp.ShowUserScreen;
 begin
   if UserScreen=nil then
@@ -38,7 +48,12 @@ end;
 
 {
   $Log$
-  Revision 1.1  1998-12-28 15:47:47  peter
+  Revision 1.2  1999-01-21 11:54:16  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.1  1998/12/28 15:47:47  peter
     + Added user screen support, display & window
     + Implemented Editor,Mouse Options dialog
     + Added location of .INI and .CFG file

+ 10 - 5
ide/text/fpmfile.inc

@@ -16,7 +16,7 @@
 
 procedure TIDEApp.NewEditor;
 begin
-  OpenEditorWindow('',0,0);
+  OpenEditorWindow(nil,'',0,0);
 end;
 
 
@@ -58,7 +58,7 @@ begin
   if Desktop^.ExecView(D)=cmOK then
   begin
     Desktop^.Lock;
-    TE:=OpenEditorWindow('',0,0);
+    TE:=OpenEditorWindow(nil,'',0,0);
     if TE<>nil then
     begin
       StartTemplate(LB^.Focused,TE^.Editor);
@@ -87,7 +87,7 @@ begin
   if OpenIt then
   begin
     FileName := FExpand(FileName);
-    OpenEditorWindow(FileName,0,0);
+    OpenEditorWindow(nil,FileName,0,0);
   end;
   Dispose(D, Done);
 end;
@@ -96,7 +96,7 @@ end;
 procedure TIDEApp.OpenRecentFile(RecentIndex: integer);
 begin
   with RecentFiles[RecentIndex] do
-  if OpenEditorWindow(FileName,LastPos.X,LastPos.Y)<>nil then
+  if OpenEditorWindow(nil,FileName,LastPos.X,LastPos.Y)<>nil then
      RemoveRecentFile(RecentIndex);
 end;
 
@@ -120,7 +120,12 @@ end;
 
 {
   $Log$
-  Revision 1.4  1999-01-14 21:42:21  peter
+  Revision 1.5  1999-01-21 11:54:17  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.4  1999/01/14 21:42:21  peter
     * source tracking from Gabor
 
   Revision 1.3  1999/01/04 11:49:46  peter

+ 13 - 8
ide/text/fpmhelp.inc

@@ -16,7 +16,7 @@
 
 procedure TIDEApp.HelpContents;
 begin
-  Help(0,hcContents,false);
+  HelpTopic('Help_Contents'{0,hcContents,false});
 end;
 
 procedure TIDEApp.HelpHelpIndex;
@@ -80,9 +80,9 @@ begin
   GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y); R.A.X:=38; R.B.Y:=R.A.Y+2;
   Insert(New(PButton, Init(R, 'O~K~', cmOK, bfDefault)));
   R.Move(0,2);
-  Insert(New(PButton, Init(R, '~N~ew', cmAddTPH, bfNormal)));
+  Insert(New(PButton, Init(R, '~N~ew', cmAddItem, bfNormal)));
   R.Move(0,2);
-  Insert(New(PButton, Init(R, '~D~elete', cmDeleteTPH, bfNormal)));
+  Insert(New(PButton, Init(R, '~D~elete', cmDeleteItem, bfNormal)));
   R.Move(0,2);
   Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
 
@@ -99,18 +99,18 @@ begin
       case Event.KeyCode of
         kbIns :
           begin
-            Message(@Self,evCommand,cmAddTPH,nil);
+            Message(@Self,evCommand,cmAddItem,nil);
             ClearEvent(Event);
           end;
         kbDel :
           begin
-            Message(@Self,evCommand,cmDeleteTPH,nil);
+            Message(@Self,evCommand,cmDeleteItem,nil);
             ClearEvent(Event);
           end;
       end;
     evCommand :
       case Event.Command of
-        cmAddTPH :
+        cmAddItem :
           begin
             New(D, Init('*.tph','Install a help file','*.tph',fdOpenButton,0));
             if Desktop^.ExecView(D)<>cmCancel then
@@ -123,7 +123,7 @@ begin
             Dispose(D, Done);
             ClearEvent(Event);
           end;
-        cmDeleteTPH :
+        cmDeleteItem :
           if LB^.Range>0 then
           begin
             LB^.List^.AtFree(LB^.Focused);
@@ -186,7 +186,12 @@ end;
 
 {
   $Log$
-  Revision 1.3  1999-01-12 14:29:34  peter
+  Revision 1.4  1999-01-21 11:54:18  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.3  1999/01/12 14:29:34  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 10 - 1
ide/text/fpmopts.inc

@@ -409,6 +409,10 @@ begin
   Dispose(D, Done);
 end;
 
+procedure TIDEApp.Tools;
+begin
+  ExecuteDialog(New(PToolsDialog, Init),nil);
+end;
 
 procedure TIDEApp.EditorOptions(Editor: PEditor);
 var D: PCenterDialog;
@@ -669,7 +673,12 @@ end;
 
 {
   $Log$
-  Revision 1.5  1999-01-12 14:29:35  peter
+  Revision 1.6  1999-01-21 11:54:19  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.5  1999/01/12 14:29:35  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 7 - 20
ide/text/fpmrun.inc

@@ -32,27 +32,9 @@ begin
       Exit;
     end;
 
-  if UserScreen=nil then
-   begin
-     ErrorBox('Sorry, user screen not available.',nil);
-     Exit;
-   end;
-  DoneMouse;
-  DoneVideo;
-
-  if Assigned(UserScreen) then
-    UserScreen^.SwitchTo;
+  DoExecute(ExeFile,GetRunParameters,false);
 
-  Exec(ExeFile,GetRunParameters);
   LastExitCode:=DosExitCode;
-
-  if Assigned(UserScreen) then
-    UserScreen^.SwitchBack;
-
-  InitVideo;
-  InitMouse;
-  ReDraw;
-  UpdateScreen(true);
 end;
 
 procedure TIDEApp.Parameters;
@@ -83,7 +65,12 @@ end;
 
 {
   $Log$
-  Revision 1.4  1999-01-14 21:42:22  peter
+  Revision 1.5  1999-01-21 11:54:20  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.4  1999/01/14 21:42:22  peter
     * source tracking from Gabor
 
   Revision 1.3  1999/01/12 14:29:36  peter

+ 24 - 1
ide/text/fpmtools.inc

@@ -23,9 +23,32 @@ begin
   end;
 end;
 
+procedure TIDEApp.ExecuteTool(Idx: integer);
+var Title,ProgramPath,Params: string;
+    W: word;
+    Err: integer;
+begin
+  if (Idx<1) or (Idx>GetToolCount) then Exit;
+  GetToolParams(Idx-1,Title,ProgramPath,Params,W);
+  Err:=ParseToolParams(Params,false);
+  if Err=-1 then Exit;
+  if Err<>0 then
+    begin ErrorBox(^C'Error parsing tool params.',nil); Exit; end;
+  DoExecute(ProgramPath,Params,false);
+  if (DosError<>0) then
+    ErrorBox('Error executing tool '+KillTilde(GetToolName(Idx-1)),nil) else
+  if DosExitCode<>0 then
+    ErrorBox('Execution successful. Exit code '+IntToStr(DosExitCode),nil);
+end;
+
 {
   $Log$
-  Revision 1.1  1998-12-22 14:27:54  peter
+  Revision 1.2  1999-01-21 11:54:21  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.1  1998/12/22 14:27:54  peter
     * moved
 
   Revision 1.2  1998/12/22 10:39:49  peter

+ 9 - 15
ide/text/fpmwnd.inc

@@ -89,7 +89,7 @@ begin
   GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y); R.A.X:=38; R.B.Y:=R.A.Y+2;
   Insert(New(PButton, Init(R, 'O~K~', cmOK, bfDefault)));
   R.Move(0,3);
-  Insert(New(PButton, Init(R, '~D~elete', cmDeleteWnd, bfNormal)));
+  Insert(New(PButton, Init(R, '~D~elete', cmDeleteItem, bfNormal)));
   R.Move(0,3);
   Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
 
@@ -116,13 +116,13 @@ begin
       case Event.KeyCode of
         kbDel :
           begin
-            Message(@Self,evCommand,cmDeleteWnd,nil);
+            Message(@Self,evCommand,cmDeleteItem,nil);
             ClearEvent(Event);
           end;
       end;
     evCommand :
       case Event.Command of
-        cmDeleteWnd :
+        cmDeleteItem :
           if C^.Count>0 then
           begin
             Message(C^.At(LB^.Focused),evCommand,cmClose,nil);
@@ -150,20 +150,14 @@ begin
   Dispose(W,Done);
 end;
 
-procedure TIDEApp.ShowScreenWindow;
-begin
-  if UserScreenWindow=nil then Exit;
-  with UserScreenWindow^ do
-   begin
-     if not GetState(sfVisible) then
-       Show;
-     MakeFirst;
-   end;
-end;
-
 {
   $Log$
-  Revision 1.5  1999-01-12 14:29:37  peter
+  Revision 1.6  1999-01-21 11:54:22  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.5  1999/01/12 14:29:37  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 134 - 6
ide/text/fpsymbol.pas

@@ -40,13 +40,18 @@ type
     TSymbolScopeView = object(TSymbolView)
       constructor Init(var Bounds: TRect; ASymbols: PSymbolCollection; AHScrollBar, AVScrollBar: PScrollBar);
       function    GetText(Item,MaxLen: Sw_Integer): String; virtual;
+      procedure   HandleEvent(var Event: TEvent); virtual;
+      procedure   Draw; virtual;
+      procedure   LookUp(S: string); virtual;
     private
       Symbols: PSymbolCollection;
+      LookupStr: string;
     end;
 
     PSymbolReferenceView = ^TSymbolReferenceView;
     TSymbolReferenceView = object(TSymbolView)
       constructor Init(var Bounds: TRect; AReferences: PReferenceCollection; AHScrollBar, AVScrollBar: PScrollBar);
+      procedure   HandleEvent(var Event: TEvent); virtual;
       function    GetText(Item,MaxLen: Sw_Integer): String; virtual;
       procedure   SelectItem(Item: Sw_Integer); virtual;
       procedure   GotoItem(Item: sw_integer); virtual;
@@ -68,10 +73,12 @@ type
     end;
 
     PBrowserWindow = ^TBrowserWindow;
-    TBrowserWindow = object(TWindow)
+    TBrowserWindow = object(TFPWindow)
       constructor Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer;
                     const AName: string; ASymbols: PSymbolCollection; AReferences: PReferenceCollection);
       procedure   HandleEvent(var Event: TEvent); virtual;
+      procedure   SetState(AState: Word; Enable: Boolean); virtual;
+      procedure   Close; virtual;
       procedure   SelectTab(BrowserTab: Sw_integer); virtual;
       function    GetPalette: PPalette; virtual;
     private
@@ -83,11 +90,19 @@ type
 procedure OpenSymbolBrowser(X,Y: Sw_integer;const Name,Line: string;
             Symbols: PSymbolCollection; References: PReferenceCollection);
 
+function IsSymbolInfoAvailable: boolean;
+
 implementation
 
 uses Commands,App,
+     WEditor,
      FPConst,FPUtils,FPVars;
 
+function IsSymbolInfoAvailable: boolean;
+begin
+  IsSymbolInfoAvailable:=BrowCol.Modules<>nil;
+end;
+
 (*procedure ReadBrowseLog(FileName: string);
 var f: text;
     IOOK,EndOfFile: boolean;
@@ -259,6 +274,56 @@ begin
   SetRange(Symbols^.Count);
 end;
 
+procedure TSymbolScopeView.HandleEvent(var Event: TEvent);
+var OldFocus: sw_integer;
+begin
+  case Event.What of
+    evKeyDown :
+      case Event.KeyCode of
+        kbBack :
+          begin
+            LookUp(copy(LookUpStr,1,length(LookUpStr)-1));
+            ClearEvent(Event);
+          end;
+      else
+        if Event.CharCode in[#32..#255] then
+          begin
+            LookUp(LookUpStr+Event.CharCode);
+            ClearEvent(Event);
+          end;
+      end;
+  end;
+  OldFocus:=Focused;
+  inherited HandleEvent(Event);
+  if OldFocus<>Focused then
+    Lookup('');
+end;
+
+procedure TSymbolScopeView.Draw;
+begin
+  inherited Draw;
+  SetCursor(2+SymbolTypLen+length(LookUpStr),Focused-TopItem);
+end;
+
+procedure TSymbolScopeView.LookUp(S: string);
+var Idx: Sw_integer;
+    NS: string;
+begin
+  NS:=LookUpStr;
+  if (Symbols=nil) or (S='') then NS:='' else
+    begin
+      S:=Symbols^.LookUp(S,Idx);
+      if Idx<>-1 then
+        begin
+          NS:=S;
+          FocusItem(Idx);
+        end;
+    end;
+  LookUpStr:=NS;
+  SetState(sfCursorVis,LookUpStr<>'');
+  DrawView;
+end;
+
 function TSymbolScopeView.GetText(Item,MaxLen: Sw_Integer): String;
 var S: string;
 begin
@@ -280,6 +345,15 @@ begin
   SetRange(References^.Count);
 end;
 
+procedure TSymbolReferenceView.HandleEvent(var Event: TEvent);
+var OldFocus: sw_integer;
+begin
+  OldFocus:=Focused;
+  inherited HandleEvent(Event);
+  if OldFocus<>Focused then
+    Message(Desktop,evBroadcast,cmClearLineHighlights,nil);
+end;
+
 function TSymbolReferenceView.GetText(Item,MaxLen: Sw_Integer): String;
 var S: string;
     P: PReference;
@@ -296,13 +370,49 @@ begin
   if Range=0 then Exit;
   R:=References^.At(Focused);
   Desktop^.Lock;
-  W:=TryToOpenFile(R^.GetFileName,R^.Position.X-1,R^.Position.Y-1);
+  W:=TryToOpenFile(nil,R^.GetFileName,R^.Position.X-1,R^.Position.Y-1);
   if W<>nil then W^.Select;
   Desktop^.UnLock;
 end;
 
+function LastBrowserWindow: PBrowserWindow;
+var BW: PBrowserWindow;
+procedure IsBW(P: PView); {$ifndef FPC}far;{$endif}
+begin
+  if (P^.HelpCtx=hcBrowserWindow) then
+    BW:=pointer(P);
+end;
+begin
+  BW:=nil;
+  Desktop^.ForEach(@IsBW);
+  LastBrowserWindow:=BW;
+end;
+
 procedure TSymbolReferenceView.TrackSource;
+var R: PReference;
+    W: PSourceWindow;
+    BW: PBrowserWindow;
+    P: TPoint;
 begin
+  Message(Desktop,evBroadcast,cmClearLineHighlights,nil);
+  if Range=0 then Exit;
+  R:=References^.At(Focused);
+  Desktop^.Lock;
+  P.X:=R^.Position.X-1; P.Y:=R^.Position.Y-1;
+  W:=TryToOpenFile(nil,R^.GetFileName,P.X,P.Y);
+  if W<>nil then
+  begin
+    BW:=LastBrowserWindow;
+    if BW=nil then
+      W^.Select
+    else
+      begin
+        Desktop^.Delete(W);
+        Desktop^.InsertBefore(W,BW^.NextView);
+      end;
+    W^.Editor^.SetHighlightRow(P.Y);
+  end;
+  Desktop^.UnLock;
 end;
 
 procedure TSymbolReferenceView.GotoItem(Item: sw_integer);
@@ -432,9 +542,6 @@ begin
       case Event.Command of
         cmSearchWindow :
           ClearEvent(Event);
-        cmSearchWindow+1..cmSearchWindow+100 :
-          if (Event.Command-cmSearchWindow=Number) then
-              ClearEvent(Event);
         cmListItemSelected :
           if Event.InfoPtr=ScopeView then
             begin
@@ -467,6 +574,22 @@ begin
   inherited HandleEvent(Event);
 end;
 
+procedure TBrowserWindow.SetState(AState: Word; Enable: Boolean);
+var OldState: word;
+begin
+  OldState:=State;
+  inherited SetState(AState,Enable);
+  if ((State xor OldState) and sfActive)<>0 then
+    if GetState(sfActive)=false then
+      Message(Desktop,evBroadcast,cmClearLineHighlights,nil);
+end;
+
+procedure TBrowserWindow.Close;
+begin
+  Message(Desktop,evBroadcast,cmClearLineHighlights,nil);
+  inherited Close;
+end;
+
 procedure TBrowserWindow.SelectTab(BrowserTab: Sw_integer);
 var Tabs: Sw_integer;
 begin
@@ -512,7 +635,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.2  1999-01-14 21:42:24  peter
+  Revision 1.3  1999-01-21 11:54:23  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.2  1999/01/14 21:42:24  peter
     * source tracking from Gabor
 
   Revision 1.1  1999/01/12 14:29:40  peter

+ 7 - 2
ide/text/fptemplt.pas

@@ -96,7 +96,7 @@ procedure ScanDir(Dir: PathStr);
 var SR: SearchRec;
     S: string;
 begin
-  if copy(Dir,length(Dir),1)<>'\' then Dir:=Dir+'\';
+  if copy(Dir,length(Dir),1)<>DirSep then Dir:=Dir+DirSep;
   FindFirst(Dir+'*.pt',AnyFile,SR);
   while (DosError=0) do
   begin
@@ -157,7 +157,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.2  1998-12-28 15:47:52  peter
+  Revision 1.3  1999-01-21 11:54:24  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.2  1998/12/28 15:47:52  peter
     + Added user screen support, display & window
     + Implemented Editor,Mouse Options dialog
     + Added location of .INI and .CFG file

+ 744 - 0
ide/text/fptools.pas

@@ -0,0 +1,744 @@
+{
+    $Id$
+    This file is part of the Free Pascal Integrated Development Environment
+    Copyright (c) 1998 by Berczi Gabor
+
+    Tool support for the IDE
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit FPTools;
+
+interface
+
+uses Objects,Drivers,Dialogs,Validate,
+     FPViews;
+
+type
+    PTool = ^TTool;
+    TTool = object(TObject)
+      constructor Init(const ATitle, AProgramPath, ACommandLine: string; AHotKey: word);
+      function    GetTitle: string; virtual;
+      procedure   GetParams(var ATitle, AProgramPath, ACommandLine: string; var AHotKey: word); virtual;
+      procedure   SetParams(const ATitle, AProgramPath, ACommandLine: string; const AHotKey: word); virtual;
+      destructor  Done; virtual;
+    private
+      Title       : PString;
+      ProgramPath : PString;
+      CommandLine : PString;
+      HotKey      : word;
+    end;
+
+    PToolCollection = ^TToolCollection;
+    TToolCollection = object(TCollection)
+      function At(Index: sw_Integer): PTool;
+    end;
+
+    PToolListBox = ^TToolListBox;
+    TToolListBox = object(TAdvancedListBox)
+      function GetText(Item: sw_integer; MaxLen: Integer): String; virtual;
+    end;
+
+    PToolParamValidator = ^TToolParamValidator;
+    TToolParamValidator = object(TValidator)
+      function  IsValid(const S: string): Boolean; virtual;
+      procedure Error; virtual;
+    private
+      ErrorPos: integer;
+    end;
+
+    PToolItemDialog = ^TToolItemDialog;
+    TToolItemDialog = object(TCenterDialog)
+      constructor Init(ATool: PTool);
+      function    Execute: Word; virtual;
+    private
+      Tool     : PTool;
+      TitleIL  : PInputLine;
+      ProgramIL: PInputLine;
+      ParamIL  : PInputLine;
+      HotKeyRB : PRadioButtons;
+    end;
+
+    PToolsDialog = ^TToolsDialog;
+    TToolsDialog = object(TCenterDialog)
+      constructor Init;
+      function    Execute: Word; virtual;
+      procedure   HandleEvent(var Event: TEvent); virtual;
+    private
+      ToolsLB : PToolListBox;
+      procedure Add;
+      procedure Edit;
+      procedure Delete;
+    end;
+
+procedure InitTools;
+function  GetToolCount: integer;
+function  GetToolName(Idx: integer): string;
+function  AddTool(Title, ProgramPath, Params: string; HotKey: word): integer;
+procedure GetToolParams(Idx: integer; var Title, ProgramPath, Params: string; var HotKey: word);
+procedure SetToolParams(Idx: integer; Title, ProgramPath, Params: string; HotKey: word);
+procedure DoneTools;
+
+function GetHotKeyName(Key: word): string;
+
+function ParseToolParams(var Params: string; CheckOnly: boolean): integer;
+
+implementation
+
+uses Dos,
+     Commands,Views,App,MsgBox,
+     FPConst,FPVars,FPUtils;
+
+type
+    THotKeyDef = record
+      Name     : string[12];
+      KeyCode  : word;
+    end;
+
+const
+     HotKeys : array[0..9] of THotKeyDef =
+      ( (Name : '~U~nassigned' ; KeyCode : kbNoKey   ),
+        (Name : 'Shift+F~2~'   ; KeyCode : kbShiftF2 ),
+        (Name : 'Shift+F~3~'   ; KeyCode : kbShiftF3 ),
+        (Name : 'Shift+F~4~'   ; KeyCode : kbShiftF4 ),
+        (Name : 'Shift+F~5~'   ; KeyCode : kbShiftF5 ),
+        (Name : 'Shift+F~6~'   ; KeyCode : kbShiftF6 ),
+        (Name : 'Shift+F~7~'   ; KeyCode : kbShiftF7 ),
+        (Name : 'Shift+F~8~'   ; KeyCode : kbShiftF8 ),
+        (Name : 'Shift+F~9~'   ; KeyCode : kbShiftF9 ),
+        (Name : 'Shift+F~1~0'  ; KeyCode : kbShiftF10));
+
+     Tools : PToolCollection = nil;
+
+function GetHotKeyCount: integer;
+begin
+  GetHotKeyCount:=ord(High(HotKeys))-ord(Low(HotKeys))+1;
+end;
+
+function GetHotKeyNameByIdx(Idx: integer): string;
+begin
+  GetHotKeyNameByIdx:=HotKeys[Idx].Name;
+end;
+
+function HotKeyToIdx(Key: word): integer;
+var Count,I: integer;
+    Found: boolean;
+begin
+  Count:=GetHotKeyCount; Found:=false;
+  I:=0;
+  while (I<Count) and (Found=false) do
+  begin
+    Found:=HotKeys[I].KeyCode=Key;
+    if Found=false then
+    Inc(I);
+  end;
+  if Found=false then I:=-1;
+  HotKeyToIdx:=I;
+end;
+
+function IdxToHotKey(Idx: integer): word;
+var Count: integer;
+    Key: word;
+begin
+  Count:=GetHotKeyCount;
+  if (0<=Idx) and (Idx<Count) then
+    Key:=HotKeys[Idx].KeyCode
+  else
+    Key:=kbNoKey;
+  IdxToHotKey:=Key;
+end;
+
+function GetHotKeyName(Key: word): string;
+var Idx: integer;
+    S: string;
+begin
+  Idx:=HotKeyToIdx(Key);
+  if Idx=0 then S:='' else
+   if Idx=-1 then S:='???' else
+    S:=GetHotKeyNameByIdx(Idx);
+  GetHotKeyName:=S;
+end;
+
+constructor TTool.Init(const ATitle, AProgramPath, ACommandLine: string; AHotKey: word);
+begin
+  inherited Init;
+  SetParams(ATitle,AProgramPath,ACommandLine,AHotKey);
+end;
+
+function TTool.GetTitle: string;
+begin
+  GetTitle:=KillTilde(GetStr(Title));
+end;
+
+procedure TTool.GetParams(var ATitle, AProgramPath, ACommandLine: string; var AHotKey: word);
+begin
+  ATitle:=GetStr(Title); AProgramPath:=GetStr(ProgramPath);
+  ACommandLine:=GetStr(CommandLine);
+  AHotKey:=HotKey;
+end;
+
+procedure TTool.SetParams(const ATitle, AProgramPath, ACommandLine: string; const AHotKey: word);
+begin
+  if Title<>nil then DisposeStr(Title); Title:=nil;
+  if ProgramPath<>nil then DisposeStr(ProgramPath); ProgramPath:=nil;
+  if CommandLine<>nil then DisposeStr(CommandLine); CommandLine:=nil;
+  Title:=NewStr(ATitle); ProgramPath:=NewStr(AProgramPath);
+  CommandLine:=NewStr(ACommandLine);
+  HotKey:=AHotKey;
+end;
+
+destructor TTool.Done;
+begin
+  inherited Done;
+  if Title<>nil then DisposeStr(Title);
+  if ProgramPath<>nil then DisposeStr(ProgramPath);
+  if CommandLine<>nil then DisposeStr(CommandLine);
+end;
+
+function TToolCollection.At(Index: sw_Integer): PTool;
+begin
+  At:=inherited At(Index);
+end;
+
+function TToolListBox.GetText(Item: sw_integer; MaxLen: Integer): String;
+var S: string;
+    P: PTool;
+begin
+  P:=List^.At(Item);
+  S:=P^.GetTitle;
+  GetText:=copy(S,1,MaxLen);
+end;
+
+procedure InitTools;
+begin
+  if Tools<>nil then DoneTools;
+  New(Tools, Init(10,20));
+end;
+
+function  GetToolCount: integer;
+var Count: integer;
+begin
+  if Tools=nil then Count:=0 else
+    Count:=Tools^.Count;
+  GetToolCount:=Count;
+end;
+
+function GetToolName(Idx: integer): string;
+var S1,S2: string;
+    W: word;
+begin
+  GetToolParams(Idx,S1,S2,S2,W);
+  GetToolName:=KillTilde(S1);
+end;
+
+function AddTool(Title, ProgramPath, Params: string; HotKey: word): integer;
+var P: PTool;
+begin
+  if Tools=nil then InitTools;
+  New(P, Init(Title,ProgramPath,Params,HotKey));
+  Tools^.Insert(P);
+  AddTool:=Tools^.IndexOf(P);
+end;
+
+procedure GetToolParams(Idx: integer; var Title, ProgramPath, Params: string; var HotKey: word);
+var P: PTool;
+begin
+  P:=Tools^.At(Idx);
+  P^.GetParams(Title,ProgramPath,Params,HotKey);
+end;
+
+procedure SetToolParams(Idx: integer; Title, ProgramPath, Params: string; HotKey: word);
+var P: PTool;
+begin
+  P:=Tools^.At(Idx);
+  P^.GetParams(Title,ProgramPath,Params,HotKey);
+end;
+
+procedure DoneTools;
+begin
+  if Tools<>nil then Dispose(Tools, Done); Tools:=nil;
+end;
+
+procedure TToolParamValidator.Error;
+begin
+  MsgParms[1].Long:=ErrorPos;
+  ErrorBox(^C'Error parsing parameters line at line position %d.',@MsgParms);
+end;
+
+function TToolParamValidator.IsValid(const S: string): Boolean;
+var P: string;
+begin
+  P:=S;
+  ErrorPos:=ParseToolParams(P,true);
+  IsValid:=ErrorPos=0;
+end;
+
+constructor TToolItemDialog.Init(ATool: PTool);
+var R,R2,R3: TRect;
+    Items: PSItem;
+    I: integer;
+    KeyCount: integer;
+begin
+  KeyCount:=GetHotKeyCount;
+
+  R.Assign(0,0,60,Max(3+KeyCount,12));
+  inherited Init(R,'Modify/New Tool');
+  Tool:=ATool;
+
+  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+36;
+  New(TitleIL, Init(R, 128)); Insert(TitleIL);
+  R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~T~itle', TitleIL)));
+  R.Move(0,3);
+  New(ProgramIL, Init(R, 128)); Insert(ProgramIL);
+  R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, 'Program ~p~ath', ProgramIL)));
+  R.Move(0,3);
+  New(ParamIL, Init(R, 128)); Insert(ParamIL);
+  ParamIL^.SetValidator(New(PToolParamValidator, Init));
+  R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, 'Command ~l~ine', ParamIL)));
+
+  R.Copy(R3); Inc(R.A.X,38); R.B.Y:=R.A.Y+KeyCount;
+  Items:=nil;
+  for I:=KeyCount-1 downto 0 do
+    Items:=NewSItem(GetHotKeyNameByIdx(I), Items);
+  New(HotKeyRB, Init(R, Items));
+  Insert(HotKeyRB);
+
+  InsertButtons(@Self);
+
+  TitleIL^.Select;
+end;
+
+function TToolItemDialog.Execute: Word;
+var R: word;
+    S1,S2,S3: string;
+    W: word;
+    L: longint;
+begin
+  Tool^.GetParams(S1,S2,S3,W);
+  TitleIL^.SetData(S1); ProgramIL^.SetData(S2); ParamIL^.SetData(S3);
+  L:=HotKeyToIdx(W); if L=-1 then L:=255;
+  HotKeyRB^.SetData(L);
+  R:=inherited Execute;
+  if R=cmOK then
+  begin
+    TitleIL^.GetData(S1); ProgramIL^.GetData(S2); ParamIL^.GetData(S3);
+    HotKeyRB^.GetData(L); W:=IdxToHotKey(L);
+    Tool^.SetParams(S1,S2,S3,W);
+  end;
+  Execute:=R;
+end;
+
+constructor TToolsDialog.Init;
+var R,R2,R3: TRect;
+    SB: PScrollBar;
+begin
+  R.Assign(0,0,46,16);
+  inherited Init(R,'Tools');
+
+  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(ToolsLB, Init(R,1,SB));
+  Insert(ToolsLB);
+  R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
+  Insert(New(PLabel, Init(R2, '~P~rogram titles', ToolsLB)));
+
+  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 TToolsDialog.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(ToolsLB) 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 TToolsDialog.Execute: Word;
+var R: word;
+    C: PToolCollection;
+    I: integer;
+    S1,S2,S3: string;
+    W: word;
+begin
+  New(C, Init(10,20));
+  if Tools<>nil then
+  for I:=0 to Tools^.Count-1 do
+    begin
+      Tools^.At(I)^.GetParams(S1,S2,S3,W);
+      C^.Insert(New(PTool, Init(S1,S2,S3,W)));
+    end;
+  ToolsLB^.NewList(C);
+  R:=inherited Execute;
+  if R=cmOK then
+    begin
+      if Tools<>nil then Dispose(Tools, Done);
+      Tools:=C;
+      Message(Application,evBroadcast,cmUpdateTools,nil);
+    end
+  else
+    Dispose(C, Done);
+  Execute:=R;
+end;
+
+procedure TToolsDialog.Add;
+var P: PTool;
+    IC: boolean;
+    S1,S2,S3: string;
+    W: word;
+begin
+  if ToolsLB^.Range>=MaxToolCount then
+    begin InformationBox(^C'Can''t install more tools...',nil); Exit; end;
+  IC:=ToolsLB^.Range=0;
+  if IC=false then
+    begin
+      P:=ToolsLB^.List^.At(ToolsLB^.Focused);
+      P^.GetParams(S1,S2,S3,W);
+    end
+  else
+    begin
+      S1:=''; S2:=''; S3:=''; W:=0;
+    end;
+  New(P, Init(S1,S2,S3,W));
+  if Application^.ExecuteDialog(New(PToolItemDialog, Init(P)), nil)=cmOK then
+    begin
+      ToolsLB^.List^.Insert(P);
+      ToolsLB^.SetRange(ToolsLB^.List^.Count);
+      ReDraw;
+    end
+  else
+    Dispose(P, Done);
+end;
+
+procedure TToolsDialog.Edit;
+var P: PTool;
+begin
+  if ToolsLB^.Range=0 then Exit;
+  P:=ToolsLB^.List^.At(ToolsLB^.Focused);
+  Application^.ExecuteDialog(New(PToolItemDialog, Init(P)), nil);
+  ReDraw;
+end;
+
+procedure TToolsDialog.Delete;
+begin
+  if ToolsLB^.Range=0 then Exit;
+  ToolsLB^.List^.AtFree(ToolsLB^.Focused);
+  ToolsLB^.SetRange(ToolsLB^.List^.Count);
+  ReDraw;
+end;
+
+procedure ReplaceStr(var S: string; const What,NewS: string);
+var I : integer;
+begin
+  repeat
+    I:=Pos(What,S);
+    if I>0 then
+    begin
+      Delete(S,I,length(What));
+      Insert(NewS,S,I);
+    end;
+  until I=0;
+end;
+
+procedure ReplaceStrI(var S: string; What: string; const NewS: string);
+var I : integer;
+    UpcaseS: string;
+begin
+  UpcaseS:=UpcaseStr(S); What:=UpcaseStr(What);
+  repeat
+    I:=Pos(What,UpcaseS);
+    if I>0 then
+    begin
+      Delete(S,I,length(What));
+      Insert(NewS,S,I);
+    end;
+  until I=0;
+end;
+
+function ParseToolParams(var Params: string; CheckOnly: boolean): integer;
+var Err: integer;
+    W: PSourceWindow;
+procedure ParseParams(Pass: integer);
+var I: integer;
+function IsAlpha(Ch: char): boolean;
+begin
+  IsAlpha:=(Upcase(Ch) in['A'..'Z','_','$']);
+end;
+function ReplacePart(StartP,EndP: integer; const S: string): integer;
+begin
+  Params:=copy(Params,1,StartP-1)+S+copy(Params,EndP+1,255);
+  ReplacePart:=length(S)-(EndP-StartP+1);
+end;
+function Consume(Ch: char): boolean;
+var OK: boolean;
+begin
+  OK:=Params[I]=Ch;
+  if OK then Inc(I);
+  Consume:=OK;
+end;
+function ReadTill(var S: string; C: char): boolean;
+var Found: boolean;
+begin
+  Found:=false; S:='';
+  while (I<=length(Params)) and (Found=false) do
+    begin
+      Found:=Params[I]=C;
+      if Found=false then
+        begin
+          S:=S+Params[I];
+          Inc(I);
+        end;
+    end;
+  ReadTill:=Found;
+end;
+var C,PrevC: char;
+    WordS: string;
+    LastWordStart: integer;
+    L: longint;
+    S: string;
+    D: DirStr; N: NameStr; E: ExtStr;
+begin
+  I:=1; WordS:=''; LastWordStart:=I; PrevC:=' ';
+  while (I<=length(Params)+1) and (Err=0) do
+  begin
+    if I<=length(Params) then C:=Params[I];
+    if (I<=length(Params)) and IsAlpha(C) then
+     begin
+       if (I=1) or (IsAlpha(PrevC)=false) then
+         begin WordS:=''; LastWordStart:=I; end;
+{       if IsAlpha(C) then ForceConcat:=false;}
+       WordS:=WordS+C;
+     end
+    else
+      begin
+        WordS:=UpcaseStr(Trim(WordS));
+        if WordS<>'' then
+        if (WordS='$COL') then
+          begin
+            if (Pass=1) then
+            begin
+              if W=nil then L:=0 else
+                L:=W^.Editor^.CurPos.X+1;
+              I:=I+ReplacePart(LastWordStart,I-1,IntToStr(L));
+            end;
+          end else
+        if (WordS='$CONFIG') then
+          begin
+            if (Pass=1) then
+              I:=I+ReplacePart(LastWordStart,I-1,INIPath);
+          end else
+        if (WordS='$DIR') then
+          begin
+            if (Pass=2) then
+              if Consume('(')=false then Err:=I else
+              if ReadTill(S,')')=false then Err:=I else
+              begin
+                Consume(')');
+                FSplit(S,D,N,E);
+                I:=I+ReplacePart(LastWordStart,I-1,D);
+              end;
+          end else
+        if (WordS='$DRIVE') then
+          begin
+            if (Pass=2) then
+              if Consume('(')=false then Err:=I else
+              if ReadTill(S,')')=false then Err:=I else
+              begin
+                Consume(')');
+                FSplit(S,D,N,E);
+                L:=Pos(':',D); if L=0 then L:=-1;
+                D:=copy(D,1,L+1);
+                I:=I+ReplacePart(LastWordStart,I-1,D);
+              end;
+          end else
+        if (WordS='$EDNAME') then
+          begin
+            if (Pass=1) then
+            begin
+              if W=nil then S:='' else
+                S:=W^.Editor^.FileName;
+              I:=I+ReplacePart(LastWordStart,I-1,S);
+            end;
+          end else
+        if (WordS='$EXENAME') then
+          begin
+            if (Pass=1) then
+              I:=I+ReplacePart(LastWordStart,I-1,EXEFile);
+          end else
+        if (WordS='$EXT') then
+          begin
+            if (Pass=2) then
+              if Consume('(')=false then Err:=I else
+              if ReadTill(S,')')=false then Err:=I else
+              begin
+                Consume(')');
+                FSplit(S,D,N,E); E:=copy(E,2,255);
+                I:=I+ReplacePart(LastWordStart,I-1,E);
+              end;
+          end else
+        if (WordS='$LINE') then
+          begin
+            if (Pass=1) then
+            begin
+              if W=nil then L:=0 else
+                L:=W^.Editor^.CurPos.Y+1;
+              I:=I+ReplacePart(LastWordStart,I-1,IntToStr(L));
+            end;
+          end else
+        if (WordS='$NAME') then
+          begin
+            if (Pass=2) then
+              if Consume('(')=false then Err:=I else
+              if ReadTill(S,')')=false then Err:=I else
+              begin
+                Consume(')');
+                FSplit(S,D,N,E);
+                I:=I+ReplacePart(LastWordStart,I-1,N);
+              end;
+          end else
+        if (WordS='$NAMEEXT') then
+          begin
+            if (Pass=2) then
+              if Consume('(')=false then Err:=I else
+              if ReadTill(S,')')=false then Err:=I else
+              begin
+                Consume(')');
+                FSplit(S,D,N,E);
+                I:=I+ReplacePart(LastWordStart,I-1,N+E);
+              end;
+          end else
+        if (WordS='$NOSWAP') then
+          begin
+            if (Pass=1) then
+            begin
+              I:=I+ReplacePart(LastWordStart,I-1,'');
+            end;
+          end else
+        if (WordS='$PROMPT') then
+          begin
+            if (Pass=3) then
+              begin
+                I:=I+ReplacePart(LastWordStart,I-1,'');
+                if CheckOnly=false then
+                  begin
+                    S:=copy(Params,I+1,255);
+                    if InputBox('Program Arguments', '~E~nter program argument',
+                      S,255-I+1)=cmOK then
+                      begin
+                        ReplacePart(LastWordStart,255,S);
+                        I:=255;
+                      end
+                    else
+                      Err:=-1;
+                  end;
+              end;
+          end else
+        if (WordS='$SAVE') then
+          begin
+            if (Pass=0) then
+              if (Params[I]=' ') and (I<=255) then Params[I]:='_';
+          end else
+        if (WordS='$SAVE_ALL') then
+          begin
+            if (Pass=2) then
+              begin
+                I:=I+ReplacePart(LastWordStart,I-1,'');
+                Message(Application,evCommand,cmSaveAll,nil);
+              end;
+          end else
+        if (WordS='$SAVE_CUR') then
+          begin
+            if (Pass=2) then
+              begin
+                I:=I+ReplacePart(LastWordStart,I-1,'');
+                Message(W,evCommand,cmSave,nil);
+              end;
+          end else
+        if (WordS='$SAVE_PROMPT') then
+          begin
+            if (Pass=2) then
+              begin
+                I:=I+ReplacePart(LastWordStart,I-1,'');
+                if W<>nil then
+                  if W^.Editor^.SaveAsk=false then
+                    Err:=-1;
+              end;
+          end else
+        if copy(WordS,1,1)='$' then
+          Err:=LastWordStart;
+        WordS:='';
+      end;
+    PrevC:=C;
+    Inc(I);
+  end;
+end;
+var Pass: integer;
+begin
+  W:=FirstEditorWindow;
+  Err:=0;
+  for Pass:=0 to 3 do
+    begin
+      ParseParams(Pass);
+      if Err<>0 then Break;
+    end;
+  ParseToolParams:=Err;
+end;
+
+END.
+{
+  $Log$
+  Revision 1.1  1999-01-21 11:54:25  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.0  1999/01/16 10:43:31  gabor
+      Original implementation
+
+}

+ 63 - 1
ide/text/fputils.pas

@@ -37,9 +37,12 @@ function IntToHexL(L: longint; MinLen: byte): string;
 function HexToInt(S: string): longint;
 function CharStr(C: char; Count: byte): string;
 function SmartPath(Path: string): string;
+Function FixPath(s:string;allowdot:boolean):string;
+function FixFileName(const s:string):string;
 function MakeExeName(const fn:string):string;
 function LExpand(S: string; MinLen: byte): string;
 function RExpand(S: string; MinLen: byte): string;
+function FitStr(S: string; Len: byte): string;
 function LTrim(S: string): string;
 function RTrim(S: string): string;
 function Trim(S: string): string;
@@ -123,6 +126,52 @@ begin
 end;
 
 
+Function FixPath(s:string;allowdot:boolean):string;
+var
+  i : longint;
+begin
+  for i:=1 to length(s) do
+   if s[i] in ['/','\'] then
+    s[i]:=DirSep;
+  if (length(s)>0) and (s[length(s)]<>DirSep) and
+     (s[length(s)]<>':') then
+   s:=s+DirSep;
+  if (not allowdot) and (s='.'+DirSep) then
+   s:='';
+  FixPath:=s;
+end;
+
+
+function FixFileName(const s:string):string;
+var
+  i      : longint;
+  NoPath : boolean;
+begin
+  NoPath:=true;
+  for i:=length(s) downto 1 do
+   begin
+     case s[i] of
+ {$ifdef Linux}
+  '/','\' : begin
+              FixFileName[i]:='/';
+              NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
+            end;
+ 'A'..'Z' : if NoPath then
+             FixFileName[i]:=char(byte(s[i])+32)
+            else
+             FixFileName[i]:=s[i];
+ {$else}
+      '/' : FixFileName[i]:='\';
+ 'A'..'Z' : FixFileName[i]:=char(byte(s[i])+32);
+ {$endif}
+     else
+      FixFileName[i]:=s[i];
+     end;
+   end;
+  FixFileName[0]:=s[0];
+end;
+
+
 function MakeExeName(const fn:string):string;
 var
   d : DirStr;
@@ -140,12 +189,20 @@ begin
   LExpand:=S;
 end;
 
+
 function RExpand(S: string; MinLen: byte): string;
 begin
   if length(S)<MinLen then S:=S+CharStr(' ',MinLen-length(S));
   RExpand:=S;
 end;
 
+
+function FitStr(S: string; Len: byte): string;
+begin
+  FitStr:=RExpand(copy(S,1,Len),Len);
+end;
+
+
 function KillTilde(S: string): string;
 var P: byte;
 begin
@@ -412,7 +469,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.3  1999-01-12 14:29:40  peter
+  Revision 1.4  1999-01-21 11:54:25  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.3  1999/01/12 14:29:40  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 6 - 2
ide/text/fpvars.pas

@@ -48,7 +48,6 @@ const ClipboardWindow  : PClipboardWindow = nil;
       AltMouseAction   : integer = acBrowseSymbol;
       StartupOptions   : longint = 0;
       LastExitCode     : integer = 0;
-      SymbolInfoLoaded : boolean = false;
 
       ActionCommands   : array[acFirstAction..acLastAction] of word =
         (cmHelpTopicSearch,cmGotoCursor,cmToggleBreakpoint,
@@ -63,7 +62,12 @@ implementation
 END.
 {
   $Log$
-  Revision 1.4  1999-01-12 14:29:41  peter
+  Revision 1.5  1999-01-21 11:54:26  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.4  1999/01/12 14:29:41  peter
     + Implemented still missing 'switch' entries in Options menu
     + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
       ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as

+ 89 - 47
ide/text/fpviews.pas

@@ -43,9 +43,12 @@ type
       constructor Init(var Bounds: TRect; AMin, AMax: longint);
     end;
 
+    TFPWindow = object(TWindow)
+      procedure HandleEvent(var Event: TEvent); virtual;
+    end;
+
     PIDEHelpWindow = ^TIDEHelpWindow;
     TIDEHelpWindow = object(THelpWindow)
-      procedure HandleEvent(var Event: TEvent); virtual;
       function  GetPalette: PPalette; virtual;
     end;
 
@@ -65,10 +68,10 @@ type
     end;
 
     PSourceWindow = ^TSourceWindow;
-    TSourceWindow = object(TWindow)
+    TSourceWindow = object(TFPWindow)
       Editor    : PSourceEditor;
       Indicator : PIndicator;
-      constructor Init(var Bounds: TRect; AFileName: PathStr);
+      constructor Init(var Bounds: TRect; AFileName: string);
       procedure   SetTitle(ATitle: string); virtual;
       procedure   UpdateTitle; virtual;
       procedure   HandleEvent(var Event: TEvent); virtual;
@@ -259,10 +262,10 @@ type
     end;
 
     PScreenWindow = ^TScreenWindow;
-    TScreenWindow = object(TWindow)
+    TScreenWindow = object(TFPWindow)
       ScreenView : PScreenView;
-      constructor Init(AScreen: PScreen);
-      procedure   Close; virtual;
+      constructor Init(AScreen: PScreen; ANumber: integer);
+      destructor  Done; virtual;
     end;
 
 function  SearchFreeWindowNo: integer;
@@ -277,6 +280,7 @@ function  ConfirmBox(S: string; Params: pointer; CanCancel: boolean): word;
 
 function IsThereAnyEditor: boolean;
 function IsThereAnyWindow: boolean;
+function FirstEditorWindow: PSourceWindow;
 
 function  SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
 procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
@@ -298,8 +302,9 @@ procedure InitReservedWords;
 
 procedure TranslateMouseClick(View: PView; var Event: TEvent);
 
-function OpenEditorWindow(FileName: string; CurX,CurY: integer): PSourceWindow;
-function TryToOpenFile(FileName: string; CurX,CurY: integer): PSourceWindow;
+function GetNextEditorBounds(var Bounds: TRect): boolean;
+function OpenEditorWindow(Bounds: PRect; FileName: string; CurX,CurY: integer): PSourceWindow;
+function TryToOpenFile(Bounds: PRect; FileName: string; CurX,CurY: integer): PSourceWindow;
 
 const
       SourceCmds  : TCommandSet =
@@ -312,6 +317,7 @@ const
       CalcClipboard  : extended = 0;
 
       OpenFileName   : string = '';
+      NewEditorOpened: boolean = false;
 
 var  MsgParms : array[1..10] of
          record
@@ -353,6 +359,15 @@ begin
   IsThereAnyWindow:=_Is;
 end;
 
+function FirstEditorWindow: PSourceWindow;
+function EditorWindow(P: PView): boolean; {$ifndef FPC}far;{$endif}
+begin
+  EditorWindow:=(P^.HelpCtx=hcSourceWindow);
+end;
+begin
+  FirstEditorWindow:=pointer(Desktop^.FirstThat(@EditorWindow));
+end;
+
 procedure InsertButtons(ADialog: PDialog);
 var R   : TRect;
     W,H : integer;
@@ -741,12 +756,16 @@ begin
   inherited HandleEvent(Event);
 end;
 
-procedure TIDEHelpWindow.HandleEvent(var Event: TEvent);
+procedure TFPWindow.HandleEvent(var Event: TEvent);
 begin
   case Event.What of
     evBroadcast :
       case Event.Command of
-        cmUpdate : ReDraw;
+        cmUpdate :
+          ReDraw;
+        cmSearchWindow+1..cmSearchWindow+99 :
+          if (Event.Command-cmSearchWindow=Number) then
+              ClearEvent(Event);
       end;
   end;
   inherited HandleEvent(Event);
@@ -758,7 +777,7 @@ begin
   GetPalette:=@P;
 end;
 
-constructor TSourceWindow.Init(var Bounds: TRect; AFileName: PathStr);
+constructor TSourceWindow.Init(var Bounds: TRect; AFileName: string);
 var HSB,VSB: PScrollBar;
     R: TRect;
     LoadFile: boolean;
@@ -813,13 +832,6 @@ begin
         cmSearchWindow :
           if @Self<>ClipboardWindow then
             ClearEvent(Event);
-        else
-          begin
-            if (Event.Command>cmSearchWindow) and (Event.Command<=cmSearchWindow+100) and
-               (Event.Command-cmSearchWindow=Number) then
-{            if Editor^.IsClipboard=false then}
-              ClearEvent(Event);
-          end;
       end;
     evCommand :
       begin
@@ -874,7 +886,7 @@ end;
 
 destructor TSourceWindow.Done;
 begin
-  Message(Application,evBroadcast,cmSourceWindowClosing,@Self);
+  Message(Application,evBroadcast,cmSourceWndClosing,@Self);
   inherited Done;
   Message(Application,evBroadcast,cmUpdate,@Self);
 end;
@@ -916,6 +928,7 @@ destructor TClipboardWindow.Done;
 begin
   inherited Done;
   Clipboard:=nil;
+  ClipboardWindow:=nil;
 end;
 
 function TAdvancedMenuBox.NewSubView(var Bounds: TRect; AMenu: PMenu;
@@ -2078,6 +2091,12 @@ begin
         end;
         if DontClear=false then ClearEvent(Event);
       end;
+    evBroadcast :
+      case Event.Command of
+        cmListItemSelected :
+          if Event.InfoPtr=@Self then
+            Message(@Self,evCommand,cmMsgTrackSource,nil);
+      end;
     evCommand :
       begin
         DontClear:=false;
@@ -2140,30 +2159,28 @@ begin
   P:=List^.At(Focused);
   if P^.ID=0 then Exit;
   Desktop^.Lock;
-  W:=TryToOpenFile(P^.GetModuleName,0,P^.ID-1);
+  GetNextEditorBounds(R);
+  if Assigned(Owner) and (Owner=pointer(ProgramInfoWindow)) then
+    R.B.Y:=Owner^.Origin.Y;
+  W:=TryToOpenFile(@R,P^.GetModuleName,0,P^.ID-1);
   if W<>nil then
     begin
-      Desktop^.GetExtent(R);
-      W^.Locate(R);
+      W^.Editor^.SetHighlightRow(P^.ID-1);
     end;
+  if Assigned(Owner) then
+    Owner^.Select;
   Desktop^.UnLock;
 end;
 
 procedure TMessageListBox.GotoSource;
 var W: PSourceWindow;
     P: PMessageItem;
-    R: TRect;
 begin
   if Range=0 then Exit;
   P:=List^.At(Focused);
   if P^.ID=0 then Exit;
   Desktop^.Lock;
-  W:=TryToOpenFile(P^.GetModuleName,0,P^.ID-1);
-  if W<>nil then
-    begin
-      Desktop^.GetExtent(R);
-      W^.Locate(R);
-    end;
+  W:=TryToOpenFile(nil,P^.GetModuleName,0,P^.ID-1);
   Message(Owner,evCommand,cmClose,nil);
   Desktop^.UnLock;
 end;
@@ -2834,12 +2851,12 @@ begin
   SetCursor(P.X-Delta.X,P.Y-Delta.Y);
 end;
 
-constructor TScreenWindow.Init(AScreen: PScreen);
+constructor TScreenWindow.Init(AScreen: PScreen; ANumber: integer);
 var R: TRect;
     VSB,HSB: PScrollBar;
 begin
   Desktop^.GetExtent(R);
-  inherited Init(R, 'User screen', wnNoNumber);
+  inherited Init(R, 'User screen', ANumber);
   Options:=Options or ofTileAble;
   GetExtent(R); R.Grow(-1,-1); R.Move(1,0); R.A.X:=R.B.X-1;
   New(VSB, Init(R)); VSB^.Options:=VSB^.Options or ofPostProcess;
@@ -2851,11 +2868,14 @@ begin
   New(ScreenView, Init(R, HSB, VSB, AScreen));
   ScreenView^.GrowMode:=gfGrowHiX+gfGrowHiY;
   Insert(ScreenView);
+
+  UserScreenWindow:=@Self;
 end;
 
-procedure TScreenWindow.Close;
+destructor TScreenWindow.Done;
 begin
-  Hide;
+  inherited Done;
+  UserScreenWindow:=nil;
 end;
 
 const InTranslate : boolean = false;
@@ -2886,23 +2906,29 @@ begin
   InTranslate:=false;
 end;
 
-function OpenEditorWindow(FileName: string; CurX,CurY: integer): PSourceWindow;
+function GetNextEditorBounds(var Bounds: TRect): boolean;
 var P: PView;
-    R: TRect;
-    W: PSourceWindow;
 begin
-{  P:=Message(Desktop,evBroadcast,cmSearchWindow,nil);}
   P:=Desktop^.First;
   while P<>nil do
   begin
     if P^.HelpCtx=hcSourceWindow then Break;
     P:=P^.NextView;
   end;
-  if P=nil then Desktop^.GetExtent(R) else
+  if P=nil then Desktop^.GetExtent(Bounds) else
      begin
-       P^.GetBounds(R);
-       Inc(R.A.X); Inc(R.A.Y);
+       P^.GetBounds(Bounds);
+       Inc(Bounds.A.X); Inc(Bounds.A.Y);
      end;
+  GetNextEditorBounds:=P<>nil;
+end;
+
+function OpenEditorWindow(Bounds: PRect; FileName: string; CurX,CurY: integer): PSourceWindow;
+var R: TRect;
+    W: PSourceWindow;
+begin
+  if Assigned(Bounds) then R.Copy(Bounds^) else
+    GetNextEditorBounds(R);
   PushStatus('Opening source file... ('+SmartPath(FileName)+')');
   New(W, Init(R, FileName));
   if W<>nil then
@@ -2921,7 +2947,7 @@ begin
   OpenEditorWindow:=W;
 end;
 
-function TryToOpenFile(FileName: string; CurX,CurY: integer): PSourceWindow;
+function TryToOpenFile(Bounds: PRect; FileName: string; CurX,CurY: integer): PSourceWindow;
 var D : DirStr;
     N : NameStr;
     E : ExtStr;
@@ -2938,7 +2964,7 @@ var OK: boolean;
 begin
   OK:=false;
   if D<>'' then OK:=CheckDir(D,N,NewExt) else
-    if CheckDir('.\',N,NewExt) then OK:=true;
+    if CheckDir('.'+DirSep,N,NewExt) then OK:=true;
   CheckExt:=OK;
 end;
 function TryToOpen: PSourceWindow;
@@ -2946,7 +2972,7 @@ var Found: boolean;
     W : PSourceWindow;
 begin
   Found:=true;
-  if E='' then
+  if E<>'' then Found:=CheckExt(E) else
     if CheckExt('.pp') then Found:=true else
       if CheckExt('.pas') then Found:=true else
         if CheckExt('.inc')=false then
@@ -2954,7 +2980,7 @@ begin
   if Found=false then W:=nil else
     begin
       FileName:=FExpand(D+N+E);
-      W:=OpenEditorWindow(FileName,CurX,CurY);
+      W:=OpenEditorWindow(Bounds,FileName,CurX,CurY);
     end;
   TryToOpen:=W;
 end;
@@ -2975,7 +3001,14 @@ begin
           SName:=PSourceWindow(W)^.Editor^.FileName;
         SName:=UpcaseStr(SName);
 
-        if E<>'' then Found:=SName=UpcaseStr(N+E) else
+        if E<>'' then
+          begin
+            if D<>'' then
+              Found:=SName=UpcaseStr(D+N+E)
+            else
+              Found:=SName=UpcaseStr(N+E);
+          end
+        else
           begin
             Found:=SName=UpcaseStr(N+'.pp');
             if Found=false then
@@ -2993,10 +3026,14 @@ begin
   W:=SearchOnDesktop;
   if W<>nil then
     begin
+      NewEditorOpened:=false;
       W^.Editor^.SetCurPtr(CurX,CurY);
     end
   else
-    W:=TryToOpen;
+    begin
+      W:=TryToOpen;
+      NewEditorOpened:=W<>nil;
+    end;
   TryToOpenFile:=W;
 end;
 
@@ -3004,7 +3041,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.5  1999-01-14 21:42:25  peter
+  Revision 1.6  1999-01-21 11:54:27  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.5  1999/01/14 21:42:25  peter
     * source tracking from Gabor
 
   Revision 1.4  1999/01/12 14:29:42  peter

+ 1 - 0
ide/text/test.pas

@@ -20,5 +20,6 @@ BEGIN
   X:=nil;
   writeln('Hello world!');
   writeln(IsOdd(3));
+  writeln(Func1);
   Halt;
 END.

+ 3 - 1
ide/text/test2.pas

@@ -14,8 +14,10 @@ function IsOdd(X: integer): boolean;
 implementation
 
 function IsOdd(X: integer): boolean;
+var Z: byte;
 begin
-  X:=X*Test8087;
+  Z:=0;
+  X:=Z*X*Test8087;
   IsOdd:=(X mod 2)=1;
 end;
 

+ 45 - 17
ide/text/weditor.pas

@@ -28,6 +28,7 @@ uses
 const
       cmFileNameChanged      = 51234;
       cmASCIIChar            = 51235;
+      cmClearLineHighlights  = 51236;
 
 {$ifdef FPC}
       EditorTextBufSize = 32768;
@@ -162,6 +163,7 @@ type
       NoSelect   : Boolean;
       Flags      : longint;
       TabSize    : integer;
+      HighlightRow: integer;
       constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
                     PScrollBar; AIndicator: PIndicator; AbufSize:Sw_Word);
       procedure   SetFlags(AFlags: longint); virtual;
@@ -180,6 +182,7 @@ type
       procedure   SetCurPtr(X, Y: Integer); virtual;
       procedure   SetSelection(A, B: TPoint); virtual;
       procedure   SetHighlight(A, B: TPoint); virtual;
+      procedure   SetHighlightRow(Row: integer); virtual;
       procedure   SelectAll(Enable: boolean); virtual;
       function    InsertFrom(Editor: PCodeEditor): Boolean; virtual;
       function    InsertText(const S: string): Boolean; virtual;
@@ -265,6 +268,7 @@ type
                     PScrollBar; AIndicator: PIndicator;const AFileName: string);
       function    Save: Boolean; virtual;
       function    SaveAs: Boolean; virtual;
+      function    SaveAsk: Boolean; virtual;
       function    LoadFile: boolean; virtual;
       function    SaveFile: boolean; virtual;
       function    Valid(Command: Word): Boolean; virtual;
@@ -279,7 +283,7 @@ function DefUseSyntaxHighlight(Editor: PFileEditor): boolean;
 const
      DefaultCodeEditorFlags : longint =
        efBackupFiles+efInsertMode+efAutoIndent+efPersistentBlocks+
-       efUseTabCharacters+efBackSpaceUnindents+efSyntaxHighlight;
+       {efUseTabCharacters+}efBackSpaceUnindents+efSyntaxHighlight;
      DefaultTabSize     : integer = 8;
 
      ToClipCmds         : TCommandSet = ([cmCut,cmCopy,cmClear]);
@@ -1030,6 +1034,7 @@ begin
   New(Lines, Init(500,1000));
   SetState(sfCursorVis,true);
   SetFlags(DefaultCodeEditorFlags); TabSize:=DefaultTabSize;
+  SetHighlightRow(-1);
   Indicator:=AIndicator;
   UpdateIndicator; LimitsChanged;
 end;
@@ -1244,6 +1249,8 @@ begin
       end;
     evBroadcast :
       case Event.Command of
+        cmClearLineHighlights :
+          SetHighlightRow(-1);
         cmScrollBarChanged:
           if (Event.InfoPtr = HScrollBar) or
             (Event.InfoPtr = VScrollBar) then
@@ -1355,11 +1362,14 @@ begin
          if X<=length(Format) then
             Color:=ColorTab[ord(Format[X])] else Color:=ColorTab[coTextColor];
 
-      if ( ((Flags and efHighlightRow)   <>0) and (PX.Y=CurPos.Y) ) then
+      if ( ((Flags and efHighlightRow)   <>0) and (PX.Y=CurPos.Y) ) and (HighlightRow=-1) then
          begin Color:=CombineColors(Color,HighlightRowColor); FreeFormat[X]:=false; end;
       if ( ((Flags and efHighlightColumn)<>0) and (PX.X=CurPos.X) ) then
          begin Color:=CombineColors(Color,HighlightColColor); FreeFormat[X]:=false; end;
 
+      if HighlightRow=AY then
+         begin Color:=CombineColors(Color,HighlightRowColor); FreeFormat[X]:=false; end;
+
       if (0<=X-1-Delta.X) and (X-1-Delta.X<MaxViewWidth) then
       MoveChar(B[X-1-Delta.X],C,Color,1);
     end;
@@ -2379,6 +2389,8 @@ begin
      SetLineText(OldPos.Y,RTrim(GetLineText(OldPos.Y)));
   if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (GetErrorMessage<>'') then
     SetErrorMessage('');
+  if ((CurPos.X<>OldPos.X) or (CurPos.Y<>OldPos.Y)) and (HighlightRow<>-1) then
+    SetHighlightRow(-1);
 end;
 
 procedure TCodeEditor.CheckSels;
@@ -2509,7 +2521,7 @@ var
             C:=coIdentifierColor;
         end;
     end;
-    if EndX>=StartX then
+    if EndX+1>=StartX then
       FillChar(Format[StartX],EndX+1-StartX,C);
     if IsAsmPrefix(WordS) and
        (InAsm=false) and (InComment=false) and (InDirective=false) then
@@ -2729,6 +2741,12 @@ begin
   HighlightChanged;
 end;
 
+procedure TCodeEditor.SetHighlightRow(Row: integer);
+begin
+  HighlightRow:=Row;
+  DrawView;
+end;
+
 procedure TCodeEditor.SelectAll(Enable: boolean);
 var A,B: TPoint;
 begin
@@ -2914,6 +2932,23 @@ begin
   end;
 end;
 
+function TFileEditor.SaveAsk: boolean;
+var OK: boolean;
+    D: Sw_integer;
+begin
+  OK:=Modified=false;
+  if OK=false then
+  begin
+    if FileName = '' then D := edSaveUntitled else D := edSaveModify;
+    case EditorDialog(D, @FileName) of
+      cmYes    : OK := Save;
+      cmNo     : begin Modified := False; OK:=true; end;
+      cmCancel : OK := False;
+    end;
+  end;
+  SaveAsk:=OK;
+end;
+
 procedure TFileEditor.HandleEvent(var Event: TEvent);
 var SH,B: boolean;
 begin
@@ -2938,23 +2973,11 @@ end;
 
 function TFileEditor.Valid(Command: Word): Boolean;
 var OK: boolean;
-    D: Sw_integer;
 begin
   OK:=inherited Valid(Command);
   if OK and ((Command=cmClose) or (Command=cmQuit)) then
      if IsClipboard=false then
-       begin
-         OK:=true;
-         if Modified then
-         begin
-           if FileName = '' then D := edSaveUntitled else D := edSaveModify;
-           case EditorDialog(D, @FileName) of
-             cmYes    : OK := Save;
-             cmNo     : Modified := False;
-             cmCancel : OK := False;
-           end;
-         end;
-    end;
+         OK:=SaveAsk;
   Valid:=OK;
 end;
 
@@ -3201,7 +3224,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.7  1999-01-14 21:41:17  peter
+  Revision 1.8  1999-01-21 11:54:31  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.7  1999/01/14 21:41:17  peter
     * use * as modified indicator
     * fixed syntax highlighting
 

+ 7 - 1
ide/text/whlpview.pas

@@ -727,6 +727,7 @@ begin
   RenderTopic;
   BuildTopicWordList;
   Lookup('');
+  SetSelection(CurPos,CurPos);
   DrawView;
   if Owner<>nil then Owner^.UnLock;
 end;
@@ -1032,7 +1033,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.2  1998-12-28 15:47:57  peter
+  Revision 1.3  1999-01-21 11:54:32  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.2  1998/12/28 15:47:57  peter
     + Added user screen support, display & window
     + Implemented Editor,Mouse Options dialog
     + Added location of .INI and .CFG file

+ 14 - 1
ide/text/wini.pas

@@ -66,6 +66,7 @@ type
       procedure   SetEntry(Section, Tag, Value: string); virtual;
       function    GetIntEntry(Section, Tag: string; Default: longint): longint; virtual;
       procedure   SetIntEntry(Section, Tag: string; Value: longint); virtual;
+      procedure   DeleteSection(Section: string); virtual;
       destructor  Done; virtual;
     private
       ReadOnly: boolean;
@@ -488,6 +489,13 @@ begin
   SetEntry(Section,Tag,IntToStr(Value));
 end;
 
+procedure TINIFile.DeleteSection(Section: string);
+var P: PINISection;
+begin
+  P:=SearchSection(Section);
+  if P<>nil then
+    Sections^.Free(P);
+end;
 
 destructor TINIFile.Done;
 begin
@@ -503,7 +511,12 @@ end;
 END.
 {
   $Log$
-  Revision 1.2  1998-12-28 15:47:58  peter
+  Revision 1.3  1999-01-21 11:54:33  peter
+    + tools menu
+    + speedsearch in symbolbrowser
+    * working run command
+
+  Revision 1.2  1998/12/28 15:47:58  peter
     + Added user screen support, display & window
     + Implemented Editor,Mouse Options dialog
     + Added location of .INI and .CFG file