699 lines
24 KiB
ObjectPascal
699 lines
24 KiB
ObjectPascal
{
|
|
********************************************************************************
|
|
|
|
YaPeTaVi - Yet another Periodic Table Viewer
|
|
Copyright (C) 2009-2011 Geoffray Levasseur <geoffray.levasseurbrandin@numericable.fr>.
|
|
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 <http://www.gnu.org/copyleft/gpl.html>. 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.
|
|
|