namedindexselection.pas 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. unit namedindexselection;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  6. ButtonPanel, database, fpjson;
  7. type
  8. TNamedIndexSelectionType = (nistSwitch, nistVariable);
  9. { TNamedIndexSelectionForm }
  10. TNamedIndexSelectionForm = class(TForm)
  11. ResultButtonPanel: TButtonPanel;
  12. NameEdit: TEdit;
  13. IndexListBox: TListBox;
  14. NameGroupBox: TGroupBox;
  15. IndexSelectorGroupBox: TGroupBox;
  16. PageListBox: TListBox;
  17. SwitchSelectorPanel: TPanel;
  18. SetMaximumButton: TButton;
  19. PageGroupBox: TGroupBox;
  20. HeaderLabel: TLabel;
  21. PageSelectorPanel: TPanel;
  22. SetMaximumPanel: TPanel;
  23. procedure IndexListBoxSelectionChange(Sender: TObject; User: boolean);
  24. procedure NameEditChange(Sender: TObject);
  25. procedure ResultPanelButtonClick(Sender: TObject);
  26. procedure PageListBoxClick(Sender: TObject);
  27. procedure SetMaximumButtonClick(Sender: TObject);
  28. private
  29. Db: TDatabase;
  30. EditedArr: TJSONArray;
  31. SelectionType: TNamedIndexSelectionType;
  32. procedure FillPages(NumItems: Integer);
  33. { Page indexes are 0-based }
  34. procedure FillItems(PageIndex: Integer; NumItems: Integer);
  35. function FormatSwitchName(Id: Integer): String;
  36. { These functions don't change DB arrays}
  37. function ShowSwitchSelection(ADb: TDatabase): Boolean;
  38. function ShowVariableSelection(ADb: TDatabase): Boolean;
  39. public
  40. SelectedSwitch: Integer;
  41. SelectedVariable: Integer;
  42. { These functions change DB arrays }
  43. function SelectSwitch(OriginalId: Integer; ADb: TDatabase): Integer;
  44. function SelectVariable(OriginalId: Integer; ADb: TDatabase): Integer;
  45. function GetIndexPage(Id: Integer): Integer;
  46. function GetItemInPage(Id: Integer): Integer;
  47. function GetSelectedId: Integer;
  48. end;
  49. resourcestring
  50. SwitchesHeader = 'Switches';
  51. VariablesHeader = 'Variables';
  52. SwitchSelectorHeading = 'Switch';
  53. VariableSelectorHeading = 'Variable';
  54. const
  55. ITEMS_PER_PAGE = 20;
  56. var
  57. NamedIndexSelectionForm: TNamedIndexSelectionForm;
  58. implementation
  59. uses
  60. Math, setmaximumformunit;
  61. {$R *.lfm}
  62. { TNamedIndexSelectionForm }
  63. procedure TNamedIndexSelectionForm.PageListBoxClick(Sender: TObject);
  64. begin
  65. FillItems(PageListBox.ItemIndex, EditedArr.Count -1);
  66. end;
  67. procedure TNamedIndexSelectionForm.SetMaximumButtonClick(Sender: TObject);
  68. var
  69. NewMaximum, I: Integer;
  70. begin
  71. NewMaximum := SetMaximumForm.RequestValue(EditedArr.Count -1, 9999);
  72. if NewMaximum = EditedArr.Count -1 then
  73. Exit;
  74. if NewMaximum < EditedArr.Count -1 then
  75. for I := EditedArr.Count -1 downto NewMaximum -1 do
  76. EditedArr.Delete(I);
  77. if NewMaximum > EditedArr.Count -1 then
  78. for I := EditedArr.Count -1 to NewMaximum -1 do
  79. EditedArr.Add('');
  80. FillPages(EditedArr.Count -1);
  81. FillItems(PageListBox.ItemIndex, EditedArr.Count -1);
  82. end;
  83. procedure TNamedIndexSelectionForm.IndexListBoxSelectionChange(Sender: TObject;
  84. User: boolean);
  85. begin
  86. NameEdit.Text := EditedArr.Strings[GetSelectedId];
  87. end;
  88. procedure TNamedIndexSelectionForm.NameEditChange(Sender: TObject);
  89. var
  90. SelectedId: Integer;
  91. begin
  92. SelectedId := GetSelectedId;
  93. if (SelectedId >= 1) and (SelectedId < EditedArr.Count) then
  94. EditedArr.Strings[SelectedId] := NameEdit.Text;
  95. IndexListBox.Items[IndexListBox.ItemIndex] := FormatSwitchName(SelectedId);
  96. end;
  97. procedure TNamedIndexSelectionForm.ResultPanelButtonClick(Sender: TObject);
  98. begin
  99. ModalResult := (Sender as TPanelBitBtn).ModalResult;
  100. if ModalResult = mrOK then begin
  101. if SelectionType = nistSwitch then
  102. SelectedSwitch := GetSelectedId
  103. else if SelectionType = nistVariable then
  104. SelectedVariable := GetSelectedId
  105. end
  106. end;
  107. procedure TNamedIndexSelectionForm.FillPages(NumItems: Integer);
  108. var
  109. I, NumPages: Integer;
  110. StartVal, EndVal: Integer;
  111. SavedItemIndex: Integer;
  112. begin
  113. NumPages := Ceil((NumItems - 1) / ITEMS_PER_PAGE);
  114. PageListBox.Items.BeginUpdate;
  115. SavedItemIndex := PageListBox.ItemIndex;
  116. PageListBox.ClearSelection;
  117. PageListBox.Items.Clear;
  118. for I := 0 to NumPages - 1 do begin
  119. StartVal := I * ITEMS_PER_PAGE + 1;
  120. if I <> NumPages - 1 then
  121. EndVal := (I+1) * ITEMS_PER_PAGE
  122. else
  123. EndVal := NumItems;
  124. PageListBox.Items.Add('%0.4d - %0.4d'.Format([StartVal, EndVal]));
  125. end;
  126. PageListBox.Items.EndUpdate;
  127. IndexListBox.ItemIndex := Min(SavedItemIndex, PageListBox.Count - 1);
  128. end;
  129. procedure TNamedIndexSelectionForm.FillItems(PageIndex: Integer;
  130. NumItems: Integer);
  131. var
  132. I: Integer;
  133. StartItem, EndItem: Integer;
  134. SavedItemIndex: Integer;
  135. begin
  136. StartItem := PageIndex * ITEMS_PER_PAGE + 1;
  137. EndItem := Min(NumItems, (PageIndex + 1) * ITEMS_PER_PAGE);
  138. IndexListBox.Items.BeginUpdate;
  139. SavedItemIndex := IndexListBox.ItemIndex;
  140. IndexListBox.ClearSelection;
  141. IndexListBox.Items.Clear;
  142. for I := StartItem to EndItem do begin
  143. if SelectionType = nistSwitch then
  144. IndexListBox.Items.Add(FormatSwitchName(I))
  145. else
  146. IndexListBox.Items.Add(FormatSwitchName(I))
  147. end;
  148. IndexListBox.Items.EndUpdate;
  149. IndexListBox.ItemIndex := Min(SavedItemIndex, IndexListBox.Count - 1);
  150. end;
  151. function TNamedIndexSelectionForm.FormatSwitchName(Id: Integer): String;
  152. begin
  153. FormatSwitchName := '%0.4d %s'.Format([Id, EditedArr.Strings[Id]]);
  154. end;
  155. function TNamedIndexSelectionForm.ShowSwitchSelection(ADb: TDatabase): Boolean;
  156. begin
  157. Db := ADb;
  158. SelectionType := nistSwitch;
  159. HeaderLabel.Caption := SwitchesHeader;
  160. IndexSelectorGroupBox.Caption := SwitchSelectorHeading;
  161. EditedArr := Db.System.Arrays['switches'].Clone as TJSONArray;
  162. Caption := SwitchesHeader;
  163. FillPages(EditedArr.Count -1);
  164. PageListBox.ItemIndex := GetIndexPage(SelectedSwitch);
  165. FillItems(PageListBox.ItemIndex, EditedArr.Count -1);
  166. IndexListBox.ItemIndex := GetItemInPage(SelectedSwitch);
  167. ShowModal;
  168. ShowSwitchSelection := ModalResult = mrOK;
  169. if ShowSwitchSelection then
  170. SelectedSwitch := GetSelectedId;
  171. end;
  172. function TNamedIndexSelectionForm.ShowVariableSelection(ADb: TDatabase
  173. ): Boolean;
  174. begin
  175. Db := ADb;
  176. SelectionType := nistVariable;
  177. HeaderLabel.Caption := VariablesHeader;
  178. IndexSelectorGroupBox.Caption := VariableSelectorHeading;
  179. EditedArr := Db.System.Arrays['variables'].Clone as TJSONArray;
  180. Caption := VariablesHeader;
  181. FillPages(EditedArr.Count -1);
  182. PageListBox.ItemIndex := GetIndexPage(SelectedVariable);
  183. FillItems(PageListBox.ItemIndex, EditedArr.Count -1);
  184. IndexListBox.ItemIndex := GetItemInPage(SelectedVariable);
  185. ShowModal;
  186. ShowVariableSelection := ModalResult = mrOK;
  187. if ShowVariableSelection then
  188. SelectedVariable := GetSelectedId;
  189. end;
  190. function TNamedIndexSelectionForm.SelectSwitch(OriginalId: Integer;
  191. ADb: TDatabase): Integer;
  192. begin
  193. if ShowSwitchSelection(ADb) then begin
  194. SelectSwitch := SelectedSwitch;
  195. Db.System.Arrays['switches'] := EditedArr;
  196. end else begin
  197. SelectSwitch := OriginalId;
  198. EditedArr.Free;
  199. EditedArr := nil
  200. end;
  201. end;
  202. function TNamedIndexSelectionForm.SelectVariable(OriginalId: Integer;
  203. ADb: TDatabase): Integer;
  204. begin
  205. if ShowVariableSelection(ADb) then begin
  206. SelectVariable := SelectedVariable;
  207. Db.System.Arrays['variables'] := EditedArr;
  208. end else begin
  209. SelectVariable := OriginalId;
  210. EditedArr.Free;
  211. EditedArr := nil
  212. end;
  213. end;
  214. function TNamedIndexSelectionForm.GetIndexPage(Id: Integer): Integer;
  215. var
  216. PageIndex: Integer;
  217. begin
  218. PageIndex := ((Id - 1) div ITEMS_PER_PAGE);
  219. GetIndexPage := Max(0, PageIndex);
  220. end;
  221. function TNamedIndexSelectionForm.GetItemInPage(Id: Integer): Integer;
  222. begin
  223. GetItemInPage := (Id - 1) mod 20;
  224. end;
  225. function TNamedIndexSelectionForm.GetSelectedId: Integer;
  226. var
  227. PageOffset: Integer;
  228. begin
  229. PageOffset := PageListBox.ItemIndex * ITEMS_PER_PAGE + 1;
  230. GetSelectedId := Max(1, PageOffset + IndexListBox.ItemIndex);
  231. end;
  232. end.