Subversion Repositories oidplus

Rev

Rev 234 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit Main;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms,
  7.   Dialogs, StdCtrls, IniFiles, Grids, Outline, ExtCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Outline1: TOutline;
  12.     Notebook1: TNotebook;
  13.     Memo1: TMemo;
  14.     Label2: TLabel;
  15.     Label8: TLabel;
  16.     Label9: TLabel;
  17.     Label10: TLabel;
  18.     Label11: TLabel;
  19.     Label12: TLabel;
  20.     Button8: TButton;
  21.     Edit9: TEdit;
  22.     Edit10: TEdit;
  23.     Edit11: TEdit;
  24.     Edit12: TEdit;
  25.     Edit13: TEdit;
  26.     Button9: TButton;
  27.     Edit14: TEdit;
  28.     Label13: TLabel;
  29.     Button5: TButton;
  30.     Edit2: TEdit;
  31.     Label14: TLabel;
  32.     Edit8: TEdit;
  33.     Button7: TButton;
  34.     Panel1: TPanel;
  35.     Label1: TLabel;
  36.     Label3: TLabel;
  37.     Label4: TLabel;
  38.     Label5: TLabel;
  39.     Label6: TLabel;
  40.     Label7: TLabel;
  41.     Edit3: TEdit;
  42.     Edit4: TEdit;
  43.     CheckBox1: TCheckBox;
  44.     ComboBox1: TComboBox;
  45.     Edit5: TEdit;
  46.     Edit6: TEdit;
  47.     ListBox1: TListBox;
  48.     Edit7: TEdit;
  49.     Button1: TButton;
  50.     Button3: TButton;
  51.     Panel2: TPanel;
  52.     Button2: TButton;
  53.     Button4: TButton;
  54.     Edit1: TEdit;
  55.     Button6: TButton;
  56.     Label15: TLabel;
  57.     procedure Outline1Change(Sender: TObject; Node: integer);
  58.     procedure Button1Click(Sender: TObject);
  59.     procedure Button3Click(Sender: TObject);
  60.     procedure Button4Click(Sender: TObject);
  61.     procedure Button7Click(Sender: TObject);
  62.     procedure Button6Click(Sender: TObject);
  63.     procedure Button8Click(Sender: TObject);
  64.     procedure Button2Click(Sender: TObject);
  65.     procedure FormCreate(Sender: TObject);
  66.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  67.     procedure CheckBox1Click(Sender: TObject);
  68.     procedure Button9Click(Sender: TObject);
  69.     procedure Edit8KeyPress(Sender: TObject; var Key: Char);
  70.     procedure Edit11Change(Sender: TObject);
  71.     procedure ListBox1KeyDown(Sender: TObject; var Key: Word;
  72.       Shift: TShiftState);
  73.     procedure Edit7KeyPress(Sender: TObject; var Key: Char);
  74.     procedure Edit2KeyPress(Sender: TObject; var Key: Char);
  75.     procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  76.     procedure Outline1KeyDown(Sender: TObject; var Key: Word;
  77.       Shift: TShiftState);
  78.     procedure Outline1Click(Sender: TObject);
  79.     procedure FormShow(Sender: TObject);
  80.   private
  81.     procedure ShowOID(oid: string; ini: TIniFile; nod: integer);
  82.     procedure ShowRA(ini: TIniFile; nod: integer);
  83.     function DBPath: string;
  84.     function GetAsn1Ids(onlyfirst: boolean): string;
  85.     procedure SaveChangesIfRequired;
  86.     procedure ShowError(msg: string);
  87.   end;
  88.  
  89. var
  90.   Form1: TForm1;
  91.  
  92. implementation
  93.  
  94. {$R *.DFM}
  95.  
  96. uses
  97.   SortStr;
  98.  
  99. const
  100.   TITLE_OID = 'Object Identifiers';
  101.   TITLE_RA = 'Registration Authorities';
  102.  
  103. procedure Split(Delimiter: string; Str: string; ListOfStrings: TStrings) ;
  104. var
  105.   p: integer;
  106. begin
  107.   ListOfStrings.Clear;
  108.   p := Pos(Delimiter, Str);
  109.   while p > 0 do
  110.   begin
  111.     ListOfStrings.Add(Copy(Str, 1, p-1));
  112.     Delete(Str, 1, p);
  113.     p := Pos(Delimiter, Str);
  114.   end;
  115.   if Str <> '' then ListOfStrings.Add(Str);
  116. end;
  117.  
  118. procedure ExpandNodeAndParents(nod: TOutlineNode);
  119. begin
  120.   if nod.Parent <> nil then ExpandNodeAndParents(nod.Parent);
  121.   nod.Expand;
  122. end;
  123.  
  124. { Source: Delphi 4 }
  125. function Trim(const S: string): string;
  126. var
  127.   I, L: Integer;
  128. begin
  129.   L := Length(S);
  130.   I := 1;
  131.   while (I <= L) and (S[I] <= ' ') do Inc(I);
  132.   if I > L then Result := '' else
  133.   begin
  134.     while S[L] <= ' ' do Dec(L);
  135.     Result := Copy(S, I, L - I + 1);
  136.   end;
  137. end;
  138.  
  139. type
  140.   TWorkItem = class(TObject)
  141.   public
  142.     sectionName: string;
  143.     ini: TIniFile;
  144.     nod: integer;
  145.   end;
  146.  
  147. procedure TForm1.ShowOID(oid: string; ini: TIniFile; nod: integer);
  148. var
  149.   i: integer;
  150.   sectionName: string;
  151.   asn1ids: string;
  152.   l: TList;
  153.   sl: TStringList;
  154.   workItem: TWorkItem;
  155. begin
  156.   l := TList.Create;
  157.   sl := TStringList.Create;
  158.  
  159.   workItem := TWorkItem.Create;
  160.   workItem.sectionName := oid;
  161.   workItem.ini := ini;
  162.   workItem.nod := nod;
  163.   l.Add(workItem);
  164.  
  165.   while l.Count > 0 do
  166.   begin
  167.     workItem := l.Items[l.Count-1];
  168.     oid := workItem.sectionName;
  169.     ini := workItem.ini;
  170.     nod := workItem.nod;
  171.     workItem.Free;
  172.     l.Delete(l.Count-1);
  173.  
  174.     if oid = 'OID:' then
  175.     begin
  176.       nod := Outline1.AddChild(nod, TITLE_OID);
  177.     end
  178.     else
  179.     begin
  180.       asn1ids := ini.ReadString(oid, 'asn1id', '');
  181.       if ini.ReadBool(oid, 'draft', false) then
  182.         nod := Outline1.AddChild(nod, Trim(oid+' '+Copy(asn1ids,1,Pos(',',asn1ids+',')-1))+' [DRAFT]')
  183.       else
  184.         nod := Outline1.AddChild(nod, Trim(oid+' '+Copy(asn1ids,1,Pos(',',asn1ids+',')-1)));
  185.     end;
  186.     sl.Clear;
  187.     for i := ini.ReadInteger(oid, 'delegates', 0) downto 1 do
  188.     begin
  189.       sectionName := ini.ReadString(oid, 'delegate'+IntToStr(i), '');
  190.       if sectionName = '' then continue;
  191.       sl.Add(sectionName);
  192.     end;
  193.     SortSL(sl);
  194.     for i := sl.Count-1 downto 0 do
  195.     begin
  196.       sectionName := sl.Strings[i];
  197.  
  198.       workItem := TWorkItem.Create;
  199.       workItem.sectionName := sectionName;
  200.       workItem.ini := ini;
  201.       workItem.nod := nod;
  202.       l.Add(workItem);
  203.     end;
  204.     if (oid = 'OID:') or (sl.Count < 125) then
  205.       ExpandNodeAndParents(Outline1.Items[nod]);
  206.   end;
  207.  
  208.   sl.Free;
  209.   l.Free;
  210. end;
  211.  
  212. procedure TForm1.ShowRA(ini: TIniFile; nod: integer);
  213. var
  214.   i: integer;
  215.   sectionName, personname: string;
  216.   sl: TStringList;
  217. begin
  218.   nod := Outline1.AddChild(nod, TITLE_RA);
  219.   sl := TStringList.Create;
  220.   for i := 1 to ini.ReadInteger('RA:', 'count', 0) do
  221.   begin
  222.     sectionName := ini.ReadString('RA:', 'ra'+IntToStr(i), '');
  223.     if sectionName = '' then continue;
  224.     personname := ini.ReadString(sectionName, 'name', '');
  225.     sl.Add(Trim(sectionName + ' ' + personname));
  226.   end;
  227.   SortSL(sl);
  228.   for i := 0 to sl.Count-1 do
  229.   begin
  230.     sectionName := sl.Strings[i];
  231.     Outline1.AddChild(nod, sectionName);
  232.     ComboBox1.Items.Add(Copy(sectionName,1,Pos(' ',sectionName+' ')-1));
  233.   end;
  234.   sl.Free;
  235.   ExpandNodeAndParents(Outline1.Items[nod]);
  236. end;
  237.  
  238. procedure TForm1.Outline1Change(Sender: TObject; Node: integer);
  239. var
  240.   ini: TIniFile;
  241.   txtFile: string;
  242. begin
  243.   SaveChangesIfRequired;
  244.  
  245.   if Copy(Outline1.Items[Outline1.SelectedItem].Text, 1, 4) = 'OID:' then
  246.   begin
  247.     Notebook1.PageIndex := 0;
  248.     ini := TIniFile.Create(DBPath+'OID.INI');
  249.     try
  250.       Edit4.Text := Copy(Outline1.Items[Outline1.SelectedItem].Text, 1,
  251.                          Pos(' ',Outline1.Items[Outline1.SelectedItem].Text+' ')-1);
  252.       ListBox1.Items.Clear;
  253.       Split(',', ini.ReadString(Edit4.Text, 'asn1id', ''), ListBox1.Items);
  254.       Edit3.Text := ini.ReadString(Edit4.Text, 'description', '');
  255.       CheckBox1.Checked := ini.ReadBool(Edit4.Text, 'draft', false);
  256.       txtFile := DBPath+ini.ReadString(Edit4.Text, 'information', '');
  257.       if FileExists(txtFile) then
  258.         Memo1.Lines.LoadFromFile(txtFile)
  259.       else
  260.         Memo1.Lines.Clear;
  261.       Memo1.Modified := false;
  262.       ComboBox1.ItemIndex := ComboBox1.Items.IndexOf(ini.ReadString(Edit4.Text, 'ra', ''));
  263.       Edit5.Text := ini.ReadString(Edit4.Text, 'createdate', '');
  264.       Edit6.Text := ini.ReadString(Edit4.Text, 'updatedate', '');
  265.       Edit7.Text := '';
  266.     finally
  267.       ini.Free;
  268.     end;
  269.     Edit1.Text := '';
  270.   end;
  271.   if Copy(Outline1.Items[Outline1.SelectedItem].Text, 1, 3) = 'RA:' then
  272.   begin
  273.     Notebook1.PageIndex := 1;
  274.     ini := TIniFile.Create(DBPath+'RA.INI');
  275.     try
  276.       Edit9.Text := Copy(Outline1.Items[Outline1.SelectedItem].Text, 1,
  277.                          Pos(' ',Outline1.Items[Outline1.SelectedItem].Text+' ')-1);
  278.       Edit10.Text := ini.ReadString(Edit9.Text, 'createdate', '');
  279.       Edit11.Text := ini.ReadString(Edit9.Text, 'name', '');
  280.       Edit12.Text := ini.ReadString(Edit9.Text, 'email', '');
  281.       Edit13.Text := ini.ReadString(Edit9.Text, 'phone', '');
  282.       Edit14.Text := ini.ReadString(Edit9.Text, 'updatedate', '');
  283.     finally
  284.       ini.Free;
  285.     end;
  286.   end;
  287.   if Outline1.Items[Outline1.SelectedItem].Text = TITLE_OID then
  288.   begin
  289.     Notebook1.PageIndex := 2;
  290.     Edit2.Text := '';
  291.   end;
  292.   if Outline1.Items[Outline1.SelectedItem].Text = TITLE_RA then
  293.   begin
  294.     Notebook1.PageIndex := 3;
  295.     Edit8.Text := '';
  296.   end;
  297. end;
  298.  
  299. procedure TForm1.FormShow(Sender: TObject);
  300. var
  301.   nod, raroot: integer;
  302.   ini: TIniFile;
  303. begin
  304.   ComboBox1.Clear;
  305.   Outline1.Clear;
  306.   nod := 0;
  307.  
  308.   ini := TIniFile.Create(DBPath+'OID.INI');
  309.   try
  310.     ShowOID('OID:', ini, nod);
  311.   finally
  312.     ini.Free;
  313.   end;
  314.  
  315.   ini := TIniFile.Create(DBPath+'RA.INI');
  316.   try
  317.     ShowRa(ini, nod);
  318.   finally
  319.     ini.Free;
  320.   end;
  321.  
  322.   Outline1Click(Outline1);
  323. end;
  324.  
  325. function Asn1IdValid(asn1id: string): boolean;
  326. var
  327.   i: integer;
  328. begin
  329.   if asn1id = '' then
  330.   begin
  331.     result := false;
  332.     exit;
  333.   end;
  334.  
  335.   if not (asn1id[1] in ['a'..'z']) then
  336.   begin
  337.     result := false;
  338.     exit;
  339.   end;
  340.  
  341.   for i := 2 to Length(asn1id) do
  342.   begin
  343.     if not (asn1id[1] in ['a'..'z', 'A'..'Z', '0'..'9', '-']) then
  344.     begin
  345.       result := false;
  346.       exit;
  347.     end;
  348.   end;
  349.  
  350.   result := true;
  351. end;
  352.  
  353. procedure TForm1.Button1Click(Sender: TObject);
  354. var
  355.   asn1id: string;
  356.   i: integer;
  357. begin
  358.   asn1id := Edit7.Text;
  359.   if asn1id = '' then exit;
  360.   for i := 0 to ListBox1.Items.Count-1 do
  361.   begin
  362.     if ListBox1.Items.Strings[i] = asn1id then ShowError('Item already exists');
  363.   end;
  364.   if not Asn1IdValid(asn1id) then ShowError('Invalid alphanumeric identifier');
  365.   ListBox1.Items.Add(asn1id);
  366.   Outline1.Items[Outline1.SelectedItem].Text := Trim(Edit4.Text + ' ' + GetAsn1Ids(true));
  367.   Edit7.Text := '';
  368. end;
  369.  
  370. procedure TForm1.Button3Click(Sender: TObject);
  371. begin
  372.   if (ListBox1.Items.Count > 0) and ListBox1.Selected[ListBox1.ItemIndex] then
  373.   begin
  374.     ListBox1.Items.Delete(ListBox1.ItemIndex);
  375.   end;
  376.   Outline1.Items[Outline1.SelectedItem].Text := Trim(Edit4.Text + ' ' + GetAsn1Ids(true));
  377. end;
  378.  
  379. function IsPositiveNumber(str: string): boolean;
  380. var
  381.   i: integer;
  382. begin
  383.   if (str = '') then
  384.   begin
  385.     result := false;
  386.     exit;
  387.   end;
  388.  
  389.   result := true;
  390.   for i := 1 to Length(str) do
  391.   begin
  392.     if not (str[i] in ['0'..'9']) then
  393.     begin
  394.       result := false;
  395.       exit;
  396.     end;
  397.   end;
  398.  
  399.   if (str[1] = '0') and (str <> '0') then
  400.   begin
  401.     result := false;
  402.     exit;
  403.   end;
  404. end;
  405.  
  406. procedure TForm1.Button4Click(Sender: TObject);
  407. var
  408.   ini: TIniFile;
  409.   i, di: integer;
  410.   oid, parent_oid, new_value: string;
  411.   nod: integer;
  412.   candidate: string;
  413. begin
  414.   if Notebook1.PageIndex = 0 then new_value := Edit1.Text;
  415.   if Notebook1.PageIndex = 2 then new_value := Edit2.Text;
  416.  
  417.   new_value := Trim(new_value);
  418.   if new_value = '' then exit;
  419.  
  420.   if not IsPositiveNumber(new_value) then ShowError('Not a valid number');
  421.  
  422.   if Notebook1.PageIndex = 0 then
  423.   begin
  424.     oid := Edit4.Text + '.' + new_value;
  425.     parent_oid := Edit4.Text;
  426.   end
  427.   else
  428.   begin
  429.     oid := 'OID:' + new_value;
  430.     parent_oid := 'OID:';
  431.   end;
  432.  
  433.   if Outline1.Items[Outline1.SelectedItem].HasItems then
  434.   for i := Outline1.Items[Outline1.SelectedItem].GetFirstChild to Outline1.Items[Outline1.SelectedItem].GetLastChild do
  435.   begin
  436.     candidate := Copy(Trim(Outline1.Lines[i-1]), 1, Pos(' ',Trim(Outline1.Lines[i-1])+' ')-1);
  437.     if oid = candidate then ShowError('Item already exists');
  438.   end;
  439.  
  440.   if (parent_oid = 'OID:') and (StrToInt(new_value) > 2) then ShowError('Number must not exceed 2');
  441.   if (parent_oid = 'OID:0') and (StrToInt(new_value) > 39) then ShowError('Number must not exceed 39');
  442.   if (parent_oid = 'OID:1') and (StrToInt(new_value) > 39) then ShowError('Number must not exceed 39');
  443.  
  444.   ini := TIniFile.Create(DBPath+'OID.INI');
  445.   try
  446.     nod := Outline1.AddChild(Outline1.SelectedItem, oid);
  447.     ComboBox1.Text := ini.ReadString(parent_oid, 'ra', '');
  448.  
  449.     di := ini.ReadInteger(parent_oid, 'delegates', 0);
  450.     ini.WriteInteger(parent_oid, 'delegates', di+1);
  451.     ini.WriteString(parent_oid, 'delegate'+IntToStr(di+1), oid);
  452.  
  453.     ini.WriteString(oid, 'createdate', DateToStr(date));
  454.     ini.WriteString(oid, 'ra', ComboBox1.Text);
  455.  
  456.     if Notebook1.PageIndex = 0 then Edit1.Text := '';
  457.     if Notebook1.PageIndex = 2 then Edit2.Text := '';
  458.  
  459.     Outline1.SelectedItem := nod;
  460.  
  461.     { ini.UpdateFile; }
  462.   finally
  463.     ini.Free;
  464.   end;
  465.  
  466.   ShowMessage('Created: ' + oid);
  467. end;
  468.  
  469. procedure TForm1.Button7Click(Sender: TObject);
  470. var
  471.   ini: TIniFile;
  472.   di: integer;
  473.   nod: integer;
  474.   sectionName, new_value, candidate: string;
  475.   i: integer;
  476. begin
  477.   ini := TIniFile.Create(DBPath+'RA.INI');
  478.   try
  479.     new_value := Edit8.Text;
  480.     new_value := Trim(new_value);
  481.     if new_value = '' then exit;
  482.  
  483.     sectionName := 'RA:'+new_value;
  484.  
  485.     if Outline1.Items[Outline1.SelectedItem].HasItems then
  486.     for i := Outline1.Items[Outline1.SelectedItem].GetFirstChild to Outline1.Items[Outline1.SelectedItem].GetLastChild do
  487.     begin
  488.       candidate := Trim(Outline1.Lines[i-1]);
  489.       if sectionName = candidate then ShowError('Item already exists');
  490.     end;
  491.  
  492.     di := ini.ReadInteger('RA:', 'count', 0);
  493.     ini.WriteInteger('RA:', 'count', di+1);
  494.     ini.WriteString('RA:', 'ra'+IntToStr(di+1), sectionName);
  495.  
  496.     nod := Outline1.AddChild(Outline1.SelectedItem, sectionName);
  497.  
  498.     ini.WriteString(sectionName, 'createdate', DateToStr(date));
  499.  
  500.     Edit8.Text := '';
  501.  
  502.     Outline1.SelectedItem := nod;
  503.  
  504.     ini.WriteString(sectionName, 'createdate', DateToStr(date));
  505.  
  506.     { ini.UpdateFile; }
  507.   finally
  508.     ini.Free;
  509.   end;
  510.  
  511.   ComboBox1.Items.Add(sectionName);
  512.  
  513.   ShowMessage('Created: ' + sectionName);
  514. end;
  515.  
  516. procedure IniReadSections(ini: TIniFile; Strings: TStrings);
  517. const
  518.   BufSize = 16384;
  519. var
  520.   Buffer, P: PChar;
  521.   FFileName: string;
  522. begin
  523.   GetMem(Buffer, BufSize);
  524.   try
  525.     Strings.BeginUpdate;
  526.     try
  527.       Strings.Clear;
  528.       FFileName := ini.FileName;
  529.       if GetPrivateProfileString(nil, nil, nil, Buffer, BufSize,
  530.         @FFileName[1]) <> 0 then
  531.       begin
  532.         P := Buffer;
  533.         while P^ <> #0 do
  534.         begin
  535.           Strings.Add(StrPas(P));
  536.           Inc(P, StrLen(P) + 1);
  537.         end;
  538.       end;
  539.     finally
  540.       Strings.EndUpdate;
  541.     end;
  542.   finally
  543.     FreeMem(Buffer, BufSize);
  544.   end;
  545. end;
  546.  
  547. procedure TForm1.Button6Click(Sender: TObject);
  548. var
  549.   ini: TIniFile;
  550.   nod: TOutlineNode;
  551.   parent_oid, this_oid: string;
  552.   i: integer;
  553.   sl: TStringList;
  554. begin
  555.   if MessageDlg('Are you sure?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then exit;
  556.  
  557.   ini := TIniFile.Create(DBPath+'OID.INI');
  558.   try
  559.     this_oid := Edit4.Text;
  560.  
  561.     if Outline1.Items[Outline1.SelectedItem].Parent.Text = TITLE_OID then
  562.       parent_oid := 'OID:'
  563.     else
  564.       parent_oid := Copy(Outline1.Items[Outline1.SelectedItem].Parent.Text, 1,
  565.                          Pos(' ', Outline1.Items[Outline1.SelectedItem].Parent.Text+' ')-1);
  566.  
  567.     nod := Outline1.Items[Outline1.SelectedItem];
  568.     Outline1.SelectedItem := nod.Parent.Index;
  569.     Outline1.Delete(nod.Index);
  570.  
  571.     ini.EraseSection(this_oid);
  572.  
  573.     sl := TStringList.Create;
  574.     IniReadSections(ini, sl);
  575.     for i := 0 to sl.Count-1 do
  576.     begin
  577.       if Copy(sl.Strings[i], 1, Length(this_oid)+1) = this_oid+'.' then
  578.       begin
  579.         ini.EraseSection(sl.Strings[i]);
  580.       end;
  581.     end;
  582.     sl.Free;
  583.  
  584.     for i := 1 to ini.ReadInteger(parent_oid, 'delegates', 0) do
  585.     begin
  586.       if ini.ReadString(parent_oid, 'delegate'+IntToStr(i), '') = this_oid then
  587.       begin
  588.         ini.WriteString(parent_oid, 'delegate'+IntToStr(i), '');
  589.       end;
  590.     end;
  591.  
  592.     { ini.UpdateFile; }
  593.   finally
  594.     ini.Free;
  595.   end;
  596. end;
  597.  
  598. procedure TForm1.Button8Click(Sender: TObject);
  599. var
  600.   ini: TIniFile;
  601.   nod: TOutlineNode;
  602.   parent_ra, this_ra: string;
  603.   i: integer;
  604. begin
  605.   if MessageDlg('Are you sure?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then exit;
  606.  
  607.   ini := TIniFile.Create(DBPath+'RA.INI');
  608.   try
  609.     this_ra := Copy(Outline1.Items[Outline1.SelectedItem].Text, 1, Pos(' ',Outline1.Items[Outline1.SelectedItem].Text+' ')-1);
  610.     if Outline1.Items[Outline1.SelectedItem].Parent.Text = TITLE_RA then
  611.       parent_ra := 'RA:'
  612.     else
  613.       parent_ra := Copy(Outline1.Items[Outline1.SelectedItem].Parent.Text, 1,
  614.                         Pos(' ', Outline1.Items[Outline1.SelectedItem].Parent.Text+' ')-1);
  615.  
  616.     nod := Outline1.Items[Outline1.SelectedItem];
  617.     Outline1.SelectedItem := nod.Parent.Index;
  618.     Outline1.Delete(nod.Index);
  619.  
  620.     ini.EraseSection(this_ra);
  621.  
  622.     for i := 1 to ini.ReadInteger(parent_ra, 'count', 0) do
  623.     begin
  624.       if ini.ReadString(parent_ra, 'ra'+IntToStr(i), '') = this_ra then
  625.       begin
  626.         ini.WriteString(parent_ra, 'ra'+IntToStr(i), '');
  627.       end;
  628.     end;
  629.  
  630.     ComboBox1.Items.Delete(ComboBox1.Items.IndexOf(this_ra));
  631.  
  632.     { ini.UpdateFile; }
  633.   finally
  634.     ini.Free;
  635.   end;
  636. end;
  637.  
  638. function RandomStr(len: integer): string;
  639. var
  640.   i: integer;
  641. begin
  642.   result := '';
  643.   for i := 1 to len do
  644.   begin
  645.     result := result + Chr(ord('A') + Random(26));
  646.   end;
  647. end;
  648.  
  649. procedure TForm1.Button2Click(Sender: TObject);
  650. var
  651.   ini: TIniFile;
  652.   txtFile, asn1s: string;
  653.   modified: boolean;
  654. begin
  655.   { Attention: Do not rely on Outline1.Items[Outline1.SelectedItem].Text, because Button2.Click
  656.     will be called in Outline1OnChange()! }
  657.  
  658.   ini := TIniFile.Create(DBPath+'OID.INI');
  659.   try
  660.     modified := false;
  661.  
  662.     if ini.ReadString(Edit4.Text, 'ra', '') <> ComboBox1.Text then
  663.     begin
  664.       modified := true;
  665.       ini.WriteString(Edit4.Text, 'ra', ComboBox1.Text);
  666.     end;
  667.  
  668.     if ini.ReadString(Edit4.Text, 'description', '') <> Edit3.Text then
  669.     begin
  670.       modified := true;
  671.       ini.WriteString(Edit4.Text, 'description', Edit3.Text);
  672.     end;
  673.  
  674.     if ini.ReadBool(Edit4.Text, 'draft', false) <> CheckBox1.Checked then
  675.     begin
  676.       modified := true;
  677.       ini.WriteBool(Edit4.Text, 'draft', CheckBox1.Checked);
  678.     end;
  679.  
  680.     if Memo1.Modified then
  681.     begin
  682.       modified := true;
  683.       if Trim(Memo1.Text) = '' then
  684.       begin
  685.         txtFile := ini.ReadString(Edit4.Text, 'information', '');
  686.         if FileExists(DBPath+txtFile) then
  687.         begin
  688.           SysUtils.DeleteFile(DBPath+txtFile);
  689.         end;
  690.         if txtFile <> '' then
  691.         begin
  692.           ini.WriteString(Edit4.Text, 'information', '')
  693.         end;
  694.       end
  695.       else
  696.       begin
  697.         txtFile := ini.ReadString(Edit4.Text, 'information', '');
  698.         if txtFile = '' then
  699.         begin
  700.           repeat
  701.             txtFile := RandomStr(8) + '.TXT';
  702.           until not FileExists(DBPath+txtFile);
  703.           ini.WriteString(Edit4.Text, 'information', txtFile);
  704.         end;
  705.  
  706.         Memo1.Lines.SaveToFile(DBPath+txtFile);
  707.         Memo1.Modified := false;
  708.       end;
  709.     end;
  710.  
  711.     asn1s := GetAsn1Ids(false);
  712.     if ini.ReadString(Edit4.Text, 'asn1id', '') <> asn1s then
  713.     begin
  714.       modified := true;
  715.       ini.WriteString(Edit4.Text, 'asn1id', asn1s);
  716.     end;
  717.  
  718.     if modified then
  719.     begin
  720.       ini.WriteString(Edit4.Text, 'updatedate', DateToStr(Date));
  721.       { ini.Updatefile; }
  722.     end;
  723.   finally
  724.     ini.Free;
  725.   end;
  726. end;
  727.  
  728. function TForm1.GetAsn1Ids(onlyfirst: boolean): string;
  729. var
  730.   i: integer;
  731. begin
  732.   result := '';
  733.   for i := 0 to ListBox1.Items.Count-1 do
  734.   begin
  735.     if result = '' then
  736.       result := ListBox1.Items.Strings[i]
  737.     else if not onlyfirst then
  738.       result := result + ',' + ListBox1.Items.Strings[i];
  739.   end;
  740. end;
  741.  
  742. function IniValueExists(ini: TIniFile; const Section, Ident: string): Boolean;
  743. var
  744.   S: TStrings;
  745. begin
  746.   S := TStringList.Create;
  747.   try
  748.     ini.ReadSection(Section, S);
  749.     Result := S.IndexOf(Ident) > -1;
  750.   finally
  751.     S.Free;
  752.   end;
  753. end;
  754.  
  755. var
  756.   MkDirTriedOnce: boolean; { Avoid that the debugger always shows the exception }
  757. procedure MakeDirIfRequired(dirname: string);
  758. begin
  759.   if dirname[Length(dirname)] = '\' then dirname := Copy(dirname, 1, Length(dirname)-1);
  760.  
  761.   if not MkDirTriedOnce then
  762.   begin
  763.     try
  764.       MkDir(dirname);
  765.     except
  766.     end;
  767.     MkDirTriedOnce := true;
  768.   end;
  769. end;
  770.  
  771. function TForm1.DBPath: string;
  772. var
  773.   ini: TIniFile;
  774. begin
  775.   ini := TIniFile.Create('.\OIDPLUS.INI');
  776.   try
  777.     if not IniValueExists(ini, 'SETTINGS', 'DATA') then
  778.     begin
  779.       result := 'DB\';
  780.       ini.WriteString('SETTINGS', 'DATA', result);
  781.       { ini.UpdateFile; }
  782.     end
  783.     else
  784.     begin
  785.       result := ini.ReadString('SETTINGS', 'DATA', 'DB\');
  786.     end;
  787.     MakeDirIfRequired(result);
  788.   finally
  789.     ini.Free;
  790.   end;
  791. end;
  792.  
  793. procedure TForm1.FormCreate(Sender: TObject);
  794. begin
  795.   Notebook1.PageIndex := 2;
  796.   Randomize;
  797. end;
  798.  
  799. procedure TForm1.SaveChangesIfRequired;
  800. begin
  801.   if Notebook1.PageIndex = 0 then Button2.Click; { Save changes }
  802.   if Notebook1.PageIndex = 1 then Button9.Click; { Save changes }
  803. end;
  804.  
  805. procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  806. begin
  807.   SaveChangesIfRequired;
  808.   CanClose := true;
  809. end;
  810.  
  811. procedure TForm1.CheckBox1Click(Sender: TObject);
  812. begin
  813.   if CheckBox1.Checked then
  814.     Outline1.Items[Outline1.SelectedItem].Text := Trim(Edit4.Text+' '+GetAsn1Ids(true))+' [DRAFT]'
  815.   else
  816.     Outline1.Items[Outline1.SelectedItem].Text := Trim(Edit4.Text+' '+GetAsn1Ids(true));
  817. end;
  818.  
  819. procedure TForm1.ShowError(msg: string);
  820. begin
  821.   MessageDlg(msg, mtError, [mbOk], 0);
  822.   Abort;
  823. end;
  824.  
  825. procedure TForm1.Button9Click(Sender: TObject);
  826. var
  827.   ini: TIniFile;
  828.   txtFile, asn1s: string;
  829.   modified: boolean;
  830. begin
  831.   { Attention: Do not rely on Outline1.Items[Outline1.SelectedItem].Text, because Button9.Click
  832.    will be called in Outline1OnChange()! }
  833.  
  834.   ini := TIniFile.Create(DBPath+'RA.INI');
  835.   try
  836.     modified := false;
  837.     if ini.ReadString(Edit9.Text, 'name', '') <> Edit11.Text then
  838.     begin
  839.       modified := true;
  840.       ini.WriteString(Edit9.Text, 'name', Edit11.Text);
  841.     end;
  842.     if ini.ReadString(Edit9.Text, 'email', '') <> Edit12.Text then
  843.     begin
  844.       modified := true;
  845.       ini.WriteString(Edit9.Text, 'email', Edit12.Text);
  846.     end;
  847.     if ini.ReadString(Edit9.Text, 'phone', '') <> Edit13.Text then
  848.     begin
  849.       modified := true;
  850.       ini.WriteString(Edit9.Text, 'phone', Edit13.Text);
  851.     end;
  852.     if modified then
  853.     begin
  854.       ini.WriteString(Edit9.Text, 'updatedate', DateToStr(Date));
  855.       { ini.Updatefile; }
  856.     end;
  857.   finally
  858.     ini.Free;
  859.   end;
  860. end;
  861.  
  862. procedure TForm1.Edit8KeyPress(Sender: TObject; var Key: Char);
  863. begin
  864.   if Key = #13 then
  865.   begin
  866.     Button7.Click;
  867.     Key := #0;
  868.     Exit;
  869.   end;
  870.   if Key = #8(*backspace*) then exit;
  871.   if Key in ['a'..'z'] then Key := UpCase(Key);
  872.   if not (Key in ['A'..'Z', '-']) then
  873.   begin
  874.     MessageBeep(0);
  875.     Key := #0;
  876.   end;
  877. end;
  878.  
  879. procedure TForm1.Edit11Change(Sender: TObject);
  880. begin
  881.   Outline1.Items[Outline1.SelectedItem].Text := Trim(Edit9.Text + ' ' + Edit11.Text);
  882. end;
  883.  
  884. procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
  885.   Shift: TShiftState);
  886. begin
  887.   If Key = 46(*DEL*) then
  888.   begin
  889.     Button3.Click;
  890.     Key := 0;
  891.   end;
  892. end;
  893.  
  894. procedure TForm1.Edit7KeyPress(Sender: TObject; var Key: Char);
  895. begin
  896.   if Key = #13 then
  897.   begin
  898.     Button1.Click;
  899.     Key := #0;
  900.   end;
  901. end;
  902.  
  903. procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
  904. begin
  905.   if Key = #13 then
  906.   begin
  907.     Button5.Click;
  908.     Key := #0;
  909.   end;
  910. end;
  911.  
  912. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
  913. begin
  914.   if Key = #13 then
  915.   begin
  916.     Button4.Click;
  917.     Key := #0;
  918.   end;
  919. end;
  920.  
  921. procedure TForm1.Outline1KeyDown(Sender: TObject; var Key: Word;
  922.   Shift: TShiftState);
  923. begin
  924.   if Key = 46(*DEL*) then
  925.   begin
  926.     if Copy(Outline1.Items[Outline1.SelectedItem].Text, 1, 4) = 'OID:' then
  927.     begin
  928.       Button6.Click;
  929.     end
  930.     else if Copy(Outline1.Items[Outline1.SelectedItem].Text, 1, 3) = 'RA:' then
  931.     begin
  932.       Button8.Click;
  933.     end
  934.     else
  935.     begin
  936.       MessageBeep(0);
  937.     end;
  938.  
  939.     Key := 0;
  940.   end;
  941. end;
  942.  
  943. procedure TForm1.Outline1Click(Sender: TObject);
  944. begin
  945.   Outline1Change(Sender, Outline1.SelectedItem);
  946. end;
  947.  
  948. end.
  949.