Changeset 15 for trunk/UAcronym.pas


Ignore:
Timestamp:
Apr 29, 2016, 12:09:44 AM (8 years ago)
Author:
chronos
Message:
  • Modified: Now project file have XML structure. Loading and saving old format is still supported using .csv extension.
  • Fixed: Question before closing modified unsaved project.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UAcronym.pas

    r14 r15  
    66
    77uses
    8   Classes, SysUtils, Contnrs;
     8  Classes, SysUtils, Contnrs, XMLConf, XMLRead, XMLWrite, DOM, UXMLUtils;
    99
    1010type
    1111  TAcronymCategories = class;
    1212  TAcronymMeanings = class;
     13  TAcronymDb = class;
    1314
    1415  TAcronymSource = class
     
    2425
    2526  TAcronym = class
     27    Db: TAcronymDb;
    2628    Name: string;
    2729    Meanings: TAcronymMeanings;
     30    procedure SaveToNode(Node: TDOMNode);
     31    procedure LoadFromNode(Node: TDOMNode);
    2832    constructor Create;
    2933    destructor Destroy; override;
     34  end;
     35
     36  { TAcronyms }
     37
     38  TAcronyms = class(TObjectList)
     39    Db: TAcronymDb;
     40    procedure SaveToNode(Node: TDOMNode);
     41    procedure LoadFromNode(Node: TDOMNode);
     42    function SearchByName(Name: string): TAcronym;
     43    function AddAcronym(Name: string): TAcronym;
    3044  end;
    3145
     
    3953    Categories: TAcronymCategories;
    4054    Source: TAcronymSource;
     55    procedure SaveToNode(Node: TDOMNode);
     56    procedure LoadFromNode(Node: TDOMNode);
    4157    constructor Create;
    4258    destructor Destroy; override;
     
    4662
    4763  TAcronymMeanings = class(TObjectList)
     64    Acronym: TAcronym;
     65    procedure SaveToNode(Node: TDOMNode);
     66    procedure LoadFromNode(Node: TDOMNode);
    4867    function SearchByName(Name: string): TAcronymMeaning;
    4968    function AddMeaning(Name: string): TAcronymMeaning;
    5069  end;
    5170
    52   { TAcronyms }
    53 
    54   TAcronyms = class(TObjectList)
    55     function SearchByName(Name: string): TAcronym;
    56     function AddAcronym(Name: string): TAcronym;
    57   end;
    58 
    5971  { TAcronymCategory }
    6072
    6173  TAcronymCategory = class
     74    Id: Integer;
    6275    Name: string;
    6376    AcronymMeanings: TAcronymMeanings;
     77    procedure SaveToNode(Node: TDOMNode);
     78    procedure LoadFromNode(Node: TDOMNode);
    6479    constructor Create;
    6580    destructor Destroy; override;
     
    6984
    7085  TAcronymCategories = class(TObjectList)
     86    procedure UpdateIds;
     87    procedure SaveToNode(Node: TDOMNode);
     88    procedure LoadFromNode(Node: TDOMNode);
    7189    function SearchByName(Name: string): TAcronymCategory;
     90    function SearchById(Id: Integer): TAcronymCategory;
    7291    function AddContext(Name: string): TAcronymCategory;
    7392    procedure AssignToStrings(Strings: TStrings);
     
    98117    procedure LoadFromFile(FileName: string);
    99118    procedure SaveToFile(FileName: string);
     119    procedure LoadFromFileCSV(FileName: string);
     120    procedure SaveToFileCSV(FileName: string);
    100121    procedure FilterList(AName: string; Items: TAcronymMeanings);
    101122    function AddAcronym(AcronymName, MeaningName: string): TAcronymMeaning;
     
    105126function AcronymComparer(Item1, Item2: Pointer): Integer;
    106127
     128
    107129implementation
     130
     131resourcestring
     132  SWrongFileFormat = 'Wrong file format';
    108133
    109134function AcronymComparer(Item1, Item2: Pointer): Integer;
     
    126151
    127152{ TAcronymMeanings }
     153
     154procedure TAcronymMeanings.SaveToNode(Node: TDOMNode);
     155var
     156  I: Integer;
     157  NewNode2: TDOMNode;
     158begin
     159  for I := 0 to Count - 1 do
     160  with TAcronymMeaning(Items[I]) do begin
     161    NewNode2 := Node.OwnerDocument.CreateElement('Meaning');
     162    Node.AppendChild(NewNode2);
     163    SaveToNode(NewNode2);
     164  end;
     165end;
     166
     167procedure TAcronymMeanings.LoadFromNode(Node: TDOMNode);
     168var
     169  Node2: TDOMNode;
     170  NewItem: TAcronymMeaning;
     171begin
     172  Count := 0;
     173  Node2 := Node.FirstChild;
     174  while Assigned(Node2) and (Node2.NodeName = 'Meaning') do begin
     175    NewItem := TAcronymMeaning.Create;
     176    NewItem.Acronym := Acronym;
     177    NewItem.LoadFromNode(Node2);
     178    Add(NewItem);
     179    Node2 := Node2.NextSibling;
     180  end;
     181end;
    128182
    129183function TAcronymMeanings.SearchByName(Name: string): TAcronymMeaning;
     
    146200{ TAcronymMeaning }
    147201
     202procedure TAcronymMeaning.SaveToNode(Node: TDOMNode);
     203var
     204  NewNode: TDOMNode;
     205  NewNode2: TDOMNode;
     206  I: Integer;
     207begin
     208  WriteString(Node, 'Name', Name);
     209  WriteString(Node, 'Description', Description);
     210  WriteString(Node, 'Language', Language);
     211
     212  NewNode := Node.OwnerDocument.CreateElement('Categories');
     213  Node.AppendChild(NewNode);
     214  for I := 0 to Categories.Count - 1 do begin
     215    NewNode2 := NewNode.OwnerDocument.CreateElement('Category');
     216    NewNode.AppendChild(NewNode2);
     217    WriteInteger(NewNode2, 'Id', TAcronymCategory(Categories[I]).Id);
     218  end;
     219end;
     220
     221procedure TAcronymMeaning.LoadFromNode(Node: TDOMNode);
     222var
     223  Node2: TDOMNode;
     224  Node3: TDOMNode;
     225  Category: TAcronymCategory;
     226  Id: Integer;
     227begin
     228  Name := ReadString(Node, 'Name', '');
     229  Description := ReadString(Node, 'Description', '');
     230  Language := ReadString(Node, 'Language', '');
     231
     232  Node3 := Node.FindNode('Categories');
     233  if Assigned(Node3) then begin
     234    Node2 := Node3.FirstChild;
     235    while Assigned(Node2) and (Node2.NodeName = 'Category') do begin
     236      Id := ReadInteger(Node2, 'Id', 0);
     237      Category := Acronym.Db.Categories.SearchById(Id);
     238      if Assigned(Category) then begin
     239        Categories.Add(Category);
     240        Category.AcronymMeanings.Add(Self);
     241      end;
     242      Node2 := Node2.NextSibling;
     243    end;
     244  end;
     245end;
     246
    148247constructor TAcronymMeaning.Create;
    149248begin
     
    163262{ TAcronyms }
    164263
     264procedure TAcronyms.SaveToNode(Node: TDOMNode);
     265var
     266  I: Integer;
     267  NewNode2: TDOMNode;
     268begin
     269  for I := 0 to Count - 1 do
     270  with TAcronym(Items[I]) do begin
     271    NewNode2 := Node.OwnerDocument.CreateElement('Acronym');
     272    Node.AppendChild(NewNode2);
     273    SaveToNode(NewNode2);
     274  end;
     275end;
     276
     277procedure TAcronyms.LoadFromNode(Node: TDOMNode);
     278var
     279  Node2: TDOMNode;
     280  NewItem: TAcronym;
     281begin
     282  Count := 0;
     283  Node2 := Node.FirstChild;
     284  while Assigned(Node2) and (Node2.NodeName = 'Acronym') do begin
     285    NewItem := TAcronym.Create;
     286    NewItem.Db := Db;
     287    NewItem.LoadFromNode(Node2);
     288    Add(NewItem);
     289    Node2 := Node2.NextSibling;
     290  end;
     291end;
     292
    165293function TAcronyms.SearchByName(Name: string): TAcronym;
    166294var
     
    182310{ TAcronymCategories }
    183311
     312procedure TAcronymCategories.UpdateIds;
     313var
     314  LastId: Integer;
     315  I: Integer;
     316begin
     317  // Get highest used ID
     318  LastId := 0;
     319  for I := 0 to Count - 1 do begin
     320    if TAcronymCategory(Items[I]).Id > LastId then LastId := TAcronymCategory(Items[I]).Id;
     321  end;
     322  // Add ID to new items without ID
     323  for I := 0 to Count - 1 do begin
     324    if TAcronymCategory(Items[I]).Id = 0 then begin
     325      Inc(LastId);
     326      TAcronymCategory(Items[I]).Id := LastId;
     327    end;
     328  end;
     329end;
     330
     331procedure TAcronymCategories.SaveToNode(Node: TDOMNode);
     332var
     333  I: Integer;
     334  NewNode2: TDOMNode;
     335begin
     336  UpdateIds;
     337  for I := 0 to Count - 1 do
     338  with TAcronymCategory(Items[I]) do begin
     339    NewNode2 := Node.OwnerDocument.CreateElement('Category');
     340    Node.AppendChild(NewNode2);
     341    SaveToNode(NewNode2);
     342  end;
     343end;
     344
     345procedure TAcronymCategories.LoadFromNode(Node: TDOMNode);
     346var
     347  Node2: TDOMNode;
     348  NewItem: TAcronymCategory;
     349begin
     350  Count := 0;
     351  Node2 := Node.FirstChild;
     352  while Assigned(Node2) and (Node2.NodeName = 'Category') do begin
     353    NewItem := TAcronymCategory.Create;
     354    NewItem.LoadFromNode(Node2);
     355    Add(NewItem);
     356    Node2 := Node2.NextSibling;
     357  end;
     358  UpdateIds;
     359end;
     360
    184361function TAcronymCategories.SearchByName(Name: string): TAcronymCategory;
    185362var
     
    192369end;
    193370
     371function TAcronymCategories.SearchById(Id: Integer): TAcronymCategory;
     372var
     373  I: Integer;
     374begin
     375  I := 0;
     376  while (I < Count) and (TAcronymCategory(Items[I]).Id <> Id) do Inc(I);
     377  if I < Count then Result := TAcronymCategory(Items[I])
     378    else Result := nil;
     379end;
     380
    194381function TAcronymCategories.AddContext(Name: string): TAcronymCategory;
    195382begin
     
    221408{ TAcronym }
    222409
     410procedure TAcronym.SaveToNode(Node: TDOMNode);
     411var
     412  NewNode: TDOMNode;
     413begin
     414  WriteString(Node, 'Name', Name);
     415
     416  NewNode := Node.OwnerDocument.CreateElement('Meanings');
     417  Node.AppendChild(NewNode);
     418  Meanings.SaveToNode(NewNode);
     419end;
     420
     421procedure TAcronym.LoadFromNode(Node: TDOMNode);
     422var
     423  NewNode: TDOMNode;
     424begin
     425  Name := ReadString(Node, 'Name', '');
     426
     427  NewNode := Node.FindNode('Meanings');
     428  if Assigned(NewNode) then
     429    Meanings.LoadFromNode(NewNode);
     430end;
     431
    223432constructor TAcronym.Create;
    224433begin
    225434  Meanings := TAcronymMeanings.Create;
     435  Meanings.Acronym := Self;
    226436end;
    227437
     
    233443
    234444{ TAcronymCategory }
     445
     446procedure TAcronymCategory.SaveToNode(Node: TDOMNode);
     447begin
     448  WriteString(Node, 'Name', Name);
     449  WriteInteger(Node, 'Id', Id);
     450end;
     451
     452procedure TAcronymCategory.LoadFromNode(Node: TDOMNode);
     453begin
     454  Name := ReadString(Node, 'Name', '');
     455  Id := ReadInteger(Node, 'Id', 0);
     456end;
    235457
    236458constructor TAcronymCategory.Create;
     
    255477  Sources := TAcronymSources.Create;
    256478  Acronyms := TAcronyms.Create;
     479  Acronyms.Db := Self;
    257480  Categories := TAcronymCategories.Create;
    258481end;
     
    267490
    268491procedure TAcronymDb.LoadFromFile(FileName: string);
     492var
     493  NewNode: TDOMNode;
     494  Doc: TXMLDocument;
     495  RootNode: TDOMNode;
     496begin
     497  if ExtractFileExt(FileName) = '.csv' then begin
     498    LoadFromFileCSV(FileName);
     499    Exit;
     500  end;
     501  Self.FileName := FileName;
     502  ReadXMLFile(Doc, FileName);
     503  with Doc do try
     504    if Doc.DocumentElement.NodeName <> 'AcronymDecoderProject' then
     505      raise Exception.Create(SWrongFileFormat);
     506    RootNode := Doc.DocumentElement;
     507    with RootNode do begin
     508      NewNode := FindNode('Categories');
     509      if Assigned(NewNode) then
     510        Categories.LoadFromNode(NewNode);
     511
     512      // Load acronyms after categories because of references
     513      NewNode := FindNode('Acronyms');
     514      if Assigned(NewNode) then
     515        Acronyms.LoadFromNode(NewNode);
     516    end;
     517  finally
     518    Doc.Free;
     519  end;
     520end;
     521
     522procedure TAcronymDb.SaveToFile(FileName: string);
     523var
     524  NewNode: TDOMNode;
     525  Doc: TXMLDocument;
     526  RootNode: TDOMNode;
     527begin
     528  if ExtractFileExt(FileName) = '.csv' then begin
     529    SaveToFileCSV(FileName);
     530    Exit;
     531  end;
     532  Self.FileName := FileName;
     533  Doc := TXMLDocument.Create;
     534  with Doc do try
     535    RootNode := CreateElement('AcronymDecoderProject');
     536    AppendChild(RootNode);
     537    with RootNode do begin
     538      NewNode := OwnerDocument.CreateElement('Categories');
     539      AppendChild(NewNode);
     540      Categories.SaveToNode(NewNode);
     541
     542      // Save acronyms after categories because of references
     543      NewNode := OwnerDocument.CreateElement('Acronyms');
     544      AppendChild(NewNode);
     545      Acronyms.SaveToNode(NewNode);
     546    end;
     547    ForceDirectories(ExtractFileDir(FileName));
     548    WriteXMLFile(Doc, FileName);
     549  finally
     550    Doc.Free;
     551  end;
     552  Modified := False;
     553end;
     554
     555procedure TAcronymDb.LoadFromFileCSV(FileName: string);
    269556var
    270557  F: TStringList;
     
    321608end;
    322609
    323 procedure TAcronymDb.SaveToFile(FileName: string);
     610procedure TAcronymDb.SaveToFileCSV(FileName: string);
    324611var
    325612  I: Integer;
Note: See TracChangeset for help on using the changeset viewer.