_frmMain.pas 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  1. unit _frmMain;
  2. interface
  3. uses
  4. Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  5. Vcl.Controls, Vcl.Forms, Vcl.Dialogs, dxSkinsCore, dxSkinOffice2019Colorful,
  6. Vcl.StdCtrls, cxClasses, cxLookAndFeels, dxSkinsForm, Vcl.ExtCtrls,
  7. dxGDIPlusClasses, cxGraphics, cxControls, cxLookAndFeelPainters,
  8. dxSkinsdxStatusBarPainter, dxStatusBar, IdIOHandler, IdIOHandlerSocket,
  9. IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent, IdComponent,
  10. IdTCPConnection, IdTCPClient, IdHTTP, _JSONConfig, dxSkinsdxBarPainter, dxBar,
  11. cxContainer, cxEdit, cxTextEdit, cxMaskEdit, cxDropDownEdit, Vcl.Menus,
  12. cxButtons, dxSkinscxPCPainter,
  13. dxBarBuiltInMenu, cxPC, System.ImageList, Vcl.ImgList, cxCheckBox, cxImageList,
  14. SynEdit, SynHighlighterJSON, SynEditHighlighter, SynHighlighterIni,
  15. SynHighlighterXML, SynHighlighterHtml, SynEditRegexSearch, SynEditMiscClasses,
  16. SynEditSearch, _SearchTextHightlighterSynEditPlugin, SynEditTypes, cxSplitter;
  17. type
  18. TMethodType = (mtGET, mtPOST, mtPATCH, mtPUT, mtDELETE);
  19. type
  20. TfrmMain = class(TForm)
  21. OpenDialog: TOpenDialog;
  22. SaveDialog: TSaveDialog;
  23. Panel1: TPanel;
  24. dxSkinController: TdxSkinController;
  25. Label1: TLabel;
  26. Image: TImage;
  27. SSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
  28. dxStatusBarResponse: TdxStatusBar;
  29. dxBarManager: TdxBarManager;
  30. dxBarManagerBar1: TdxBar;
  31. dxBarSubItem3: TdxBarSubItem;
  32. dxBarButton3: TdxBarButton;
  33. btnSave: TdxBarButton;
  34. btnSaveAs: TdxBarButton;
  35. dxBarButton6: TdxBarButton;
  36. dxBarSubItem1: TdxBarSubItem;
  37. dxBarButton7: TdxBarButton;
  38. dxBarSubItem2: TdxBarSubItem;
  39. tbbtnRun: TdxBarButton;
  40. Label2: TLabel;
  41. edtFullURL: TcxTextEdit;
  42. btnRun: TcxButton;
  43. PageControlResponse: TcxPageControl;
  44. tabContent: TcxTabSheet;
  45. tabHeaders: TcxTabSheet;
  46. pnlHeader: TPanel;
  47. dxBarSubItem4: TdxBarSubItem;
  48. tbbtnStayOnTop: TdxBarButton;
  49. edtBaseURL: TcxTextEdit;
  50. Label3: TLabel;
  51. btnAdd: TcxButton;
  52. cxImageList: TcxImageList;
  53. btnDelete: TcxButton;
  54. comboPresets: TcxComboBox;
  55. Label4: TLabel;
  56. btnEdit: TcxButton;
  57. btnCopyPreset: TcxButton;
  58. Label5: TLabel;
  59. Label6: TLabel;
  60. comboMethod: TcxComboBox;
  61. PageControlParams: TcxPageControl;
  62. tabURLParams: TcxTabSheet;
  63. cxTabSheet2: TcxTabSheet;
  64. Panel3: TPanel;
  65. Panel4: TPanel;
  66. Label7: TLabel;
  67. tabPostData: TcxTabSheet;
  68. tbbtnAutoOpenLastUsed: TdxBarButton;
  69. Label8: TLabel;
  70. Panel5: TPanel;
  71. comboPostContentType: TcxComboBox;
  72. cxTabSheet3: TcxTabSheet;
  73. chkUseBasicAuth: TcxCheckBox;
  74. Label9: TLabel;
  75. edtAuthUsername: TcxTextEdit;
  76. edtAuthPassword: TcxTextEdit;
  77. Label10: TLabel;
  78. dxBarButton2: TdxBarButton;
  79. tbbtnAutoSaveProject: TdxBarButton;
  80. PopupEditor: TdxBarPopupMenu;
  81. pmnuCutJsonContent: TdxBarButton;
  82. pmnuCopyJsonContent: TdxBarButton;
  83. pmnuPasteJsonContent: TdxBarButton;
  84. pmnuFormatJsonContent: TdxBarButton;
  85. pmnuUndoJsonContent: TdxBarButton;
  86. pmnuRedoJsonContent: TdxBarButton;
  87. pmnuSelectAll: TdxBarButton;
  88. pmnuCompactJson: TdxBarButton;
  89. btnCopyFullURL: TcxButton;
  90. dxBarDockControl1: TdxBarDockControl;
  91. SynIniSyn: TSynIniSyn;
  92. SynJSONSyn: TSynJSONSyn;
  93. EditorContent: TSynEdit;
  94. EditorResponseHeaders: TSynEdit;
  95. EditorURLParams: TSynEdit;
  96. EditorExtraHeaders: TSynEdit;
  97. EditorPostData: TSynEdit;
  98. SynXMLSyn: TSynXMLSyn;
  99. pmnuFormatXML: TdxBarButton;
  100. pmnuCompactXML: TdxBarButton;
  101. pmnuBiggerEditor: TdxBarButton;
  102. btnPasteFullURL: TcxButton;
  103. SynHTMLSyn: TSynHTMLSyn;
  104. SynEditSearch: TSynEditSearch;
  105. SynEditRegexSearch: TSynEditRegexSearch;
  106. cxSplitter1: TcxSplitter;
  107. dxStatusBarApp: TdxStatusBar;
  108. Panel2: TPanel;
  109. chkResponseAutoformat: TcxCheckBox;
  110. procedure FormShow(Sender: TObject);
  111. procedure FormCreate(Sender: TObject);
  112. procedure FormDestroy(Sender: TObject);
  113. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  114. procedure dxBarButton6Click(Sender: TObject);
  115. procedure dxBarButton3Click(Sender: TObject);
  116. procedure btnSaveAsClick(Sender: TObject);
  117. procedure dxBarButton7Click(Sender: TObject);
  118. procedure tbbtnRunClick(Sender: TObject);
  119. procedure dxBarSubItem3Popup(Sender: TObject);
  120. procedure btnRunClick(Sender: TObject);
  121. procedure FormResize(Sender: TObject);
  122. procedure tbbtnStayOnTopClick(Sender: TObject);
  123. procedure pmnuCutJsonContentClick(Sender: TObject);
  124. procedure pmnuPasteJsonContentClick(Sender: TObject);
  125. procedure pmnuCopyJsonContentClick(Sender: TObject);
  126. procedure btnAddClick(Sender: TObject);
  127. procedure btnDeleteClick(Sender: TObject);
  128. procedure comboPresetsPropertiesChange(Sender: TObject);
  129. procedure btnSaveClick(Sender: TObject);
  130. procedure btnEditClick(Sender: TObject);
  131. procedure btnCopyPresetClick(Sender: TObject);
  132. procedure edtBaseURLPropertiesChange(Sender: TObject);
  133. procedure EditorURLParamsChange(Sender: TObject);
  134. procedure comboMethodPropertiesChange(Sender: TObject);
  135. procedure tbbtnAutoOpenLastUsedClick(Sender: TObject);
  136. procedure dxBarButton2Click(Sender: TObject);
  137. procedure tbbtnAutoSaveProjectClick(Sender: TObject);
  138. procedure pmnuFormatJsonContentClick(Sender: TObject);
  139. procedure EditorContentMouseUp(Sender: TObject; Button: TMouseButton;
  140. Shift: TShiftState; X, Y: Integer);
  141. procedure EditorPostDataMouseUp(Sender: TObject; Button: TMouseButton;
  142. Shift: TShiftState; X, Y: Integer);
  143. procedure PopupEditorPopup(Sender: TObject);
  144. procedure pmnuUndoJsonContentClick(Sender: TObject);
  145. procedure pmnuRedoJsonContentClick(Sender: TObject);
  146. procedure pmnuSelectAllClick(Sender: TObject);
  147. procedure pmnuCompactJsonClick(Sender: TObject);
  148. procedure EditorResponseHeadersMouseUp(Sender: TObject; Button: TMouseButton;
  149. Shift: TShiftState; X, Y: Integer);
  150. procedure EditorExtraHeadersMouseUp(Sender: TObject; Button: TMouseButton;
  151. Shift: TShiftState; X, Y: Integer);
  152. procedure btnCopyFullURLClick(Sender: TObject);
  153. procedure EditorURLParamsMouseUp(Sender: TObject; Button: TMouseButton;
  154. Shift: TShiftState; X, Y: Integer);
  155. procedure pmnuFormatXMLClick(Sender: TObject);
  156. procedure pmnuCompactXMLClick(Sender: TObject);
  157. procedure comboPostContentTypePropertiesChange(Sender: TObject);
  158. procedure pmnuBiggerEditorClick(Sender: TObject);
  159. procedure EditorContentKeyUp(Sender: TObject; var Key: Word;
  160. Shift: TShiftState);
  161. procedure edtFullURLPropertiesChange(Sender: TObject);
  162. procedure btnPasteFullURLClick(Sender: TObject);
  163. procedure EditorResponseHeadersKeyUp(Sender: TObject; var Key: Word;
  164. Shift: TShiftState);
  165. procedure EditorURLParamsKeyUp(Sender: TObject; var Key: Word;
  166. Shift: TShiftState);
  167. procedure EditorExtraHeadersKeyUp(Sender: TObject; var Key: Word;
  168. Shift: TShiftState);
  169. procedure EditorPostDataKeyUp(Sender: TObject; var Key: Word;
  170. Shift: TShiftState);
  171. procedure EditorEnter(Sender: TObject);
  172. procedure EditorExit(Sender: TObject);
  173. private
  174. FProjectConfig: TJSONConfig;
  175. FActiveProject: string;
  176. FActivePreset: string;
  177. FIsTempProjectLoaded: Boolean;
  178. FTempProjectFile: string;
  179. FRoamingSavePath: string;
  180. FSearchFromCaret: Boolean;
  181. FPresetsList: TStringList;
  182. FHTTP: TIdHTTP;
  183. function GetTempProjectFile: string;
  184. function GetAppVersion: string;
  185. procedure UpdateFullURL;
  186. procedure LoadProject;
  187. procedure SaveProject;
  188. procedure SaveProjectAs(const LoadAfterSave: Boolean);
  189. procedure Run;
  190. procedure AddPreset(const APresetName: string);
  191. procedure DeletePreset(const AID: Integer);
  192. procedure LoadPreset;
  193. procedure SavePreset;
  194. procedure ShowError(const AErrorText: string);
  195. procedure DoGETRequest(const AMethodType: TMethodType);
  196. procedure DoPOSTRequest(const AMethodType: TMethodType);
  197. procedure UpdateEditor(const AText: string);
  198. procedure UpdatePresetsCombobox;
  199. procedure CheckForUpdate;
  200. function GenerateGuid: string;
  201. function Encode(const AText: string): string;
  202. function Decode(const AText: string): string;
  203. public
  204. MainConfig: TJSONConfig;
  205. ActiveEditor: TSynEdit;
  206. gbSearchBackwards: Boolean;
  207. gbSearchCaseSensitive: Boolean;
  208. gbSearchFromCaret: Boolean;
  209. gbSearchSelectionOnly: Boolean;
  210. gbSearchTextAtCaret: Boolean;
  211. gbSearchWholeWords: Boolean;
  212. gbSearchRegex: Boolean;
  213. gsSearchText: string;
  214. gsSearchTextHistory: string;
  215. gsReplaceText: string;
  216. gsReplaceTextHistory: string;
  217. procedure DoSearchReplaceText(AReplace: Boolean; ABackwards: Boolean);
  218. procedure ShowSearchReplaceDialog(AReplace: Boolean);
  219. end;
  220. const
  221. iCurrentConfigVersion: Integer = 2;
  222. var
  223. frmMain: TfrmMain;
  224. implementation
  225. {$R *.dfm}
  226. uses System.NetEncoding, System.UITypes, _EncryptStr, JsonDataObjects, IdGlobal, System.IOUtils, uRwXmlDOM,
  227. _frmBiggerEditor, IdUri, _frmSearch, ShellApi;
  228. procedure TfrmMain.tbbtnRunClick(Sender: TObject);
  229. begin
  230. Run;
  231. end;
  232. procedure TfrmMain.tbbtnStayOnTopClick(Sender: TObject);
  233. begin
  234. if tbbtnStayOnTop.Down then
  235. begin
  236. FormStyle := fsStayOnTop;
  237. end
  238. else
  239. begin
  240. FormStyle := fsNormal;
  241. end;
  242. end;
  243. procedure TfrmMain.UpdateEditor(const AText: string);
  244. begin
  245. ActiveEditor.Lines.Text := AText;
  246. end;
  247. procedure TfrmMain.UpdateFullURL;
  248. var
  249. i: Integer;
  250. dmy: string;
  251. strlist: TStringList;
  252. begin
  253. edtFullURL.Text := edtBaseURL.Text;
  254. if EditorURLParams.Lines.Count > 0 then
  255. begin
  256. dmy := '?';
  257. for i := 0 to EditorURLParams.Lines.Count - 1 do
  258. begin
  259. if dmy <> '?' then dmy := dmy + '&';
  260. strlist := TStringList.Create;
  261. try
  262. strlist.Text := StringReplace(EditorURLParams.Lines[i], '=', #13#10, [rfReplaceAll]);
  263. if strlist.Count = 2 then
  264. begin
  265. dmy := dmy + TNetEncoding.URL.Encode(strlist[0]) + '=' + TNetEncoding.URL.Encode(strlist[1]);
  266. end;
  267. finally
  268. strlist.Free;
  269. end;
  270. end;
  271. edtFullURL.Text := edtFullURL.Text + dmy;
  272. end;
  273. end;
  274. procedure TfrmMain.UpdatePresetsCombobox;
  275. var
  276. i: Integer;
  277. begin
  278. comboPresets.Properties.Items.Clear;
  279. for i := 0 to FPresetsList.Count - 1 do
  280. begin
  281. comboPresets.Properties.Items.Add(Decode(FPresetsList.ValueFromIndex[i]));
  282. end;
  283. end;
  284. procedure TfrmMain.tbbtnAutoOpenLastUsedClick(Sender: TObject);
  285. begin
  286. MainConfig.WriteBool('Project', 'AutoOpenLastUsed', tbbtnAutoOpenLastUsed.Down);
  287. end;
  288. procedure TfrmMain.tbbtnAutoSaveProjectClick(Sender: TObject);
  289. begin
  290. MainConfig.WriteBool('Project', 'AutoSaveProject', tbbtnAutoSaveProject.Down);
  291. end;
  292. procedure TfrmMain.dxBarButton2Click(Sender: TObject);
  293. begin
  294. FActiveProject := GetTempProjectFile;
  295. FIsTempProjectLoaded := True;
  296. LoadProject;
  297. end;
  298. procedure TfrmMain.dxBarButton3Click(Sender: TObject);
  299. begin
  300. OpenDialog.InitialDir := MainConfig.ReadString('Dialogs', 'LastOpenDir', ExtractFilePath(ParamStr(0)));
  301. if OpenDialog.Execute then
  302. begin
  303. MainConfig.WriteString('Dialogs', 'LastOpenDir', ExtractFilePath(OpenDialog.FileName));
  304. FActiveProject := OpenDialog.FileName;
  305. FIsTempProjectLoaded := False;
  306. LoadProject;
  307. end;
  308. end;
  309. procedure TfrmMain.AddPreset(const APresetName: string);
  310. begin
  311. FPresetsList.AddPair(GenerateGuid, Encode(APresetName));
  312. UpdatePresetsCombobox;
  313. comboPresets.ItemIndex := comboPresets.Properties.Items.Count - 1;
  314. FProjectConfig.WriteString('Presets', 'Presets', FPresetsList.Text);
  315. end;
  316. procedure TfrmMain.btnAddClick(Sender: TObject);
  317. var
  318. dmy: string;
  319. begin
  320. if InputQuery('Add Preset', 'Enter a preset name:', dmy) then
  321. begin
  322. AddPreset(dmy);
  323. end;
  324. end;
  325. procedure TfrmMain.btnDeleteClick(Sender: TObject);
  326. begin
  327. if comboPresets.Properties.Items.Count = 1 then
  328. begin
  329. MessageDlg('Thet last preset can''t be deleted. Please create a new preset if you want to delete this.', mtError, [mbOK], 0);
  330. end
  331. else
  332. begin
  333. if MessageDlg('Really delete preset "' + comboPresets.Text + '"?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  334. begin
  335. DeletePreset(comboPresets.ItemIndex);
  336. FProjectConfig.WriteString('Presets', 'Presets', FPresetsList.Text);
  337. end;
  338. end;
  339. end;
  340. procedure TfrmMain.btnEditClick(Sender: TObject);
  341. var
  342. dmy: string;
  343. idx: Integer;
  344. begin
  345. SavePreset;
  346. dmy := comboPresets.Text;
  347. idx := comboPresets.ItemIndex;
  348. if InputQuery('Edit Preset', 'Rename preset:', dmy) then
  349. begin
  350. comboPresets.Properties.Items[comboPresets.ItemIndex] := dmy;
  351. FPresetsList.ValueFromIndex[idx] := Encode(dmy);
  352. comboPresets.ItemIndex := idx;
  353. FProjectConfig.WriteString('Presets', 'Presets', FPresetsList.Text);
  354. end;
  355. end;
  356. procedure TfrmMain.btnPasteFullURLClick(Sender: TObject);
  357. begin
  358. edtFullURL.Clear;
  359. edtFullURL.SetFocus;
  360. edtFullURL.PasteFromClipboard;
  361. end;
  362. procedure TfrmMain.btnCopyFullURLClick(Sender: TObject);
  363. begin
  364. edtFullURL.SelectAll;
  365. edtFullURL.CopyToClipboard;
  366. end;
  367. procedure TfrmMain.btnCopyPresetClick(Sender: TObject);
  368. var
  369. idx: Integer;
  370. begin
  371. SavePreset;
  372. idx := comboPresets.ItemIndex;
  373. AddPreset('Copy of ' + comboPresets.Text);
  374. FProjectConfig.CopySection('Preset_' + FPresetsList.Names[idx], 'Preset_' + FPresetsList.Names[comboPresets.ItemIndex]);
  375. LoadPreset;
  376. end;
  377. procedure TfrmMain.btnRunClick(Sender: TObject);
  378. begin
  379. Run;
  380. end;
  381. procedure TfrmMain.btnSaveAsClick(Sender: TObject);
  382. begin
  383. SaveProjectAs(True);
  384. end;
  385. procedure TfrmMain.btnSaveClick(Sender: TObject);
  386. begin
  387. SaveProject;
  388. end;
  389. procedure TfrmMain.CheckForUpdate;
  390. begin
  391. TThread.CreateAnonymousThread(
  392. procedure
  393. var
  394. HTTP: TIdHTTP;
  395. bNewVersion: Boolean;
  396. strlist: TStringList;
  397. fs: TFileStream;
  398. UpdateFile: TStringList;
  399. begin
  400. bNewVersion := False;
  401. HTTP := TIdHTTP.Create(nil);
  402. strlist := TStringList.Create;
  403. try
  404. try
  405. strlist.Text := HTTP.Get('https://www.simnet.cx/WebUpdate/RESTDebugger/Update.txt');
  406. except
  407. bNewVersion := False;
  408. raise;
  409. end;
  410. if strlist.Count = 2 then
  411. begin
  412. if strlist[0] = GetAppVersion then
  413. begin
  414. bNewVersion := False;
  415. end
  416. else
  417. begin
  418. DeleteFile(IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Update.exe');
  419. fs := TFileStream.Create(IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Update.exe', fmCreate);
  420. try
  421. try
  422. HTTP.Get(strlist[1], fs);
  423. except
  424. bNewVersion := False;
  425. raise;
  426. end;
  427. finally
  428. fs.Free;
  429. end;
  430. bNewVersion := True;
  431. end;
  432. end;
  433. finally
  434. strlist.Free;
  435. HTTP.Free;
  436. TThread.Synchronize(TThread.CurrentThread,
  437. procedure
  438. begin
  439. if bNewVersion then
  440. begin
  441. //Create Update file and start it
  442. UpdateFile := TStringList.Create;
  443. try
  444. UpdateFile.Add('timeout 1');
  445. UpdateFile.Add('taskkill /F /IM RESTDebugger.exe');
  446. UpdateFile.Add('"%~dp0Update.exe" -o"' + ExtractFilePath(ParamStr(0)) + '" -y');
  447. UpdateFile.Add('start "" "' + ParamStr(0) + '"');
  448. UpdateFile.Add('del "%~dp0Update.exe"');
  449. UpdateFile.Add('del "%~dp0Update.cmd"');
  450. UpdateFile.SaveToFile(IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Update.cmd');
  451. finally
  452. UpdateFile.Free;
  453. end;
  454. if MessageDlg('Es ist eine neue Software Version verfügbar. Möchten Sie diese nun installieren?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  455. begin
  456. ShellExecute(handle, 'open', PChar(IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Update.cmd'), nil, nil, SW_HIDE);
  457. Close;
  458. end
  459. else
  460. begin
  461. //CleanUp temp files
  462. DeleteFile(IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Update.cmd');
  463. DeleteFile(IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Update.exe');
  464. end;
  465. end;
  466. end);
  467. end;
  468. end).Start;
  469. end;
  470. procedure TfrmMain.comboMethodPropertiesChange(Sender: TObject);
  471. begin
  472. tabPostData.TabVisible := (comboMethod.ItemIndex = 1) or (comboMethod.ItemIndex = 2) or (comboMethod.ItemIndex = 3);
  473. case comboMethod.ItemIndex of
  474. 1: tabPostData.Caption := 'Post Data';
  475. 2: tabPostData.Caption := 'Patch Data';
  476. 3: tabPostData.Caption := 'Put Data';
  477. end;
  478. if (comboMethod.ItemIndex = 0) and (PageControlParams.ActivePage = nil) then
  479. begin
  480. PageControlParams.ActivePage := tabURLParams;
  481. end;
  482. end;
  483. procedure TfrmMain.comboPostContentTypePropertiesChange(Sender: TObject);
  484. begin
  485. if Pos('application/json', comboPostContentType.Text) > 0 then
  486. begin
  487. EditorPostData.Highlighter := SynJSONSyn;
  488. end
  489. else
  490. if Pos('text/xml', comboPostContentType.Text) > 0 then
  491. begin
  492. EditorPostData.Highlighter := SynXMLSyn;
  493. end
  494. else
  495. if Pos('text/html', comboPostContentType.Text) > 0 then
  496. begin
  497. EditorPostData.Highlighter := SynHTMLSyn;
  498. end
  499. else
  500. begin
  501. EditorPostData.Highlighter := nil;
  502. end;
  503. end;
  504. procedure TfrmMain.comboPresetsPropertiesChange(Sender: TObject);
  505. begin
  506. if FActivePreset <> '' then
  507. begin
  508. SavePreset;
  509. end;
  510. FActivePreset := comboPresets.Text;
  511. LoadPreset;
  512. end;
  513. procedure TfrmMain.pmnuBiggerEditorClick(Sender: TObject);
  514. begin
  515. frmBiggerEditor.ShowModal;
  516. UpdateFullURL;
  517. end;
  518. procedure TfrmMain.pmnuCompactJsonClick(Sender: TObject);
  519. var
  520. ja: TJsonArray;
  521. jo: TJsonObject;
  522. begin
  523. if ActiveEditor.Lines.Count > 0 then
  524. begin
  525. if Length(ActiveEditor.Lines[0]) > 0 then
  526. begin
  527. if ActiveEditor.Lines[0][1] = '{' then
  528. begin
  529. jo := TJsonObject.Create;
  530. Screen.Cursor := crHourGlass;
  531. try
  532. try
  533. jo.FromJSON(ActiveEditor.Lines.Text);
  534. except
  535. on E: Exception do
  536. begin
  537. ShowError(E.Message);
  538. end;
  539. end;
  540. UpdateEditor(jo.ToJSON(True));
  541. finally
  542. Screen.Cursor := crDefault;
  543. jo.Free;
  544. end;
  545. end
  546. else
  547. if ActiveEditor.Lines[0][1] = '[' then
  548. begin
  549. ja := TJsonArray.Create;
  550. Screen.Cursor := crHourGlass;
  551. try
  552. try
  553. ja.FromJSON(ActiveEditor.Lines.Text);
  554. except
  555. on E: Exception do
  556. begin
  557. ShowError(E.Message);
  558. end;
  559. end;
  560. UpdateEditor(ja.ToJSON(True));
  561. finally
  562. Screen.Cursor := crDefault;
  563. ja.Free;
  564. end;
  565. end;
  566. end;
  567. end;
  568. end;
  569. procedure TfrmMain.pmnuCompactXMLClick(Sender: TObject);
  570. var
  571. xml: TRwDomDocument;
  572. begin
  573. xml := TRwDOMDocument.Create;
  574. Screen.Cursor := crHourGlass;
  575. try
  576. xml.LoadXML(ActiveEditor.Lines.Text);
  577. UpdateEditor(xml.XML);
  578. finally
  579. xml.Free;
  580. Screen.Cursor := crDefault;
  581. end;
  582. end;
  583. procedure TfrmMain.pmnuCopyJsonContentClick(Sender: TObject);
  584. begin
  585. ActiveEditor.CopyToClipboard;
  586. end;
  587. procedure TfrmMain.pmnuCutJsonContentClick(Sender: TObject);
  588. begin
  589. ActiveEditor.CutToClipboard;
  590. end;
  591. procedure TfrmMain.DeletePreset(const AID: Integer);
  592. begin
  593. comboPresets.Properties.OnChange := nil;
  594. comboPresets.Properties.Items.Delete(AID);
  595. FProjectConfig.DeleteSection('Preset_' + FPresetsList.Names[AID]);
  596. FPresetsList.Delete(AID);
  597. comboPresets.ItemIndex := comboPresets.Properties.Items.Count - 1;
  598. FActivePreset := comboPresets.Text;
  599. LoadPreset;
  600. comboPresets.Properties.OnChange := comboPresetsPropertiesChange;
  601. end;
  602. function TfrmMain.Decode(const AText: string): string;
  603. begin
  604. Result := TNetEncoding.Base64.Decode(AText);
  605. end;
  606. procedure TfrmMain.DoGETRequest(const AMethodType: TMethodType);
  607. var
  608. dmy: string;
  609. begin
  610. try
  611. case AMethodType of
  612. mtGET: dmy := FHTTP.Get(edtFullURL.Text);
  613. mtDELETE: dmy := FHTTP.Delete(edtFullURL.Text);
  614. end;
  615. if FHTTP.ResponseCode.ToString[1] <> '2' then
  616. begin
  617. ShowError(FHTTP.ResponseText);
  618. end;
  619. except
  620. on E: EIdHTTPProtocolException do
  621. begin
  622. dmy := E.ErrorMessage;
  623. ShowError(E.Message);
  624. end;
  625. end;
  626. ActiveEditor := EditorContent;
  627. UpdateEditor(dmy);
  628. ActiveEditor := EditorResponseHeaders;
  629. UpdateEditor(FHTTP.Response.RawHeaders.Text);
  630. end;
  631. procedure TfrmMain.DoPOSTRequest(const AMethodType: TMethodType);
  632. var
  633. dmy: string;
  634. strstream: TStringStream;
  635. begin
  636. strstream := TStringStream.Create(EditorPostData.Lines.Text, TEncoding.UTF8);
  637. try
  638. FHTTP.Request.ContentType := comboPostContentType.Text;
  639. FHTTP.Request.CharSet := 'utf-8';
  640. try
  641. case AMethodType of
  642. mtPOST: dmy := FHTTP.Post(edtFullURL.Text, strstream);
  643. mtPATCH: dmy := FHTTP.Patch(edtFullURL.Text, strstream);
  644. mtPUT: dmy := FHTTP.Put(edtFullURL.Text, strstream);
  645. end;
  646. if FHTTP.ResponseCode.ToString[1] <> '2' then
  647. begin
  648. ShowError(FHTTP.ResponseText);
  649. end;
  650. except
  651. on E: EIdHTTPProtocolException do
  652. begin
  653. dmy := E.ErrorMessage;
  654. ShowError(E.Message);
  655. end;
  656. end;
  657. finally
  658. strstream.Free;
  659. end;
  660. ActiveEditor := EditorContent;
  661. UpdateEditor(dmy);
  662. ActiveEditor := EditorResponseHeaders;
  663. UpdateEditor(FHTTP.Response.RawHeaders.Text);
  664. end;
  665. procedure TfrmMain.DoSearchReplaceText(AReplace, ABackwards: Boolean);
  666. var
  667. Options: TSynSearchOptions;
  668. begin
  669. if AReplace then
  670. Options := [ssoPrompt, ssoReplace, ssoReplaceAll]
  671. else
  672. Options := [];
  673. if ABackwards then
  674. Include(Options, ssoBackwards);
  675. if gbSearchCaseSensitive then
  676. Include(Options, ssoMatchCase);
  677. if not FSearchFromCaret then
  678. Include(Options, ssoEntireScope);
  679. if gbSearchSelectionOnly then
  680. Include(Options, ssoSelectedOnly);
  681. if gbSearchWholeWords then
  682. Include(Options, ssoWholeWord);
  683. if gbSearchRegex then
  684. ActiveEditor.SearchEngine := SynEditRegexSearch
  685. else
  686. ActiveEditor.SearchEngine := SynEditSearch;
  687. if ActiveEditor.SearchReplace(gsSearchText, gsReplaceText, Options) = 0 then
  688. begin
  689. MessageDlg('Text not found.', mtInformation, [mbOK], 0);
  690. end;
  691. end;
  692. procedure TfrmMain.dxBarButton6Click(Sender: TObject);
  693. begin
  694. Close;
  695. end;
  696. procedure TfrmMain.dxBarButton7Click(Sender: TObject);
  697. begin
  698. MessageDlg('Simnet REST Debugger' + #13#10 + GetAppVersion, mtInformation, [mbOK], 0);
  699. end;
  700. procedure TfrmMain.dxBarSubItem3Popup(Sender: TObject);
  701. begin
  702. btnSave.Enabled := not FIsTempProjectLoaded;
  703. end;
  704. procedure TfrmMain.EditorEnter(Sender: TObject);
  705. begin
  706. (Sender as TSynEdit).ActiveLineColor := $00E6FFFA;
  707. end;
  708. procedure TfrmMain.EditorExit(Sender: TObject);
  709. begin
  710. (Sender as TSynEdit).ActiveLineColor := clNone;
  711. end;
  712. procedure TfrmMain.EditorContentKeyUp(Sender: TObject; var Key: Word;
  713. Shift: TShiftState);
  714. begin
  715. if Key = vkF11 then
  716. begin
  717. ActiveEditor := EditorContent;
  718. pmnuBiggerEditorClick(Sender);
  719. end;
  720. if Key = vkF3 then
  721. begin
  722. ActiveEditor := EditorContent;
  723. DoSearchReplaceText(false, gbSearchBackwards);
  724. end;
  725. if (Key = 70) and (Shift = [ssCtrl]) then
  726. begin
  727. ActiveEditor := EditorContent;
  728. ShowSearchReplaceDialog(false);
  729. end;
  730. end;
  731. procedure TfrmMain.EditorContentMouseUp(Sender: TObject; Button: TMouseButton;
  732. Shift: TShiftState; X, Y: Integer);
  733. begin
  734. if Button = mbRight then
  735. begin
  736. ActiveEditor := EditorContent;
  737. PopupEditor.PopupFromCursorPos;
  738. end;
  739. end;
  740. procedure TfrmMain.EditorExtraHeadersKeyUp(Sender: TObject; var Key: Word;
  741. Shift: TShiftState);
  742. begin
  743. if Key = vkF11 then
  744. begin
  745. ActiveEditor := EditorExtraHeaders;
  746. pmnuBiggerEditorClick(Sender);
  747. end;
  748. end;
  749. procedure TfrmMain.EditorExtraHeadersMouseUp(Sender: TObject;
  750. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  751. begin
  752. if Button = mbRight then
  753. begin
  754. ActiveEditor := EditorExtraHeaders;
  755. PopupEditor.PopupFromCursorPos;
  756. end;
  757. end;
  758. procedure TfrmMain.EditorResponseHeadersKeyUp(Sender: TObject; var Key: Word;
  759. Shift: TShiftState);
  760. begin
  761. if Key = vkF11 then
  762. begin
  763. ActiveEditor := EditorResponseHeaders;
  764. pmnuBiggerEditorClick(Sender);
  765. end;
  766. end;
  767. procedure TfrmMain.EditorResponseHeadersMouseUp(Sender: TObject; Button: TMouseButton;
  768. Shift: TShiftState; X, Y: Integer);
  769. begin
  770. if Button = mbRight then
  771. begin
  772. ActiveEditor := EditorResponseHeaders;
  773. PopupEditor.PopupFromCursorPos;
  774. end;
  775. end;
  776. procedure TfrmMain.EditorPostDataKeyUp(Sender: TObject; var Key: Word;
  777. Shift: TShiftState);
  778. begin
  779. if Key = vkF11 then
  780. begin
  781. ActiveEditor := EditorPostData;
  782. pmnuBiggerEditorClick(Sender);
  783. end;
  784. end;
  785. procedure TfrmMain.EditorPostDataMouseUp(Sender: TObject; Button: TMouseButton;
  786. Shift: TShiftState; X, Y: Integer);
  787. begin
  788. if Button = mbRight then
  789. begin
  790. ActiveEditor := EditorPostData;
  791. PopupEditor.PopupFromCursorPos;
  792. end;
  793. end;
  794. procedure TfrmMain.EditorURLParamsChange(Sender: TObject);
  795. begin
  796. UpdateFullURL;
  797. end;
  798. procedure TfrmMain.EditorURLParamsKeyUp(Sender: TObject; var Key: Word;
  799. Shift: TShiftState);
  800. begin
  801. if Key = vkF11 then
  802. begin
  803. ActiveEditor := EditorURLParams;
  804. pmnuBiggerEditorClick(Sender);
  805. end;
  806. end;
  807. procedure TfrmMain.EditorURLParamsMouseUp(Sender: TObject; Button: TMouseButton;
  808. Shift: TShiftState; X, Y: Integer);
  809. begin
  810. if Button = mbRight then
  811. begin
  812. ActiveEditor := EditorURLParams;
  813. PopupEditor.PopupFromCursorPos;
  814. end;
  815. end;
  816. procedure TfrmMain.edtBaseURLPropertiesChange(Sender: TObject);
  817. begin
  818. if edtBaseURL.Focused then
  819. begin
  820. UpdateFullURL;
  821. end;
  822. end;
  823. procedure TfrmMain.edtFullURLPropertiesChange(Sender: TObject);
  824. var
  825. uri: TIdURI;
  826. begin
  827. if edtFullURL.Focused then
  828. begin
  829. uri := TIdURI.Create(edtFullURL.Text);
  830. try
  831. EditorURLParams.Lines.Text := StringReplace(uri.Params, '&', #13#10, [rfReplaceAll]);
  832. edtBaseURL.Text := StringReplace(edtFullURL.Text, '?' + uri.Params, '', [rfReplaceAll]);
  833. finally
  834. uri.Free;
  835. end;
  836. end;
  837. end;
  838. function TfrmMain.Encode(const AText: string): string;
  839. begin
  840. Result := StringReplace(TNetEncoding.Base64.Encode(AText), #13#10, '', [rfReplaceAll]);
  841. end;
  842. procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
  843. begin
  844. MainConfig.WriteInteger('MainWindowPos', 'Left', Left);
  845. MainConfig.WriteInteger('MainWindowPos', 'Top', Top);
  846. MainConfig.WriteInteger('MainWindowPos', 'Width', Width);
  847. MainConfig.WriteInteger('MainWindowPos', 'Height', Height);
  848. MainConfig.WriteBool('MainWindowPos', 'StayOnTop', FormStyle = fsStayOnTop);
  849. MainConfig.WriteInteger('MainWindowPos', 'HeaderHeight', pnlHeader.Height);
  850. MainConfig.WriteBool('Search', 'gbSearchBackwards', gbSearchBackwards);
  851. MainConfig.WriteBool('Search', 'gbSearchCaseSensitive', gbSearchCaseSensitive);
  852. MainConfig.WriteBool('Search', 'gbSearchFromCaret', gbSearchFromCaret);
  853. MainConfig.WriteBool('Search', 'gbSearchSelectionOnly', gbSearchSelectionOnly);
  854. MainConfig.WriteBool('Search', 'gbSearchTextAtCaret', gbSearchTextAtCaret);
  855. MainConfig.WriteBool('Search', 'gbSearchWholeWords', gbSearchWholeWords);
  856. MainConfig.WriteBool('Search', 'gbSearchRegex', gbSearchRegex);
  857. MainConfig.WriteString('Search', 'gsSearchText', gsSearchText);
  858. MainConfig.WriteString('Search', 'gsSearchTextHistory', gsSearchTextHistory);
  859. MainConfig.WriteString('Search', 'gsReplaceText', gsReplaceText);
  860. MainConfig.WriteString('Search', 'gsReplaceTextHistory', gsReplaceTextHistory);
  861. SavePreset;
  862. if FProjectConfig.FileModified then
  863. begin
  864. if (tbbtnAutoSaveProject.Down) and (not FIsTempProjectLoaded) then
  865. begin
  866. SaveProject;
  867. end
  868. else
  869. begin
  870. if MessageDlg('The project file has changed. Do you want to save it?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  871. begin
  872. if FIsTempProjectLoaded then
  873. begin
  874. SaveProjectAs(False);
  875. end
  876. else
  877. begin
  878. SaveProject;
  879. end;
  880. end;
  881. end;
  882. end;
  883. if FileExists(FTempProjectFile) then
  884. begin
  885. DeleteFile(FTempProjectFile);
  886. end;
  887. end;
  888. procedure TfrmMain.FormCreate(Sender: TObject);
  889. begin
  890. FRoamingSavePath := IncludeTrailingPathDelimiter(TPath.GetHomePath) + 'Simnet\RESTDebugger\';
  891. ForceDirectories(FRoamingSavePath);
  892. MainConfig := TJSONConfig.Create(FRoamingSavePath + 'AppConfig.json');
  893. FActiveProject := '';
  894. FActivePreset := '';
  895. FPresetsList := TStringList.Create;
  896. FPresetsList.NameValueSeparator := ':';
  897. ActiveEditor := nil;
  898. if (not MainConfig.ReadBool('Main', 'FirstStartShown')) and (FileExists(IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'Example Config.rdproj')) then
  899. begin
  900. FActiveProject := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'Example Config.rdproj';
  901. FIsTempProjectLoaded := False;
  902. MainConfig.WriteBool('Main', 'FirstStartShown', True);
  903. MainConfig.WriteString('Project', 'LastUsed', FActiveProject);
  904. end
  905. else
  906. begin
  907. if (ParamStr(1) <> '') then
  908. begin
  909. FActiveProject := ParamStr(1);
  910. FIsTempProjectLoaded := False;
  911. end
  912. else
  913. begin
  914. if (MainConfig.ReadBool('Project', 'AutoOpenLastUsed', True)) and (FileExists(MainConfig.ReadString('Project', 'LastUsed'))) then
  915. begin
  916. FActiveProject := MainConfig.ReadString('Project', 'LastUsed');
  917. FIsTempProjectLoaded := False;
  918. end
  919. else
  920. begin
  921. FActiveProject := GetTempProjectFile;
  922. FIsTempProjectLoaded := True;
  923. end;
  924. end;
  925. end;
  926. with TSearchTextHightlighterSynEditPlugin.Create(EditorContent) do
  927. begin
  928. Attribute.Background := $0078AAFF;
  929. end;
  930. LoadProject;
  931. end;
  932. procedure TfrmMain.FormDestroy(Sender: TObject);
  933. begin
  934. FPresetsList.Free;
  935. FProjectConfig.Free;
  936. MainConfig.Free;
  937. end;
  938. procedure TfrmMain.FormResize(Sender: TObject);
  939. begin
  940. Image.Left := Width - 45;
  941. end;
  942. procedure TfrmMain.FormShow(Sender: TObject);
  943. begin
  944. dxStatusBarApp.Panels[0].Text := 'Copyright © by Simnet ' + FormatDateTime('yyyy', now);
  945. Left := MainConfig.ReadInteger('MainWindowPos', 'Left', Round((Screen.Width - Width) div 2));
  946. if Left >= Screen.Width then
  947. begin
  948. Left := 10;
  949. end;
  950. Top := MainConfig.ReadInteger('MainWindowPos', 'Top', Round((Screen.Height - Height) div 2));
  951. if Top >= Screen.Height then
  952. begin
  953. Top := 10;
  954. end;
  955. Width := MainConfig.ReadInteger('MainWindowPos', 'Width', 720);
  956. Height := MainConfig.ReadInteger('MainWindowPos', 'Height', 930);
  957. if MainConfig.ReadBool('MainWindowPos', 'StayOnTop') then
  958. begin
  959. FormStyle := fsStayOnTop;
  960. tbbtnStayOnTop.Down := True;
  961. end
  962. else
  963. begin
  964. FormStyle := fsNormal;
  965. tbbtnStayOnTop.Down := False;
  966. end;
  967. pnlHeader.Height := MainConfig.ReadInteger('MainWindowPos', 'HeaderHeight', 370);
  968. tbbtnAutoOpenLastUsed.Down := MainConfig.ReadBool('Project', 'AutoOpenLastUsed', True);
  969. tbbtnAutoSaveProject.Down := MainConfig.ReadBool('Project', 'AutoSaveProject', True);
  970. EditorContent.Lines.Clear;
  971. EditorResponseHeaders.Lines.Clear;
  972. dxStatusBarResponse.Panels[0].Text := '';
  973. dxStatusBarResponse.Panels[1].Text := '';
  974. dxStatusBarResponse.Panels[2].Text := '';
  975. gbSearchBackwards := MainConfig.ReadBool('Search', 'gbSearchBackwards', gbSearchBackwards);
  976. gbSearchCaseSensitive := MainConfig.ReadBool('Search', 'gbSearchCaseSensitive', gbSearchCaseSensitive);
  977. gbSearchFromCaret :=MainConfig.ReadBool('Search', 'gbSearchFromCaret', gbSearchFromCaret);
  978. gbSearchSelectionOnly := MainConfig.ReadBool('Search', 'gbSearchSelectionOnly', gbSearchSelectionOnly);
  979. gbSearchTextAtCaret := MainConfig.ReadBool('Search', 'gbSearchTextAtCaret', gbSearchTextAtCaret);
  980. gbSearchWholeWords := MainConfig.ReadBool('Search', 'gbSearchWholeWords', gbSearchWholeWords);
  981. gbSearchRegex := MainConfig.ReadBool('Search', 'gbSearchRegex', gbSearchRegex);
  982. gsSearchText := MainConfig.ReadString('Search', 'gsSearchText', gsSearchText);
  983. gsSearchTextHistory := MainConfig.ReadString('Search', 'gsSearchTextHistory', gsSearchTextHistory);
  984. gsReplaceText := MainConfig.ReadString('Search', 'gsReplaceText', gsReplaceText);
  985. gsReplaceTextHistory := MainConfig.ReadString('Search', 'gsReplaceTextHistory', gsReplaceTextHistory);
  986. CheckForUpdate;
  987. end;
  988. function TfrmMain.GenerateGuid: string;
  989. var
  990. guid: TGUID;
  991. begin
  992. CreateGUID(guid);
  993. Result := GUIDToString(guid);
  994. Result := StringReplace(Result, '{', '', [rfReplaceAll]);
  995. Result := StringReplace(Result, '}', '', [rfReplaceAll]);
  996. Result := StringReplace(Result, '-', '', [rfReplaceAll]);
  997. Result := LowerCase(Result);
  998. end;
  999. function TfrmMain.GetAppVersion: string;
  1000. var
  1001. VerInfoSize: DWORD;
  1002. VerInfo: Pointer;
  1003. VerValueSize: DWORD;
  1004. VerValue: PVSFixedFileInfo;
  1005. dmy: DWORD;
  1006. begin
  1007. Result := '';
  1008. VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), dmy);
  1009. if VerInfoSize = 0 then Exit;
  1010. GetMem(VerInfo, VerInfoSize);
  1011. try
  1012. GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
  1013. VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
  1014. with VerValue^ do
  1015. begin
  1016. Result := IntToStr(dwFileVersionMS shr 16);
  1017. Result := Result + '.' + IntToStr(dwFileVersionMS and $FFFF);
  1018. Result := Result + '.' + IntToStr(dwFileVersionLS shr 16);
  1019. Result := Result + '.' + IntToStr(dwFileVersionLS and $FFFF);
  1020. end;
  1021. finally
  1022. FreeMem(VerInfo, VerInfoSize);
  1023. end;
  1024. end;
  1025. function TfrmMain.GetTempProjectFile: string;
  1026. var
  1027. iSize: Integer;
  1028. guid: TGUID;
  1029. begin
  1030. iSize := Winapi.Windows.GetTempPath(0, nil);
  1031. SetLength(Result, iSize);
  1032. iSize := Winapi.Windows.GetTempPath(iSize, @Result[1]);
  1033. SetLength(Result, iSize);
  1034. Result := IncludeTrailingPathDelimiter(Result);
  1035. CreateGUID(guid);
  1036. Result := Result + guid.ToString + '.rdproj';
  1037. FTempProjectFile := Result;
  1038. end;
  1039. procedure TfrmMain.LoadPreset;
  1040. var
  1041. preset: string;
  1042. idx: Integer;
  1043. begin
  1044. idx := comboPresets.Properties.Items.IndexOf(FActivePreset);
  1045. if idx > -1 then
  1046. begin
  1047. preset := 'Preset_' + FPresetsList.Names[idx];
  1048. edtBaseURL.Text := FProjectConfig.ReadString(preset, 'BaseURL');
  1049. comboMethod.ItemIndex := FProjectConfig.ReadInteger(preset, 'Method', 0);
  1050. EditorURLParams.Lines.Text := FProjectConfig.ReadString(preset, 'URLParams');
  1051. EditorExtraHeaders.Lines.Text := FProjectConfig.ReadString(preset, 'ExtraHeaders');
  1052. EditorPostData.Lines.Text := FProjectConfig.ReadString(preset, 'PostData');
  1053. comboPostContentType.Text := FProjectConfig.ReadString(preset, 'PostDataContentType', 'application/json');
  1054. chkResponseAutoformat.Checked := FProjectConfig.ReadBool(preset, 'ResponseAutoFormat', false);
  1055. chkUseBasicAuth.Checked := FProjectConfig.ReadBool(preset, 'UseBasicAuth');
  1056. edtAuthUsername.Text := TEncryptStr.DecryptString(FProjectConfig.ReadString(preset, 'AuthUsername'));
  1057. edtAuthPassword.Text := TEncryptStr.DecryptString(FProjectConfig.ReadString(preset, 'AuthPassword'));
  1058. UpdateFullURL;
  1059. end;
  1060. end;
  1061. procedure TfrmMain.LoadProject;
  1062. var
  1063. strlist: TStringList;
  1064. i: Integer;
  1065. begin
  1066. if FIsTempProjectLoaded then
  1067. begin
  1068. dxStatusBarApp.Panels[1].Text := 'Default project loaded.';
  1069. Caption := 'Simnet REST Debugger';
  1070. end
  1071. else
  1072. begin
  1073. dxStatusBarApp.Panels[1].Text := 'Loaded project: ' + FActiveProject;
  1074. Caption := ExtractFileName(FActiveProject) + ' - Simnet REST Debugger';
  1075. MainConfig.WriteString('Project', 'LastUsed', FActiveProject);
  1076. end;
  1077. if Assigned(FProjectConfig) then
  1078. begin
  1079. FProjectConfig.Free;
  1080. end;
  1081. FProjectConfig := TJSONConfig.Create(FActiveProject, False);
  1082. FProjectConfig.AutoSave := False;
  1083. if FProjectConfig.ReadInteger('Presets', 'ConfigVersion') <> iCurrentConfigVersion then
  1084. begin
  1085. //Upgrade config to newest version
  1086. strlist := TStringList.Create;
  1087. try
  1088. strlist.Text := FProjectConfig.ReadString('Presets', 'Presets');
  1089. FPresetsList.Clear;
  1090. for i := 0 to strlist.Count - 1 do
  1091. begin
  1092. FPresetsList.AddPair(GenerateGuid, Encode(strlist[i]));
  1093. FProjectConfig.RenameSection('Preset_' + i.ToString, 'Preset_' + FPresetsList.Names[i]);
  1094. end;
  1095. FProjectConfig.WriteString('Presets', 'Presets', FPresetsList.Text);
  1096. FProjectConfig.WriteInteger('Presets', 'ConfigVersion', iCurrentConfigVersion);
  1097. FProjectConfig.Save;
  1098. finally
  1099. strlist.Free;
  1100. end;
  1101. end;
  1102. FPresetsList.Clear;
  1103. FPresetsList.DelimitedText := FProjectConfig.ReadString('Presets', 'Presets');
  1104. UpdatePresetsCombobox;
  1105. if comboPresets.Properties.Items.Count = 0 then
  1106. begin
  1107. // Add default
  1108. AddPreset('Default');
  1109. FProjectConfig.Save;
  1110. end
  1111. else
  1112. begin
  1113. comboPresets.ItemIndex := FProjectConfig.ReadInteger('Presets', 'LastUsed', 0);
  1114. end;
  1115. PageControlParams.ActivePage := tabURLParams;
  1116. PageControlResponse.ActivePage := tabContent;
  1117. end;
  1118. procedure TfrmMain.pmnuPasteJsonContentClick(Sender: TObject);
  1119. begin
  1120. ActiveEditor.PasteFromClipboard;
  1121. end;
  1122. procedure TfrmMain.pmnuRedoJsonContentClick(Sender: TObject);
  1123. begin
  1124. ActiveEditor.Redo;
  1125. end;
  1126. procedure TfrmMain.pmnuSelectAllClick(Sender: TObject);
  1127. begin
  1128. ActiveEditor.SelectAll;
  1129. end;
  1130. procedure TfrmMain.pmnuUndoJsonContentClick(Sender: TObject);
  1131. begin
  1132. ActiveEditor.Undo;
  1133. end;
  1134. procedure TfrmMain.PopupEditorPopup(Sender: TObject);
  1135. begin
  1136. pmnuPasteJsonContent.Enabled := ActiveEditor.CanPaste;
  1137. pmnuUndoJsonContent.Enabled := ActiveEditor.CanUndo;
  1138. pmnuRedoJsonContent.Enabled := ActiveEditor.CanRedo;
  1139. if ActiveEditor.Highlighter = SynJSONSyn then
  1140. begin
  1141. pmnuFormatJsonContent.Visible := ivAlways;
  1142. pmnuCompactJson.Visible := ivAlways;
  1143. pmnuFormatXML.Visible := ivNever;
  1144. pmnuCompactXML.Visible := ivNever;
  1145. end
  1146. else
  1147. if ActiveEditor.Highlighter = SynXMLSyn then
  1148. begin
  1149. pmnuFormatJsonContent.Visible := ivNever;
  1150. pmnuCompactJson.Visible := ivNever;
  1151. pmnuFormatXML.Visible := ivAlways;
  1152. pmnuCompactXML.Visible := ivAlways;
  1153. end
  1154. else
  1155. begin
  1156. pmnuFormatJsonContent.Visible := ivNever;
  1157. pmnuCompactJson.Visible := ivNever;
  1158. pmnuFormatXML.Visible := ivNever;
  1159. pmnuCompactXML.Visible := ivNever;
  1160. end;
  1161. if ActiveEditor = frmBiggerEditor.EditorBiggerEditor then
  1162. begin
  1163. pmnuBiggerEditor.Visible := ivNever;
  1164. end
  1165. else
  1166. begin
  1167. pmnuBiggerEditor.Visible := ivAlways;
  1168. end;
  1169. end;
  1170. procedure TfrmMain.pmnuFormatJsonContentClick(Sender: TObject);
  1171. var
  1172. ja: TJsonArray;
  1173. jo: TJsonObject;
  1174. begin
  1175. if ActiveEditor.Lines.Count > 0 then
  1176. begin
  1177. if Length(ActiveEditor.Lines[0]) > 0 then
  1178. begin
  1179. if ActiveEditor.Lines[0][1] = '{' then
  1180. begin
  1181. jo := TJsonObject.Create;
  1182. Screen.Cursor := crHourGlass;
  1183. try
  1184. try
  1185. jo.FromJSON(ActiveEditor.Lines.Text);
  1186. except
  1187. on E: Exception do
  1188. begin
  1189. ShowError(E.Message);
  1190. end;
  1191. end;
  1192. UpdateEditor(jo.ToJSON(False));
  1193. finally
  1194. Screen.Cursor := crDefault;
  1195. jo.Free;
  1196. end;
  1197. end
  1198. else
  1199. if ActiveEditor.Lines[0][1] = '[' then
  1200. begin
  1201. ja := TJsonArray.Create;
  1202. Screen.Cursor := crHourGlass;
  1203. try
  1204. try
  1205. ja.FromJSON(ActiveEditor.Lines.Text);
  1206. except
  1207. on E: Exception do
  1208. begin
  1209. ShowError(E.Message);
  1210. end;
  1211. end;
  1212. UpdateEditor(ja.ToJSON(False));
  1213. finally
  1214. Screen.Cursor := crDefault;
  1215. ja.Free;
  1216. end;
  1217. end;
  1218. end;
  1219. end;
  1220. end;
  1221. procedure TfrmMain.pmnuFormatXMLClick(Sender: TObject);
  1222. var
  1223. xml: TRwDomDocument;
  1224. begin
  1225. xml := TRwDOMDocument.Create;
  1226. try
  1227. Screen.Cursor := crHourGlass;
  1228. xml.LoadXML(ActiveEditor.Lines.Text);
  1229. UpdateEditor(xml.FormattedXML);
  1230. finally
  1231. xml.Free;
  1232. Screen.Cursor := crDefault;
  1233. end;
  1234. end;
  1235. procedure TfrmMain.Run;
  1236. var
  1237. tick: Cardinal;
  1238. begin
  1239. FHTTP := TIdHTTP.Create(nil);
  1240. FHTTP.IOHandler := SSLIOHandlerSocketOpenSSL;
  1241. FHTTP.HTTPOptions := [];
  1242. FHTTP.HandleRedirects := True;
  1243. FHTTP.AllowCookies := True;
  1244. FHTTP.Request.UserAgent := 'Simnet REST Debugger/' + GetAppVersion;
  1245. try
  1246. EditorContent.Lines.Clear;
  1247. EditorResponseHeaders.Lines.Clear;
  1248. Screen.Cursor := crHourGlass;
  1249. tick := GetTickCount;
  1250. try
  1251. FHTTP.Request.CustomHeaders.Clear;
  1252. FHTTP.Request.CustomHeaders.AddStrings(EditorExtraHeaders.Lines);
  1253. if chkUseBasicAuth.Checked then
  1254. begin
  1255. FHTTP.Request.Username := edtAuthUsername.Text;
  1256. FHTTP.Request.Password := edtAuthPassword.Text;
  1257. FHTTP.Request.BasicAuthentication := True;
  1258. end
  1259. else
  1260. begin
  1261. FHTTP.Request.BasicAuthentication := False;
  1262. FHTTP.Request.Username := '';
  1263. FHTTP.Request.Password := '';
  1264. end;
  1265. if comboMethod.ItemIndex = 0 then
  1266. begin
  1267. // GET
  1268. DoGETRequest(mtGET);
  1269. end
  1270. else
  1271. if comboMethod.ItemIndex = 1 then
  1272. begin
  1273. // POST
  1274. DoPOSTRequest(mtPOST);
  1275. end
  1276. else
  1277. if comboMethod.ItemIndex = 2 then
  1278. begin
  1279. // PATCH
  1280. DoPOSTRequest(mtPATCH);
  1281. end
  1282. else
  1283. if comboMethod.ItemIndex = 3 then
  1284. begin
  1285. // PUT
  1286. DoPOSTRequest(mtPUT);
  1287. end
  1288. else
  1289. if comboMethod.ItemIndex = 4 then
  1290. begin
  1291. // DELETE
  1292. DoGETRequest(mtDELETE);
  1293. end;
  1294. finally
  1295. ActiveEditor := EditorContent;
  1296. EditorContent.SetFocus;
  1297. if Pos('application/json', FHTTP.Response.ContentType) > 0 then
  1298. begin
  1299. EditorContent.Highlighter := SynJSONSyn;
  1300. if chkResponseAutoformat.Checked then
  1301. begin
  1302. pmnuFormatJsonContentClick(nil);
  1303. end;
  1304. end
  1305. else
  1306. if Pos('text/xml', FHTTP.Response.ContentType) > 0 then
  1307. begin
  1308. EditorContent.Highlighter := SynXMLSyn;
  1309. if chkResponseAutoformat.Checked then
  1310. begin
  1311. pmnuFormatXMLClick(nil);
  1312. end;
  1313. end
  1314. else
  1315. if Pos('text/html', FHTTP.Response.ContentType) > 0 then
  1316. begin
  1317. EditorContent.Highlighter := SynHTMLSyn;
  1318. end
  1319. else
  1320. begin
  1321. EditorContent.Highlighter := nil;
  1322. end;
  1323. dxStatusBarResponse.Panels[0].Text := FormatFloat('Response Time: 0, ms', GetTickCount - tick);
  1324. dxStatusBarResponse.Panels[1].Text := 'Response Code: ' + FHTTP.ResponseCode.ToString;
  1325. dxStatusBarResponse.Panels[2].Text := 'Response Content: ' + FHTTP.Response.ContentType;
  1326. Screen.Cursor := crDefault;
  1327. end;
  1328. finally
  1329. FHTTP.Free;
  1330. end;
  1331. end;
  1332. procedure TfrmMain.SavePreset;
  1333. var
  1334. preset: string;
  1335. idx: Integer;
  1336. begin
  1337. idx := comboPresets.Properties.Items.IndexOf(FActivePreset);
  1338. if idx > -1 then
  1339. begin
  1340. preset := 'Preset_' + FPresetsList.Names[idx];
  1341. FProjectConfig.WriteString(preset, 'BaseURL', edtBaseURL.Text);
  1342. FProjectConfig.WriteInteger(preset, 'Method', comboMethod.ItemIndex);
  1343. FProjectConfig.WriteString(preset, 'URLParams', EditorURLParams.Lines.Text);
  1344. FProjectConfig.WriteString(preset, 'PostData', EditorPostData.Lines.Text);
  1345. FProjectConfig.WriteString(preset, 'ExtraHeaders', EditorExtraHeaders.Lines.Text);
  1346. FProjectConfig.WriteString(preset, 'PostDataContentType', comboPostContentType.Text);
  1347. FProjectConfig.WriteBool(preset, 'ResponseAutoFormat', chkResponseAutoformat.Checked);
  1348. FProjectConfig.WriteBool(preset, 'UseBasicAuth', chkUseBasicAuth.Checked);
  1349. FProjectConfig.WriteString(preset, 'AuthUsername', TEncryptStr.EncryptString(edtAuthUsername.Text));
  1350. FProjectConfig.WriteString(preset, 'AuthPassword', TEncryptStr.EncryptString(edtAuthPassword.Text));
  1351. FProjectConfig.WriteInteger('Presets', 'LastUsed', idx);
  1352. end;
  1353. end;
  1354. procedure TfrmMain.SaveProject;
  1355. begin
  1356. SavePreset;
  1357. FProjectConfig.WriteInteger('Presets', 'ConfigVersion', iCurrentConfigVersion);
  1358. FProjectConfig.Save;
  1359. end;
  1360. procedure TfrmMain.SaveProjectAs(const LoadAfterSave: Boolean);
  1361. var
  1362. fname: string;
  1363. begin
  1364. SaveDialog.InitialDir := MainConfig.ReadString('Dialogs', 'LastSaveDir', ExtractFilePath(ParamStr(0)));
  1365. if SaveDialog.Execute then
  1366. begin
  1367. fname := SaveDialog.FileName;
  1368. MainConfig.WriteString('Dialogs', 'LastSaveDir', ExtractFilePath(fname));
  1369. fname := ChangeFileExt(fname, '');
  1370. fname := fname + '.rdproj';
  1371. SaveProject;
  1372. CopyFile(PChar(FProjectConfig.FileName), PChar(fname), False);
  1373. if LoadAfterSave then
  1374. begin
  1375. FIsTempProjectLoaded := False;
  1376. FActiveProject := fname;
  1377. LoadProject;
  1378. end;
  1379. end;
  1380. end;
  1381. procedure TfrmMain.ShowError(const AErrorText: string);
  1382. begin
  1383. MessageDlg(AErrorText, mtError, [mbOK], 0);
  1384. end;
  1385. procedure TfrmMain.ShowSearchReplaceDialog(AReplace: Boolean);
  1386. begin
  1387. with frmSearch do
  1388. begin
  1389. // assign search options
  1390. SearchBackwards := gbSearchBackwards;
  1391. SearchCaseSensitive := gbSearchCaseSensitive;
  1392. SearchFromCursor := gbSearchFromCaret;
  1393. SearchInSelectionOnly := gbSearchSelectionOnly;
  1394. // start with last search text
  1395. SearchText := gsSearchText;
  1396. if gbSearchTextAtCaret then
  1397. begin
  1398. // if something is selected search for that text
  1399. if ActiveEditor.SelAvail and (ActiveEditor.BlockBegin.Line = ActiveEditor.BlockEnd.Line)
  1400. then
  1401. SearchText := ActiveEditor.SelText
  1402. else
  1403. SearchText := ActiveEditor.GetWordAtRowCol(ActiveEditor.CaretXY);
  1404. end;
  1405. SearchTextHistory := gsSearchTextHistory;
  1406. SearchWholeWords := gbSearchWholeWords;
  1407. if ShowModal = mrOK then
  1408. begin
  1409. gbSearchBackwards := SearchBackwards;
  1410. gbSearchCaseSensitive := SearchCaseSensitive;
  1411. gbSearchFromCaret := SearchFromCursor;
  1412. gbSearchSelectionOnly := SearchInSelectionOnly;
  1413. gbSearchWholeWords := SearchWholeWords;
  1414. gbSearchRegex := SearchRegularExpression;
  1415. gsSearchText := SearchText;
  1416. gsSearchTextHistory := SearchTextHistory;
  1417. FSearchFromCaret := gbSearchFromCaret;
  1418. if gsSearchText <> '' then
  1419. begin
  1420. DoSearchReplaceText(AReplace, gbSearchBackwards);
  1421. FSearchFromCaret := TRUE;
  1422. end;
  1423. end;
  1424. end;
  1425. end;
  1426. end.