{ ******************************************************************************** YaPeTaVi - Yet another Periodic Table Viewer Copyright (C) 2009-2011 Geoffray Levasseur . All rights reserved. http://www.geoffray-levasseur.org/ This source is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A copy of the GNU General Public License is available on the World Wide Web at . You can also obtain it by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ******************************************************************************** Description: Element list class } unit uElemListClass; {$mode objfpc}{$H+} interface uses ComCtrls, Classes, SysUtils, uStrings, uCommon; type TElemFamily = (atAlkaline, atRareEarth, atNonMetal, atAlkalieMetal, atOtherMetal, atHalogen, atTransMetal, atNobleGas, atMetalloid); const AFamilyStr: array[TElemFamily] of string = (rsAlcaline, rsRareEarth, rsNonMetal, rsAlkalieMetal, rsOtherMetal, rsHalogen, rsTransMetal, rsNobleGas, rsMetalloid); type TIonisationEnergy = record First: Double; Second: Double; Third: Double; end; St2 = String[2]; TElement = record Name: string; ShortName: St2; Mass: Double; CAS: string; DiscoYear: Integer; Discoverer: string; Etymology: String; Family: TElemFamily; Block: Char; MeltingPt: Double; BoilingPt: Double; ElecAffinity: Double; ElecConf: string; CovalentRd: integer; //in picometer so no real needed VanDerWaalsRd: integer; //in picometer so no real needed IonisationEnergy: TIonisationEnergy; Electroneg: Double; Radioactivity: string; Number: byte; Aspect: string; Use: string; WikiLink: string; end; TElemArray = array[0..ElemNumber] of TElement; TElemSortType = (estNumber, estName, estSymbol, estDiscoveryDate, estMass, estMeltingPoint, estBoilingPoint, estElectronicAffinity, estCovalentRadius, estVanDerWaalsRadius, estFirstIonisationEnergy, estSecondIonisationEnergy, estThirdIonisationEnergy, estElectronegativity); TFilterKind = (fkDate, fkMass, fkMeltingPoint, fkBoilingPoint, fkElectronicAffinity, fkCovalentRadius, fkVanDerWaalsRadius, fkFirstIonisationEnergy, fkSecondIonisationEnergy, fkThirdIonisationEnergy, fkElectronegativity); TFilter = record Min, Max: Double; Kind: TFilterKind; DisplayUnknow: Boolean; end; PFilterNode = ^TFilterNode; TFilterNode = record Item: TFilter; Next, Prev: PFilterNode; end; TElemList = class(TPersistent) private FFilterTable: Boolean; FFilterList: Boolean; FFilterGraph: Boolean; FElements: TElemArray; FSortType: TElemSortType; FSortUpToDown: Boolean; FSortUnknowFirst: Boolean; FSortedElements: TElemArray; FMinMass, FMaxMass: Double; FMinDiscoveryDate, FMaxDiscoveryDate: Integer; FMinMeltingPt, FMaxMeltingPt: Double; FMinBoilingPt, FMaxBoilingPt: Double; FMinElecAffinity, FMaxElecAffinity: Double; FMinCovalentRd, FMaxCovalentRd: Integer; FMinVanDerWaalsRd, FMaxVanDerWaalsRd: Integer; FMinFirstIonisationEnergy, FMaxFirstIonisationEnergy: Double; FMinSecondIonisationEnergy, FMaxSecondIonisationEnergy: Double; FMinThirdIonisationEnergy, FMaxThirdIonisationEnergy: Double; FMinElectroneg, FMaxElectroneg: Double; FMinFilteredMass, FMaxFilteredMass: Double; FMinFilteredDiscoveryDate, FMaxFilteredDiscoveryDate: Integer; FMinFilteredMeltingPt, FMaxFilteredMeltingPt: Double; FMinFilteredBoilingPt, FMaxFilteredBoilingPt: Double; FMinFilteredElecAffinity, FMaxFilteredElecAffinity: Double; FMinFilteredCovalentRd, FMaxFilteredCovalentRd: Integer; FMinFilteredVanDerWaalsRd, FMaxFilteredVanDerWaalsRd: Integer; FMinFilteredFirstIonisationEnergy, FMaxFilteredFirstIonisationEnergy: Double; FMinFilteredSecondIonisationEnergy, FMaxFilteredSecondIonisationEnergy: Double; FMinFilteredThirdIonisationEnergy, FMaxFilteredThirdIonisationEnergy: Double; FMinFilteredElectroneg, FMaxFilteredElectroneg: Double; FUpdating: Boolean; FFltCount: Integer; FFltFirst: PFilterNode; procedure SetSortType(const AType: TElemSortType); procedure SetSortUpToDown(const AUpToDown: Boolean); procedure SetSortUnknowFirst(const AUnknowFirst: Boolean); procedure UpdateMinMax; procedure UpdateFilteredMinMax; procedure Sort; protected function FltGet(Index: Integer): TFilter; virtual; function FltGetCount: Integer; virtual; procedure FltPut(Index: Integer; const Flt: TFilter); virtual; public constructor Create(AOwner: TComponent); virtual; destructor Destroy; override; function Filtered(const I: Integer): Boolean; function InActiveRange(const I: Integer): Boolean; function Add(const FElem: TElement): integer; function AddFilter(Flt: TFilter): integer; procedure RemoveFilter(Index: Integer); procedure ClearFilters; procedure UpdateList(var AListView: TListView); procedure UpdateList(var AListItems: TStrings); property FilterTable: Boolean read FFilterTable write FFilterTable default True; property FilterList: Boolean read FFilterList write FFilterList default True; property FilterGraph: Boolean read FFilterGraph write FFilterGraph default True; property Elements: TElemArray read FElements; property SortedElements: TElemArray read FSortedElements; property Filters[Index: integer]: TFilter read FltGet write FltPut; property FiltersCount: integer read FltGetCount; property MinDiscoveryDate: integer read FMinDiscoveryDate default 0; property MaxDiscoveryDate: integer read FMaxDiscoveryDate default 0; property MinMass: Double read FMinMass; property MaxMass: Double read FMaxMass; property MinMeltingPoint: Double read FMinMeltingPt; property MaxMeltingPoint: Double read FMaxMeltingPt; property MinBoilingPoint: Double read FMinBoilingPt; property MaxBoilingPoint: Double read FMaxBoilingPt; property MinElectronicAffinity: Double read FMinElecAffinity; property MaxElectronicAffinity: Double read FMaxElecAffinity; property MinCovalentRadius: integer read FMinCovalentRd default 0; property MaxCovalentRadius: integer read FMaxCovalentRd default 0; property MinVanDerWaalsRadius: integer read FMinVanDerWaalsRd default 0; property MaxVanDerWaalsRadius: integer read FMaxVanDerWaalsRd default 0; property MinFirstIonisationEnergy: Double read FMinFirstIonisationEnergy; property MaxFirstIonisationEnergy: Double read FMaxFirstIonisationEnergy; property MinSecondIonisationEnergy: Double read FMinSecondIonisationEnergy; property MaxSecondIonisationEnergy: Double read FMaxSecondIonisationEnergy; property MinThirdIonisationEnergy: Double read FMinThirdIonisationEnergy; property MaxThirdIonisationEnergy: Double read FMaxThirdIonisationEnergy; property MinElectronegativity: Double read FMinElectroneg; property MaxElectronegativity: Double read FMaxElectroneg; property MinFilteredMass: Double read FMinFilteredMass; property MaxFilteredMass: Double read FMaxFilteredMass; property MinFilteredMeltingPoint: Double read FMinFilteredMeltingPt; property MaxFilteredMeltingPoint: Double read FMaxFilteredMeltingPt; property MinFilteredBoilingPoint: Double read FMinFilteredBoilingPt; property MaxFilteredBoilingPoint: Double read FMaxFilteredBoilingPt; property MinFilteredElectronicAffinity: Double read FMinFilteredElecAffinity; property MaxFilteredElectronicAffinity: Double read FMaxFilteredElecAffinity; property MinFilteredCovalentRadius: integer read FMinFilteredCovalentRd default 0; property MaxFilteredCovalentRadius: integer read FMaxFilteredCovalentRd default 0; property MinFilteredVanDerWaalsRadius: integer read FMinFilteredVanDerWaalsRd default 0; property MaxFilteredVanDerWaalsRadius: integer read FMaxFilteredVanDerWaalsRd default 0; property MinFilteredFirstIonisationEnergy: Double read FMinFilteredFirstIonisationEnergy; property MaxFilteredFirstIonisationEnergy: Double read FMaxFilteredFirstIonisationEnergy; property MinFilteredSecondIonisationEnergy: Double read FMinFilteredSecondIonisationEnergy; property MaxFilteredSecondIonisationEnergy: Double read FMaxFilteredSecondIonisationEnergy; property MinFilteredThirdIonisationEnergy: Double read FMinFilteredThirdIonisationEnergy; property MaxFilteredThirdIonisationEnergy: Double read FMaxFilteredThirdIonisationEnergy; property MinFilteredElectronegativity: Double read FMinFilteredElectroneg; property MaxFilteredElectronegativity: Double read FMaxFilteredElectroneg; property SortType: TElemSortType read FSortType write SetSortType default estNumber; property SortUpToDown: Boolean read FSortUpToDown write SetSortUpToDown default False; property SortUnknowFirst: Boolean read FSortUnknowFirst write SetSortUnknowFirst default True; procedure BeginUpdate; procedure EndUpdate; function GetDiscovererList: TStrings; procedure DbgShowFilters; end; implementation uses uSort, uUtils, uDebug, Forms, Dialogs; procedure TElemList.ClearFilters; var Node: PFilterNode; begin if FFltFirst <> nil then begin repeat Node := FFltFirst; FFltFirst := FFltFirst^.Next; Dispose(Node); until FFltFirst = nil; end; end; function TElemList.AddFilter(Flt: TFilter): integer; var I: integer; Node, Node2: PFilterNode; begin Node := FFltFirst; I := 0; if Node = nil then begin New(Node); Node^.Item := Flt; Node^.Prev := nil; Node^.Next := nil; FFltFirst := Node; Result := 0; Exit; end; while Node^.Next <> nil do begin Node := Node^.Next; Inc(I); end; New(Node2); Node2^.Item := Flt; Node2^.Next := nil; Node2^.Prev := Node; Node^.Next := Node2; Result := I; Application.ProcessMessages; end; function TElemList.FltGet(Index: integer): TFilter; var I: integer; Node: PFilterNode; begin Node := FFltFirst; if Index = 0 then begin Result := FFltFirst^.Item; Exit; end; for I := 0 to Index - 1 do if Node <> nil then Node := Node^.Next else Exit; //this is an error (leave an exception) if Node <> nil then Result := Node^.Item; end; procedure TElemList.FltPut(Index: integer; const Flt: TFilter); var I: integer; Node: PFilterNode; begin Node := FFltFirst; if Index = 0 then begin FFltFirst^.Item := Flt; Exit; end; for I := 0 to Index do if Node <> nil then Node := Node^.Next else Exit; //this is an error as above if Node <> nil then Node^.Item := Flt; end; function TElemList.FltGetCount: integer; var I: integer; Node: PFilterNode; begin Node := FFltFirst; I := 0; if Node <> nil then while Node <> nil do begin Node := Node^.Next; Inc(I); end; Result := I; end; procedure TElemList.RemoveFilter(Index: integer); var Node: PFilterNode; I: integer; begin Node := FFltFirst; if Index = 0 then begin if Node^.Next <> nil then Node^.Next^.Prev := nil; FFltFirst := Node^.Next; Dispose(Node); Exit; end; for I := 1 to Index do if Node <> nil then Node := Node^.Next else Exit; //show error here if Node <> nil then begin Node^.Prev^.Next := Node^.Next; if Node^.Next <> nil then Node^.Next^.Prev := Node^.Prev; Dispose(Node); end; //add an else statement showing an error end; constructor TElemList.Create(AOwner: TComponent); begin FUpdating := False; FFltCount := 0; FFltFirst := nil; end; destructor TElemList.Destroy; begin ClearFilters; inherited; end; function TElemList.Filtered(const I: Integer): Boolean; var bDate, bMass, bMelting, bBoiling, bCovalent, bVanDerWaals, bElecAff, bElectroneg, bFIE, bSIE, bTIE: Boolean; begin if FUpdating then begin UpdateMinMax; UpdateFilteredMinMax; Sort; end; {$warning TElemList.Filtered: To be done} end; function TELemList.InActiveRange(const I: Integer): Boolean; begin Result := not Filtered(I); end; function TElemList.Add(const FElem: TElement): integer; begin FElements[FElem.Number] := FElem; Result := FElem.Number; PrintLnDbg('Element #' + IntToStr(FElem.Number) + ' added successfully', vlHigh); if not FUpdating then begin UpdateMinMax; UpdateFilteredMinMax; Sort; end; end; procedure TElemList.UpdateList(var AListView: TListView); begin if FUpdating then begin UpdateMinMax; UpdateFilteredMinMax; Sort; end; {$warning TElemList.UpdtateList(ListView): To be done} end; procedure TElemList.UpdateList(var AListItems: TStrings); begin if FUpdating then begin UpdateMinMax; UpdateFilteredMinMax; Sort; end; {$warning TElemList.UpdtateList(Strings): To be done} end; procedure TElemList.SetSortType(const AType: TElemSortType); begin FSortType := AType; if not FUpdating then Sort; end; procedure TElemList.SetSortUpToDown(const AUpToDown: Boolean); begin FSortUpToDown := AUpToDown; if not FUpdating then Sort; end; procedure TElemList.SetSortUnknowFirst(const AUnknowFirst: Boolean); begin FSortUnknowFirst := AUnknowFirst; if not FUpdating then Sort; end; procedure TElemList.UpdateMinMax; var I: integer; begin PrintLnDbg('Updating min and max values...', vlLow); for I := 1 to ElemNumber do begin if FElements[I].Mass > FMaxMass then FMaxMass := FElements[I].Mass; if FElements[I].DiscoYear > FMaxDiscoveryDate then FMaxDiscoveryDate := FElements[I].DiscoYear; if FElements[I].MeltingPt > FMaxMeltingPt then FMaxMeltingPt := FElements[I].MeltingPt; if FElements[I].BoilingPt > FMaxBoilingPt then FMaxBoilingPt := FElements[I].BoilingPt; if FElements[I].ElecAffinity > FMaxElecAffinity then FMaxElecAffinity := FElements[I].ElecAffinity; if FElements[I].CovalentRd > FMaxCovalentRd then FMaxCovalentRd := FElements[I].CovalentRd; if FElements[I].VanDerWaalsRd > FMaxVanDerWaalsRd then FMaxVanDerWaalsRd := FElements[I].VanDerWaalsRd; if FElements[I].IonisationEnergy.First > FMaxFirstIonisationEnergy then FMaxFirstIonisationEnergy := FElements[I].IonisationEnergy.First; if FElements[I].IonisationEnergy.Second > FMaxSecondIonisationEnergy then FMaxSecondIonisationEnergy := FElements[I].IonisationEnergy.Second; if FElements[I].IonisationEnergy.Third > FMaxThirdIonisationEnergy then FMaxThirdIonisationEnergy := FElements[I].IonisationEnergy.Third; if FElements[I].Electroneg > FMaxElectroneg then FMaxElectroneg := FElements[I].Electroneg; end; FMinMass := FMaxMass; FMinDiscoveryDate := FMaxDiscoveryDate; FMinMeltingPt := FMaxMeltingPt; FMinBoilingPt := FMaxBoilingPt; FMinElecAffinity := FMaxElecAffinity; FMinCovalentRd := FMaxCovalentRd; FMinVanDerWaalsRd := FMaxVanDerWaalsRd; FMinFirstIonisationEnergy := FMaxFirstIonisationEnergy; FMinSecondIonisationEnergy := FMaxSecondIonisationEnergy; FMinThirdIonisationEnergy := FMaxThirdIonisationEnergy; FMinElectroneg := FMaxElectroneg; for I := 1 to ElemNumber do begin if (FElements[I].Mass < FMinMass) and (FElements[I].Mass <> 0) then FMinMass := FElements[I].Mass; if (FElements[I].DiscoYear < FMinDiscoveryDate) and (FElements[I].DiscoYear <> 0) then FMinDiscoveryDate := FElements[I].DiscoYear; if (FElements[I].MeltingPt < FMinMeltingPt) and (FElements[I].MeltingPt <> 0) then FMinMeltingPt := FElements[I].MeltingPt; if (FElements[I].BoilingPt < FMinBoilingPt) and (FElements[I].BoilingPt <> 0) then FMinBoilingPt := FElements[I].BoilingPt; if (FElements[I].ElecAffinity < FMinElecAffinity) then FMinElecAffinity := FElements[I].ElecAffinity; if (FElements[I].CovalentRd < FMinCovalentRd) and (FElements[I].CovalentRd <> 0) then FMinCovalentRd := FElements[I].CovalentRd; if (FElements[I].VanDerWaalsRd < FMinVanDerWaalsRd) and (FElements[I].VanDerWaalsRd <> 0) then FMinVanDerWaalsRd := FElements[I].VanDerWaalsRd; if (FElements[I].IonisationEnergy.First < FMinFirstIonisationEnergy) and (FElements[I].IonisationEnergy.First <> 0) then FMinFirstIonisationEnergy := FElements[I].IonisationEnergy.First; if (FElements[I].IonisationEnergy.Second < FMinSecondIonisationEnergy) and (FElements[I].IonisationEnergy.Second <> 0) then FMinSecondIonisationEnergy := FElements[I].IonisationEnergy.Second; if (FElements[I].IonisationEnergy.Third < FMinThirdIonisationEnergy) and (FElements[I].IonisationEnergy.Third <> 0) then FMinThirdIonisationEnergy := FElements[I].IonisationEnergy.Third; if (FElements[I].Electroneg < FMinElectroneg) and (FElements[I].Electroneg <> -1) then FMinElectroneg := FElements[I].Electroneg; end; end; procedure TElemList.UpdateFilteredMinMax; var I: integer; begin PrintLnDbg('Updating min and max filtered values...', vlLow); for I := 1 to ElemNumber do begin if (FElements[I].Mass > FMaxFilteredMass) and InActiveRange(I) then FMaxFilteredMass := FElements[I].Mass; if (FElements[I].DiscoYear > FMaxFilteredDiscoveryDate) and InActiveRange(I) then FMaxFilteredDiscoveryDate := FElements[I].DiscoYear; if (FElements[I].MeltingPt > FMaxFilteredMeltingPt) and InActiveRange(I) then FMaxFilteredMeltingPt := FElements[I].MeltingPt; if (FElements[I].BoilingPt > FMaxFilteredBoilingPt) and InActiveRange(I) then FMaxFilteredBoilingPt := FElements[I].BoilingPt; if (FElements[I].ElecAffinity > FMaxFilteredElecAffinity) and InActiveRange(I) then FMaxFilteredElecAffinity := FElements[I].ElecAffinity; if (FElements[I].CovalentRd > FMaxFilteredCovalentRd) and InActiveRange(I) then FMaxFilteredCovalentRd := FElements[I].CovalentRd; if (FElements[I].VanDerWaalsRd > FMaxFilteredVanDerWaalsRd) and InActiveRange(I) then FMaxFilteredVanDerWaalsRd := FElements[I].VanDerWaalsRd; if (FElements[I].IonisationEnergy.First > FMaxFilteredFirstIonisationEnergy) and InActiveRange(I) then FMaxFilteredFirstIonisationEnergy := FElements[I].IonisationEnergy.First; if (FElements[I].IonisationEnergy.Second > FMaxFilteredSecondIonisationEnergy) and InActiveRange(I) then FMaxFilteredSecondIonisationEnergy := FElements[I].IonisationEnergy.Second; if (FElements[I].IonisationEnergy.Third > FMaxFilteredThirdIonisationEnergy) and InActiveRange(I) then FMaxFilteredThirdIonisationEnergy := FElements[I].IonisationEnergy.Third; if (FElements[I].Electroneg > FMaxFilteredElectroneg) and InActiveRange(I) then FMaxFilteredElectroneg := FElements[I].Electroneg; end; FMinFilteredMass := FMaxFilteredMass; FMinFilteredDiscoveryDate := FMaxFilteredDiscoveryDate; FMinFilteredMeltingPt := FMaxFilteredMeltingPt; FMinFilteredBoilingPt := FMaxFilteredBoilingPt; FMinFilteredElecAffinity := FMaxFilteredElecAffinity; FMinFilteredCovalentRd := FMaxFilteredCovalentRd; FMinFilteredVanDerWaalsRd := FMaxFilteredVanDerWaalsRd; FMinFilteredFirstIonisationEnergy := FMaxFilteredFirstIonisationEnergy; FMinFilteredSecondIonisationEnergy := FMaxFilteredSecondIonisationEnergy; FMinFilteredThirdIonisationEnergy := FMaxFilteredThirdIonisationEnergy; FMinFilteredElectroneg := FMaxFilteredElectroneg; for I := 1 to ElemNumber do begin if (FElements[I].Mass < FMinFilteredMass) and (FElements[I].Mass <> 0) and InActiveRange(I) then FMinFilteredMass := FElements[I].Mass; if (FElements[I].DiscoYear < FMinFilteredDiscoveryDate) and (FElements[I].DiscoYear <> 0) and InActiveRange(I) then FMinFilteredDiscoveryDate := FElements[I].DiscoYear; if (FElements[I].MeltingPt < FMinFilteredMeltingPt) and (FElements[I].MeltingPt <> 0) and InActiveRange(I) then FMinFilteredMeltingPt := FElements[I].MeltingPt; if (FElements[I].BoilingPt < FMinFilteredBoilingPt) and (FElements[I].BoilingPt <> 0) and InActiveRange(I) then FMinFilteredBoilingPt := FElements[I].BoilingPt; if (FElements[I].ElecAffinity < FMinFilteredElecAffinity) and InActiveRange(I) then FMinFilteredElecAffinity := FElements[I].ElecAffinity; if (FElements[I].CovalentRd < FMinFilteredCovalentRd) and (FElements[I].CovalentRd <> 0) and InActiveRange(I) then FMinFilteredCovalentRd := FElements[I].CovalentRd; if (FElements[I].VanDerWaalsRd < FMinFilteredVanDerWaalsRd) and (FElements[I].VanDerWaalsRd <> 0) and InActiveRange(I) then FMinFilteredVanDerWaalsRd := FElements[I].VanDerWaalsRd; if (FElements[I].IonisationEnergy.First < FMinFilteredFirstIonisationEnergy) and (FElements[I].IonisationEnergy.First <> 0) and InActiveRange(I) then FMinFilteredFirstIonisationEnergy := FElements[I].IonisationEnergy.First; if (FElements[I].IonisationEnergy.Second < FMinFilteredSecondIonisationEnergy) and (FElements[I].IonisationEnergy.Second <> 0) and InActiveRange(I) then FMinFilteredSecondIonisationEnergy := FElements[I].IonisationEnergy.Second; if (FElements[I].IonisationEnergy.Third < FMinFilteredThirdIonisationEnergy) and (FElements[I].IonisationEnergy.Third <> 0) and InActiveRange(I) then FMinFilteredThirdIonisationEnergy := FElements[I].IonisationEnergy.Third; if (FElements[I].Electroneg < FMinFilteredElectroneg) and (FElements[I].Electroneg <> -1) and InActiveRange(I) then FMinFilteredElectroneg := FElements[I].Electroneg; end; end; //there's only arround 110 elements to sort so a "dirty" sort is quitte quick //enough procedure TElemList.Sort; begin PrintLnDbg('-- Sorting elements...', vlHigh); Inc(DebugLevel); case FSortType of estName: SortByName(FElements, FSortedElements, FSortUpToDown); estSymbol: SortByShortName(FElements, FSortedElements, FSortUpToDown); estDiscoveryDate : SortByDate(FElements, FSortedElements, FSortUpToDown, FSortUnknowFirst); estMass: SortByMass(FElements, FSortedElements, FSortUpToDown); else SortByAtNum(FElements, FSortedElements, FSortUpToDown); end; Dec(DebugLevel); PrintLnDbg('-- Done', vlHigh); end; procedure TElemList.BeginUpdate; begin FUpdating := True; end; procedure TElemList.EndUpdate; begin FUpdating := False; UpdateMinMax; UpdateFilteredMinMax; Sort; end; function TElemList.GetDiscovererList: TStrings; var I, J: integer; SDisco: string; Strs: TStringList; begin PrintLnDbg('-- Building discoverer list...', vlHigh); Inc(DebugLevel); Strs := TStringList.Create; for I := 1 to ElemNumber do if FElements[I].Discoverer <> '' then for J := 1 to CountItemsInStr(FElements[I].Discoverer, ',') do begin SDisco := Trim(GetItemInStr(FElements[I].Discoverer, ',', J)); if StrExistsInList(Strs, SDisco) = -1 then begin Strs.Add(SDisco); PrintLnDbg('Discoverer found: ' + SDisco, vlHigh); end; end; Result := Strs; Dec(VerboseLevel); PrintLnDbg('-- Done', vlHigh); end; procedure TElemList.DbgShowFilters; var I: integer; S, Tmp: String; begin S := IntToStr(FltGetCount) + ' counted filters:' + LineEnding; for I := 0 to FiltersCount - 1 do begin case Filters[I].Kind of fkDate: Tmp := 'Date'; fkBoilingPoint: Tmp := 'Boiling point'; fkCovalentRadius: Tmp := 'Covalent Radius'; fkElectronegativity: Tmp := 'Electronegativity'; fkElectronicAffinity: Tmp := 'Electronic Affinity'; fkFirstIonisationEnergy: Tmp := 'First Ionisation Energy'; fkMass: Tmp := 'Mass'; fkMeltingPoint: Tmp := 'Melting Point'; fkSecondIonisationEnergy: Tmp := 'Second Ionisation Energy'; fkThirdIonisationEnergy: Tmp := 'Third Ionisation Energy'; fkVanDerWaalsRadius: Tmp := 'Van Der Walls Radius'; end; S := S + Tmp + ': '#9' (min: ' + FloatToStr(Filters[I].Min) + ' / max: ' + FloatToStr(Filters[I].Max) + ')' + LineEnding; end; ShowMessage(S); end; end.