FormDocument.pas 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197
  1. unit FormDocument;
  2. interface
  3. uses
  4. jsonhelper, JsonDocument,
  5. WinSizeUtil, LineNumbersMemoFMX,
  6. System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  7. System.Math, System.StrUtils, FMX.DialogService,
  8. FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  9. FMX.Controls.Presentation, FMX.Layouts, FMX.TreeView, FMX.Objects, System.JSON,
  10. FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, System.ImageList, FMX.ImgList, FMX.Text,
  11. FMX.ListBox, FMX.Edit, FMX.TabControl, FMX.Menus, FMX.Ani, FMX.Effects,
  12. FMX.Filter.Effects, System.Generics.Collections, System.Actions, FMX.ActnList,
  13. System.Math.Vectors, FMX.Controls3D, FMX.Layers3D, FMX.EditBox, FMX.NumberBox;
  14. type
  15. TfmDocument = class(TForm)
  16. pmTreeViewItem: TPopupMenu;
  17. miMoveDown: TMenuItem;
  18. imglstJSONKind: TImageList;
  19. miMoveUp: TMenuItem;
  20. pnlSizeBorder: TPanel;
  21. lytMiddle: TLayout;
  22. rctFooter: TRectangle;
  23. lytLeftAndRight: TLayout;
  24. rctLeft: TRectangle;
  25. rctLeftToolBar: TRectangle;
  26. rctBtnCollapseAll: TRectangle;
  27. ColorAnimation6: TColorAnimation;
  28. pathBtnCollapseAll: TPath;
  29. rctBtnExpandAll: TRectangle;
  30. ColorAnimation7: TColorAnimation;
  31. pathBtnExpandAll: TPath;
  32. lytLeftToolBar_right: TLayout;
  33. rctBtnDelete: TRectangle;
  34. ColorAnimation8: TColorAnimation;
  35. Path2: TPath;
  36. rctBtnAddSubItem: TRectangle;
  37. ColorAnimation9: TColorAnimation;
  38. pathBtnAddSub: TPath;
  39. rctBtnAddItem: TRectangle;
  40. ColorAnimation10: TColorAnimation;
  41. pathBtnAddBrother: TPath;
  42. rctBtnMoveDown: TRectangle;
  43. ColorAnimation11: TColorAnimation;
  44. pathBtnMoveDown: TPath;
  45. rctBtnMoveUp: TRectangle;
  46. ColorAnimation12: TColorAnimation;
  47. pathBtnMoveUp: TPath;
  48. tvJson: TTreeView;
  49. rctDrap: TRectangle;
  50. rctRight: TRectangle;
  51. rctRightTopBar: TRectangle;
  52. edtName: TEdit;
  53. cbValueType: TComboBox;
  54. rctRightMiddle: TRectangle;
  55. mmoEdit: TMemo;
  56. rctForBoolValue: TRectangle;
  57. rbTrue: TRadioButton;
  58. rbFalse: TRadioButton;
  59. slL_R: TSplitter;
  60. rctTitleBar: TRectangle;
  61. rctTitleBarForMove: TRectangle;
  62. rctBtnClose: TRectangle;
  63. aniForCloseBtn: TColorAnimation;
  64. pathCloseBtn: TPath;
  65. rctBtnMin: TRectangle;
  66. aniForMinBtn: TColorAnimation;
  67. pathMinBtn: TPath;
  68. rctBtnMax: TRectangle;
  69. aniForMaxBtn: TColorAnimation;
  70. pathMaxBtn: TPath;
  71. lblCaption: TLabel;
  72. imgLogo: TImage;
  73. lblFilename: TLabel;
  74. rctToolBar: TRectangle;
  75. MenuBar1: TMenuBar;
  76. miFile: TMenuItem;
  77. miFileNew: TMenuItem;
  78. miFileOpen: TMenuItem;
  79. miFileOpenRecent: TMenuItem;
  80. miFileSave: TMenuItem;
  81. miFileSaveAs: TMenuItem;
  82. miFileClose: TMenuItem;
  83. miEdit: TMenuItem;
  84. miEditMoveUp: TMenuItem;
  85. miEditMoveDown: TMenuItem;
  86. miView: TMenuItem;
  87. miViewShowLog: TMenuItem;
  88. miViewDarkStyle: TMenuItem;
  89. BitmapAnimation1: TBitmapAnimation;
  90. miViewFont: TMenuItem;
  91. miHelp: TMenuItem;
  92. miHelpHelp: TMenuItem;
  93. miHelpAbout: TMenuItem;
  94. txtMsg: TText;
  95. aniMsg: TFloatAnimation;
  96. miWindow: TMenuItem;
  97. mi1: TMenuItem;
  98. miWindowShowAll: TMenuItem;
  99. miWindowItems: TMenuItem;
  100. lblPath: TLabel;
  101. rctLinePos: TRectangle;
  102. lblLineAndPos: TLabel;
  103. ErrorLight: TCircle;
  104. rctIndent: TRectangle;
  105. lblIndent: TLabel;
  106. rctWordWarp: TRectangle;
  107. ColorAnimation13: TColorAnimation;
  108. miViewLang: TMenuItem;
  109. pathWordWrap: TPath;
  110. procedure tvJsonChange(Sender: TObject);
  111. procedure mmoEditChangeTracking(Sender: TObject);
  112. procedure FormCreate(Sender: TObject);
  113. procedure cbValueTypeChange(Sender: TObject);
  114. procedure FormResize(Sender: TObject);
  115. procedure slL_RMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  116. procedure rctBtnCloseClick(Sender: TObject);
  117. procedure rctBtnMaxClick(Sender: TObject);
  118. procedure rctBtnMinClick(Sender: TObject);
  119. procedure mmoEditViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
  120. procedure edtNameChangeTracking(Sender: TObject);
  121. procedure rctBtnCollapseAllMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  122. procedure rctBtnExpandAllMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  123. procedure rctIndentClick(Sender: TObject);
  124. procedure rctWordWarpClick(Sender: TObject);
  125. procedure rctBtnMoveUpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  126. procedure rctBtnMoveDownMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  127. procedure tvJsonDragChange(SourceItem, DestItem: TTreeViewItem; var Allow: Boolean);
  128. procedure tvJsonDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF; var Operation: TDragOperation);
  129. procedure tvJsonMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
  130. procedure rctBtnDeleteClick(Sender: TObject);
  131. procedure pmTreeViewItemPopup(Sender: TObject);
  132. procedure tvJsonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  133. procedure JsonFileDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF; var Operation: TDragOperation);
  134. procedure JsonFileDragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF);
  135. procedure rbTrueFalseChange(Sender: TObject);
  136. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  137. procedure FormDestroy(Sender: TObject);
  138. procedure rctBtnAddItemMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  139. procedure rctBtnAddSubItemMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  140. procedure miFileOpenRecentApplyStyleLookup(Sender: TObject);
  141. procedure FormActivate(Sender: TObject);
  142. procedure miWindowShowAllApplyStyleLookup(Sender: TObject);
  143. procedure ErrorLightClick(Sender: TObject);
  144. private
  145. FDoc: TJsonDocument;
  146. FIsUpdating: Boolean;
  147. FLinesMemoUtil: TLinesMemoUtil;
  148. FIndent: Integer;
  149. FCurrentJSONKind: TJSONKind;
  150. FRightPanelWidthPercent: Single; // 右侧宽度占整个窗口的比例
  151. procedure SetIndent(AValue: Integer);
  152. function GetWordWarp: Boolean;
  153. procedure SetWordWarp(AValue: Boolean);
  154. property Indent: Integer read FIndent write SetIndent;
  155. property WordWarp: Boolean read GetWordWarp write SetWordWarp;
  156. public
  157. property Doc: TJsonDocument read FDoc;
  158. private
  159. procedure InitUI;
  160. procedure miFileOepnedClick(Sender: TObject);
  161. procedure miRecentFilesClick(Sender: TObject);
  162. procedure FilenameChanged(ASender: TObject);
  163. procedure SetErrInfo(const AMsg: string);
  164. public
  165. procedure SetLang;
  166. procedure NewFile;
  167. procedure OpenFile(const AFilename: string);
  168. procedure SetStyleBook;
  169. procedure InitOpenedFileMenu;
  170. procedure InitRecentFile;
  171. procedure ShowInfo(AText: string; ALevel: Integer = 0; ADelay: Single = 3.0);
  172. end;
  173. var
  174. fmDocument: TfmDocument;
  175. implementation
  176. {$R *.fmx}
  177. uses JSONTreeView, memo_json_auto, data_const, pub, Logger, fmFontDialog,
  178. rjson, FormMain;
  179. procedure TfmDocument.FilenameChanged(ASender: TObject);
  180. var
  181. strTmp: string;
  182. begin
  183. if FDoc.FileName = '' then
  184. begin
  185. strTmp := c_untitled_filename;
  186. for var i := 1 to 9999 do
  187. begin
  188. if g_pub.DocumentWindowList.GetWindowByFilename(strTmp) = nil then
  189. Break;
  190. strTmp := c_untitled_filename + ' (' + i.ToString + ')';
  191. end;
  192. lblFilename.Text := strTmp
  193. end
  194. else
  195. begin
  196. lblFilename.Text := FDoc.FileName;
  197. {$IFDEF MACOS}
  198. fmMain.InitMacOsRecentFile;
  199. {$ENDIF}
  200. end;
  201. {$IFDEF MACOS}
  202. Caption := app_name + ' ' + app_version + ' [' + lblFilename.Text + ']';
  203. {$ENDIF}
  204. end;
  205. procedure TfmDocument.SetErrInfo(const AMsg: string);
  206. begin
  207. ErrorLight.TagString := AMsg;
  208. ErrorLight.Fill.Color := IfThen(AMsg.IsEmpty, $FF00FF00, $FFFF0000);
  209. end;
  210. procedure TfmDocument.FormCreate(Sender: TObject);
  211. var
  212. LDisplay: TDisplay;
  213. begin
  214. FDoc := TJsonDocument.Create;
  215. FDoc.OnFilenameChanged := FilenameChanged;
  216. if g_pub.DocumentWindowList.LastActive <> nil then
  217. begin
  218. Position := TFormPosition.Designed;
  219. Left := g_pub.DocumentWindowList.LastActive.Left + 28;
  220. Top := g_pub.DocumentWindowList.LastActive.Top + 28;
  221. Width := g_pub.DocumentWindowList.LastActive.Width;
  222. Height := g_pub.DocumentWindowList.LastActive.Height;
  223. LDisplay := Screen.DisplayFromForm(g_pub.DocumentWindowList.LastActive);
  224. if (Left > LDisplay.BoundsRect.Right - 320) or (Top > LDisplay.BoundsRect.Bottom - 240) then
  225. begin
  226. Left := 0;
  227. Top := 0;
  228. end;
  229. end;
  230. g_pub.DocumentWindowList.Add(self);
  231. FIsUpdating := False;
  232. TMemoJsonAuto.Create(self, mmoEdit);
  233. FLinesMemoUtil := TLinesMemoUtil.Create(self, mmoEdit);
  234. InitUI;
  235. end;
  236. procedure TfmDocument.FormDestroy(Sender: TObject);
  237. begin
  238. FDoc.Free;
  239. end;
  240. procedure TfmDocument.FormResize(Sender: TObject);
  241. begin
  242. rctRight.Width := IfThen((Width - 10) * FRightPanelWidthPercent > slL_R.MinSize,
  243. IfThen((Width - 10) * (1.0 - FRightPanelWidthPercent) >= slL_R.MinSize, (Width - 10) * FRightPanelWidthPercent, (Width - 10) - slL_R.MinSize),
  244. slL_R.MinSize);
  245. {$IFDEF MSWINDOWS}
  246. pathMaxBtn.Data.Data := IfThen(WindowState = TWindowState.wsMaximized, c_ResPathData, c_MaxPathData);
  247. {$ENDIF}
  248. end;
  249. procedure TfmDocument.InitUI;
  250. begin
  251. {$IFDEF MACOS}
  252. rctTitleBar.Visible := False;
  253. pnlSizeBorder.StyleLookup := 'panelstyle_macos_frame';
  254. mmoEdit.TextSettings.Font.Family := 'SimSong'; // [BIZ UDGothic] [BIZ UDMincho] [PCMyungjo] [SimSong]
  255. rctToolBar.Visible := False;
  256. rctToolBar.Free;
  257. lytMiddle.Margins.Left := 2;
  258. lytMiddle.Margins.Right := 2;
  259. lytMiddle.Margins.Top := 2;
  260. {$ELSE}
  261. Transparency := True;
  262. with TWinSizeHelper.Create(self) do
  263. begin
  264. SetControlled(pnlSizeBorder);
  265. SetTitleBar(rctTitleBarForMove);
  266. CanMaximized := True;
  267. end;
  268. for var item in g_pub.Languages do
  269. begin
  270. var
  271. mi := TMenuItem.Create(miViewLang);
  272. mi.Text := item['caption'].ToStr('None');
  273. mi.RadioItem := True;
  274. mi.GroupIndex := 10;
  275. mi.OnClick := fmMain.actViewLangExecute;
  276. miViewLang.AddObject(mi);
  277. end;
  278. {$ENDIF}
  279. SetLang;
  280. Caption := app_name + ' ' + app_version;
  281. lblCaption.Text := Caption;
  282. rctDrap.Visible := False;
  283. OnResize := nil;
  284. Indent := g_pub.Config['editor.indent'].ToInt(4);
  285. WordWarp := g_pub.Config['editor.wordWarp'];
  286. SetStyleBook;
  287. FRightPanelWidthPercent := 0.5;
  288. rctRight.Width := (Width - 10) * FRightPanelWidthPercent;
  289. OnResize := FormResize;
  290. end;
  291. procedure TfmDocument.SetStyleBook;
  292. const
  293. c_PathColors: array [Boolean] of TAlphaColor = ({false:}$FF000000, {true:}$FFFFFFFF);
  294. begin
  295. tvJson.ScrollBy(tvJson.ViewportPosition.X, tvJson.ViewportPosition.Y); // 否则切换时会偶发异常
  296. StyleBook := g_pub.StyleBook;
  297. fmMain.actViewDarkStyle.Checked := g_pub.IsDarkStyle;
  298. tvJson.ShowScrollBars := True;
  299. for var item in [pathMaxBtn.Fill, pathMinBtn.Fill, pathCloseBtn.Fill] do
  300. item.Color := c_PathColors[fmMain.actViewDarkStyle.Checked];
  301. mmoEdit.TextSettings.FontColor := c_PathColors[fmMain.actViewDarkStyle.Checked];
  302. end;
  303. procedure TfmDocument.SetLang;
  304. begin
  305. {$IFDEF MSWINDOWS}
  306. miViewLang.Items[g_pub.LangIndex].IsChecked := True;
  307. {$ENDIF}
  308. rctIndent.Hint := g_pub.LangStr('strIndent');
  309. rctWordWarp.Hint := g_pub.LangStr('strWordWarp');
  310. end;
  311. procedure TfmDocument.NewFile;
  312. begin
  313. FDoc.New;
  314. FIsUpdating := True;
  315. try
  316. tvJson.Clear;
  317. SetTreeItem(tvJson, FDoc.JsonRoot);
  318. tvJson.ExpandAll;
  319. tvJson.Items[0].Select;
  320. mmoEdit.SetFocus;
  321. mmoEdit.Text := '{' + sLineBreak + StringOfChar(' ', Indent) + sLineBreak + '}';
  322. mmoEdit.CaretPosition := TCaretPosition.Create(1, Indent);
  323. cbValueType.ItemIndex := 0;
  324. finally
  325. FIsUpdating := False;
  326. end;
  327. end;
  328. procedure TfmDocument.OpenFile(const AFilename: string);
  329. begin
  330. if FDoc.Open(AFilename, True, False) then
  331. begin
  332. FIsUpdating := True;
  333. try
  334. tvJson.Clear;
  335. tvJson.BeginUpdate;
  336. SetTreeItem(tvJson, FDoc.JsonRoot);
  337. tvJson.EndUpdate;
  338. tvJson.ExpandAll;
  339. mmoEdit.Text := '';
  340. ShowInfo('Open: ' + AFilename);
  341. finally
  342. FIsUpdating := False;
  343. end;
  344. if tvJson.Count > 0 then
  345. begin
  346. tvJson.Items[0].Select;
  347. end;
  348. end
  349. else
  350. begin
  351. ShowMessage('An error occurred while opening the file.!');
  352. end;
  353. end;
  354. procedure TfmDocument.tvJsonChange(Sender: TObject);
  355. var
  356. selItem: TJSONTreeViewItem;
  357. LJsonKind: TJSONKind;
  358. begin
  359. if FIsUpdating then
  360. Exit;
  361. FIsUpdating := True;
  362. try
  363. SetErrInfo('');
  364. selItem := TJSONTreeViewItem(tvJson.Selected);
  365. if selItem = nil then
  366. begin
  367. mmoEdit.Text := '';
  368. Exit;
  369. end;
  370. edtName.Text := selItem.LastPath;
  371. mmoEdit.Text := selItem.Value;
  372. lblPath.Text := selItem.Path;
  373. edtName.Enabled := not selItem.Key.IsEmpty;
  374. LJsonKind := selItem.JsonValue.JsonKind;
  375. cbValueType.ItemIndex := ord(LJsonKind) - 1;
  376. if LJsonKind in [jkObject, jkArray] then
  377. begin
  378. mmoEdit.Text := selItem.JsonValue.Format(Indent);
  379. end
  380. else
  381. begin
  382. mmoEdit.Text := selItem.Value;
  383. if LJsonKind = jkBoolean then
  384. begin
  385. rbTrue.IsChecked := selItem.JsonValue.AsType<Boolean>;
  386. rbFalse.IsChecked := not rbTrue.IsChecked;
  387. end;
  388. end;
  389. finally
  390. FIsUpdating := False;
  391. end;
  392. end;
  393. procedure TfmDocument.tvJsonDragChange(SourceItem, DestItem: TTreeViewItem; var Allow: Boolean);
  394. var
  395. Pos: TPointF;
  396. Source, Dest: TJSONTreeViewItem;
  397. begin
  398. Allow := False;
  399. rctDrap.Visible := False;
  400. if DestItem = nil then
  401. Exit;
  402. Dest := TJSONTreeViewItem(DestItem);
  403. Source := TJSONTreeViewItem(SourceItem);
  404. if Source.IsChild(Dest) then
  405. begin
  406. {$IFDEF DEBUG}
  407. g_Logger.Debug('父条目不能插入子条目!');
  408. {$ENDIF}
  409. Exit;
  410. end;
  411. Pos := Dest.ScreenToLocal(Screen.MousePos);
  412. if Pos.Y < Dest.LocalRect.Height / 4 then
  413. begin
  414. if ((Dest.ParentItem = Source.ParentItem) and (Dest.Index - Source.Index = 1)) or (Dest.ParentItem = nil) then
  415. begin
  416. {$IFDEF DEBUG}
  417. g_Logger.Debug('Do nothing');
  418. {$ENDIF}
  419. end
  420. else
  421. begin
  422. {$IFDEF DEBUG}
  423. g_Logger.Debug('前边插入');
  424. {$ENDIF}
  425. TJSONTreeViewItem(Source).ExtractFromParent(True);
  426. TJSONTreeViewItem(Dest.ParentItem).InsertItem(Dest.Index, Source, True);
  427. Source.Select;
  428. end;
  429. end
  430. else if Pos.Y > Dest.LocalRect.Height / 4 * 3 then
  431. begin
  432. if ((Dest.ParentItem = Source.ParentItem) and (Source.Index - Dest.Index = 1)) or (Dest.ParentItem = nil) then
  433. begin
  434. {$IFDEF DEBUG}
  435. g_Logger.Debug('Do nothing');
  436. {$ENDIF}
  437. end
  438. else
  439. begin
  440. {$IFDEF DEBUG}
  441. g_Logger.Debug('后边插入');
  442. {$ENDIF}
  443. TJSONTreeViewItem(Source).ExtractFromParent(True);
  444. TJSONTreeViewItem(Dest.ParentItem).InsertItem(Dest.Index + 1, Source, True);
  445. Source.Select;
  446. end;
  447. end
  448. else
  449. begin
  450. if not Dest.JsonValue.IsObjectOrArray then
  451. begin
  452. {$IFDEF DEBUG}
  453. g_Logger.Debug('Do nothing');
  454. {$ENDIF}
  455. end
  456. else
  457. begin
  458. {$IFDEF DEBUG}
  459. g_Logger.Debug('插入子项');
  460. {$ENDIF}
  461. TJSONTreeViewItem(Source).ExtractFromParent(True);
  462. Dest.AddItem(Source, True);
  463. Source.Select;
  464. end;
  465. end;
  466. end;
  467. procedure TfmDocument.tvJsonDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF; var Operation: TDragOperation);
  468. var
  469. Pos: TPointF;
  470. Source, Dest: TJSONTreeViewItem;
  471. LRect: TRectF;
  472. LPoint: TPointF;
  473. begin
  474. Operation := TDragOperation.None;
  475. Dest := TJSONTreeViewItem(tvJson.ItemByPoint(Point.X, Point.Y));
  476. if Dest = nil then
  477. Exit;
  478. Source := TJSONTreeViewItem(Data.Source);
  479. if Source.IsChild(Dest) then
  480. Exit;
  481. LRect := Dest.BoundsRect;
  482. Pos := Dest.ScreenToLocal(Screen.MousePos);
  483. LPoint := tvJson.ScreenToLocal(Dest.LocalToScreen(PointF(0, 0)));
  484. if Pos.Y < Dest.LocalRect.Height / 4 then
  485. begin
  486. if ((Dest.ParentItem = Source.ParentItem) and (Dest.Index - Source.Index = 1)) or (Dest.ParentItem = nil) then
  487. begin
  488. rctDrap.Visible := False;
  489. end
  490. else
  491. begin
  492. rctDrap.Height := Dest.Height / 2;
  493. rctDrap.Position.Y := LPoint.Y - rctDrap.Height / 2 + tvJson.ViewportPosition.Y;
  494. rctDrap.Position.X := LPoint.X + tvJson.ViewportPosition.X;
  495. rctDrap.Width := tvJson.ClipRect.Width - 10 - rctDrap.Position.X + tvJson.ViewportPosition.X;
  496. rctDrap.Visible := True;
  497. end;
  498. end
  499. else if Pos.Y > Dest.LocalRect.Height / 4 * 3 then
  500. begin
  501. if ((Dest.ParentItem = Source.ParentItem) and (Source.Index - Dest.Index = 1)) or (Dest.ParentItem = nil) then
  502. begin
  503. rctDrap.Visible := False;
  504. end
  505. else
  506. begin
  507. rctDrap.Height := Dest.Height / 2;
  508. rctDrap.Position.Y := LPoint.Y - rctDrap.Height / 2 + Dest.Height + tvJson.ViewportPosition.Y;
  509. rctDrap.Position.X := LPoint.X + tvJson.ViewportPosition.X;
  510. rctDrap.Width := tvJson.ClipRect.Width - 10 - rctDrap.Position.X + tvJson.ViewportPosition.X;
  511. rctDrap.Visible := True;
  512. end;
  513. end
  514. else
  515. begin
  516. if not Dest.JsonValue.IsObjectOrArray then
  517. begin
  518. rctDrap.Visible := False;
  519. end
  520. else
  521. begin
  522. rctDrap.Height := Dest.Height / 4 * 3;
  523. rctDrap.Position.Y := LPoint.Y + (Dest.Height - rctDrap.Height) / 2 + tvJson.ViewportPosition.Y;
  524. rctDrap.Position.X := LPoint.X + tvJson.ViewportPosition.X;
  525. rctDrap.Width := tvJson.ClipRect.Width - 10 - rctDrap.Position.X + tvJson.ViewportPosition.X;
  526. rctDrap.Visible := True;
  527. end;
  528. end;
  529. end;
  530. procedure TfmDocument.tvJsonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  531. var
  532. LItem: TTreeViewItem;
  533. begin
  534. if ssRight in Shift then
  535. begin
  536. LItem := tvJson.ItemByPoint(X, Y);
  537. if LItem <> nil then
  538. begin
  539. LItem.Select;
  540. pmTreeViewItem.Popup(Screen.MousePos.X, Screen.MousePos.Y);
  541. end;
  542. end;
  543. end;
  544. procedure TfmDocument.tvJsonMouseMove(Sender: TObject; Shift: TShiftState; X,
  545. Y: Single);
  546. begin
  547. if not(ssLeft in Shift) then
  548. rctDrap.Visible := False;
  549. end;
  550. {-------------------------------------------------------------------------------
  551. 名称: TfmDocument.actHelpAboutExecute
  552. 说明: 关于
  553. 参数: Sender
  554. -------------------------------------------------------------------------------}
  555. procedure TfmDocument.cbValueTypeChange(Sender: TObject);
  556. var
  557. LJValue:
  558. TJsonValue;
  559. treeItem:
  560. TJSONTreeViewItem;
  561. bValue:
  562. Boolean;
  563. begin
  564. FCurrentJSONKind := TJSONKind(cbValueType.ItemIndex + 1);
  565. rctForBoolValue.Visible := FCurrentJSONKind = jkBoolean;
  566. mmoEdit.Visible := FCurrentJSONKind <> jkBoolean;
  567. mmoEdit.Enabled := FCurrentJSONKind in [jkObject, jkArray, jkString, jkNumber];
  568. treeItem := TJSONTreeViewItem(tvJson.Selected);
  569. if FIsUpdating or (treeItem = nil) then
  570. Exit;
  571. LJValue := nil;
  572. FIsUpdating := True;
  573. try
  574. try
  575. case FCurrentJSONKind of
  576. jkObject:
  577. begin
  578. LJValue := TJsonValue.ParseJSONValue(mmoEdit.Text, True, False);
  579. if not(LJValue is TJSONObject) then
  580. begin
  581. FreeAndNil(LJValue);
  582. mmoEdit.Text := '{' + sLineBreak + StringOfChar(' ', Indent) + sLineBreak + '}';
  583. mmoEdit.CaretPosition := TCaretPosition.Create(1, Indent);
  584. mmoEdit.SetFocus;
  585. LJValue := TJSONObject.Create;
  586. end;
  587. end;
  588. jkArray:
  589. begin
  590. LJValue := TJsonValue.ParseJSONValue(mmoEdit.Text, True, False);
  591. if not(LJValue is TJSONArray) then
  592. begin
  593. FreeAndNil(LJValue);
  594. LJValue := TJSONArray.Create;
  595. mmoEdit.Text := '[' + sLineBreak + StringOfChar(' ', Indent) + sLineBreak + ']';
  596. mmoEdit.CaretPosition := TCaretPosition.Create(1, Indent);
  597. mmoEdit.SetFocus;
  598. end;
  599. end;
  600. jkString:
  601. begin
  602. LJValue := TJSONString.Create(mmoEdit.Text);
  603. mmoEdit.GoToTextEnd;
  604. mmoEdit.SetFocus;
  605. end;
  606. jkNumber:
  607. begin
  608. LJValue := TJsonValue.ParseJSONValue(mmoEdit.Text.Trim, True, False);
  609. if not(LJValue is TJSONNumber) then
  610. begin
  611. FreeAndNil(LJValue);
  612. LJValue := TJSONNumber.Create(0);
  613. end;
  614. mmoEdit.Text := LJValue.Value;
  615. mmoEdit.GoToTextEnd;
  616. mmoEdit.SetFocus;
  617. end;
  618. jkBoolean:
  619. begin
  620. bValue := StrToBoolDef(mmoEdit.Text.Trim, False);
  621. LJValue := TJSONBool.Create(bValue);
  622. mmoEdit.Text := LJValue.Value;
  623. if bValue then
  624. begin
  625. rbTrue.IsChecked := True;
  626. end
  627. else
  628. begin
  629. rbFalse.IsChecked := True;
  630. end;
  631. end;
  632. jkNull:
  633. begin
  634. LJValue := TJSONNull.Create;
  635. mmoEdit.Text := LJValue.Value;
  636. end;
  637. end;
  638. except
  639. on E: Exception do
  640. SetErrInfo(E.Message);
  641. end;
  642. treeItem.ClearItem;
  643. treeItem.JsonValue := LJValue;
  644. treeItem.ReText;
  645. SetTreeItems(treeItem, LJValue);
  646. if treeItem.ParentItem = nil then
  647. begin
  648. FDoc.JsonRoot := LJValue;
  649. end;
  650. finally
  651. FIsUpdating := False;
  652. end;
  653. end;
  654. procedure TfmDocument.edtNameChangeTracking(Sender: TObject);
  655. var
  656. treeItem: TJSONTreeViewItem;
  657. begin
  658. if FIsUpdating or Trim(edtName.Text).IsEmpty then
  659. Exit;
  660. FIsUpdating := True;
  661. try
  662. treeItem := TJSONTreeViewItem(tvJson.Selected);
  663. if treeItem <> nil then
  664. begin
  665. TJSONPair(treeItem.JsonData).Rename(Trim(edtName.Text));
  666. treeItem.Text := Trim(edtName.Text) + ': ' + treeItem.Value;
  667. end;
  668. finally
  669. FIsUpdating := False;
  670. end;
  671. end;
  672. procedure TfmDocument.ErrorLightClick(Sender: TObject);
  673. begin
  674. if not ErrorLight.TagString.IsEmpty then
  675. ShowInfo(ErrorLight.TagString, 1, 5);
  676. end;
  677. procedure TfmDocument.FormActivate(Sender: TObject);
  678. var
  679. LIndex: Integer;
  680. begin
  681. LIndex := g_pub.DocumentWindowList.IndexOf(self);
  682. if LIndex > 0 then
  683. begin
  684. g_pub.DocumentWindowList.Move(LIndex, 0);
  685. {$IFDEF DEBUG}
  686. g_Logger.Debug('窗口激活,移动到列表首位!');
  687. {$ENDIF}
  688. end;
  689. end;
  690. procedure TfmDocument.FormClose(Sender: TObject; var Action: TCloseAction);
  691. begin
  692. g_pub.Config['editor.indent'] := Indent;
  693. g_pub.Config['editor.wordWarp'] := mmoEdit.TextSettings.WordWrap;
  694. g_pub.DocumentWindowList.Remove(self);
  695. Action := TCloseAction.caFree;
  696. end;
  697. procedure TfmDocument.mmoEditChangeTracking(Sender: TObject);
  698. var
  699. LJValue: TJsonValue;
  700. treeItem: TJSONTreeViewItem;
  701. begin
  702. treeItem := TJSONTreeViewItem(tvJson.Selected);
  703. if FIsUpdating or (treeItem = nil) then
  704. Exit;
  705. LJValue := nil;
  706. SetErrInfo('');
  707. FIsUpdating := True;
  708. try
  709. try
  710. if FCurrentJSONKind = jkString then
  711. begin
  712. LJValue := TJSONString.Create(mmoEdit.Text);
  713. end
  714. else
  715. begin
  716. LJValue := TJsonValue.ParseJSONValue(mmoEdit.Text, True, True);
  717. if LJValue.JsonKind <> FCurrentJSONKind then
  718. begin
  719. FreeAndNil(LJValue);
  720. end;
  721. end;
  722. except
  723. on E: Exception do
  724. SetErrInfo(E.Message);
  725. end;
  726. if LJValue <> nil then
  727. begin
  728. if treeItem.JsonValue.ToString = LJValue.ToString then
  729. begin
  730. FreeAndNil(LJValue);
  731. end
  732. else
  733. begin
  734. treeItem.BeginUpdate;
  735. treeItem.ClearItem;
  736. treeItem.JsonValue := LJValue;
  737. if treeItem.ParentItem = nil then
  738. begin
  739. FDoc.JsonRoot := LJValue;
  740. end;
  741. treeItem.ReText;
  742. SetTreeItems(treeItem, LJValue);
  743. treeItem.EndUpdate;
  744. end;
  745. end;
  746. finally
  747. FIsUpdating := False;
  748. end;
  749. end;
  750. procedure TfmDocument.mmoEditViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
  751. begin
  752. lblLineAndPos.Text := (mmoEdit.CaretPosition.Line + 1).ToString + ': ' + (mmoEdit.CaretPosition.Pos + 1).ToString;
  753. end;
  754. procedure TfmDocument.pmTreeViewItemPopup(Sender: TObject);
  755. var
  756. selItem: TJSONTreeViewItem;
  757. begin
  758. selItem := TJSONTreeViewItem(tvJson.Selected);
  759. if selItem = nil then
  760. begin
  761. for var i := 0 to pmTreeViewItem.ItemsCount - 1 do
  762. pmTreeViewItem.Items[i].Enabled := False;
  763. Exit;
  764. end;
  765. fmMain.actEditMoveUp.Enabled := selItem.Index <> 0;
  766. fmMain.actEditMoveDown.Enabled := (selItem.ParentItem <> nil) and (selItem.Index < selItem.ParentItem.Count - 1);
  767. end;
  768. procedure TfmDocument.rbTrueFalseChange(Sender: TObject);
  769. var
  770. treeItem: TJSONTreeViewItem;
  771. begin
  772. treeItem := TJSONTreeViewItem(tvJson.Selected);
  773. if FIsUpdating or (treeItem = nil) then
  774. Exit;
  775. mmoEdit.Text := rbTrue.IsChecked.ToString(TUseBoolStrs.True).ToLower;
  776. end;
  777. procedure TfmDocument.rctBtnAddItemMouseDown(Sender: TObject;
  778. Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  779. var
  780. newItem, selItem, parItem: TJSONTreeViewItem;
  781. LIndex: Integer;
  782. begin
  783. if tvJson.Selected = nil then
  784. Exit;
  785. if tvJson.Selected.ParentItem = nil then
  786. Exit;
  787. selItem := TJSONTreeViewItem(tvJson.Selected);
  788. parItem := selItem.MyParentItem;
  789. LIndex := selItem.Index;
  790. newItem := TJSONTreeViewItem.Create(nil);
  791. if parItem.JsonValue is TJSONObject then
  792. begin
  793. newItem.JsonData := TJSONPair.Create('newItem', 'new value');
  794. end
  795. else
  796. begin
  797. newItem.JsonData := TJSONString.Create('newItem');
  798. end;
  799. parItem.InsertItem(LIndex + 1, newItem, True);
  800. newItem.Select;
  801. end;
  802. procedure TfmDocument.rctBtnAddSubItemMouseDown(Sender: TObject;
  803. Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  804. var
  805. newItem, selItem: TJSONTreeViewItem;
  806. begin
  807. if tvJson.Selected = nil then
  808. Exit;
  809. selItem := TJSONTreeViewItem(tvJson.Selected);
  810. if not selItem.JsonValue.IsObjectOrArray then
  811. Exit;
  812. newItem := TJSONTreeViewItem.Create(nil);
  813. if selItem.JsonValue is TJSONObject then
  814. begin
  815. newItem.JsonData := TJSONPair.Create('newItem', 'new value');
  816. end
  817. else
  818. begin
  819. newItem.JsonData := TJSONString.Create('newItem');
  820. end;
  821. selItem.AddItem(newItem, True);
  822. newItem.Select;
  823. end;
  824. procedure TfmDocument.rctBtnCloseClick(Sender: TObject);
  825. begin
  826. Close;
  827. end;
  828. procedure TfmDocument.rctBtnCollapseAllMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  829. begin
  830. if tvJson.Selected <> nil then
  831. tvJson.Selected.CollapseAll
  832. else
  833. tvJson.CollapseAll;
  834. end;
  835. procedure TfmDocument.rctBtnDeleteClick(Sender: TObject);
  836. var
  837. selItem: TJSONTreeViewItem;
  838. parItem: TJSONTreeViewItem;
  839. LIndex: Integer;
  840. begin
  841. if tvJson.Selected = nil then
  842. Exit;
  843. if tvJson.Selected.ParentItem = nil then
  844. Exit;
  845. TDialogService.MessageDialog('Confirm deletion of this item?', TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], TMsgDlgBtn.mbNo, 0,
  846. procedure(const AResult: TModalResult)
  847. begin
  848. if AResult = mrYes then
  849. begin
  850. selItem := TJSONTreeViewItem(tvJson.Selected);
  851. LIndex := selItem.Index;
  852. parItem := selItem.ExtractFromParent(True);
  853. selItem.JsonData.Free;
  854. selItem.Free;
  855. if LIndex < parItem.Count then
  856. parItem.Items[LIndex].Select
  857. else if parItem.Count > 0 then
  858. parItem.Items[parItem.Count - 1].Select
  859. else
  860. parItem.Select;
  861. end;
  862. end);
  863. end;
  864. procedure TfmDocument.rctBtnExpandAllMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  865. begin
  866. if tvJson.Selected <> nil then
  867. begin
  868. if tvJson.Selected.ParentItem <> nil then
  869. begin
  870. tvJson.Selected.ExpandAll;
  871. end
  872. else
  873. begin
  874. tvJson.ExpandAll;
  875. end;
  876. end
  877. else
  878. begin
  879. tvJson.ExpandAll;
  880. end;
  881. end;
  882. procedure TfmDocument.rctBtnMaxClick(Sender: TObject);
  883. begin
  884. {$IFDEF MSWINDOWS}
  885. if WindowState = TWindowState.wsMaximized then
  886. begin
  887. WindowState := TWindowState.wsNormal;
  888. end
  889. else
  890. begin
  891. WindowState := TWindowState.wsMaximized;
  892. end;
  893. {$ENDIF}
  894. end;
  895. procedure TfmDocument.rctBtnMinClick(Sender: TObject);
  896. begin
  897. fmMain.OnActivate := nil;
  898. try
  899. Hide;
  900. if g_pub.DocumentWindowList.NumOfVisible <= 0 then
  901. begin
  902. fmMain.WindowState := TWindowState.wsMinimized;
  903. fmMain.Deactivate;
  904. end;
  905. finally
  906. fmMain.OnActivate := fmMain.FormActivate;
  907. end;
  908. end;
  909. procedure TfmDocument.rctBtnMoveDownMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  910. begin
  911. fmMain.actEditMoveDownExecute(Sender);
  912. end;
  913. procedure TfmDocument.rctBtnMoveUpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  914. begin
  915. fmMain.actEditMoveUpExecute(Sender);
  916. end;
  917. procedure TfmDocument.miFileOpenRecentApplyStyleLookup(Sender: TObject);
  918. begin
  919. {$IFDEF MSWINDOWS}
  920. if TThread.GetTickCount - miFileOpenRecent.Tag > 2000 then // 防止多次触发
  921. begin
  922. InitRecentFile;
  923. miFileOpenRecent.Tag := TThread.GetTickCount;
  924. end;
  925. {$ENDIF}
  926. end;
  927. procedure TfmDocument.miFileOepnedClick(Sender: TObject);
  928. begin
  929. if TMenuItem(Sender).TagObject <> nil then
  930. begin
  931. TfmDocument(TMenuItem(Sender).TagObject).Show;
  932. //TfmDocument(TMenuItem(Sender).TagObject).Activate;
  933. //TfmDocument(TMenuItem(Sender).TagObject).BringToFront;
  934. end;
  935. end;
  936. procedure TfmDocument.miRecentFilesClick(Sender: TObject);
  937. var
  938. LFilename: string;
  939. LDocWin: TDocumentWindow;
  940. begin
  941. if TMenuItem(Sender).Tag = -100 then
  942. begin
  943. g_pub.Config['recent'] := nil;
  944. end
  945. else
  946. begin
  947. LFilename := TMenuItem(Sender).Text;
  948. LDocWin := g_pub.DocumentWindowList.GetWindowByFilename(LFilename);
  949. if LDocWin <> nil then
  950. LDocWin.Show
  951. else
  952. OpenFile(LFilename);
  953. end;
  954. end;
  955. procedure TfmDocument.miWindowShowAllApplyStyleLookup(Sender: TObject);
  956. begin
  957. {$IFDEF MSWINDOWS}
  958. if TThread.GetTickCount - miWindowItems.Tag > 2000 then // 防止多次触发
  959. begin
  960. InitOpenedFileMenu;
  961. miWindowItems.Tag := TThread.GetTickCount;
  962. end;
  963. {$ENDIF}
  964. end;
  965. procedure TfmDocument.rctIndentClick(Sender: TObject);
  966. begin
  967. FIsUpdating := True;
  968. try
  969. case Indent of
  970. 0:
  971. Indent := 2;
  972. 2:
  973. Indent := 4;
  974. 4:
  975. Indent := 0;
  976. end;
  977. //Indent := IfThen(Indent = 2, 4, 2);
  978. finally
  979. FIsUpdating := False;
  980. end;
  981. end;
  982. procedure TfmDocument.JsonFileDragDrop(Sender: TObject;
  983. const
  984. Data:
  985. TDragObject;
  986. const
  987. Point:
  988. TPointF);
  989. begin
  990. if Length(Data.Files) = 1 then
  991. begin
  992. OpenFile(Data.Files[0]);
  993. end;
  994. end;
  995. procedure TfmDocument.JsonFileDragOver(Sender: TObject;
  996. const
  997. Data:
  998. TDragObject;
  999. const
  1000. Point:
  1001. TPointF;
  1002. var
  1003. Operation: TDragOperation);
  1004. begin
  1005. if Length(Data.Files) = 1 then
  1006. Operation := TDragOperation.Link;
  1007. end;
  1008. procedure TfmDocument.rctWordWarpClick(Sender: TObject);
  1009. begin
  1010. WordWarp := not WordWarp;
  1011. end;
  1012. procedure TfmDocument.slL_RMouseUp(Sender: TObject;
  1013. Button: TMouseButton;
  1014. Shift: TShiftState;
  1015. X, Y: Single);
  1016. begin
  1017. FRightPanelWidthPercent := rctRight.Width / (pnlSizeBorder.Width - 10);
  1018. end;
  1019. procedure TfmDocument.SetIndent(AValue: Integer);
  1020. begin
  1021. if FIndent = AValue then
  1022. Exit;
  1023. FIndent := AValue;
  1024. lblIndent.Text := AValue.ToString;
  1025. if tvJson.Selected <> nil then
  1026. begin
  1027. if TJSONTreeViewItem(tvJson.Selected).JsonValue.IsObjectOrArray then
  1028. begin
  1029. if FIndent > 0 then
  1030. begin
  1031. mmoEdit.Text := TJSONTreeViewItem(tvJson.Selected).JsonValue.Format(FIndent);
  1032. end
  1033. else
  1034. begin
  1035. mmoEdit.Text := TJSONTreeViewItem(tvJson.Selected).JsonValue.ToString;
  1036. end;
  1037. end;
  1038. end;
  1039. end;
  1040. function TfmDocument.GetWordWarp: Boolean;
  1041. begin
  1042. Result := mmoEdit.TextSettings.WordWrap;
  1043. end;
  1044. procedure TfmDocument.SetWordWarp(AValue: Boolean);
  1045. begin
  1046. if mmoEdit.TextSettings.WordWrap = AValue then
  1047. Exit;
  1048. FIsUpdating := True;
  1049. try
  1050. mmoEdit.TextSettings.WordWrap := AValue;
  1051. pathWordWrap.Fill.Color := IfThen(mmoEdit.TextSettings.WordWrap, $FF00FF00, $FF808080);
  1052. finally
  1053. FIsUpdating := False;
  1054. end;
  1055. end;
  1056. procedure TfmDocument.InitOpenedFileMenu;
  1057. var
  1058. miTmp: TMenuItem;
  1059. begin
  1060. miWindowItems.Clear;
  1061. for var item in g_pub.DocumentWindowList do
  1062. begin
  1063. miTmp := TMenuItem.Create(miWindowItems);
  1064. miTmp.TagObject := item;
  1065. miTmp.Text := item.lblFilename.Text;
  1066. miTmp.OnClick := miFileOepnedClick;
  1067. miWindowItems.AddObject(miTmp);
  1068. miTmp.Enabled := self <> item;
  1069. end;
  1070. end;
  1071. procedure TfmDocument.InitRecentFile;
  1072. var
  1073. miTmp: TMenuItem;
  1074. begin
  1075. miFileOpenRecent.Clear;
  1076. for var item in g_pub.Config['recent'] do
  1077. begin
  1078. miTmp := TMenuItem.Create(miFileOpenRecent);
  1079. miTmp.Text := item;
  1080. miTmp.OnClick := miRecentFilesClick;
  1081. miFileOpenRecent.AddObject(miTmp);
  1082. miTmp.Enabled := (miTmp.Text <> FDoc.FileName) and FileExists(miTmp.Text);
  1083. end;
  1084. if miFileOpenRecent.ItemsCount > 0 then
  1085. begin
  1086. miTmp := TMenuItem.Create(miFileOpenRecent);
  1087. miTmp.Text := '-';
  1088. miFileOpenRecent.AddObject(miTmp);
  1089. miTmp := TMenuItem.Create(miFileOpenRecent);
  1090. //miTmp.Text := 'Clear';
  1091. //miTmp.Tag := -100;
  1092. miTmp.Action := fmMain.actFileClearRecent;
  1093. //miTmp.OnClick := miRecentFilesClick;
  1094. miFileOpenRecent.AddObject(miTmp);
  1095. end
  1096. else
  1097. begin
  1098. miTmp := TMenuItem.Create(miFileOpenRecent);
  1099. miTmp.Text := 'No file!';
  1100. miTmp.Enabled := False;
  1101. miFileOpenRecent.AddObject(miTmp);
  1102. end;
  1103. end;
  1104. procedure TfmDocument.ShowInfo(AText: string; ALevel: Integer = 0; ADelay: Single = 3.0);
  1105. begin
  1106. aniMsg.Stop;
  1107. txtMsg.Text := AText;
  1108. case ALevel of
  1109. 0:
  1110. txtMsg.TextSettings.FontColor := IfThen(fmMain.actViewDarkStyle.Checked, $FFFFFFFF, $FF000000);
  1111. 1:
  1112. txtMsg.TextSettings.FontColor := $FFFF0000;
  1113. end;
  1114. txtMsg.Opacity := 1.0;
  1115. aniMsg.Delay := ADelay;
  1116. aniMsg.Start;
  1117. end;
  1118. initialization
  1119. end.