Misc.pas 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. ////////////////////////////////////////////////////////////////
  2. // IMPORTANT NOTICE:
  3. // Do not include ShareMem unit in the project. Faulting to
  4. // such thing would cause an EInvalidPointer error when
  5. // LuaEdit will close.
  6. ////////////////////////////////////////////////////////////////
  7. unit Misc;
  8. interface
  9. uses
  10. Registry, SysUtils, SynEdit, SynEditTypes, SynEditMiscClasses, Graphics,
  11. SynCompletionProposal, Variants, Classes, Windows, Messages, Lua, LuaLib,
  12. LauxLib, LuaUtils, LuaSyntax, IniFiles, Forms, Dialogs, Controls, WinSock,
  13. StdCtrls, JvTabBar;
  14. const
  15. LUAEDIT_UNKNOW_MSG = 0;
  16. LUAEDIT_HINT_MSG = 1;
  17. LUAEDIT_WARNING_MSG = 2;
  18. LUAEDIT_ERROR_MSG = 3;
  19. LUA_DBGSTEPOVER = 1;
  20. LUA_DBGSTEPINTO = 2;
  21. LUA_DBGSTOP = 3;
  22. LUA_DBGPLAY = 4;
  23. LUA_DBGPAUSE = 5;
  24. HIGHLIGHT_STACK = 0;
  25. HIGHLIGHT_ERROR = 1;
  26. HIGHLIGHT_BREAKLINE = 2;
  27. HIGHLIGHT_SELECT = 3;
  28. BKPT_DISABLED = 0;
  29. BKPT_ENABLED = 1;
  30. SIF_ACTPROJECT = 0;
  31. SIF_OPENED = 1;
  32. SIF_DIRECTORY = 2;
  33. JVPAGE_RING_FILES = 0;
  34. JVPAGE_RING_CLIPBOARD = 1;
  35. JVPAGE_RING_BRWHISTORY = 2;
  36. RDBG_EMPTY = '@@N\A@@';
  37. HOOK_MASK = LUA_MASKCALL or LUA_MASKRET or LUA_MASKLINE;
  38. PRINT_SIZE = 16384;
  39. SUB_TABLE_MAX = 99;
  40. ArgIdent = 'arg';
  41. type
  42. //////////////////////////////////////////////////////////////////////////////
  43. // Copy data message data types
  44. //////////////////////////////////////////////////////////////////////////////
  45. TCopyDataType = (cdtAnsiString = 0, cdtWideString = 1, cdtBinary = 2);
  46. //////////////////////////////////////////////////////////////////////////////
  47. // Miscellaneous forwards and definitions
  48. //////////////////////////////////////////////////////////////////////////////
  49. ELuaEditException = class(Exception);
  50. ESocketException = class(Exception);
  51. TInitializer = function(L: PLua_State): Integer; stdcall;
  52. PTInitializer = ^TInitializer;
  53. TLuaEditProject = class;
  54. //////////////////////////////////////////////////////////////////////////////
  55. // Remote debugging function templates (for "plugin" oriented logic)
  56. //////////////////////////////////////////////////////////////////////////////
  57. TInitiateServer = function(var S: TSocket; var SCom: TSocket; Port: Integer; TimeOut: Integer): Boolean; stdcall;
  58. PTInitiateServer = ^TInitiateServer;
  59. TInitiateClient = function(var S: TSocket; RemoteIP: PChar; Port: Integer; UploadDir: PChar; TimeOut: Integer): Boolean; stdcall;
  60. PTInitiateClient = ^TInitiateClient;
  61. TGetLocalIP = function(): PChar; stdcall;
  62. PTGetLocalIP = ^TGetLocalIP;
  63. TSocketCreate = function(IsClient: Boolean; ErrorMessage: PChar): TSocket; stdcall;
  64. PTSocketCreate = ^TSocketCreate;
  65. TSocketConnect = function(S: TSocket; RemotePort: Integer; RemoteIP, ErrorMessage: PChar; Silent: Boolean = False): Boolean; stdcall;
  66. PTSocketConnect = ^TSocketConnect;
  67. TSocketDisconnect = function(S: TSocket; ErrorMessage: PChar): Boolean; stdcall;
  68. PTSocketDisconnect = ^TSocketDisconnect;
  69. TSocketSend = function(S: TSocket; var Buf; Len, Flags: Integer; ErrorMessage: PChar): Boolean; stdcall;
  70. PTSocketSend = ^TSocketSend;
  71. TSocketReceive = function(S: TSocket; var Buf; Flags: Integer; ErrorMessage: PChar): Boolean; stdcall;
  72. PTSocketReceive = ^TSocketReceive;
  73. TSendFile = function(S: TSocket; LocalPath, RemotePath, ErrMsg: PChar): Boolean; stdcall;
  74. PTSendFile = ^TSendFile;
  75. TReceiveFile = function(S: TSocket; ErrMsg: PChar): Boolean; stdcall;
  76. PTReceiveFile = ^TReceiveFile;
  77. TSendDebugInfos = function(S: TSocket; L: PLua_State; AR: Plua_Debug; ErrMsg: PChar): Boolean; stdcall;
  78. PTSendDebugInfos = ^TSendDebugInfos;
  79. TReceiveDebugInfos = function(S: TSocket; var L: PLua_State; var AR: Plua_Debug; var Locals, Globals: PChar; ErrMsg: PChar): Boolean; stdcall;
  80. PTReceiveDebugInfos = ^TReceiveDebugInfos;
  81. TSendIsBreakpointAtLineRemote = function(S: TSocket; Line: Integer; ErrMsg: PChar): Boolean; stdcall;
  82. PTSendIsBreakpointAtLineRemote = ^TSendIsBreakpointAtLineRemote;
  83. TReceiveIsBreakpointAtLineLocal = function(S: TSocket; var Line: Integer; ErrMsg: PChar): Boolean; stdcall;
  84. PTReceiveIsBreakpointAtLineLocal = ^TReceiveIsBreakpointAtLineLocal;
  85. TSendIsBreakpointAtLineLocal = function(S: TSocket; Line, HitCount: Integer; Condition, ErrMsg: PChar): Boolean; stdcall;
  86. PTSendIsBreakpointAtLineLocal = ^TSendIsBreakpointAtLineLocal;
  87. TReceiveIsBreakpointAtLineRemote = function(S: TSocket; var Line: Integer; var HitCount; var Condition: PChar; ErrMsg: PChar): Boolean; stdcall;
  88. PTReceiveIsBreakpointAtLineRemote = ^TReceiveIsBreakpointAtLineRemote;
  89. //////////////////////////////////////////////////////////////////////////////
  90. // Miscellaneous class
  91. //////////////////////////////////////////////////////////////////////////////
  92. {Implementation of TRegistry but featuring default values for Read* functions}
  93. TAdvanceRegistry = class(TRegistry)
  94. public
  95. function ReadCurrency(const Name: String; Default: Currency): Currency; overload;
  96. function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer; Default: Integer): Integer; overload;
  97. function ReadBool(const Name: String; Default: Boolean): Boolean; overload;
  98. function ReadDate(const Name: String; Default: TDateTime): TDateTime; overload;
  99. function ReadDateTime(const Name: String; Default: TDateTime): TDateTime; overload;
  100. function ReadFloat(const Name: String; Default: Double): Double; overload;
  101. function ReadInteger(const Name: String; Default: Integer): Integer; overload;
  102. function ReadString(const Name: String; Default: String): String; overload;
  103. function ReadTime(const Name: String; Default: TDateTime): TDateTime; overload;
  104. end;
  105. TEditorColors = class(TObject)
  106. IsItalic: Boolean;
  107. IsBold: Boolean;
  108. IsUnderline: Boolean;
  109. Foreground: String;
  110. Background: String;
  111. private
  112. constructor Create;
  113. end;
  114. TFctInfo = class(TObject)
  115. FctDef: String;
  116. Params: String;
  117. Line: Integer;
  118. public
  119. constructor Create;
  120. end;
  121. TBreakInfo = class(TObject)
  122. FileName: String; // Path of file where the break happened
  123. Call: String; // Actual text at line break
  124. LineOut: String; // Line number to display
  125. Line: Integer; // Actual line definition in script
  126. public
  127. constructor Create;
  128. end;
  129. TDebugSupportPlugin = class(TSynEditPlugin)
  130. protected
  131. procedure PaintDebugGlyphs(ACanvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
  132. procedure AfterPaint(ACanvas: TCanvas; const AClip: TRect; FirstLine, LastLine: integer); override;
  133. procedure LinesInserted(FirstLine, Count: integer); override;
  134. procedure LinesDeleted(FirstLine, Count: integer); override;
  135. end;
  136. TBreakpoint = class
  137. iHitCount: Integer;
  138. iLine: Integer;
  139. iStatus: Integer;
  140. sCondition: String;
  141. public
  142. constructor Create;
  143. end;
  144. TLineDebugInfos = class
  145. lstBreakpoint: TList;
  146. iLineError: Integer;
  147. iCurrentLineDebug: Integer;
  148. iStackMarker: Integer;
  149. public
  150. constructor Create;
  151. destructor Destroy; override;
  152. function IsBreakPointLine(iLine: Integer): Boolean;
  153. function GetBreakpointStatus(iLine: Integer): Integer;
  154. procedure AddBreakpointAtLine(iLine: Integer);
  155. procedure EnableDisableBreakpointAtLine(iLine: Integer);
  156. function GetBreakpointAtLine(iLine: Integer): TBreakpoint;
  157. procedure RemoveBreakpointAtLine(iLine: Integer);
  158. function GetLineCondition(iLine: Integer): String;
  159. end;
  160. //////////////////////////////////////////////////////////////////////////////
  161. // Editor's classes
  162. //////////////////////////////////////////////////////////////////////////////
  163. {
  164. ** CLASS DIAGRAM - Indentation is relevant of inheritance **
  165. TLuaEditFile .................................... Base class
  166. |
  167. |-TLuaEditGUIForm............................... GUI form file (linked with a lua file)
  168. |
  169. |-TLuaEditBasicTextFile ........................ Basic text file
  170. | |
  171. | |-TLuaEditDebugFile ......................... Basic text file which is debuggable
  172. | |
  173. | |-TLuaEditUnit ........................... Lua script file
  174. | |
  175. | |-TLuaEditMacro .......................... Lua script file used for user customized interface in LuaEdit
  176. |
  177. |-TLuaEditProject .............................. Lua project which contains other files
  178. }
  179. // Object type enumeration
  180. TLuaEditFileType = (otTextFile, otLuaEditUnit, otLuaEditProject, otLuaEditMacro, otLuaEditForm);
  181. TLuaEditDebugFilesTypeSet = set of TLuaEditFileType;
  182. TLuaEditTextFilesTypeSet = set of TLuaEditFileType;
  183. {Base class for all major file classes}
  184. TLuaEditFile = class
  185. FOTFileType: TLuaEditFileType;
  186. FLastTimeModified: TDateTime;
  187. FName: String;
  188. FPath: String;
  189. FDisplayPath: String;
  190. FIsReadOnly: Boolean;
  191. FIsNew: Boolean;
  192. FHasChanged: Boolean;
  193. FIsLoaded: Boolean;
  194. FPrjOwner: TLuaEditProject;
  195. public
  196. constructor Create(Path: String; otType: TLuaEditFileType = otTextFile);
  197. function Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; virtual;
  198. function SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; virtual;
  199. published
  200. property FileType: TLuaEditFileType read FOTFileType write FOTFileType;
  201. property LastTimeModified: TDateTime read FLastTimeModified write FLastTimeModified;
  202. property Name: String read FName write FName;
  203. property Path: String read FPath write FPath;
  204. property DisplayPath: String read FDisplayPath write FDisplayPath;
  205. property IsReadOnly: Boolean read FIsReadOnly write FIsReadOnly;
  206. property IsNew: Boolean read FIsNew write FIsNew;
  207. property HasChanged: Boolean read FHasChanged write FHasChanged;
  208. property IsLoaded: Boolean read FIsLoaded write FIsLoaded;
  209. property PrjOwner: TLuaEditProject read FPrjOwner write FPrjOwner;
  210. end;
  211. // Forward declaration
  212. TLuaEditDebugFile = class;
  213. TLuaEditGUIForm = class(TLuaEditFile)
  214. FGUIDesignerForm: TForm;
  215. FLinkedDebugFile: TLuaEditDebugFile;
  216. public
  217. constructor Create(Path: String; otType: TLuaEditFileType = otLuaEditForm);
  218. destructor Destroy; override;
  219. published
  220. property GUIDesignerForm: TForm read FGUIDesignerForm write FGUIDesignerForm;
  221. property LinkedDebugFile: TLuaEditDebugFile read FLinkedDebugFile write FLinkedDebugFile;
  222. end;
  223. TLuaEditBasicTextFile = class(TLuaEditFile)
  224. FLastEditedLine: Integer;
  225. FSynUnit: TSynEdit;
  226. FAssociatedTab: TJvTabBarItem;
  227. public
  228. constructor Create(Path: String; otType: TLuaEditFileType = otTextFile);
  229. destructor Destroy; override;
  230. function Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; override;
  231. function SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; override;
  232. published
  233. property LastEditedLine: Integer read FLastEditedLine write FLastEditedLine;
  234. property SynUnit: TSynEdit read FSynUnit write FSynUnit;
  235. property AssociatedTab: TJvTabBarItem read FAssociatedTab write FAssociatedTab;
  236. end;
  237. TLuaEditDebugFile = class(TLuaEditBasicTextFile)
  238. FLinkedGUIForm: TLuaEditGUIForm;
  239. FSynCompletion: TSynCompletionProposal;
  240. FSynParams: TSynCompletionProposal;
  241. FDebugPlugin: TDebugSupportPlugin;
  242. FDebugInfos: TLineDebugInfos;
  243. FPrevLineNumber: Integer;
  244. public
  245. constructor Create(Path: String; otType: TLuaEditFileType = otTextFile);
  246. destructor Destroy; override;
  247. function Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; override;
  248. function SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; override;
  249. procedure SaveBreakpoints();
  250. procedure GetBreakpoints();
  251. published
  252. property LinkedGUIForm: TLuaEditGUIForm read FLinkedGUIForm write FLinkedGUIForm;
  253. property SynCompletion: TSynCompletionProposal read FSynCompletion write FSynCompletion;
  254. property SynParams: TSynCompletionProposal read FSynParams write FSynParams;
  255. property DebugPlugin: TDebugSupportPlugin read FDebugPlugin write FDebugPlugin;
  256. property DebugInfos: TLineDebugInfos read FDebugInfos write FDebugInfos;
  257. property PrevLineNumber: Integer read FPrevLineNumber write FPrevLineNumber;
  258. end;
  259. {Class containing informations and functions about lua script files}
  260. TLuaEditUnit = class(TLuaEditDebugFile)
  261. lstFunctions: TStringList;
  262. public
  263. constructor Create(Path: String; otType: TLuaEditFileType = otLuaEditUnit);
  264. destructor Destroy; override;
  265. end;
  266. {Class containing informations and functions about luaedit macro files}
  267. TLuaEditMacro = class(TLuaEditDebugFile)
  268. lstFunctions: TStringList;
  269. public
  270. constructor Create(Path: String; otType: TLuaEditFileType = otLuaEditMacro);
  271. destructor Destroy; override;
  272. end;
  273. {Class containing informations and functions about lua project files}
  274. TLuaEditProject = class(TLuaEditFile)
  275. sInitializer: String;
  276. sRemoteIP: String;
  277. sRemoteDirectory: String;
  278. sRuntimeDirectory: String;
  279. sTargetLuaUnit: String;
  280. sCompileDirectory: String;
  281. sCompileExtension: String;
  282. AutoIncRevNumber: Boolean;
  283. iVersionMajor: Integer;
  284. iVersionMinor: Integer;
  285. iVersionRelease: Integer;
  286. iVersionRevision: Integer;
  287. iRemotePort: Integer;
  288. iConnectTimeOut: Integer;
  289. lstUnits: TList;
  290. pTargetLuaUnit: TLuaEditUnit;
  291. public
  292. constructor Create(Path: String; otType: TLuaEditFileType = otLuaEditProject);
  293. destructor Destroy; override;
  294. procedure AddFile(pFile: TLuaEditFile); overload;
  295. function AddFile(FileName: String; IsNew: Boolean): TLuaEditBasicTextFile; overload;
  296. procedure GetProjectFromDisk(Path: String);
  297. function Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; override;
  298. function SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean; override;
  299. procedure RealoadProject();
  300. end;
  301. // LuaEditSys.dll functions...
  302. function GetFileLastTimeModified(const sFileName: PChar): TDateTime; cdecl; external 'LuaEditSys.dll';
  303. function GetFileReadOnlyAttr(const sFileName: PChar): Boolean; cdecl; external 'LuaEditSys.dll';
  304. function GetFileSizeStr(Size: Cardinal): PChar; cdecl; external 'LuaEditSys.dll';
  305. function GetFileVersion(const FileName: PChar): PChar; cdecl; external 'LuaEditSys.dll';
  306. function GetOSInfo: PChar; cdecl; external 'LuaEditSys.dll';
  307. function SetPrivilege(sPrivilegeName : PChar; bEnabled : boolean): boolean; cdecl; external 'LuaEditSys.dll';
  308. procedure ToggleFileReadOnlyAttr(const sFileName: PChar); cdecl; external 'LuaEditSys.dll';
  309. function WinExit(iFlags: integer): Boolean; cdecl; external 'LuaEditSys.dll';
  310. function BrowseURL(URL: PChar): Boolean; cdecl; external 'LuaEditSys.dll';
  311. // Other Misc functions
  312. function GetLuaEditInstallPath(): String;
  313. function FileExistsAbs(FileName: String): Boolean;
  314. implementation
  315. uses
  316. Main, Breakpoints, ReadOnlyMsgBox, ProjectTree, GUIDesigner, LuaEditMessages;
  317. ///////////////////////////////////////////////////////////////////
  318. // Misc functions
  319. ///////////////////////////////////////////////////////////////////
  320. // This function finds LuaEdit's install path and returns it
  321. function GetLuaEditInstallPath(): String;
  322. var
  323. pReg: TRegistry;
  324. begin
  325. Result := '';
  326. pReg := TRegistry.Create;
  327. pReg.RootKey := HKEY_LOCAL_MACHINE;
  328. if pReg.OpenKey('\Software\LuaEdit', False) then
  329. Result := pReg.ReadString('ApplicationPath');
  330. pReg.Free;
  331. end;
  332. function FileExistsAbs(FileName: String): Boolean;
  333. begin
  334. Result := (DirectoryExists(ExtractFileDir(FileName)) and (FileExists(FileName)));
  335. end;
  336. ///////////////////////////////////////////////////////////////////
  337. // TAdvanceRegistry class
  338. ///////////////////////////////////////////////////////////////////
  339. function TAdvanceRegistry.ReadCurrency(const Name: String; Default: Currency): Currency;
  340. begin
  341. try
  342. Result := ReadCurrency(Name);
  343. except
  344. Result := Default;
  345. end;
  346. end;
  347. function TAdvanceRegistry.ReadBinaryData(const Name: String; var Buffer; BufSize: Integer; Default: Integer): Integer;
  348. begin
  349. try
  350. Result := ReadBinaryData(Name, Buffer, BufSize);
  351. except
  352. Result := Default;
  353. end;
  354. end;
  355. function TAdvanceRegistry.ReadBool(const Name: String; Default: Boolean): Boolean;
  356. begin
  357. try
  358. Result := ReadBool(Name);
  359. except
  360. Result := Default;
  361. end;
  362. end;
  363. function TAdvanceRegistry.ReadDate(const Name: String; Default: TDateTime): TDateTime;
  364. begin
  365. try
  366. Result := ReadDate(Name);
  367. except
  368. Result := Default;
  369. end;
  370. end;
  371. function TAdvanceRegistry.ReadDateTime(const Name: String; Default: TDateTime): TDateTime;
  372. begin
  373. try
  374. Result := ReadDateTime(Name);
  375. except
  376. Result := Default;
  377. end;
  378. end;
  379. function TAdvanceRegistry.ReadFloat(const Name: String; Default: Double): Double;
  380. begin
  381. try
  382. Result := ReadFloat(Name);
  383. except
  384. Result := Default;
  385. end;
  386. end;
  387. function TAdvanceRegistry.ReadInteger(const Name: String; Default: Integer): Integer;
  388. begin
  389. try
  390. Result := ReadInteger(Name);
  391. except
  392. Result := Default;
  393. end;
  394. end;
  395. function TAdvanceRegistry.ReadString(const Name: String; Default: String): String;
  396. begin
  397. try
  398. Result := ReadString(Name);
  399. if Result = '' then
  400. Result := Default;
  401. except
  402. Result := Default;
  403. end;
  404. end;
  405. function TAdvanceRegistry.ReadTime(const Name: String; Default: TDateTime): TDateTime;
  406. begin
  407. try
  408. Result := ReadTime(Name);
  409. except
  410. Result := Default;
  411. end;
  412. end;
  413. ///////////////////////////////////////////////////////////////////
  414. // TEditorColors class
  415. ///////////////////////////////////////////////////////////////////
  416. constructor TEditorColors.Create;
  417. begin
  418. IsItalic := False;
  419. IsBold := False;
  420. IsUnderline := False;
  421. Foreground := 'clBlack';
  422. Background := 'clBlack';
  423. end;
  424. ///////////////////////////////////////////////////////////////////
  425. // TFctInfo
  426. ///////////////////////////////////////////////////////////////////
  427. constructor TFctInfo.Create;
  428. begin
  429. FctDef := '';
  430. Params := '';
  431. Line := -1;
  432. end;
  433. ///////////////////////////////////////////////////////////////////
  434. // TBreakInfo
  435. ///////////////////////////////////////////////////////////////////
  436. constructor TBreakInfo.Create;
  437. begin
  438. FileName := '';
  439. Call := '';
  440. LineOut := '';
  441. Line := -1;
  442. end;
  443. ///////////////////////////////////////////////////////////////////
  444. // TBreakpoint class
  445. ///////////////////////////////////////////////////////////////////
  446. constructor TBreakpoint.Create;
  447. begin
  448. iHitCount := 0;
  449. iLine := -1;
  450. iStatus := BKPT_ENABLED;
  451. sCondition := '';
  452. end;
  453. ///////////////////////////////////////////////////////////////////
  454. // TLineDebugInfos class
  455. ///////////////////////////////////////////////////////////////////
  456. constructor TLineDebugInfos.Create;
  457. begin
  458. lstBreakpoint := TList.Create;
  459. iLineError := -1;
  460. iStackMarker := -1;
  461. iCurrentLineDebug := -1;
  462. end;
  463. destructor TLineDebugInfos.Destroy;
  464. var
  465. x: Integer;
  466. begin
  467. for x := 0 to lstBreakpoint.Count - 1 do
  468. begin
  469. lstBreakpoint.Delete(x);
  470. end;
  471. lstBreakpoint.Free;
  472. end;
  473. function TLineDebugInfos.IsBreakPointLine(iLine: Integer): Boolean;
  474. var
  475. x: Integer;
  476. begin
  477. Result := False;
  478. for x := 0 to lstBreakpoint.Count - 1 do
  479. begin
  480. if iLine = TBreakpoint(lstBreakpoint.Items[x]).iLine then
  481. begin
  482. Result := True;
  483. break;
  484. end;
  485. end;
  486. end;
  487. function TLineDebugInfos.GetBreakpointStatus(iLine: Integer): Integer;
  488. var
  489. x: Integer;
  490. begin
  491. Result := -1;
  492. for x := 0 to lstBreakpoint.Count - 1 do
  493. begin
  494. if iLine = TBreakpoint(lstBreakpoint.Items[x]).iLine then
  495. begin
  496. Result := TBreakpoint(lstBreakpoint.Items[x]).iStatus;
  497. break;
  498. end;
  499. end;
  500. end;
  501. function TLineDebugInfos.GetBreakpointAtLine(iLine: Integer): TBreakpoint;
  502. var
  503. x: Integer;
  504. begin
  505. Result := nil;
  506. for x := 0 to lstBreakpoint.Count - 1 do
  507. begin
  508. if iLine = TBreakpoint(lstBreakpoint.Items[x]).iLine then
  509. begin
  510. Result := TBreakpoint(lstBreakpoint.Items[x]);
  511. break;
  512. end;
  513. end;
  514. end;
  515. procedure TLineDebugInfos.AddBreakpointAtLine(iLine: Integer);
  516. var
  517. pNewBreakpoint: TBreakpoint;
  518. begin
  519. pNewBreakpoint := TBreakpoint.Create;
  520. pNewBreakpoint.iLine := iLine;
  521. lstBreakpoint.Add(pNewBreakpoint);
  522. end;
  523. procedure TLineDebugInfos.EnableDisableBreakpointAtLine(iLine: Integer);
  524. var
  525. x: Integer;
  526. begin
  527. for x := 0 to lstBreakpoint.Count - 1 do
  528. begin
  529. if TBreakpoint(lstBreakpoint.Items[x]).iLine = iLine then
  530. begin
  531. if TBreakpoint(lstBreakpoint.Items[x]).iStatus = BKPT_ENABLED then
  532. TBreakpoint(lstBreakpoint.Items[x]).iStatus := BKPT_DISABLED
  533. else
  534. TBreakpoint(lstBreakpoint.Items[x]).iStatus := BKPT_ENABLED;
  535. Break;
  536. end;
  537. end;
  538. end;
  539. procedure TLineDebugInfos.RemoveBreakpointAtLine(iLine: Integer);
  540. var
  541. x: Integer;
  542. begin
  543. for x := 0 to lstBreakpoint.Count - 1 do
  544. begin
  545. if TBreakpoint(lstBreakpoint.Items[x]).iLine = iLine then
  546. begin
  547. lstBreakpoint.Delete(x);
  548. Break;
  549. end;
  550. end;
  551. end;
  552. function TLineDebugInfos.GetLineCondition(iLine: Integer): String;
  553. var
  554. x: Integer;
  555. begin
  556. for x := 0 to lstBreakpoint.Count - 1 do
  557. begin
  558. if TBreakpoint(lstBreakpoint.Items[x]).iLine = iLine then
  559. begin
  560. Result := TrimLeft(TBreakpoint(lstBreakpoint.Items[x]).sCondition);
  561. Break;
  562. end;
  563. end;
  564. end;
  565. ///////////////////////////////////////////////////////////////////
  566. // TDebugSupportPlugin class
  567. ///////////////////////////////////////////////////////////////////
  568. procedure TDebugSupportPlugin.AfterPaint(ACanvas: TCanvas; const AClip: TRect; FirstLine, LastLine: integer);
  569. begin
  570. PaintDebugGlyphs(ACanvas, AClip, FirstLine, LastLine);
  571. end;
  572. procedure TDebugSupportPlugin.PaintDebugGlyphs(ACanvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
  573. var
  574. LH, X, Y: integer;
  575. ImgIndex: integer;
  576. pLuaUnit: TLuaEditUnit;
  577. begin
  578. if Assigned(frmLuaEditMain.jvUnitBar.SelectedTab) then
  579. begin
  580. pLuaUnit := TLuaEditUnit(frmLuaEditMain.jvUnitBar.SelectedTab.Data);
  581. FirstLine := pLuaUnit.synUnit.RowToLine(FirstLine);
  582. LastLine := pLuaUnit.synUnit.RowToLine(LastLine);
  583. X := 1;
  584. LH := pLuaUnit.synUnit.LineHeight;
  585. while FirstLine <= LastLine do
  586. begin
  587. ImgIndex := -1;
  588. Y := (LH - frmLuaEditMain.imlActions.Height) div 2 + LH * (pLuaUnit.synUnit.LineToRow(FirstLine) - pLuaUnit.synUnit.TopLine);
  589. if pLuaUnit.DebugInfos.IsBreakPointLine(FirstLine) then
  590. begin
  591. if pLuaUnit.DebugInfos.GetBreakpointStatus(FirstLine) = BKPT_ENABLED then
  592. ImgIndex := 27
  593. else
  594. ImgIndex := 28;
  595. end;
  596. if TLuaEditUnit(frmLuaEditMain.jvUnitBar.SelectedTab.Data).DebugInfos.iCurrentLineDebug = FirstLine then
  597. ImgIndex := 29;
  598. if ((pLuaUnit.DebugInfos.IsBreakPointLine(FirstLine)) and (TLuaEditUnit(frmLuaEditMain.jvUnitBar.SelectedTab.Data).DebugInfos.iCurrentLineDebug = FirstLine)) then
  599. begin
  600. if pLuaUnit.DebugInfos.GetBreakpointStatus(FirstLine) = BKPT_ENABLED then
  601. ImgIndex := 30
  602. else
  603. ImgIndex := 43;
  604. end;
  605. if ImgIndex > 0 then
  606. frmLuaEditMain.imlActions.Draw(ACanvas, X, Y, ImgIndex);
  607. Inc(FirstLine);
  608. end;
  609. end;
  610. end;
  611. procedure TDebugSupportPlugin.LinesInserted(FirstLine, Count: integer);
  612. var
  613. pLuaUnit: TLuaEditUnit;
  614. x: Integer;
  615. begin
  616. pLuaUnit := TLuaEditUnit(frmLuaEditMain.jvUnitBar.SelectedTab.Data);
  617. for x := 0 to pLuaUnit.DebugInfos.lstBreakpoint.Count - 1 do
  618. begin
  619. if TBreakpoint(pLuaUnit.DebugInfos.lstBreakpoint.Items[x]).iLine >= FirstLine then
  620. begin
  621. TBreakpoint(pLuaUnit.DebugInfos.lstBreakpoint.Items[x]).iLine := TBreakpoint(pLuaUnit.DebugInfos.lstBreakpoint.Items[x]).iLine + Count;
  622. end;
  623. end;
  624. pLuaUnit.synUnit.Refresh;
  625. frmBreakpoints.RefreshBreakpointList;
  626. end;
  627. procedure TDebugSupportPlugin.LinesDeleted(FirstLine, Count: integer);
  628. var
  629. pLuaUnit: TLuaEditUnit;
  630. x: Integer;
  631. begin
  632. pLuaUnit := TLuaEditUnit(frmLuaEditMain.jvUnitBar.SelectedTab.Data);
  633. for x := 0 to pLuaUnit.DebugInfos.lstBreakpoint.Count - 1 do
  634. begin
  635. if TBreakpoint(pLuaUnit.DebugInfos.lstBreakpoint.Items[x]).iLine >= FirstLine then
  636. begin
  637. TBreakpoint(pLuaUnit.DebugInfos.lstBreakpoint.Items[x]).iLine := TBreakpoint(pLuaUnit.DebugInfos.lstBreakpoint.Items[x]).iLine - Count;
  638. end;
  639. end;
  640. pLuaUnit.synUnit.Refresh;
  641. frmBreakpoints.RefreshBreakpointList;
  642. end;
  643. ///////////////////////////////////////////////////////////////////
  644. // TLuaEditFile class
  645. ///////////////////////////////////////////////////////////////////
  646. constructor TLuaEditFile.Create(Path: String; otType: TLuaEditFileType);
  647. begin
  648. FOTFileType := otType;
  649. FPath := Path;
  650. // Get Last Time accessed and readonly state
  651. if ((Path <> '') and FileExistsAbs(Path)) then
  652. begin
  653. FLastTimeModified := GetFileLastTimeModified(PChar(Path));
  654. FIsReadOnly := GetFileReadOnlyAttr(PChar(Path));
  655. FDisplayPath := FPath;
  656. end
  657. else
  658. begin
  659. FPath := GetLuaEditInstallPath() + '\Templates\Template' + ExtractFileExt(Path);
  660. FDisplayPath := '?\' + ExtractFileName(Path);
  661. FLastTimeModified := Now;
  662. FIsReadOnly := False;
  663. end;
  664. FName := ChangeFileExt(ExtractFileName(Path), '');
  665. end;
  666. function TLuaEditFile.Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean;
  667. begin
  668. FDisplayPath := Path;
  669. end;
  670. function TLuaEditFile.SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean;
  671. begin
  672. FDisplayPath := Path;
  673. end;
  674. ///////////////////////////////////////////////////////////////////
  675. // TLuaEditGUIForm class
  676. ///////////////////////////////////////////////////////////////////
  677. constructor TLuaEditGUIForm.Create(Path: String; otType: TLuaEditFileType);
  678. begin
  679. inherited Create(Path, otType);
  680. FLinkedDebugFile := nil;
  681. FGUIDesignerForm := TGUIForm1.Create(nil);
  682. TGUIForm1(FGUIDesignerForm).pLuaEditGUIForm := Self;
  683. end;
  684. destructor TLuaEditGUIForm.Destroy;
  685. begin
  686. inherited Destroy;
  687. if Assigned(FGUIDesignerForm) then
  688. FGUIDesignerForm.Free;
  689. end;
  690. ///////////////////////////////////////////////////////////////////
  691. // TLuaEditBasicTextFile class
  692. ///////////////////////////////////////////////////////////////////
  693. constructor TLuaEditBasicTextFile.Create(Path: String; otType: TLuaEditFileType);
  694. begin
  695. inherited Create(Path, otType);
  696. FLastEditedLine := -1;
  697. FAssociatedTab := nil;
  698. // Set some properties
  699. FSynUnit := TSynEdit.Create(frmLuaEditMain.pnlMain);
  700. FSynUnit.Parent := frmLuaEditMain.pnlMain;
  701. FSynUnit.Visible := False;
  702. FSynUnit.Align := alClient;
  703. FSynUnit.MaxScrollWidth := 10000;
  704. FSynUnit.WantTabs := True;
  705. FSynUnit.ShowHint := True;
  706. FSynUnit.PopupMenu := frmLuaEditMain.ppmEditor;
  707. FSynUnit.BookMarkOptions.LeftMargin := 15;
  708. // Set event handlers
  709. FSynUnit.OnChange := frmLuaEditMain.synEditChange;
  710. FSynUnit.OnScroll := frmLuaEditMain.synEditScroll;
  711. FSynUnit.OnDblClick := frmLuaEditMain.synEditDblClick;
  712. FSynUnit.OnMouseMove := frmLuaEditMain.synEditMouseMove;
  713. FSynUnit.OnMouseCursor := frmLuaEditMain.synEditMouseCursor;
  714. FSynUnit.OnReplaceText := frmLuaEditMain.SynEditReplaceText;
  715. FSynUnit.OnKeyUp := frmLuaEditMain.synEditKeyUp;
  716. FSynUnit.OnClick := frmLuaEditMain.synEditClick;
  717. FSynUnit.OnSpecialLineColors := frmLuaEditMain.synEditSpecialLineColors;
  718. FSynUnit.OnGutterClick := frmLuaEditMain.synEditGutterClick;
  719. // Initialize lua highlighter engine
  720. if otType in LuaEditDebugFilesTypeSet then
  721. FSynUnit.Highlighter := TSynLuaSyn.Create(nil);
  722. // Load content in the synedit control if required
  723. if ((not IsNew) and FileExistsAbs(Path)) then
  724. SynUnit.Lines.LoadFromFile(Path);
  725. end;
  726. destructor TLuaEditBasicTextFile.Destroy;
  727. begin
  728. inherited Destroy;
  729. FSynUnit.Free;
  730. end;
  731. function TLuaEditBasicTextFile.SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean;
  732. var
  733. xPos, IncValue, iAnswer, TempIncValue: Integer;
  734. bResult: Boolean;
  735. pMsgBox: TfrmReadOnlyMsgBox;
  736. begin
  737. try
  738. try
  739. frmLuaEditMain.jvchnNotifier.Active := False;
  740. Result := True;
  741. // save only if the file is opened in the tab...
  742. // if not, there is no way that the file was modified so no needs to save
  743. if Assigned(Self.AssociatedTab) then
  744. begin
  745. // Popup a open dialog according to parameters and the state of the file
  746. if ((IsNew and not bNoDialog) or (bForceDialog)) then
  747. begin
  748. frmLuaEditMain.sdlgSaveAsUnit.FileName := ExtractFileName(FName);
  749. if ExtractFileExt(FPath) = '.lua' then
  750. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 1
  751. else if ExtractFileExt(FPath) = '.lmc' then
  752. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 2
  753. else if ExtractFileExt(FPath) = '.txt' then
  754. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 3
  755. else
  756. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 4;
  757. if frmLuaEditMain.sdlgSaveAsUnit.Execute then
  758. begin
  759. Path := frmLuaEditMain.sdlgSaveAsUnit.FileName;
  760. if IsNew then
  761. frmLuaEditMain.MonitorFileToRecent(Path);
  762. end
  763. else
  764. begin
  765. // Return false because action was cancel and quit function
  766. Result := False;
  767. Exit;
  768. end;
  769. end;
  770. // Getting currently assigned number
  771. IncValue := -1; // For future testing
  772. xPos := Length(ExtractFileExt(Path)) + 1; // Assign initial try position
  773. bResult := True; // For a first try
  774. while bResult do
  775. begin
  776. bResult := TryStrToInt(Copy(Path, Length(Path) - xPos + 1, xPos - Length(ExtractFileExt(Path))), TempIncValue);
  777. if bResult then
  778. begin
  779. IncValue := TempIncValue;
  780. Inc(XPos);
  781. end;
  782. end;
  783. if IncValue = -1 then
  784. IncValue := 1 // Give an initial value
  785. else
  786. Inc(IncValue); // Increment actual value
  787. // Build the new name
  788. Path := Copy(Self.Path, 1, Length(Self.Path) - xPos + 1) + IntToStr(IncValue) + ExtractFileExt(Self.Path);
  789. // Check if file is read only first
  790. while (GetFileReadOnlyAttr(PChar(Path)) and (FileExistsAbs(Path))) do
  791. begin
  792. pMsgBox := TfrmReadOnlyMsgBox.Create(nil);
  793. iAnswer := pMsgBox.MessageBox('The project '+Path+' is read-only. Save anyway? ', 'LuaEdit');
  794. pMsgBox.Free;
  795. if iAnswer = mrOk then
  796. begin
  797. ToggleFileReadOnlyAttr(PChar(Path));
  798. // Now that we wrote on the disk we may retrieve the time it has been writen
  799. LastTimeModified := GetFileLastTimeModified(PChar(Path));
  800. IsReadOnly := False;
  801. end
  802. else if iAnswer = mrYes then
  803. begin
  804. // Popup an open dialog according to parameters and the state of the file
  805. frmLuaEditMain.sdlgSaveAsUnit.FileName := ExtractFileName(Self.Name);
  806. if frmLuaEditMain.sdlgSaveAsUnit.Execute then
  807. begin
  808. Path := frmLuaEditMain.sdlgSaveAsUnit.FileName;
  809. end
  810. else
  811. begin
  812. // Return false because action was cancel and quit function
  813. Result := False;
  814. Exit;
  815. end;
  816. end
  817. else
  818. begin
  819. Result := False;
  820. Exit;
  821. end;
  822. end;
  823. FPath := Path;
  824. PrjOwner.HasChanged := True; // Since the name has changed, the project must be saved
  825. SynUnit.Lines.SaveToFile(FPath); // Save to file to hard drive
  826. FName := ExtractFileName(FPath); // Get short name for fast display
  827. IsNew := False; // The file is no more new
  828. HasChanged := False; // The has no more changes
  829. SynUnit.Modified := False; // The actual editor must not notice any changes now
  830. LastTimeModified := GetFileLastTimeModified(PChar(Path)); // Now we wrote on the disk we may retrieve the time it has been writen
  831. inherited SaveInc(Path);
  832. end;
  833. except
  834. frmLuaEditMessages.Put('Could not save file "'+FPath+'" on disk!', LUAEDIT_ERROR_MSG, FPath);
  835. Result := False;
  836. end;
  837. finally
  838. // Refresh interface
  839. frmLuaEditMain.RefreshOpenedUnits;
  840. frmLuaEditMain.jvUnitBarChange(frmLuaEditMain.jvUnitBar);
  841. frmProjectTree.BuildProjectTree;
  842. frmLuaEditMain.BuildReopenMenu;
  843. frmLuaEditMain.stbMain.Panels[5].Text := '';
  844. frmLuaEditMain.stbMain.Refresh;
  845. SynUnit.Refresh;
  846. frmLuaEditMain.jvchnNotifier.Active := True;
  847. end;
  848. end;
  849. function TLuaEditBasicTextFile.Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean;
  850. var
  851. iAnswer: Integer;
  852. pMsgBox: TfrmReadOnlyMsgBox;
  853. begin
  854. try
  855. try
  856. frmLuaEditMain.jvchnNotifier.Active := False;
  857. Result := True;
  858. // save only if the file is opened in the tab...
  859. // if not, there is no way that the file was modified so no needs to save
  860. if Assigned(Self.AssociatedTab) then
  861. begin
  862. // Popup a open dialog according to parameters and the state of the file
  863. if ((IsNew and not bNoDialog) or (bForceDialog)) then
  864. begin
  865. frmLuaEditMain.sdlgSaveAsUnit.FileName := ExtractFileName(Self.Name);
  866. if ExtractFileExt(FPath) = '.lua' then
  867. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 1
  868. else if ExtractFileExt(FPath) = '.lmc' then
  869. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 2
  870. else if ExtractFileExt(FPath) = '.txt' then
  871. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 3
  872. else
  873. frmLuaEditMain.sdlgSaveAsUnit.FilterIndex := 4;
  874. if frmLuaEditMain.sdlgSaveAsUnit.Execute then
  875. begin
  876. Path := frmLuaEditMain.sdlgSaveAsUnit.FileName;
  877. PrjOwner.HasChanged := True;
  878. if IsNew then
  879. frmLuaEditMain.MonitorFileToRecent(Path);
  880. end
  881. else
  882. begin
  883. // Return false because action was cancel and quit function
  884. Result := False;
  885. Exit;
  886. end;
  887. end;
  888. // Check if file is read only first
  889. while (GetFileReadOnlyAttr(PChar(Path)) and (FileExistsAbs(Path))) do
  890. begin
  891. pMsgBox := TfrmReadOnlyMsgBox.Create(nil);
  892. iAnswer := pMsgBox.MessageBox('The project '+Path+' is read-only. Save anyway? ', 'LuaEdit');
  893. pMsgBox.Free;
  894. if iAnswer = mrOk then
  895. begin
  896. ToggleFileReadOnlyAttr(PChar(Path));
  897. // Now that we wrote on the disk we may retrieve the time it has been writen
  898. LastTimeModified := GetFileLastTimeModified(PChar(Path));
  899. IsReadOnly := False;
  900. end
  901. else if iAnswer = mrYes then
  902. begin
  903. // Popup an open dialog according to parameters and the state of the file
  904. frmLuaEditMain.sdlgSaveAsUnit.FileName := ExtractFileName(Self.Name);
  905. if frmLuaEditMain.sdlgSaveAsUnit.Execute then
  906. begin
  907. Path := frmLuaEditMain.sdlgSaveAsUnit.FileName;
  908. PrjOwner.HasChanged := True;
  909. end
  910. else
  911. begin
  912. // Return false because action was cancel and quit function
  913. Result := False;
  914. Exit;
  915. end;
  916. end
  917. else
  918. begin
  919. Result := False;
  920. Exit;
  921. end;
  922. end;
  923. synUnit.Lines.SaveToFile(Path); // Save the file to hard drive
  924. Self.Name := ExtractFileName(Path); // Get short name for fast display
  925. Self.Path := Path; // Assign filepath to class filepath
  926. IsNew := False; // The file is not new anymore
  927. HasChanged := False; // The file does't have anymore changes
  928. synUnit.Modified := False; // The actual editor must not notice any changes now
  929. LastTimeModified := GetFileLastTimeModified(PChar(Path)); // Now we wrote on the disk we may retrieve the time it has been writen
  930. inherited Save(Path);
  931. end;
  932. except
  933. frmLuaEditMessages.Put('Could not save file "'+FPath+'" on disk!', LUAEDIT_ERROR_MSG, FPath);
  934. Result := False;
  935. end;
  936. finally
  937. // Refresh interface
  938. frmLuaEditMain.RefreshOpenedUnits;
  939. frmLuaEditMain.jvUnitBarChange(frmLuaEditMain.jvUnitBar);
  940. frmProjectTree.BuildProjectTree;
  941. frmLuaEditMain.BuildReopenMenu;
  942. frmLuaEditMain.stbMain.Panels[5].Text := '';
  943. frmLuaEditMain.stbMain.Refresh;
  944. synUnit.Refresh;
  945. frmLuaEditMain.jvchnNotifier.Active := True;
  946. end;
  947. end;
  948. ///////////////////////////////////////////////////////////////////
  949. // TLuaEditDebugFile class
  950. ///////////////////////////////////////////////////////////////////
  951. constructor TLuaEditDebugFile.Create(Path: String; otType: TLuaEditFileType);
  952. begin
  953. inherited Create(Path, otType);
  954. FLinkedGUIForm := nil;
  955. FDebugInfos := TLineDebugInfos.Create;
  956. FDebugPlugin := TDebugSupportPlugin.Create(SynUnit);
  957. FSynCompletion := frmLuaEditMain.GetBaseCompletionProposal();
  958. FSynCompletion.Editor := SynUnit;
  959. FSynParams := frmLuaEditMain.GetBaseParamsProposal();
  960. FSynParams.TriggerChars := '(';
  961. FSynParams.Editor := SynUnit;
  962. FPrevLineNumber := SynUnit.Lines.Count;
  963. end;
  964. destructor TLuaEditDebugFile.Destroy;
  965. begin
  966. inherited Destroy;
  967. FDebugInfos.Free;
  968. FSynCompletion.Free;
  969. FSynParams.Free;
  970. end;
  971. function TLuaEditDebugFile.Save(Path: String; bNoDialog: Boolean; bForceDialog: Boolean): Boolean;
  972. begin
  973. Result := inherited Save(Path, bNoDialog, bForceDialog);
  974. // Reinitialize variables
  975. DebugInfos.iLineError := -1; // Do not display anymore the current line error
  976. // Save breakpoints if feature is enabled
  977. if Main.SaveBreakpoints then
  978. SaveBreakpoints();
  979. // Refresh stuff...
  980. frmLuaEditMain.stbMain.Refresh;
  981. SynUnit.Refresh;
  982. end;
  983. function TLuaEditDebugFile.SaveInc(Path: String; bNoDialog: Boolean; bForceDialog: Boolean): Boolean;
  984. begin
  985. Result := inherited SaveInc(Path, bNoDialog, bForceDialog);
  986. // Reinitialize variables
  987. DebugInfos.iLineError := -1; // Do not display anymore the current line error
  988. // Save breakpoints if feature is enabled
  989. if Main.SaveBreakpoints then
  990. SaveBreakpoints();
  991. // Refresh stuff...
  992. frmLuaEditMain.stbMain.Refresh;
  993. SynUnit.Refresh;
  994. end;
  995. procedure TLuaEditDebugFile.SaveBreakpoints();
  996. var
  997. x, iBreakpointInc: Integer;
  998. sSectionName: String;
  999. pBreakpointFile: TIniFile;
  1000. pBreakpoint: TBreakpoint;
  1001. begin
  1002. // Only if at least on breakpoint is present
  1003. if DebugInfos.lstBreakpoint.Count > 0 then
  1004. begin
  1005. // Erase existing file if any to ensure a new clean breakpoint file
  1006. // NOTE: IniFiles append datas when they already exists
  1007. if FileExistsAbs(ChangeFileExt(Path, '.lbf')) then
  1008. DeleteFile(PChar(ChangeFileExt(Path, '.lbf')));
  1009. // Create the ini file engine and the file on the hard drive
  1010. pBreakpointFile := TIniFile.Create(ChangeFileExt(Path, '.lbf'));
  1011. // Initialize stuff...
  1012. iBreakpointInc := 0;
  1013. // Go through all breakpoints and save them in the file
  1014. for x := 0 to DebugInfos.lstBreakpoint.Count - 1 do
  1015. begin
  1016. pBreakpoint := TBreakpoint(DebugInfos.lstBreakpoint[x]); // Assign list object pointer to local pointer for easier usage
  1017. Inc(iBreakpointInc); // Increase local incrementer number for unique section name
  1018. sSectionName := 'Breakpoint' + IntToStr(iBreakpointInc); // Build unique section name
  1019. // Write datas
  1020. pBreakpointFile.WriteInteger(sSectionName, 'Line', pBreakpoint.iLine);
  1021. pBreakpointFile.WriteInteger(sSectionName, 'Status', pBreakpoint.iStatus);
  1022. pBreakpointFile.WriteString(sSectionName, 'Condition', pBreakpoint.sCondition);
  1023. end;
  1024. // Commit data in the file and free local pointer
  1025. pBreakpointFile.UpdateFile;
  1026. pBreakpointFile.Free;
  1027. end;
  1028. end;
  1029. procedure TLuaEditDebugFile.GetBreakpoints();
  1030. var
  1031. x: Integer;
  1032. lstSections: TStringList;
  1033. pBreakpointFile: TIniFile;
  1034. pBreakpoint: TBreakpoint;
  1035. begin
  1036. // Only if a .lbf file with the same name as the .lua file is existing
  1037. if FileExistsAbs(ChangeFileExt(Path, '.lbf')) then
  1038. begin
  1039. lstSections := TStringList.Create; // Create the section list
  1040. pBreakpointFile := TIniFile.Create(ChangeFileExt(Path, '.lbf')); // Create the ini file engine and the file on the hard drive
  1041. // Read all sections name
  1042. pBreakpointFile.ReadSections(lstSections);
  1043. // Empty actual list of breakpoints if any
  1044. for x := DebugInfos.lstBreakpoint.Count - 1 downto 0 do
  1045. begin
  1046. pBreakpoint := TBreakpoint(DebugInfos.lstBreakpoint[x]);
  1047. DebugInfos.lstBreakpoint.Delete(x);
  1048. pBreakpoint.Free;
  1049. end;
  1050. // Go through all section (one section = one breakpoint)
  1051. for x := 0 to lstSections.Count - 1 do
  1052. begin
  1053. // Create new object
  1054. pBreakpoint := TBreakpoint.Create;
  1055. // Read data from file and assign it to new object
  1056. pBreakpoint.iLine := pBreakpointFile.ReadInteger(lstSections.Strings[x], 'Line', 1);
  1057. pBreakpoint.iStatus := pBreakpointFile.ReadInteger(lstSections.Strings[x], 'Status', BKPT_ENABLED);
  1058. pBreakpoint.sCondition := pBreakpointFile.ReadString(lstSections.Strings[x], 'Condition', '');
  1059. // Add breakpoint object to unit breakpoint list
  1060. DebugInfos.lstBreakpoint.Add(pBreakpoint);
  1061. end;
  1062. // Free local pointers and refresh associated synedit
  1063. lstSections.Free;
  1064. pBreakpointFile.Free;
  1065. if Assigned(synUnit) then
  1066. synUnit.Refresh;
  1067. end;
  1068. end;
  1069. ///////////////////////////////////////////////////////////////////
  1070. // TLuaEditProject class
  1071. ///////////////////////////////////////////////////////////////////
  1072. constructor TLuaEditProject.Create(Path: String; otType: TLuaEditFileType);
  1073. begin
  1074. inherited Create(Path, otType);
  1075. lstUnits := TList.Create;
  1076. iVersionMajor := 1;
  1077. iVersionMinor := 0;
  1078. iVersionRelease := 0;
  1079. iVersionRevision := 0;
  1080. AutoIncRevNumber := False;
  1081. iRemotePort := 1024;
  1082. sRemoteIP := '0.0.0.0';
  1083. sRemoteDirectory := '';
  1084. sCompileDirectory := '';
  1085. sCompileExtension := '.luac';
  1086. end;
  1087. destructor TLuaEditProject.Destroy;
  1088. begin
  1089. inherited Destroy;
  1090. lstUnits.Free;
  1091. end;
  1092. procedure TLuaEditProject.AddFile(pFile: TLuaEditFile);
  1093. begin
  1094. if FName = '[@@SingleUnits@@]' then
  1095. lstUnits.Insert(lstUnits.Count, pFile)
  1096. else
  1097. lstUnits.Add(pFile);
  1098. FHasChanged := True;
  1099. end;
  1100. function TLuaEditProject.AddFile(FileName: String; IsNew: Boolean): TLuaEditBasicTextFile;
  1101. var
  1102. pFile: TLuaEditFile;
  1103. begin
  1104. if ExtractFileExt(FileName) = '.gui' then
  1105. pFile := TLuaEditGUIForm.Create(FileName)
  1106. else if ExtractFileExt(FileName) = '.lua' then
  1107. pFile := TLuaEditDebugFile(TLuaEditUnit.Create(FileName))
  1108. else if ExtractFileExt(FileName) = '.lmc' then
  1109. pFile := TLuaEditDebugFile(TLuaEditMacro.Create(FileName))
  1110. else
  1111. pFile := TLuaEditBasicTextFile.Create(FileName);
  1112. pFile.PrjOwner := Self;
  1113. pFile.IsNew := IsNew;
  1114. if FName = '[@@SingleUnits@@]' then
  1115. lstUnits.Insert(lstUnits.Count, pFile)
  1116. else
  1117. lstUnits.Add(pFile);
  1118. Result := TLuaEditBasicTextFile(pFile);
  1119. FHasChanged := True;
  1120. end;
  1121. procedure TLuaEditProject.GetProjectFromDisk(Path: String);
  1122. var
  1123. x: Integer;
  1124. pLuaUnit: TLuaEditUnit;
  1125. fFile: TIniFile;
  1126. lstTmpFiles: TStringList;
  1127. sUnitName: String;
  1128. begin
  1129. fFile := TIniFile.Create(Path);
  1130. lstTmpFiles := TStringList.Create;
  1131. // Read the [Description] section
  1132. FName := fFile.ReadString('Description', 'Name', 'LuaProject');
  1133. iVersionMajor := fFile.ReadInteger('Description', 'VersionMajor', 1);
  1134. iVersionMinor := fFile.ReadInteger('Description', 'VersionMinor', 0);
  1135. iVersionRelease := fFile.ReadInteger('Description', 'VersionRelease', 0);
  1136. iVersionRevision := fFile.ReadInteger('Description', 'VersionRevision', 0);
  1137. AutoIncRevNumber := fFile.ReadBool('Description', 'AutoIncRevNumber', False);
  1138. // Read the [Options] section
  1139. // None for now...
  1140. // Read the [Debug] section
  1141. sInitializer := fFile.ReadString('Debug', 'Initializer', '');
  1142. sRemoteIP := fFile.ReadString('Debug', 'RemoteIP', '0.0.0.0');
  1143. sRemoteDirectory := fFile.ReadString('Debug', 'RemoteDirectory', '');
  1144. iRemotePort := fFile.ReadInteger('Debug', 'RemotePort', 1024);
  1145. iConnectTimeOut := fFile.ReadInteger('Debug', 'ConnectTimeOut', 10);
  1146. sRuntimeDirectory := fFile.ReadString('Debug', 'RuntimeDirectory', 'C:\');
  1147. sTargetLuaUnit := fFile.ReadString('Debug', 'TargetLuaUnit', '[Current Unit]');
  1148. sCompileDirectory := fFile.ReadString('Debug', 'CompileDirectory', '');
  1149. sCompileExtension := fFile.ReadString('Debug', 'CompileExtension', '.luac');
  1150. pTargetLuaUnit := nil; // Will be filled later
  1151. // Initialize project variables and global variables
  1152. FPath := Path;
  1153. IsNew := False;
  1154. HasChanged := False;
  1155. LuaProjects.Add(Self);
  1156. ActiveProject := Self;
  1157. frmLuaEditMain.MonitorFileToRecent(FPath);
  1158. // Read [Files] section
  1159. fFile.ReadSection('Files', lstTmpFiles);
  1160. if lstTmpFiles.Count > 0 then
  1161. begin
  1162. // Open each individual
  1163. for x := 0 to lstTmpFiles.Count - 1 do
  1164. begin
  1165. sUnitName := ExpandUNCFileName(ExtractFilePath(FPath) + fFile.ReadString('Files', lstTmpFiles.Strings[x], ''));
  1166. if FileExistsAbs(sUnitName) then
  1167. begin
  1168. // Initialize unit and global variables considering the fact that open was a success
  1169. pLuaUnit := TLuaEditUnit(AddFile(sUnitName, False));
  1170. pLuaUnit.Path := sUnitName;
  1171. pLuaUnit.Name := ExtractFileName(sUnitName);
  1172. pLuaUnit.IsLoaded := True;
  1173. // Add first loaded file in the tabs
  1174. if x = 0 then
  1175. frmLuaEditMain.AddFileInTab(pLuaUnit);
  1176. end
  1177. else
  1178. begin
  1179. // Initialize unit and global variables considering the fact that open was a failure
  1180. Application.MessageBox(PChar('The file "'+sUnitName+'" is innexistant!'), 'LuaEdit', MB_OK+MB_ICONERROR);
  1181. pLuaUnit := TLuaEditUnit(AddFile(sUnitName, False));
  1182. pLuaUnit.IsLoaded := False;
  1183. end;
  1184. if pLuaUnit.Name = sTargetLuaUnit then
  1185. pTargetLuaUnit := pLuaUnit;
  1186. end;
  1187. end;
  1188. fFile.Free;
  1189. lstTmpFiles.Free;
  1190. end;
  1191. function TLuaEditProject.SaveInc(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean;
  1192. var
  1193. pFile: TIniFile;
  1194. x, xPos, IncValue, iAnswer, TempIncValue: integer;
  1195. bResult: Boolean;
  1196. pMsgBox: TfrmReadOnlyMsgBox;
  1197. begin
  1198. inherited SaveInc(Path);
  1199. frmLuaEditMain.jvchnNotifier.Active := False;
  1200. Result := True;
  1201. // Popup a open dialog according to parameters and the state of the file
  1202. if ((IsNew and not bNoDialog) or (bForceDialog)) then
  1203. begin
  1204. frmLuaEditMain.sdlgSaveAsPrj.FileName := Self.Name + '.lpr';
  1205. if frmLuaEditMain.sdlgSaveAsPrj.Execute then
  1206. begin
  1207. Path := frmLuaEditMain.sdlgSaveAsPrj.FileName;
  1208. end
  1209. else
  1210. begin
  1211. // Return false because action was cancel and quit function
  1212. Result := False;
  1213. Exit;
  1214. end;
  1215. end;
  1216. // Getting currently assigned number
  1217. IncValue := -1; // For future testing
  1218. xPos := Length(ExtractFileExt(Path)) + 1; // Assign initial try position
  1219. bResult := True; // For a first try
  1220. while bResult do
  1221. begin
  1222. bResult := TryStrToInt(Copy(Path, Length(Path) - xPos + 1, xPos - Length(ExtractFileExt(Path))), TempIncValue);
  1223. if bResult then
  1224. begin
  1225. IncValue := TempIncValue;
  1226. Inc(XPos);
  1227. end;
  1228. end;
  1229. if IncValue = -1 then
  1230. IncValue := 1 // Give an initial value
  1231. else
  1232. Inc(IncValue); // Increment actual value
  1233. Path := Copy(Path, 1, Length(Path) - xPos + 1) + IntToStr(IncValue) + ExtractFileExt(Path); // Build the new name
  1234. // Check if file is read only first
  1235. while (GetFileReadOnlyAttr(PChar(Path)) and (FileExistsAbs(Path))) do
  1236. begin
  1237. pMsgBox := TfrmReadOnlyMsgBox.Create(nil);
  1238. iAnswer := pMsgBox.MessageBox('The project '+Path+' is read-only. Save anyway? ', 'LuaEdit');
  1239. pMsgBox.Free;
  1240. if iAnswer = mrOk then
  1241. begin
  1242. ToggleFileReadOnlyAttr(PChar(Path));
  1243. // Now that we wrote on the disk we may retrieve the time it has been writen
  1244. LastTimeModified := GetFileLastTimeModified(PChar(Path));
  1245. IsReadOnly := False;
  1246. end
  1247. else if iAnswer = mrYes then
  1248. begin
  1249. // Popup an open dialog according to parameters and the state of the file
  1250. frmLuaEditMain.sdlgSaveAsPrj.FileName := Self.Name + '.lpr';
  1251. if frmLuaEditMain.sdlgSaveAsPrj.Execute then
  1252. begin
  1253. Path := frmLuaEditMain.sdlgSaveAsPrj.FileName;
  1254. if IsNew then
  1255. frmLuaEditMain.MonitorFileToRecent(Path);
  1256. end
  1257. else
  1258. begin
  1259. // Return false because action was cancel and quit function
  1260. Result := False;
  1261. Exit;
  1262. end;
  1263. end
  1264. else
  1265. begin
  1266. Result := False;
  1267. Exit;
  1268. end;
  1269. end;
  1270. // Erase existing file if any to ensure a new clean project
  1271. // NOTE: IniFiles append stuff to it when they already exists
  1272. if FileExistsAbs(Path) then
  1273. DeleteFile(PChar(Path));
  1274. pFile := TIniFile.Create(Path); // Create project file writer engine (using *.ini files way)
  1275. // Increasing Revision Number if feature is selected
  1276. if AutoIncRevNumber then
  1277. Inc(iVersionRevision);
  1278. // Write data for [Description] section
  1279. pFile.WriteString('Description', 'Name', Self.Name);
  1280. pFile.WriteInteger('Description', 'VersionMajor', iVersionMajor);
  1281. pFile.WriteInteger('Description', 'VersionMinor', iVersionMinor);
  1282. pFile.WriteInteger('Description', 'VersionRelease', iVersionRelease);
  1283. pFile.WriteInteger('Description', 'VersionRevision', iVersionRevision);
  1284. pFile.WriteBool('Description', 'AutoIncRevNumber', AutoIncRevNumber);
  1285. // Write data for [Options] section
  1286. // None for now...
  1287. // Write data for [Debug] section
  1288. pFile.WriteString('Debug', 'Initializer', sInitializer);
  1289. pFile.WriteString('Debug', 'RemoteIP', sRemoteIP);
  1290. pFile.WriteString('Debug', 'RemoteDirectory', sRemoteDirectory);
  1291. pFile.WriteInteger('Debug', 'RemotePort', iRemotePort);
  1292. pFile.WriteInteger('Debug', 'ConnectTimeOut', iConnectTimeOut);
  1293. pFile.WriteString('Debug', 'RuntimeDirectory', sRuntimeDirectory);
  1294. pFile.WriteString('Debug', 'TargetLuaUnit', sTargetLuaUnit);
  1295. pFile.WriteString('Debug', 'CompileDirectory', sCompileDirectory);
  1296. pFile.WriteString('Debug', 'CompileExtension', sCompileExtension);
  1297. // Wrtie data for [Files] section
  1298. for x := 0 to lstUnits.Count - 1 do
  1299. begin
  1300. // Write the file with a relative path
  1301. pFile.WriteString('Files', 'File'+IntToStr(x), ExtractRelativePath(ExtractFilePath(Self.Path), TLuaEditUnit(lstUnits.Items[x]).Path));
  1302. end;
  1303. if Self.Path <> Path then
  1304. Self.Path := Path;
  1305. // Initialize stuff...
  1306. IsNew := False;
  1307. HasChanged := False;
  1308. frmProjectTree.BuildProjectTree;
  1309. pFile.UpdateFile;
  1310. pFile.Free;
  1311. frmLuaEditMain.jvUnitBarChange(frmLuaEditMain.jvUnitBar);
  1312. frmLuaEditMain.BuildReopenMenu;
  1313. // Now we wrote on the disk we may retrieve the time it has been writen
  1314. LastTimeModified := GetFileLastTimeModified(PChar(Path));
  1315. frmLuaEditMain.jvchnNotifier.Active := True;
  1316. end;
  1317. function TLuaEditProject.Save(Path: String; bNoDialog: Boolean = False; bForceDialog: Boolean = False): Boolean;
  1318. var
  1319. pFile: TIniFile;
  1320. x, iAnswer: integer;
  1321. pMsgBox: TfrmReadOnlyMsgBox;
  1322. begin
  1323. inherited Save(Path);
  1324. frmLuaEditMain.jvchnNotifier.Active := False;
  1325. Result := True;
  1326. // Popup an open dialog according to parameters and the state of the file
  1327. if ((IsNew and not bNoDialog) or (bForceDialog)) then
  1328. begin
  1329. frmLuaEditMain.sdlgSaveAsPrj.FileName := Self.Name + '.lpr';
  1330. if frmLuaEditMain.sdlgSaveAsPrj.Execute then
  1331. begin
  1332. Path := frmLuaEditMain.sdlgSaveAsPrj.FileName;
  1333. if IsNew then
  1334. frmLuaEditMain.MonitorFileToRecent(Path);
  1335. end
  1336. else
  1337. begin
  1338. // Return false because action was cancel and quit function
  1339. Result := False;
  1340. Exit;
  1341. end;
  1342. end;
  1343. // Check if file is read only first
  1344. while (GetFileReadOnlyAttr(PChar(Path)) and (FileExistsAbs(Path))) do
  1345. begin
  1346. pMsgBox := TfrmReadOnlyMsgBox.Create(nil);
  1347. iAnswer := pMsgBox.MessageBox('The project '+Path+' is read-only. Save anyway? ', 'LuaEdit');
  1348. pMsgBox.Free;
  1349. if iAnswer = mrOk then
  1350. begin
  1351. ToggleFileReadOnlyAttr(PChar(Path));
  1352. // Now that we wrote on the disk we may retrieve the time it has been writen
  1353. LastTimeModified := GetFileLastTimeModified(PChar(Path));
  1354. IsReadOnly := False;
  1355. end
  1356. else if iAnswer = mrYes then
  1357. begin
  1358. // Popup an open dialog according to parameters and the state of the file
  1359. frmLuaEditMain.sdlgSaveAsPrj.FileName := Self.Name + '.lpr';
  1360. if frmLuaEditMain.sdlgSaveAsPrj.Execute then
  1361. begin
  1362. Path := frmLuaEditMain.sdlgSaveAsPrj.FileName;
  1363. end
  1364. else
  1365. begin
  1366. // Return false because action was cancel and quit function
  1367. Result := False;
  1368. Exit;
  1369. end;
  1370. end
  1371. else
  1372. begin
  1373. Result := False;
  1374. Exit;
  1375. end;
  1376. end;
  1377. // Erase existing file if any to ensure a new clean project
  1378. // NOTE: IniFiles append datas when they already exists
  1379. if FileExistsAbs(Path) then
  1380. DeleteFile(PChar(Path));
  1381. if Self.Path <> Path then
  1382. Self.Path := Path;
  1383. pFile := TIniFile.Create(Path); // Create project file writer engine (using *.ini files way)
  1384. // Increasing Revision Number if feature is selected
  1385. if AutoIncRevNumber then
  1386. Inc(iVersionRevision);
  1387. // Write data for [Description] section
  1388. pFile.WriteString('Description', 'Name', Self.Name);
  1389. pFile.WriteInteger('Description', 'VersionMajor', iVersionMajor);
  1390. pFile.WriteInteger('Description', 'VersionMinor', iVersionMinor);
  1391. pFile.WriteInteger('Description', 'VersionRelease', iVersionRelease);
  1392. pFile.WriteInteger('Description', 'VersionRevision', iVersionRevision);
  1393. pFile.WriteBool('Description', 'AutoIncRevNumber', AutoIncRevNumber);
  1394. // Write data for [Options] section
  1395. // None for now...
  1396. // Write data for [Debug] section
  1397. pFile.WriteString('Debug', 'Initializer', sInitializer);
  1398. pFile.WriteString('Debug', 'RemoteIP', sRemoteIP);
  1399. pFile.WriteString('Debug', 'RemoteDirectory', sRemoteDirectory);
  1400. pFile.WriteInteger('Debug', 'RemotePort', iRemotePort);
  1401. pFile.WriteInteger('Debug', 'ConnectTimeOut', iConnectTimeOut);
  1402. pFile.WriteString('Debug', 'RuntimeDirectory', sRuntimeDirectory);
  1403. pFile.WriteString('Debug', 'TargetLuaUnit', sTargetLuaUnit);
  1404. pFile.WriteString('Debug', 'CompileDirectory', sCompileDirectory);
  1405. pFile.WriteString('Debug', 'CompileExtension', sCompileExtension);
  1406. // Wrtie data for [Files] section
  1407. for x := 0 to lstUnits.Count - 1 do
  1408. // Write the file with a relative path
  1409. pFile.WriteString('Files', 'File'+IntToStr(x), ExtractRelativePath(ExtractFilePath(Self.Path), TLuaEditUnit(lstUnits.Items[x]).Path));
  1410. // Initialize stuff...
  1411. IsNew := False;
  1412. HasChanged := False;
  1413. frmProjectTree.BuildProjectTree;
  1414. frmLuaEditMain.jvUnitBarChange(frmLuaEditMain.jvUnitBar);
  1415. frmLuaEditMain.BuildReopenMenu;
  1416. pFile.UpdateFile;
  1417. pFile.Free;
  1418. // Now we wrote on the disk we may retrieve the time it has been writen
  1419. LastTimeModified := GetFileLastTimeModified(PChar(Path));
  1420. frmLuaEditMain.jvchnNotifier.Active := True;
  1421. end;
  1422. procedure TLuaEditProject.RealoadProject();
  1423. var
  1424. x: Integer;
  1425. pLuaUnit: TLuaEditUnit;
  1426. begin
  1427. // remove files from project
  1428. for x := lstUnits.Count - 1 downto 0 do
  1429. begin
  1430. pLuaUnit := TLuaEditUnit(lstUnits.Items[x]);
  1431. // Prompt user to save file if modified or new
  1432. if pLuaUnit.HasChanged or pLuaUnit.IsNew then
  1433. begin
  1434. if Application.MessageBox(PChar('Save changes to file '+pLuaUnit.Path+'?'), 'LuaEdit', MB_YESNO+MB_ICONQUESTION) = IDYES then
  1435. begin
  1436. if SaveUnitsInc then
  1437. pLuaUnit.SaveInc(pLuaUnit.Path)
  1438. else
  1439. pLuaUnit.Save(pLuaUnit.Path);
  1440. end;
  1441. end;
  1442. // Remove file from tabs
  1443. if Assigned(pLuaUnit.AssociatedTab) then
  1444. begin
  1445. frmLuaEditMain.jvUnitBar.Tabs.Delete(pLuaUnit.AssociatedTab.Index);
  1446. LuaOpenedFiles.Remove(pLuaUnit);
  1447. end;
  1448. pLuaUnit.PrjOwner.lstUnits.Remove(pLuaUnit);
  1449. end;
  1450. // Remove projects from current project list
  1451. LuaProjects.Remove(Self);
  1452. // Reload the project...
  1453. GetProjectFromDisk(Self.Path);
  1454. end;
  1455. ///////////////////////////////////////////////////////////////////
  1456. // TLuaEditUnit class
  1457. ///////////////////////////////////////////////////////////////////
  1458. constructor TLuaEditUnit.Create(Path: String; otType: TLuaEditFileType);
  1459. begin
  1460. inherited Create(Path, otType);
  1461. lstFunctions := TStringList.Create;
  1462. end;
  1463. destructor TLuaEditUnit.Destroy;
  1464. begin
  1465. inherited Destroy;
  1466. lstFunctions.Free;
  1467. end;
  1468. ///////////////////////////////////////////////////////////////////
  1469. // TLuaEditMacro class
  1470. ///////////////////////////////////////////////////////////////////
  1471. constructor TLuaEditMacro.Create(Path: String; otType: TLuaEditFileType);
  1472. begin
  1473. inherited Create(Path, otType);
  1474. lstFunctions := TStringList.Create;
  1475. end;
  1476. destructor TLuaEditMacro.Destroy;
  1477. begin
  1478. inherited Destroy;
  1479. lstFunctions.Free;
  1480. end;
  1481. end.