Browse Source

Refactor: manage sub-form lifecycle and restructuring GUI

Herman Schoenfeld 7 years ago
parent
commit
f86b6d32d7

+ 2 - 3
Units/Forms/UFRMAbout.pas

@@ -20,13 +20,13 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, ExtCtrls, StdCtrls, Buttons;
+  Dialogs, ExtCtrls, StdCtrls, Buttons, UCommonUI;
 
 type
 
   { TFRMAbout }
 
-  TFRMAbout = class(TForm)
+  TFRMAbout = class(TApplicationForm)
     Image1: TImage;
     Label1: TLabel;
     Memo1: TMemo;
@@ -72,7 +72,6 @@ begin
   OpenURL(TLabel(Sender).Caption);
 end;
 
-
 procedure TFRMAbout.OpenURL(Url: String);
 begin
   OpenDocument(pchar(URL))

+ 4 - 0
Units/Forms/UFRMAccountExplorer.lfm

@@ -477,6 +477,10 @@ object FRMAccountExplorer: TFRMAccountExplorer
         Caption = 'New Operation'
         OnClick = miNewOperationClick
       end
+      object miDecodePayload: TMenuItem
+        Caption = 'Decode Payload'
+        OnClick = miDecodePayloadClick
+      end
       object N1: TMenuItem
         Caption = '-'
       end

+ 19 - 4
Units/Forms/UFRMAccountExplorer.pas

@@ -6,13 +6,14 @@ interface
 
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
-  ExtCtrls, StdCtrls, Buttons, Grids, Menus, UGridUtils, UNode, UAccounts, UBlockChain;
+  ExtCtrls, StdCtrls, Buttons, Grids, Menus, UCommonUI,
+  UGridUtils, UNode, UAccounts, UBlockChain;
 
 type
 
   { TFRMAccountExplorer }
 
-  TFRMAccountExplorer = class(TForm)
+  TFRMAccountExplorer = class(TApplicationForm)
     bbAccountsRefresh: TBitBtn;
     bbAccountsRefresh1: TBitBtn;
     bbAccountsRefresh2: TBitBtn;
@@ -80,8 +81,18 @@ type
     lblSelectedAccountsCount1: TLabel;
     lblSelectedAccountsCount2: TLabel;
     meAccountExplorerMenu : TMainMenu;
+    miDecodePayload: TMenuItem;
+    miAccountInformation: TMenuItem;
+    miAddAccountToSelected: TMenuItem;
     miFindAccount: TMenuItem;
+    miFindNextAccountWithHighBalance: TMenuItem;
+    miFindPreviousAccountWithHighBalance: TMenuItem;
+    miNewOperation: TMenuItem;
+    miRemoveAccountFromSelected: TMenuItem;
     miTools: TMenuItem;
+    N1: TMenuItem;
+    N2: TMenuItem;
+    N3: TMenuItem;
     pcAccountsOptions: TPageControl;
     pcAccountsOptions1: TPageControl;
     pcAccountsOptions2: TPageControl;
@@ -146,6 +157,7 @@ type
     procedure FormDestroy(Sender: TObject);
     procedure miAccountInformationClick(Sender: TObject);
     procedure miAddAccountToSelectedClick(Sender: TObject);
+    procedure miDecodePayloadClick(Sender: TObject);
     procedure miFindNextAccountWithHighBalanceClick(Sender: TObject);
     procedure miFindPreviousAccountWithHighBalanceClick(Sender: TObject);
     procedure miNewOperationClick(Sender: TObject);
@@ -278,8 +290,6 @@ procedure TFRMAccountExplorer.FillAccountInformation(const Strings: TStrings; Co
 Var account : TAccount;
   s : String;
 begin
-//AntonB AccountNumber is type LongWord not cand negative
-//  if AccountNumber<0 then exit;
   account := TUserInterface.Node.Operations.SafeBoxTransaction.Account(AccountNumber);
   if account.name<>'' then s:='Name: '+account.name
   else s:='';
@@ -814,6 +824,11 @@ begin
   sbSelectedAccountsAddClick(Sender);
 end;
 
+procedure TFRMAccountExplorer.miDecodePayloadClick(Sender: TObject);
+begin
+  FOperationsAccountGrid.ShowModalDecoder(TUserInterface.WalletKeys,TUserInterface.AppParams);
+end;
+
 procedure TFRMAccountExplorer.miRemoveAccountFromSelectedClick(Sender: TObject);
 begin
   Self.pcAccountsOptions.ActivePage := Self.tsMultiSelectAccounts;

+ 1 - 1
Units/Forms/UFRMAccountInfo.pas

@@ -7,7 +7,7 @@ uses
   Dialogs, StdCtrls;
 
 type
-  TFRMAccountInfo = class(TForm)
+  TFRMAccountInfo = class(TApplicationForm)
     Label1: TLabel;
     lblAccount: TLabel;
     Label6: TLabel;

+ 3 - 3
Units/Forms/UFRMAccountSelect.pas

@@ -20,8 +20,8 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, UAccounts, Grids, StdCtrls, Buttons, ExtCtrls, UWalletKeys, UNode,
-  UGridUtils, UConst, UThread;
+  Dialogs, UAccounts, Grids, StdCtrls, Buttons, ExtCtrls, UCommonUI,
+  UWalletKeys, UNode, UGridUtils, UConst, UThread;
 
 const
   CT_AS_MyAccounts = $0001;
@@ -63,7 +63,7 @@ type
 
   { TFRMAccountSelect }
 
-  TFRMAccountSelect = class(TForm)
+  TFRMAccountSelect = class(TApplicationForm)
     cbAccountsName: TCheckBox;
     ebMinBalance: TEdit;
     ebMaxBalance: TEdit;

+ 2 - 2
Units/Forms/UFRMBlockExplorer.pas

@@ -6,13 +6,13 @@ interface
 
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
-  StdCtrls, Grids, Menus, UGridUtils;
+  StdCtrls, Grids, Menus, UCommonUI, UGridUtils;
 
 type
 
   { TFRMBlockExplorer }
 
-  TFRMBlockExplorer = class(TForm)
+  TFRMBlockExplorer = class(TApplicationForm)
     dgBlockChainExplorer: TDrawGrid;
     ebBlockChainBlockEnd: TEdit;
     ebBlockChainBlockStart: TEdit;

+ 3 - 2
Units/Forms/UFRMLogs.lfm

@@ -7,6 +7,7 @@ object FRMLogs: TFRMLogs
   ClientHeight = 466
   ClientWidth = 868
   OnCreate = FormCreate
+  OnDestroy = FormDestroy
   LCLVersion = '1.6.4.0'
   object pnlTopLogs: TPanel
     Left = 0
@@ -20,9 +21,9 @@ object FRMLogs: TFRMLogs
     TabOrder = 0
     object cbShowDebugLogs: TCheckBox
       Left = 15
-      Height = 17
+      Height = 19
       Top = 10
-      Width = 105
+      Width = 115
       Caption = 'Show Debug Logs'
       TabOrder = 0
     end

+ 13 - 7
Units/Forms/UFRMLogs.pas

@@ -7,18 +7,19 @@ interface
 uses
     LCLIntf,
     SysUtils, Classes, Graphics, Controls, Forms,
-    Dialogs, ExtCtrls,  StdCtrls,
+    Dialogs, ExtCtrls,  StdCtrls, UCommonUI,
     ULog, UBlockChain;
 
 type
 
   { TFRMLogs }
 
-  TFRMLogs = class(TForm)
+  TFRMLogs = class(TApplicationForm)
     cbShowDebugLogs: TCheckBox;
     memoLogs: TMemo;
     pnlTopLogs: TPanel;
     procedure FormCreate(Sender: TObject);
+    procedure FormDestroy(Sender: TObject);
     procedure OnNewLog(logtype : TLogType; Time : TDateTime; ThreadID : Cardinal; Const sender, logtext : AnsiString);
   private
     { private declarations }
@@ -36,6 +37,16 @@ uses  UUserInterface;
 
 { TFRMLogs }
 
+procedure TFRMLogs.FormCreate(Sender: TObject);
+begin
+  TUserInterface.Log.OnNewLog := OnNewLog;
+end;
+
+procedure TFRMLogs.FormDestroy(Sender: TObject);
+begin
+  TUserInterface.Log.OnNewLog := nil;
+end;
+
 procedure TFRMLogs.OnNewLog(logtype: TLogType; Time : TDateTime; ThreadID : Cardinal; const sender,logtext: AnsiString);
 Var s : AnsiString;
 begin
@@ -54,10 +65,5 @@ begin
   //
 end;
 
-procedure TFRMLogs.FormCreate(Sender: TObject);
-begin
-  TUserInterface.Log.OnNewLog := OnNewLog;
-end;
-
 end.
 

+ 2 - 2
Units/Forms/UFRMMemoText.pas

@@ -5,10 +5,10 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, Buttons, ExtCtrls;
+  Dialogs, StdCtrls, Buttons, ExtCtrls, UCommonUI;
 
 type
-  TFRMMemoText = class(TForm)
+  TFRMMemoText = class(TApplicationForm)
     pnlBottom: TPanel;
     Memo: TMemo;
     bbCancel: TBitBtn;

+ 2 - 2
Units/Forms/UFRMMessages.pas

@@ -7,14 +7,14 @@ interface
 uses
   LCLIntf, LCLType,
   SysUtils, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, Menus,
+  Dialogs, StdCtrls, Menus, UCommonUI,
   UNode, UNetProtocol, UCrypto, UFRMWallet,UConst;
 
 type
 
   { TFRMMessages }
 
-  TFRMMessages = class(TForm)
+  TFRMMessages = class(TApplicationForm)
     bbSendAMessage: TButton;
     Label11: TLabel;
     Label12: TLabel;

+ 2 - 2
Units/Forms/UFRMNewPrivateKeyType.pas

@@ -20,10 +20,10 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, Buttons, ExtCtrls, UWalletKeys,UCrypto;
+  Dialogs, StdCtrls, Buttons, ExtCtrls, UCommonUI, UWalletKeys,UCrypto;
 
 type
-  TFRMNewPrivateKeyType = class(TForm)
+  TFRMNewPrivateKeyType = class(TApplicationForm)
     Label1: TLabel;
     ebName: TEdit;
     rgKeyType: TRadioGroup;

+ 8 - 8
Units/Forms/UFRMNodes.lfm

@@ -1,7 +1,7 @@
 object FRMNodes: TFRMNodes
-  Left = 971
+  Left = 570
   Height = 444
-  Top = 399
+  Top = 333
   Width = 861
   Caption = 'Nodes'
   ClientHeight = 444
@@ -10,16 +10,16 @@ object FRMNodes: TFRMNodes
   LCLVersion = '1.6.4.0'
   object Label3: TLabel
     Left = 15
-    Height = 13
+    Height = 15
     Top = 15
-    Width = 96
+    Width = 106
     Caption = 'Active Connections:'
     ParentColor = False
   end
   object Label6: TLabel
     Left = 15
-    Height = 13
-    Top = 295
+    Height = 15
+    Top = 293
     Width = 198
     Anchors = [akLeft, akRight, akBottom]
     Caption = 'Known Node Servers:'
@@ -27,8 +27,8 @@ object FRMNodes: TFRMNodes
   end
   object Label7: TLabel
     Left = 15
-    Height = 13
-    Top = 191
+    Height = 15
+    Top = 189
     Width = 99
     Anchors = [akLeft, akRight, akBottom]
     Caption = 'Blacklisted Nodes'

+ 32 - 16
Units/Forms/UFRMNodes.pas

@@ -7,14 +7,19 @@ interface
 uses
   LCLIntf, LCLType,
   Messages, SysUtils, Classes, Graphics, Controls, Forms,
-  Dialogs, ExtCtrls, StdCtrls,
-  ULog,  UBlockChain, UNode, Menus,  UNetProtocol,  UFRMWallet;
+  Dialogs, ExtCtrls, StdCtrls, UCommonUI,
+  ULog,  UBlockChain, UNode, Menus,  UNetProtocol;
+
+Const
+  CM_PC_NetConnectionUpdated = WM_USER + 1;
+  CM_PC_BlackListUpdated = WM_USER + 2;
+  CM_PC_NetNodeServersUpdated = WM_USER + 3;
 
 type
 
   { TFRMNodes }
 
-  TFRMNodes = class(TForm)
+  TFRMNodes = class(TApplicationForm)
     Label3: TLabel;
     Label6: TLabel;
     Label7: TLabel;
@@ -24,8 +29,9 @@ type
     procedure FormCreate(Sender: TObject);
   private
     { private declarations }
-    FMustProcessNetConnectionUpdated : Boolean;
     procedure CM_NetConnectionUpdated(var Msg: TMessage); message CM_PC_NetConnectionUpdated;
+    procedure CM_BlackListUpdated(var Msg: TMessage); message CM_PC_BlackListUpdated;
+    procedure CM_NetNodeServersUpdated(var Msg: TMessage); message CM_PC_NetNodeServersUpdated;
   public
     { public declarations }
 
@@ -35,9 +41,6 @@ type
     procedure OnNetNodeServersUpdated;
   end;
 
-var
-  FRMNodes: TFRMNodes = nil;
-
 implementation
 
 Uses UTime;
@@ -48,8 +51,12 @@ Uses UTime;
 
 procedure TFRMNodes.FormCreate(Sender: TObject);
 begin
+  OnNetConnectionsUpdated;
+  OnNetNodeServersUpdated;
+  OnNetBlackListUpdated;
 end;
 
+
 procedure TFRMNodes.CM_NetConnectionUpdated(var Msg: TMessage);
 Const CT_BooleanToString : Array[Boolean] of String = ('False','True');
 Var i : integer;
@@ -128,11 +135,17 @@ begin
       TNetData.NetData.NetConnections.UnlockList;
     end;
   Finally
-    FMustProcessNetConnectionUpdated := false;
+    //FMustProcessNetConnectionUpdated := false;
   End;
 end;
 
-procedure TFRMNodes.OnNetNodeServersUpdated;
+procedure TFRMNodes.OnNetConnectionsUpdated;
+begin
+  // Ensure handled in UI thread
+  PostMessage(Self.Handle,CM_PC_NetConnectionUpdated,0,0);
+end;
+
+procedure TFRMNodes.CM_NetNodeServersUpdated(var Msg: TMessage);
 Var i : integer;
  P : PNodeServerAddress;
  l : TList;
@@ -181,7 +194,13 @@ begin
   end;
 end;
 
-procedure TFRMNodes.OnNetBlackListUpdated;
+procedure TFRMNodes.OnNetNodeServersUpdated;
+begin
+  // Ensure handled in UI thread
+  PostMessage(Self.Handle,CM_PC_NetNodeServersUpdated,0,0);
+end;
+
+procedure TFRMNodes.CM_BlackListUpdated(var Msg: TMessage);
 Const CT_TRUE_FALSE : Array[Boolean] Of AnsiString = ('FALSE','TRUE');
 Var i,j,n : integer;
  P : PNodeServerAddress;
@@ -218,13 +237,10 @@ begin
   end;
 end;
 
-procedure TFRMNodes.OnNetConnectionsUpdated;
+procedure TFRMNodes.OnNetBlackListUpdated;
 begin
-  // TODO - refactor this ugly infinite loop check out
-  if FMustProcessNetConnectionUpdated then exit;
-  FMustProcessNetConnectionUpdated := true;
-  PostMessage(Self.Handle,CM_PC_NetConnectionUpdated,0,0);  // Ends up calling CM_NetConnectionUpdated
+  // Ensure handled in UI thread
+  PostMessage(Self.Handle,CM_PC_BlackListUpdated,0,0);
 end;
 
-
 end.

+ 4 - 5
Units/Forms/UFRMNodesIp.lfm

@@ -1,7 +1,7 @@
 object FRMNodesIp: TFRMNodesIp
-  Left = 716
+  Left = 771
   Height = 367
-  Top = 383
+  Top = 23
   Width = 334
   BorderIcons = [biSystemMenu]
   BorderStyle = bsSingle
@@ -12,9 +12,8 @@ object FRMNodesIp: TFRMNodesIp
   Font.Color = clWindowText
   Font.Height = -11
   Font.Name = 'Tahoma'
-  OnCreate = FormCreate
   Position = poOwnerFormCenter
-  LCLVersion = '1.6.0.4'
+  LCLVersion = '1.6.4.0'
   object Label1: TLabel
     Left = 30
     Height = 13
@@ -78,7 +77,7 @@ object FRMNodesIp: TFRMNodesIp
     Left = 35
     Height = 19
     Top = 285
-    Width = 201
+    Width = 164
     Caption = 'Connect ONLY to these nodes'
     OnClick = cbTryOnlyWithThisServersClick
     TabOrder = 3

+ 48 - 60
Units/Forms/UFRMNodesIp.pas

@@ -7,87 +7,42 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, Buttons, UAppParams;
+  Dialogs, StdCtrls, Buttons,
+  UCommonUI, UAppParams;
 
 type
-  TFRMNodesIp = class(TForm)
+  TFRMNodesIp = class(TApplicationForm)
     memoNodesIp: TMemo;
     Label1: TLabel;
     bbOk: TBitBtn;
     bbCancel: TBitBtn;
     cbTryOnlyWithThisServers: TCheckBox;
     procedure bbOkClick(Sender: TObject);
-    procedure FormCreate(Sender: TObject);
     procedure cbTryOnlyWithThisServersClick(Sender: TObject);
   private
-    FAppParams: TAppParams;
-    procedure SetAppParams(const Value: TAppParams);
     { Private declarations }
+    procedure Refresh;
+  protected
+    procedure ActivateFirstTime; override;
   public
     { Public declarations }
-    Procedure PrepareData;
-    Property AppParams : TAppParams read FAppParams write SetAppParams;
   end;
 
 implementation
 
 uses
-  UNetProtocol, UNode, UConst;
+  UUserInterface, UNetProtocol, UNode, UConst;
 
 {$R *.lfm}
 
-
 { TFRMNodesIp }
 
-procedure TFRMNodesIp.bbOkClick(Sender: TObject);
-Var nsarr : TNodeServerAddressArray;
-  ips : AnsiString;
+procedure TFRMNodesIp.ActivateFirstTime;
 begin
-  TNode.DecodeIpStringToNodeServerAddressArray(memoNodesIp.Lines.Text,nsarr);
-  if (length(nsarr)=0) And (cbTryOnlyWithThisServers.Checked) then begin
-    raise Exception.Create('No valid IP in list!');
-  end;
-  // Encode
-  ips := TNode.EncodeNodeServerAddressArrayToIpString(nsarr);
-  if Assigned(FAppParams) then begin
-    FAppParams.ParamByName[CT_PARAM_PeerCache].SetAsString(ips);
-    if cbTryOnlyWithThisServers.Checked then Begin
-      FAppParams.ParamByName[CT_PARAM_TryToConnectOnlyWithThisFixedServers].SetAsString(ips);
-      TNetData.NetData.DiscoverFixedServersOnly(nsarr);
-      Application.MessageBox(PChar('Restart application to take effect'),PChar(Application.Title),MB_OK);
-    end else begin
-      FAppParams.ParamByName[CT_PARAM_TryToConnectOnlyWithThisFixedServers].SetAsString('');
-      setlength(nsarr,0);
-      TNetData.NetData.DiscoverFixedServersOnly(nsarr);
-    end;
-  end;
-  setlength(nsarr,0);
-  ModalResult := MrOk;
+  Refresh;
 end;
 
-procedure TFRMNodesIp.cbTryOnlyWithThisServersClick(Sender: TObject);
-begin
-  if cbTryOnlyWithThisServers.Checked then begin
-    cbTryOnlyWithThisServers.Font.Color := clRed;
-    cbTryOnlyWithThisServers.Font.Style := [fsBold];
-  end else begin
-    cbTryOnlyWithThisServers.ParentFont := true;
-  end;
-  if cbTryOnlyWithThisServers.Checked then begin
-    Application.MessageBox(PChar('ALERT:'+#10+
-      'If "'+cbTryOnlyWithThisServers.Caption+'" is checked '+#10+
-      'and no valid server found, you will be alone!')
-      ,PChar(Application.Title),MB_OK+MB_ICONWARNING);
-  end;
-end;
-
-procedure TFRMNodesIp.FormCreate(Sender: TObject);
-begin
-  FAppParams := Nil;
-  PrepareData;
-end;
-
-procedure TFRMNodesIp.PrepareData;
+procedure TFRMNodesIp.Refresh;
 Var
   nsarr : TNodeServerAddressArray;
   i : Integer;
@@ -95,9 +50,8 @@ Var
   aux : AnsiString;
 begin
   memoNodesIp.Clear;
-  if Not Assigned(FAppParams) then exit;
   setlength(nsarr,0);
-  ips := FAppParams.ParamByName[CT_PARAM_TryToConnectOnlyWithThisFixedServers].GetAsString('');
+  ips := TUserInterface.AppParams.ParamByName[CT_PARAM_TryToConnectOnlyWithThisFixedServers].GetAsString('');
   if trim(ips)<>'' then begin
     cbTryOnlyWithThisServers.Checked := true;
     TNode.DecodeIpStringToNodeServerAddressArray(ips,nsarr);
@@ -119,10 +73,44 @@ begin
   setlength(nsarr,0);
 end;
 
-procedure TFRMNodesIp.SetAppParams(const Value: TAppParams);
+procedure TFRMNodesIp.bbOkClick(Sender: TObject);
+Var nsarr : TNodeServerAddressArray;
+  ips : AnsiString;
+begin
+  TNode.DecodeIpStringToNodeServerAddressArray(memoNodesIp.Lines.Text,nsarr);
+  if (length(nsarr)=0) And (cbTryOnlyWithThisServers.Checked) then begin
+    raise Exception.Create('No valid IP in list!');
+  end;
+  // Encode
+  ips := TNode.EncodeNodeServerAddressArrayToIpString(nsarr);
+  TUserInterface.AppParams.ParamByName[CT_PARAM_PeerCache].SetAsString(ips);
+  if cbTryOnlyWithThisServers.Checked then Begin
+    TUserInterface.AppParams.ParamByName[CT_PARAM_TryToConnectOnlyWithThisFixedServers].SetAsString(ips);
+    TNetData.NetData.DiscoverFixedServersOnly(nsarr);
+    Application.MessageBox(PChar('Restart application to take effect'),PChar(Application.Title),MB_OK);
+  end else begin
+    TUserInterface.AppParams.ParamByName[CT_PARAM_TryToConnectOnlyWithThisFixedServers].SetAsString('');
+    setlength(nsarr,0);
+    TNetData.NetData.DiscoverFixedServersOnly(nsarr);
+  end;
+  setlength(nsarr,0);
+  ModalResult := MrOk;
+end;
+
+procedure TFRMNodesIp.cbTryOnlyWithThisServersClick(Sender: TObject);
 begin
-  FAppParams := Value;
-  PrepareData;
+  if cbTryOnlyWithThisServers.Checked then begin
+    cbTryOnlyWithThisServers.Font.Color := clRed;
+    cbTryOnlyWithThisServers.Font.Style := [fsBold];
+  end else begin
+    cbTryOnlyWithThisServers.ParentFont := true;
+  end;
+  if cbTryOnlyWithThisServers.Checked then begin
+    Application.MessageBox(PChar('ALERT:'+#10+
+      'If "'+cbTryOnlyWithThisServers.Caption+'" is checked '+#10+
+      'and no valid server found, you will be alone!')
+      ,PChar(Application.Title),MB_OK+MB_ICONWARNING);
+  end;
 end;
 
 end.

+ 3 - 2
Units/Forms/UFRMOperation.pas

@@ -20,7 +20,8 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, UNode, UWalletKeys, UCrypto, Buttons, UBlockChain,
+  Dialogs, StdCtrls, UCommonUI,
+  UNode, UWalletKeys, UCrypto, Buttons, UBlockChain,
   UAccounts, UFRMAccountSelect, ActnList, ComCtrls, Types, UCommon;
 
 Const
@@ -30,7 +31,7 @@ type
 
   { TFRMOperation }
 
-  TFRMOperation = class(TForm)
+  TFRMOperation = class(TApplicationForm)
     ebChangeName: TEdit;
     ebChangeType: TEdit;
     ebSignerAccount: TEdit;

+ 1 - 1
Units/Forms/UFRMOperationExplorer.lfm

@@ -70,7 +70,7 @@ object FRMOperationExplorer: TFRMOperationExplorer
         OnClick = miFindOperationByOpHashClick
       end
       object miDecodePayload: TMenuItem
-        Caption = 'Decode Payload Operations Explorer'
+        Caption = 'Decode Payload'
         ShortCut = 113
         OnClick = miDecodePayloadClick
       end

+ 1 - 4
Units/Forms/UFRMOperationExplorer.pas

@@ -14,7 +14,7 @@ type
 
   { TFRMOperationExplorer }
 
-  TFRMOperationExplorer = class(TForm)
+  TFRMOperationExplorer = class(TApplicationForm)
     dgOperationsExplorer: TDrawGrid;
     ebFilterOperationsEndBlock: TEdit;
     ebFilterOperationsStartBlock: TEdit;
@@ -71,7 +71,6 @@ begin
   FOperationsExplorerGrid.ShowModalDecoder(TUserInterface.WalletKeys, TUserInterface.AppParams);
 end;
 
-
 procedure TFRMOperationExplorer.miFindOperationByOpHashClick(Sender: TObject);
 var
   FRM : TFRMPayloadDecoder;
@@ -94,8 +93,6 @@ begin
   end;
 end;
 
-
-
 procedure TFRMOperationExplorer.ebFilterOperationsAccountExit(Sender: TObject);
 Var bstart,bend : Int64;
 begin

+ 2 - 3
Units/Forms/UFRMPascalCoinWalletConfig.pas

@@ -20,7 +20,7 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, Buttons, ComCtrls, UAppParams, UWalletKeys;
+  Dialogs, StdCtrls, Buttons, ComCtrls, UCommonUI, UAppParams, UWalletKeys;
 
 type
 
@@ -28,7 +28,7 @@ type
 
   { TFRMPascalCoinWalletConfig }
 
-  TFRMPascalCoinWalletConfig = class(TForm)
+  TFRMPascalCoinWalletConfig = class(TApplicationForm)
     cbJSONRPCMinerServerActive: TCheckBox;
     ebDefaultFee: TEdit;
     Label1: TLabel;
@@ -216,7 +216,6 @@ begin
   UpdateWalletConfig;
 end;
 
-
 procedure TFRMPascalCoinWalletConfig.UpdateWalletConfig;
 Var i, iselected : Integer;
   s : String;

+ 3 - 3
Units/Forms/UFRMPayloadDecoder.pas

@@ -20,14 +20,14 @@ interface
 uses
   LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, UBlockChain, UCrypto, UWalletKeys, Buttons, ComCtrls,
-  UAppParams;
+  Dialogs, StdCtrls, UCommonUI,
+  UBlockChain, UCrypto, UWalletKeys, Buttons, ComCtrls,UAppParams;
 
 type
 
   { TFRMPayloadDecoder }
 
-  TFRMPayloadDecoder = class(TForm)
+  TFRMPayloadDecoder = class(TApplicationForm)
     Label1: TLabel;
     lblBlock: TLabel;
     lblDateTime: TLabel;

+ 3 - 3
Units/Forms/UFRMPendingOperations.lfm

@@ -1,7 +1,7 @@
 object FRMPendingOperations: TFRMPendingOperations
-  Left = 283
+  Left = 156
   Height = 357
-  Top = 313
+  Top = 188
   Width = 860
   Caption = 'Pending Operations'
   ClientHeight = 337
@@ -61,7 +61,7 @@ object FRMPendingOperations: TFRMPendingOperations
         OnClick = miFindOperationbyOpHashClick
       end
       object miDecodePayLoad: TMenuItem
-        Caption = 'Decode Payload Pending Operations'
+        Caption = 'Decode Payload'
         OnClick = miDecodePayLoadClick
       end
     end

+ 3 - 3
Units/Forms/UFRMPendingOperations.pas

@@ -6,13 +6,13 @@ interface
 
 uses
   Classes, Forms, Grids,
-  ExtCtrls, StdCtrls, Menus, UGridUtils;
+  ExtCtrls, StdCtrls, Menus, UCommonUI, UGridUtils;
 
 type
 
   { TFRMPendingOperations }
 
-  TFRMPendingOperations = class(TForm)
+  TFRMPendingOperations = class(TApplicationForm)
     dgPendingOperations: TDrawGrid;
     Label10: TLabel;
     PendingOperationsMenu: TMainMenu;
@@ -59,7 +59,7 @@ end;
 
 procedure TFRMPendingOperations.miDecodePayLoadClick(Sender: TObject);
 begin
-
+  FPendingOperationsGrid.ShowModalDecoder(TUserInterface.WalletKeys,TUserInterface.AppParams);
 end;
 
 procedure TFRMPendingOperations.miFindOperationbyOpHashClick(Sender: TObject);

+ 1 - 1
Units/Forms/UFRMSaleAccounts.pas

@@ -9,7 +9,7 @@ uses
   Dialogs, StdCtrls, UAccounts, Buttons, ActnList;
 
 type
-  TFRMSaleAccounts = class(TForm)
+  TFRMSaleAccounts = class(TApplicationForm)
     lblAccountCaption: TLabel;
     ebSenderAccount: TEdit;
     memoAccounts: TMemo;

+ 2 - 9
Units/Forms/UFRMSyncronizationDialog.pas

@@ -6,13 +6,13 @@ interface
 
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
-  StdCtrls;
+  StdCtrls, UCommonUI;
 
 type
 
   { TFRMSyncronizationDialog }
 
-  TFRMSyncronizationDialog = class(TForm)
+  TFRMSyncronizationDialog = class(TApplicationForm)
     HideButton:TButton;
     Image1:TImage;
     Label16:TLabel;
@@ -111,16 +111,10 @@ end;
 
 procedure TFRMSyncronizationDialog.UpdateBlockChainState;
 Var
-  isMining : boolean;
-//  hr : Int64;
-  i,mc : Integer;
-  s : String;
-  mtl : TList;
   f, favg : real;
 begin
   if not TUserInterface.Started then exit;
   UpdateNodeStatus;
-  mc := 0;
   if Assigned(TUserInterface.Node) then begin
     if TUserInterface.Node.Bank.BlocksCount>0 then begin
       lblCurrentBlock.Caption :=  Inttostr(TUserInterface.Node.Bank.BlocksCount)+' (0..'+Inttostr(TUserInterface.Node.Bank.BlocksCount-1)+')'; ;
@@ -144,7 +138,6 @@ begin
         CT_CalcNewTargetBlocksAverage DIV 2,FormatFloat('0.0',TUserInterface.Node.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 2)),
         CT_CalcNewTargetBlocksAverage DIV 4,FormatFloat('0.0',TUserInterface.Node.Bank.GetActualTargetSecondsAverage(CT_CalcNewTargetBlocksAverage DIV 4))]);
   end else begin
-    isMining := false;
     lblCurrentBlock.Caption := '';
     lblCurrentAccounts.Caption := '';
     lblCurrentBlockTime.Caption := '';

+ 10 - 8
Units/Forms/UFRMWallet.lfm

@@ -14,6 +14,8 @@ object FRMWallet: TFRMWallet
   Font.Height = -11
   Font.Name = 'Tahoma'
   Menu = meMainMenu
+  OnClose = FormClose
+  OnCloseQuery = FormCloseQuery
   OnCreate = FormCreate
   OnDestroy = FormDestroy
   OnResize = FormResize
@@ -108,7 +110,7 @@ object FRMWallet: TFRMWallet
     top = 496
     object miWallet: TMenuItem
       Caption = 'Wallet'
-      object miPrivatekeys: TMenuItem
+      object miPrivateKeys: TMenuItem
         Caption = 'Private Keys'
         Bitmap.Data = {
           36040000424D3604000000000000360000002800000010000000100000000100
@@ -149,7 +151,7 @@ object FRMWallet: TFRMWallet
         Hint = 'Show Private Keys'
         ImageIndex = 2
         ShortCut = 16464
-        OnClick = miPrivatekeysClick
+        OnClick = miPrivateKeysClick
       end
       object miN1: TMenuItem
         Caption = '-'
@@ -159,9 +161,9 @@ object FRMWallet: TFRMWallet
         ShortCut = 16463
         OnClick = miOptionsClick
       end
-      object IPnodes1: TMenuItem
-        Caption = 'Available Node List'
-        OnClick = IPnodes1Click
+      object miSeedNodes: TMenuItem
+        Caption = 'Seed Nodes'
+        OnClick = miSeedNodesClick
       end
       object N1: TMenuItem
         Caption = '-'
@@ -244,11 +246,11 @@ object FRMWallet: TFRMWallet
         OnClick = miSyncDialogClick
       end
     end
-    object miAbout: TMenuItem
+    object miAboutMenu: TMenuItem
       Caption = 'About'
-      object miAboutPascalCoin: TMenuItem
+      object miAbout: TMenuItem
         Caption = 'About Pascal Coin...'
-        OnClick = miAboutPascalCoinClick
+        OnClick = miAboutClick
       end
     end
   end

+ 54 - 54
Units/Forms/UFRMWallet.pas

@@ -20,17 +20,16 @@ interface
 {$I ./../PascalCoin/config.inc}
 
 uses
-  LCLIntf, LCLType, LMessages,
   Messages, SysUtils, Classes, Graphics, Controls, Forms,
-  Dialogs, ExtCtrls, ComCtrls, UWalletKeys, StdCtrls,
-  ULog, Grids, UAppParams,
-  UBlockChain, UNode, UGridUtils, UAccounts, Menus,// Types,
-  UNetProtocol, UCrypto, Buttons, ButtonPanel, ActnList, UPoolMining, URPC,
-  UFRMAccountSelect, UCommon, UCommonUI, UFRMSyncronizationDialog;
+  Dialogs, ExtCtrls, ComCtrls, UWalletKeys,
+  ULog,
+  UBlockChain, UNode, UGridUtils, UAccounts, Menus,
+  UNetProtocol, UCrypto, Buttons, ActnList, UPoolMining,
+  UCommon, UCommonUI;
 
 Const
   CM_PC_WalletKeysChanged = WM_USER + 1;
-  CM_PC_NetConnectionUpdated = WM_USER + 2;
+  CM_PC_ConnectivityChanged = WM_USER + 2;
 
 type
 
@@ -52,45 +51,47 @@ type
     meMainMenu: TMainMenu;
     miWallet: TMenuItem;
     miOptions: TMenuItem;
-    miPrivatekeys: TMenuItem;
+    miPrivateKeys: TMenuItem;
     miN1: TMenuItem;
+    miAboutMenu: TMenuItem;
     miAbout: TMenuItem;
-    miAboutPascalCoin: TMenuItem;
     N1: TMenuItem;
     miClose: TMenuItem;
     ilIcons: TImageList;
     ApplicationEvents: TApplicationProperties;
-    IPnodes1: TMenuItem;
+    miSeedNodes: TMenuItem;
     pnlSelectedAccountsBottom: TPanel;
     tbFooter: TToolBar;
     tbtnConnectivity: TToolButton;
     tbtnSync: TToolButton;
     tbtnWalletLock: TToolButton;
+    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
+    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
     procedure FormCreate(Sender: TObject);
+    procedure FormDestroy(Sender: TObject);
     procedure FormResize(Sender: TObject);
     procedure miAccountExplorerClick(Sender: TObject);
     procedure miBlockExplorerClick(Sender: TObject);
-    procedure FormDestroy(Sender: TObject);
     procedure miLogsClick(Sender: TObject);
     procedure miMessagesClick(Sender: TObject);
     procedure miSyncDialogClick(Sender:TObject);
-    procedure sbFooterBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
-      const Rect: TRect);
-    procedure tbtnConnectivityClick(Sender:TObject);
     procedure miNodesClick(Sender: TObject);
     procedure miPendingOperationsClick(Sender: TObject);
     procedure miOperationsExplorerClick(Sender: TObject);
-    procedure tbtnSyncClick(Sender: TObject);
-    procedure tbtnWalletLockClick(Sender:TObject);
     procedure miOptionsClick(Sender: TObject);
-    procedure miAboutPascalCoinClick(Sender: TObject);
-    procedure miPrivatekeysClick(Sender: TObject);
+    procedure miAboutClick(Sender: TObject);
+    procedure miPrivateKeysClick(Sender: TObject);
     procedure miCloseClick(Sender: TObject);
-    procedure MiDecodePayloadFOperationsExplorerGridClick(Sender: TObject);
+    procedure tbtnSyncClick(Sender: TObject);
+    procedure tbtnWalletLockClick(Sender:TObject);
+    procedure tbtnConnectivityClick(Sender:TObject);
+    procedure sbFooterBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; const Rect: TRect);
     procedure ApplicationEventsMinimize(Sender: TObject);
-    procedure IPnodes1Click(Sender: TObject);
+    procedure miSeedNodesClick(Sender: TObject);
   private
     FLastFooterToolBarDrawRect : TRect;
+    procedure CM_WalletChanged(var Msg: TMessage); message CM_PC_WalletKeysChanged;
+    procedure CM_ConnectivityChanged(var Msg: TMessage); message CM_PC_ConnectivityChanged;
     procedure OnConnectivityChanged(Sender: TObject);
     procedure OnWalletChanged(Sender: TObject);
   protected
@@ -98,14 +99,13 @@ type
     procedure RefreshConnectivityIcon;
     procedure ActivateFirstTime; override;
     Function ForceMining : Boolean; virtual;
-    procedure CM_WalletChanged(var Msg: TMessage); message CM_PC_WalletKeysChanged;
   end;
 
 implementation
 
 {$R *.lfm}
 
-uses UThread, UOpTransaction, UUserInterface;
+uses LCLIntf, UUserInterface, UThread, UOpTransaction;
 
 const
   CT_FOOTER_TOOLBAR_LEFT_PADDING = 8;
@@ -121,8 +121,21 @@ begin
   FLastFooterToolBarDrawRect := TRect.Empty;
 end;
 
+procedure TFRMWallet.FormCloseQuery(Sender: TObject; var CanClose: boolean);
+begin
+
+end;
+
+procedure TFRMWallet.FormClose(Sender: TObject; var CloseAction: TCloseAction);
+begin
+  CloseAction := caHide;
+  // TODO - ask to go background or quit
+  // if quit then
+  TUserInterface.Quit;
+
+end;
+
 procedure TFRMWallet.ActivateFirstTime;
-var count : Integer;
 begin
   TUserInterface.WalletKeys.OnChanged.Add(OnWalletChanged);
   TNetData.NetData.OnConnectivityChanged.Add(OnConnectivityChanged);
@@ -153,11 +166,6 @@ end;
 
 {%region Form methods}
 
-procedure TFRMWallet.CM_WalletChanged(var Msg: TMessage);
-begin
-  OnWalletChanged(Self);
-end;
-
 function TFRMWallet.ForceMining: Boolean;
 begin
   Result := false;
@@ -184,12 +192,10 @@ begin
 end;
 
 procedure TFRMWallet.RefreshConnectivityIcon;
-var   active : boolean;
 const
   ImageIndexConst : array[false..true] of integer=(1,0);
   HintConst : array[false..true] of String =('Network is inactive. Click activate.','Network is active. Click to deactivate.');
 begin
-  active := TNetData.NetData.NetConnectionsActive;
   tbtnConnectivity.ImageIndex := ImageIndexConst[TNetData.NetData.NetConnectionsActive];
   tbtnConnectivity.Hint :=  HintConst[TNetData.NetData.NetConnectionsActive];
 end;
@@ -208,16 +214,28 @@ end;
 
 {%region Handlers: Wallet, Network}
 
-procedure TFRMWallet.OnWalletChanged(Sender: TObject);
+procedure TFRMWallet.CM_WalletChanged(var Msg: TMessage);
 begin
   RefreshWalletLockIcon;
 end;
 
-procedure TFRMWallet.OnConnectivityChanged(Sender: TObject);
+procedure TFRMWallet.OnWalletChanged(Sender: TObject);
+begin
+  // Ensure handled in UI thread
+  PostMessage(Self.Handle,CM_PC_WalletKeysChanged,0,0);
+end;
+
+procedure TFRMWallet.CM_ConnectivityChanged(var Msg: TMessage);
 begin
   RefreshConnectivityIcon;
 end;
 
+procedure TFRMWallet.OnConnectivityChanged(Sender: TObject);
+begin
+  // Ensure handled in UI thread
+  PostMessage(Self.Handle,CM_PC_ConnectivityChanged,0,0);
+end;
+
 {%endregion}
 
 {%region Handlers: Menu Items }
@@ -279,12 +297,12 @@ begin
   TUserInterface.ShowAccountExplorer
 end;
 
-procedure TFRMWallet.IPnodes1Click(Sender: TObject);
+procedure TFRMWallet.miSeedNodesClick(Sender: TObject);
 begin
-  TUserInterface.ShowNodeIPDialog(Self);
+  TUserInterface.ShowSeedNodesDialog(Self);
 end;
 
-procedure TFRMWallet.miAboutPascalCoinClick(Sender: TObject);
+procedure TFRMWallet.miAboutClick(Sender: TObject);
 begin
   TUserInterface.ShowAboutBox(Self);
 end;
@@ -294,30 +312,12 @@ begin
   Close;
 end;
 
-procedure TFRMWallet.MiDecodePayloadFOperationsExplorerGridClick(Sender: TObject);
-begin
-  raise Exception.Create('Not Implemented');
-//  { TODO 5 -oAntonB -csub-forms :
-//  Menu Item Decode PayLoad use info about active page. That Shows different modal forms on different active pages. I delete pages now. I change Decode PayLoad to:
-//  I add 3 menu Items:Decode Payload miPendingOperations Explorer, Decode Payload Pending, miPendingOperations,Decode Payload My miAccountExplorer }
-////  if PageControl.ActivePage=tsOperations then begin
-//  if Sender=MiDecodePayloadFOperationsExplorerGrid then begin
-//    FOperationsExplorerGrid.ShowModalDecoder(TUserInterface.WalletKeys,TUserInterface.AppParams);
-////  end else if PageControl.ActivePage=tsPendingOperations then begin
-//  end else if Sender=MiDecodePayLoadPendingOperations then begin
-//    FPendingOperationsGrid.ShowModalDecoder(TUserInterface.WalletKeys,TUserInterface.AppParams);
-////  end else if PageControl.ActivePage=tsMyAccounts then begin
-//  end else if Sender=MiDecodePayloadOperationsAccount then begin
-//    FOperationsAccountGrid.ShowModalDecoder(TUserInterface.WalletKeys,TUserInterface.AppParams);
-//  end;
-end;
-
 procedure TFRMWallet.miOptionsClick(Sender: TObject);
 begin
   TUserInterface.ShowOptionsDialog(Self);
 end;
 
-procedure TFRMWallet.miPrivatekeysClick(Sender: TObject);
+procedure TFRMWallet.miPrivateKeysClick(Sender: TObject);
 begin
   TUserInterface.ShowPrivateKeysDialog(Self);
 end;

+ 3 - 5
Units/Forms/UFRMWalletKeys.pas

@@ -19,14 +19,14 @@ interface
 
 uses
   Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, UWalletKeys, Buttons,
+  Dialogs, StdCtrls, UCommonUI, UWalletKeys, Buttons,
   LMessages, clipbrd, UConst, UCommon;
 
 Const
   CM_PC_WalletKeysChanged = LM_USER + 1;
 
 type
-  TFRMWalletKeys = class(TForm)
+  TFRMWalletKeys = class(TApplicationForm)
     lbWalletKeys: TListBox;
     bbExportPrivateKey: TBitBtn;
     lblEncryptionTypeCaption: TLabel;
@@ -83,8 +83,7 @@ type
 implementation
 
 uses
-  LCLIntf, LCLType,
-  UCrypto, UAccounts, UUserInterface, UFRMNewPrivateKeyType, UAES;
+  LCLIntf, LCLType, UCrypto, UAccounts, UUserInterface, UFRMNewPrivateKeyType, UAES;
 
 {$R *.lfm}
 
@@ -447,7 +446,6 @@ end;
 procedure TFRMWalletKeys.OnWalletKeysChanged(Sender : TObject);
 begin
   PostMessage(Self.Handle,CM_PC_WalletKeysChanged,0,0);
-  //if Assigned(FOldOnChanged) then FOldOnChanged(Sender);   XXXXX HS 2017-09-07: is this procedure needed anymore?
 end;
 
 procedure TFRMWalletKeys.SetWalletKeys(const Value: TWalletKeys);

+ 1 - 1
Units/Forms/UFRMWalletKeys2.pas

@@ -8,7 +8,7 @@ uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
 
 type
-  TFRMWalletKeys2 = class(TForm)
+  TFRMWalletKeys2 = class(TApplicationForm)
   private
     { private declarations }
   public

+ 57 - 20
Units/Forms/UUserInterface.pas

@@ -6,6 +6,7 @@ interface
 
 uses
   SysUtils, Classes, Forms, Controls, Windows, ExtCtrls,
+  UCommonUI,
   UAccounts, UNode, UWalletKeys, UAppParams, UConst, UFolderHelper, UGridUtils, URPC, UPoolMining, ULog, UThread, UNetProtocol, UCrypto,
   UFRMWallet, UFRMSyncronizationDialog, UFRMAccountExplorer, UFRMPendingOperations, UFRMOperation,
   UFRMLogs, UFRMMessages, UFRMNodes, UFRMBlockExplorer, UFRMWalletKeys;
@@ -14,6 +15,7 @@ type
   { Forward Declarations }
   TLoadSafeBoxThread = class;
 
+
   { TMinerPrivateKey }
 
   TMinerPrivateKey = (mpk_NewEachTime, mpk_Random, mpk_Selected);
@@ -40,7 +42,6 @@ type
       FWalletKeys : TWalletKeysExt; static;
 
       FRPCServer : TRPCServer; static;
-      FMustProcessWalletChanged : Boolean; static;
       FPoolMiningServer : TPoolMiningServer; static;
 
       FUpdating : Boolean; static;
@@ -71,6 +72,7 @@ type
 
       // Handlers
       class procedure TimerUpdateStatusTimer(Sender: TObject);
+      class procedure OnSubFormDestroyed(Sender: TObject);
 
       // Blockchain event handlers. TODO: refactor this out with TNotifyEvents
       // so forms that need these messages subscribe directly
@@ -103,7 +105,7 @@ type
       class procedure ShowNewOperationDialog(parentForm : TForm; accounts : TOrderedCardinalList; defaultFee : Cardinal);
       class procedure ShowSyncronizationDialog(parentForm : TForm);
       class procedure ShowWalletKeysDialog(parentForm : TForm);
-      class procedure ShowNodeIPDialog(parentForm : TForm);
+      class procedure ShowSeedNodesDialog(parentForm : TForm);
       class procedure ShowAccountInformationDialog(parentForm : TForm; account : UInt64);
       class procedure ShowPrivateKeysDialog(parentForm: TForm);
       class procedure UnlockWallet(parentForm: TForm;  walletKeys : TWalletKeys);
@@ -120,6 +122,7 @@ type
   end;
 
   { TLoadSafeBoxThread }
+
   TLoadSafeBoxThread = Class(TPCThread)
   protected
     procedure BCExecute; override;
@@ -127,7 +130,7 @@ type
 
 implementation
 
-uses Dialogs, UCommon, UCommonUI, UOpenSSL, UFileStorage, UTime, UFRMAbout, UFRMNodesIp, UFRMPascalCoinWalletConfig ;
+uses Dialogs, UCommon, UOpenSSL, UFileStorage, UTime, UFRMAbout, UFRMNodesIp, UFRMPascalCoinWalletConfig ;
 
 {%region UI Lifecyle}
 
@@ -157,6 +160,7 @@ begin
 
     // Create main form and try icon
     FWallet := mainForm as TFRMWallet;
+    FWallet.CloseAction := caFree;     // wallet is destroyed on close
     if (FWallet = nil)
       then raise Exception.Create('Main form is not TWallet');
     FTrayIcon := TTrayIcon.Create(TUserInterface.FWallet);
@@ -289,7 +293,7 @@ class procedure TUserInterface.Quit;
 Var i : Integer;
   step : String;
 begin
-  TLog.NewLog(ltinfo,Classname,'Destroying form - START');
+  TLog.NewLog(ltinfo,Classname,'Quit Application - START');
   Try
     FreeAndNil(FRPCServer);
     FreeAndNil(FPoolMiningServer);
@@ -316,6 +320,7 @@ begin
     TNode.Node.NetServer.Active := false;
     FNode := Nil;
 
+    // Destroy NetData
     TNetData.NetData.Free;
 
     step := 'Processing messages 1';
@@ -344,10 +349,10 @@ begin
     FreeAndNil(FUILock);
   Except
     On E:Exception do begin
-      TLog.NewLog(lterror,Classname,'Error destroying Form step: '+step+' Errors ('+E.ClassName+'): ' +E.Message);
+      TLog.NewLog(lterror,Classname,'Error quiting application step: '+step+' Errors ('+E.ClassName+'): ' +E.Message);
     end;
   End;
-  TLog.NewLog(ltinfo,Classname,'Destroying form - END');
+  TLog.NewLog(ltinfo,Classname,'Error quiting application - END');
   FreeAndNil(FLog);
   Sleep(100);
 end;
@@ -452,12 +457,11 @@ begin
   End;
 end;
 
-class procedure TUserInterface.ShowNodeIPDialog(parentForm : TForm);
+class procedure TUserInterface.ShowSeedNodesDialog(parentForm : TForm);
 Var FRM : TFRMNodesIp;
 begin
   FRM := TFRMNodesIp.Create(parentForm);
   Try
-    FRM.AppParams := TUserInterface.AppParams;
     FRM.ShowModal;
   Finally
     FRM.Free;
@@ -582,7 +586,9 @@ begin
     FUILock.Acquire;
     if not Assigned(FAccountExplorer) then begin
        FAccountExplorer := TFRMAccountExplorer.Create(FWallet);
-       FWallet.SetSubFormCoordinate(FAccountExplorer);
+       FAccountExplorer.CloseAction:= caFree;
+       FAccountExplorer.OnDestroyed:= Self.OnSubFormDestroyed;
+       FAccountExplorer.SetSubFormCoordinate(FAccountExplorer);
     end;
     FAccountExplorer.Refresh;
     FAccountExplorer.Show;
@@ -597,6 +603,8 @@ begin
     FUILock.Acquire;
     if not Assigned(FBlockExplorerForm) then begin
        FBlockExplorerForm := TFRMBlockExplorer.Create(FWallet);
+       FBlockExplorerForm.CloseAction:= caFree;
+       FBlockExplorerForm.OnDestroyed:= Self.OnSubFormDestroyed;
        FWallet.SetSubFormCoordinate(FBlockExplorerForm);
     end;
     FBlockExplorerForm.Show;
@@ -611,6 +619,8 @@ begin
     FUILock.Acquire;
     if not Assigned(FOperationsExplorerForm) then begin
       FOperationsExplorerForm := TFRMOperation.Create(FWallet);
+      FOperationsExplorerForm.CloseAction:= caFree;
+      FOperationsExplorerForm.OnDestroyed:= Self.OnSubFormDestroyed;
       FWallet.SetSubFormCoordinate(FOperationsExplorerForm);
     end;
     FOperationsExplorerForm.Show;
@@ -625,6 +635,8 @@ begin
     FUILock.Acquire;
     if not Assigned(FPendingOperationForm) then begin
       FPendingOperationForm := TFRMPendingOperations.Create(FWallet);
+      FPendingOperationForm.CloseAction:= caFree;
+      FPendingOperationForm.OnDestroyed:= Self.OnSubFormDestroyed;
       FWallet.SetSubFormCoordinate(FPendingOperationForm);
     end;
     FPendingOperationForm.Show;
@@ -639,6 +651,8 @@ begin
     FUILock.Acquire;
     if not Assigned(FMessagesForm) then begin
        FMessagesForm := TFRMMessages.Create(FWallet);
+       FMessagesForm.CloseAction:= caFree;
+       FMessagesForm.OnDestroyed:= Self.OnSubFormDestroyed;
        FWallet.SetSubFormCoordinate(FMessagesForm);
     end;
     FMessagesForm.Show;
@@ -653,6 +667,8 @@ begin
     FUILock.Acquire;
     if not Assigned(FNodesForm) then begin
        FNodesForm := TFRMNodes.Create(FWallet);
+       FNodesForm.CloseAction:= caFree;
+       FNodesForm.OnDestroyed:= Self.OnSubFormDestroyed;
        FWallet.SetSubFormCoordinate(FNodesForm);
     end;
     FNodesForm.Show;
@@ -667,6 +683,8 @@ begin
     FUILock.Acquire;
     if not Assigned(FLogsForm) then begin
        FLogsForm := TFRMLogs.Create(FWallet);
+       FLogsForm.CloseAction:= caFree;
+       FLogsForm.OnDestroyed:= Self.OnSubFormDestroyed;
        FWallet.SetSubFormCoordinate(FLogsForm);
     end;
     FLogsForm.Show;
@@ -797,12 +815,6 @@ class procedure TUserInterface.NotifyConfigChanged;
 Var wa : Boolean;
   i : Integer;
 begin
-// AntonB logs form not visible now at start and OnNewLog := Nil
-//  tsLogs.TabVisible := FAppParams.ParamByName[CT_PARAM_ShowLogs].GetAsBoolean(false);
-//  if (Not tsLogs.TabVisible) then begin
-//    FLog.OnNewLog := Nil;
-//    if PageControl.ActivePage = tsLogs then PageControl.ActivePage := tsMyAccounts;
-//  end else FLog.OnNewLog := OnNewLog;
   if FAppParams.ParamByName[CT_PARAM_SaveLogFiles].GetAsBoolean(false) then begin
     if FAppParams.ParamByName[CT_PARAM_SaveDebugLogs].GetAsBoolean(false) then FLog.SaveTypes := CT_TLogTypes_ALL
     else FLog.SaveTypes := CT_TLogTypes_DEFAULT;
@@ -995,7 +1007,7 @@ begin
   Try
     RefreshConnectionStatusDisplay;
     FSyncronizationDialog.UpdateBlockChainState;
-    // UpdateNodeStatus; AntonB in UpdateBlockChainState call UpdateNodeStatus
+    FSyncronizationDialog.UpdateNodeStatus;
   Except
     On E:Exception do begin
       E.Message := 'Exception at TimerUpdate '+E.ClassName+': '+E.Message;
@@ -1013,10 +1025,34 @@ begin
   Application.BringToFront();
 end;
 
-{%endregion}
+class procedure TUserInterface.OnSubFormDestroyed(Sender: TObject);
+begin
+  try
+    FUILock.Acquire;
+    if Sender = FAccountExplorer then
+      FAccountExplorer := nil // form free's on close
+    else if Sender = FPendingOperationForm then
+      FPendingOperationForm := nil // form free's on close
+    else if Sender = FOperationsExplorerForm then
+      FOperationsExplorerForm := nil // form free's on close
+    else if Sender = FBlockExplorerForm then
+      FBlockExplorerForm := nil // form free's on close
+    else if Sender = FLogsForm then
+      FLogsForm := nil // form free's on close
+    else if Sender = FNodesForm then
+      FNodesForm := nil // form free's on close
+    else if Sender = FMessagesForm then
+      FMessagesForm := nil
+    else
+      raise Exception.Create('Internal Error: [NotifySubFormDestroyed] encountered an unknown sub-form instance');
+  finally
+    FUILock.Release;
+  end;
+end;
 
+{%endregion}
 
-{ TUserInterfaceStartupThread }
+{ TLoadSafeBoxThread }
 
 procedure TLoadSafeBoxThread.BCExecute;
 begin
@@ -1027,8 +1063,9 @@ begin
   Synchronize( TUserInterface.FinishedLoadingApp );
 end;
 
+initialization
+// TODO - any startup code needed here?
 finalization
-  TUserInterface.FWallet.Destroy;
-
+// TODO - final cleanup here, show a modal dialog?
 end.
 

+ 1 - 1
Units/PascalCoin/UBlockChain.pas

@@ -710,7 +710,7 @@ begin
         FLastOperationBlock.initial_safe_box_hash := TCrypto.DoSha256(CT_Genesis_Magic_String_For_Old_Block_Hash); // Genesis hash
       end;
     finally
-      FBankLock.Release; // AntonB If fast close Wallet after open this Error string
+      FBankLock.Release; // TODO - If fast close Wallet after open this Error string
     end;
     for i := 0 to FNotifyList.Count - 1 do begin
       TPCBankNotify(FNotifyList.Items[i]).NotifyNewBlock;

+ 1 - 2
Units/PascalCoin/UThread.pas

@@ -323,8 +323,7 @@ begin
   end;
 end;
 
-function TPCThreadList.TryLockList(MaxWaitMilliseconds: Cardinal;
-  var lockedList: TList): Boolean;
+function TPCThreadList.TryLockList(MaxWaitMilliseconds: Cardinal; var lockedList: TList): Boolean;
 begin
   lockedList := FList;
   Result := TPCThread.TryProtectEnterCriticalSection(Self,MaxWaitMilliseconds,FLock);

+ 1 - 1
Units/PascalCoin/UWalletKeys.pas

@@ -310,7 +310,7 @@ end;
 function TWalletKeys.LockWallet: Boolean;
 begin
   // Return true when wallet has a password, locking it. False if there password is empty string
-  FWalletPassword := ''; //AntonB - this clear Password on lock - is block lock
+  FWalletPassword := '';
   GeneratePrivateKeysFromPassword;
   Result := Not IsValidPassword;
   FOnChanged.Invoke(Self);

+ 33 - 8
Units/Utils/UCommonUI.pas

@@ -29,15 +29,22 @@ type
     private
       FActivatedCount : UInt32;
       FActivateFirstTime : TNotifyEvent;
+      FDestroyed : TNotifyEvent;
+      FCloseAction : TCloseAction;
       procedure NotifyActivateFirstTime;
+      procedure NotifyDestroyed;
     protected
       FUILock : TCriticalSection;
       procedure DoCreate; override;
-      procedure DoDestroy; override;
       procedure Activate; override;
       procedure ActivateFirstTime; virtual;
+      procedure DoClose(var CloseAction: TCloseAction); override;
+      procedure DoDestroy; override;
+      procedure DoDestroyed; virtual;
     published
+      property CloseAction : TCloseAction read FCloseAction write FCloseAction;
       property OnActivateFirstTime : TNotifyEvent read FActivateFirstTime write FActivateFirstTime;
+      property OnDestroyed : TNotifyEvent read FDestroyed write FDestroyed;
   end;
 
   { TWinControlHelper }
@@ -62,13 +69,7 @@ begin
   inherited;
   FUILock := TCriticalSection.Create;
   FActivatedCount := 0;
-end;
-
-procedure TApplicationForm.DoDestroy;
-begin
-  inherited;
-  FUILock.Destroy;
-  FUILock := nil;
+  FCloseAction:=caHide;
 end;
 
 procedure TApplicationForm.Activate;
@@ -83,6 +84,23 @@ procedure TApplicationForm.ActivateFirstTime;
 begin;
 end;
 
+procedure TApplicationForm.DoClose(var CloseAction: TCloseAction);
+begin
+  CloseAction := FCloseAction;
+end;
+
+procedure TApplicationForm.DoDestroy;
+begin
+  inherited;
+  FActivatedCount:=0;
+  FUILock.Destroy;
+  FUILock := nil;
+  NotifyDestroyed;
+end;
+
+procedure TApplicationForm.DoDestroyed;
+begin;
+end;
 
 procedure TApplicationForm.NotifyActivateFirstTime;
 begin
@@ -91,6 +109,13 @@ begin
     FActivateFirstTime(Self);
 end;
 
+procedure TApplicationForm.NotifyDestroyed;
+begin
+  DoDestroyed;
+  if Assigned(FDestroyed) then
+    FDestroyed(Self);
+end;
+
 {%endregion}
 
 {%region TWinControlHelper}