fptemplt.pas 6.8 KB

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