fptemplt.pas 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Template support routines for the IDE
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit FPTemplt;
  12. interface
  13. uses FPViews;
  14. const
  15. tsDate = '$DATE';
  16. tsDateCustom = '$DATE(';
  17. tsTime = '$TIME';
  18. tsPrompt = '$PROMPT(';
  19. {$ifdef useresstrings}
  20. resourcestring
  21. {$else}
  22. const
  23. {$endif}
  24. dialog_fillintemplateparameter = 'Fill in template parameter';
  25. function GetTemplateCount: integer;
  26. function GetTemplateName(Index: integer): string;
  27. function StartTemplate(Index: integer; Editor: PSourceEditor): boolean;
  28. procedure InitTemplates;
  29. procedure DoneTemplates;
  30. implementation
  31. uses
  32. Dos,Objects,
  33. FVConsts,
  34. MsgBox,
  35. WUtils,
  36. WEditor,
  37. FPConst,FPVars,FPUtils;
  38. type
  39. PTemplate = ^TTemplate;
  40. TTemplate = record
  41. Name : PString;
  42. Path : PString;
  43. end;
  44. PTemplateCollection = ^TTemplateCollection;
  45. TTemplateCollection = object(TSortedCollection)
  46. function At(Index: Integer): PTemplate;
  47. procedure FreeItem(Item: Pointer); virtual;
  48. function Compare(Key1, Key2: Pointer): Sw_Integer; virtual;
  49. end;
  50. const Templates : PTemplateCollection = nil;
  51. function NewTemplate(const Name, Path: string): PTemplate;
  52. var P: PTemplate;
  53. begin
  54. New(P);
  55. FillChar(P^,SizeOf(P^),0);
  56. P^.Name:=NewStr(Name);
  57. P^.Path:=NewStr(Path);
  58. NewTemplate:=P;
  59. end;
  60. procedure DisposeTemplate(P: PTemplate);
  61. begin
  62. if assigned(P) then
  63. begin
  64. if assigned(P^.Name) then
  65. DisposeStr(P^.Name);
  66. if assigned(P^.Path) then
  67. DisposeStr(P^.Path);
  68. Dispose(P);
  69. end;
  70. end;
  71. function TTemplateCollection.At(Index: Integer): PTemplate;
  72. begin
  73. At:=inherited At(Index);
  74. end;
  75. procedure TTemplateCollection.FreeItem(Item: Pointer);
  76. begin
  77. if assigned(Item) then
  78. DisposeTemplate(Item);
  79. end;
  80. function TTemplateCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  81. var R: Sw_integer;
  82. K1: PTemplate absolute Key1;
  83. K2: PTemplate absolute Key2;
  84. begin
  85. if K1^.Name^<K2^.Name^ then R:=-1 else
  86. if K1^.Name^>K2^.Name^ then R:= 1 else
  87. R:=0;
  88. Compare:=R;
  89. end;
  90. function GetTemplateCount: integer;
  91. var Count: integer;
  92. begin
  93. if Templates=nil then Count:=0 else Count:=Templates^.Count;
  94. GetTemplateCount:=Count;
  95. end;
  96. function GetTemplateName(Index: integer): string;
  97. begin
  98. GetTemplateName:=Templates^.At(Index)^.Name^;
  99. end;
  100. function SearchStr(const InS, SubS: string; var P: sw_integer): boolean;
  101. begin
  102. P:=Pos(SubS,InS);
  103. SearchStr:=(P<>0);
  104. end;
  105. procedure ReplaceStr(var S: string; StartP,Len: sw_integer; const NewS: string);
  106. begin
  107. Delete(S,StartP,Len);
  108. Insert(NewS,S,StartP);
  109. end;
  110. function ReadStringPos(const InS: string; StartP: sw_integer; var Expr: string; var EndPos: sw_integer): sw_integer;
  111. const Enclosers : string[2] = '''"';
  112. var OK: boolean;
  113. Encloser: char;
  114. P: sw_integer;
  115. begin
  116. OK:=false; Expr:=''; P:=StartP; EndPos:=-1;
  117. if length(InS)>=P then
  118. begin
  119. P:=Pos(InS[P],Enclosers);
  120. OK:=(P<>0);
  121. if OK then
  122. begin
  123. OK:=false;
  124. Encloser:=Enclosers[P];
  125. P:=StartP;
  126. Inc(P);
  127. while (P<=length(InS)) do
  128. begin
  129. if InS[P]<>Encloser then
  130. Expr:=Expr+InS[P]
  131. else
  132. if (P+1<=length(InS)) and (InS[P+1]=Encloser) then
  133. Expr:=Expr+InS[P]
  134. else
  135. begin
  136. OK:=true;
  137. Break;
  138. end;
  139. Inc(P);
  140. end;
  141. EndPos:=P;
  142. end;
  143. end;
  144. if OK then
  145. ReadStringPos:=length(Expr)
  146. else
  147. ReadStringPos:=-1;
  148. end;
  149. {function ReadString(const InS: string; StartP: sw_integer; var Expr: string): sw_integer;
  150. var P: sw_integer;
  151. begin
  152. ReadString:=ReadStringPos(InS,StartP,Expr,P);
  153. end;}
  154. function ProcessTemplateLine(var S: string): boolean;
  155. var OK: boolean;
  156. P,EndP: sw_integer;
  157. Name,Expr: string;
  158. begin
  159. OK:=true;
  160. repeat
  161. P:=0; Expr:='';
  162. if OK and SearchStr(S,tsPrompt,P) then
  163. if ReadStringPos(S,P+length(tsPrompt),Name,EndP)>=0 then
  164. if copy(S,EndP+1,1)=')' then
  165. begin
  166. OK:=InputBox(dialog_fillintemplateparameter,Name,Expr,255)=cmOK;
  167. if OK then
  168. ReplaceStr(S,P,EndP-P+1+1,Expr);
  169. end;
  170. if OK and SearchStr(S,tsDateCustom,P) then
  171. if ReadStringPos(S,P+length(tsDateCustom),Expr,EndP)>=0 then
  172. if copy(S,EndP+1,1)=')' then
  173. ReplaceStr(S,P,EndP-P+1+1,FormatDateTimeL(Now,Expr));
  174. if OK and SearchStr(S,tsDate,P) then
  175. ReplaceStr(S,P,length(tsDate),FormatDateTimeL(Now,'yyyy/mm/dd'));
  176. if OK and SearchStr(S,tsTime,P) then
  177. ReplaceStr(S,P,length(tsTime),FormatDateTimeL(Now,'hh:nn:ss'));
  178. until P=0;
  179. ProcessTemplateLine:=OK;
  180. end;
  181. function ProcessTemplate(Editor: PSourceEditor): boolean;
  182. var OK: boolean;
  183. I: sw_integer;
  184. S,OrigS: string;
  185. begin
  186. OK:=true;
  187. with Editor^ do
  188. for I:=0 to GetLineCount-1 do
  189. begin
  190. S:=GetDisplayText(I); OrigS:=S;
  191. OK:=ProcessTemplateLine(S);
  192. if OK=false then Break;
  193. if S<>OrigS then
  194. begin
  195. SetDisplayText(I,S);
  196. UpdateAttrs(I,attrAll);
  197. DrawView;
  198. end;
  199. end;
  200. ProcessTemplate:=OK;
  201. end;
  202. function StartTemplate(Index: integer; Editor: PSourceEditor): boolean;
  203. var
  204. T: PTemplate;
  205. OK: boolean;
  206. begin
  207. T:=Templates^.At(Index);
  208. OK:=StartEditor(Editor,T^.Path^);
  209. if OK then
  210. begin
  211. ProcessTemplate(Editor);
  212. end;
  213. StartTemplate:=OK;
  214. end;
  215. {*****************************************************************************
  216. InitTemplates
  217. *****************************************************************************}
  218. procedure InitTemplates;
  219. procedure ScanDir(Dir: PathStr);
  220. var SR: SearchRec;
  221. S: string;
  222. PT : PTemplate;
  223. i : sw_integer;
  224. begin
  225. {$ifdef HASAMIGA}
  226. if (copy(Dir,length(Dir),1)<>DirSep) and (copy(Dir,length(Dir),1)<>DriveSeparator) then Dir:=Dir+DirSep;
  227. {$else}
  228. if copy(Dir,length(Dir),1)<>DirSep then Dir:=Dir+DirSep;
  229. {$endif}
  230. FindFirst(Dir+'*'+TemplateExt,AnyFile,SR);
  231. while (DosError=0) do
  232. begin
  233. S:=NameOf(SR.Name);
  234. S:=LowerCaseStr(S);
  235. S[1]:=Upcase(S[1]);
  236. PT:=NewTemplate(S,FExpand(Dir+SR.Name));
  237. if not Templates^.Search(PT,i) then
  238. Templates^.Insert(PT)
  239. else
  240. DisposeTemplate(PT);
  241. FindNext(SR);
  242. end;
  243. FindClose(SR);
  244. end;
  245. begin
  246. New(Templates, Init(10,10));
  247. ScanDir('.');
  248. ScanDir(IDEDir);
  249. end;
  250. procedure DoneTemplates;
  251. begin
  252. if assigned(Templates) then
  253. begin
  254. Dispose(Templates, Done);
  255. Templates:=nil;
  256. end;
  257. end;
  258. END.