Subversion Repositories oidplus

Rev

Rev 233 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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