fptemplt.pas 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Template support routines for the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPTemplt;
  13. interface
  14. uses FPViews;
  15. const
  16. tsDate = '$DATE';
  17. tsDateCustom = '$DATE(';
  18. tsTime = '$TIME';
  19. tsPrompt = '$PROMPT(';
  20. function GetTemplateCount: integer;
  21. function GetTemplateName(Index: integer): string;
  22. function StartTemplate(Index: integer; Editor: PSourceEditor): boolean;
  23. procedure InitTemplates;
  24. procedure DoneTemplates;
  25. implementation
  26. uses
  27. Dos,Objects,
  28. Commands,MsgBox,
  29. WUtils,
  30. {$ifdef EDITORS}
  31. Editors,
  32. {$else}
  33. WEditor,
  34. {$endif}
  35. FPConst,FPVars,FPString,FPUtils;
  36. type
  37. PTemplate = ^TTemplate;
  38. TTemplate = record
  39. Name : PString;
  40. Path : PString;
  41. end;
  42. PTemplateCollection = ^TTemplateCollection;
  43. TTemplateCollection = object(TSortedCollection)
  44. function At(Index: Integer): PTemplate;
  45. procedure FreeItem(Item: Pointer); virtual;
  46. function Compare(Key1, Key2: Pointer): Sw_Integer; virtual;
  47. end;
  48. const Templates : PTemplateCollection = nil;
  49. function NewTemplate(const Name, Path: string): PTemplate;
  50. var P: PTemplate;
  51. begin
  52. New(P);
  53. FillChar(P^,SizeOf(P^),0);
  54. P^.Name:=NewStr(Name);
  55. P^.Path:=NewStr(Path);
  56. NewTemplate:=P;
  57. end;
  58. procedure DisposeTemplate(P: PTemplate);
  59. begin
  60. if assigned(P) then
  61. begin
  62. if assigned(P^.Name) then
  63. DisposeStr(P^.Name);
  64. if assigned(P^.Path) then
  65. DisposeStr(P^.Path);
  66. Dispose(P);
  67. end;
  68. end;
  69. function TTemplateCollection.At(Index: Integer): PTemplate;
  70. begin
  71. At:=inherited At(Index);
  72. end;
  73. procedure TTemplateCollection.FreeItem(Item: Pointer);
  74. begin
  75. if assigned(Item) then
  76. DisposeTemplate(Item);
  77. end;
  78. function TTemplateCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  79. var R: Sw_integer;
  80. K1: PTemplate absolute Key1;
  81. K2: PTemplate absolute Key2;
  82. begin
  83. if K1^.Name^<K2^.Name^ then R:=-1 else
  84. if K1^.Name^>K2^.Name^ then R:= 1 else
  85. R:=0;
  86. Compare:=R;
  87. end;
  88. function GetTemplateCount: integer;
  89. var Count: integer;
  90. begin
  91. if Templates=nil then Count:=0 else Count:=Templates^.Count;
  92. GetTemplateCount:=Count;
  93. end;
  94. function GetTemplateName(Index: integer): string;
  95. begin
  96. GetTemplateName:=Templates^.At(Index)^.Name^;
  97. end;
  98. function SearchStr(const InS, SubS: string; var P: sw_integer): boolean;
  99. begin
  100. P:=Pos(SubS,InS);
  101. SearchStr:=(P<>0);
  102. end;
  103. procedure ReplaceStr(var S: string; StartP,Len: sw_integer; const NewS: string);
  104. begin
  105. Delete(S,StartP,Len);
  106. Insert(NewS,S,StartP);
  107. end;
  108. function ReadStringPos(const InS: string; StartP: sw_integer; var Expr: string; var EndPos: sw_integer): sw_integer;
  109. const Enclosers : string[2] = '''"';
  110. var OK: boolean;
  111. Encloser: char;
  112. P: sw_integer;
  113. begin
  114. OK:=false; Expr:=''; P:=StartP; EndPos:=-1;
  115. if length(InS)>=P then
  116. begin
  117. P:=Pos(InS[P],Enclosers);
  118. OK:=(P<>0);
  119. if OK then
  120. begin
  121. OK:=false;
  122. Encloser:=Enclosers[P];
  123. P:=StartP;
  124. Inc(P);
  125. while (P<=length(InS)) do
  126. begin
  127. if InS[P]<>Encloser then
  128. Expr:=Expr+InS[P]
  129. else
  130. if (P+1<=length(InS)) and (InS[P+1]=Encloser) then
  131. Expr:=Expr+InS[P]
  132. else
  133. begin
  134. OK:=true;
  135. Break;
  136. end;
  137. Inc(P);
  138. end;
  139. EndPos:=P;
  140. end;
  141. end;
  142. if OK then
  143. ReadStringPos:=length(Expr)
  144. else
  145. ReadStringPos:=-1;
  146. end;
  147. {function ReadString(const InS: string; StartP: sw_integer; var Expr: string): sw_integer;
  148. var P: sw_integer;
  149. begin
  150. ReadString:=ReadStringPos(InS,StartP,Expr,P);
  151. end;}
  152. function ProcessTemplateLine(var S: string): boolean;
  153. var OK: boolean;
  154. P,EndP: sw_integer;
  155. Name,Expr: string;
  156. begin
  157. OK:=true;
  158. repeat
  159. P:=0; Expr:='';
  160. if OK and SearchStr(S,tsPrompt,P) then
  161. if ReadStringPos(S,P+length(tsPrompt),Name,EndP)>=0 then
  162. if copy(S,EndP+1,1)=')' then
  163. begin
  164. OK:=InputBox(dialog_fillintemplateparameter,Name,Expr,255)=cmOK;
  165. if OK then
  166. ReplaceStr(S,P,EndP-P+1+1,Expr);
  167. end;
  168. if OK and SearchStr(S,tsDateCustom,P) then
  169. if ReadStringPos(S,P+length(tsDateCustom),Expr,EndP)>=0 then
  170. if copy(S,EndP+1,1)=')' then
  171. ReplaceStr(S,P,EndP-P+1+1,FormatDateTimeL(Now,Expr));
  172. if OK and SearchStr(S,tsDate,P) then
  173. ReplaceStr(S,P,length(tsDate),FormatDateTimeL(Now,'yyyy/mm/dd'));
  174. if OK and SearchStr(S,tsTime,P) then
  175. ReplaceStr(S,P,length(tsTime),FormatDateTimeL(Now,'hh:nn:ss'));
  176. until P=0;
  177. ProcessTemplateLine:=OK;
  178. end;
  179. function ProcessTemplate(Editor: PSourceEditor): boolean;
  180. var OK: boolean;
  181. I: sw_integer;
  182. S,OrigS: string;
  183. begin
  184. OK:=true;
  185. with Editor^ do
  186. for I:=0 to GetLineCount-1 do
  187. begin
  188. S:=GetDisplayText(I); OrigS:=S;
  189. OK:=ProcessTemplateLine(S);
  190. if OK=false then Break;
  191. if S<>OrigS then
  192. begin
  193. SetDisplayText(I,S);
  194. UpdateAttrs(I,attrAll);
  195. end;
  196. end;
  197. ProcessTemplate:=OK;
  198. end;
  199. function StartTemplate(Index: integer; Editor: PSourceEditor): boolean;
  200. var
  201. T: PTemplate;
  202. OK: boolean;
  203. begin
  204. T:=Templates^.At(Index);
  205. OK:=StartEditor(Editor,T^.Path^);
  206. if OK then
  207. begin
  208. ProcessTemplate(Editor);
  209. end;
  210. StartTemplate:=OK;
  211. end;
  212. {*****************************************************************************
  213. InitTemplates
  214. *****************************************************************************}
  215. procedure InitTemplates;
  216. procedure ScanDir(Dir: PathStr);
  217. var SR: SearchRec;
  218. S: string;
  219. PT : PTemplate;
  220. i : sw_integer;
  221. begin
  222. if copy(Dir,length(Dir),1)<>DirSep then Dir:=Dir+DirSep;
  223. FindFirst(Dir+'*'+TemplateExt,AnyFile,SR);
  224. while (DosError=0) do
  225. begin
  226. S:=NameOf(SR.Name);
  227. S:=LowerCaseStr(S);
  228. S[1]:=Upcase(S[1]);
  229. PT:=NewTemplate(S,FExpand(Dir+SR.Name));
  230. if not Templates^.Search(PT,i) then
  231. Templates^.Insert(PT)
  232. else
  233. DisposeTemplate(PT);
  234. FindNext(SR);
  235. end;
  236. {$ifdef FPC}
  237. FindClose(SR);
  238. {$endif def FPC}
  239. end;
  240. begin
  241. New(Templates, Init(10,10));
  242. ScanDir('.');
  243. ScanDir(IDEDir);
  244. end;
  245. procedure DoneTemplates;
  246. begin
  247. if assigned(Templates) then
  248. begin
  249. Dispose(Templates, Done);
  250. Templates:=nil;
  251. end;
  252. end;
  253. END.
  254. {
  255. $Log$
  256. Revision 1.1 2000-07-13 09:48:36 michael
  257. + Initial import
  258. Revision 1.10 2000/06/22 09:07:12 pierre
  259. * Gabor changes: see fixes.txt
  260. Revision 1.9 2000/05/02 08:42:28 pierre
  261. * new set of Gabor changes: see fixes.txt
  262. Revision 1.8 1999/06/25 00:33:40 pierre
  263. * avoid lost memory on duplicate Template Items
  264. Revision 1.7 1999/03/08 14:58:11 peter
  265. + prompt with dialogs for tools
  266. Revision 1.6 1999/03/01 15:42:03 peter
  267. + Added dummy entries for functions not yet implemented
  268. * MenuBar didn't update itself automatically on command-set changes
  269. * Fixed Debugging/Profiling options dialog
  270. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is
  271. set
  272. * efBackSpaceUnindents works correctly
  273. + 'Messages' window implemented
  274. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  275. + Added TP message-filter support (for ex. you can call GREP thru
  276. GREP2MSG and view the result in the messages window - just like in TP)
  277. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  278. so topic search didn't work...
  279. * In FPHELP.PAS there were still context-variables defined as word instead
  280. of THelpCtx
  281. * StdStatusKeys() was missing from the statusdef for help windows
  282. + Topic-title for index-table can be specified when adding a HTML-files
  283. Revision 1.5 1999/02/18 13:44:35 peter
  284. * search fixed
  285. + backward search
  286. * help fixes
  287. * browser updates
  288. Revision 1.4 1999/02/16 17:13:56 pierre
  289. + findclose added for FPC
  290. Revision 1.3 1999/01/21 11:54:24 peter
  291. + tools menu
  292. + speedsearch in symbolbrowser
  293. * working run command
  294. Revision 1.2 1998/12/28 15:47:52 peter
  295. + Added user screen support, display & window
  296. + Implemented Editor,Mouse Options dialog
  297. + Added location of .INI and .CFG file
  298. + Option (INI) file managment implemented (see bottom of Options Menu)
  299. + Switches updated
  300. + Run program
  301. Revision 1.2 1998/12/22 10:39:51 peter
  302. + options are now written/read
  303. + find and replace routines
  304. }