From f124ccd0c2c27644613f7d892bb7ce636130fae7 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Sat, 15 Oct 2016 09:37:58 +0200 Subject: [PATCH] Finished proper DateTime support Added Copy functionality for dictionary details to monitor form --- Test/source/MainFrm.dfm | 4 +-- Test/source/MainFrm.pas | 2 +- X2Log.Details.Default.pas | 7 +++++ X2Log.Intf.pas | 11 +++++-- X2Log.Observer.MonitorForm.dfm | 4 +-- X2Log.Observer.MonitorForm.pas | 53 +++++++++++++++++++++++++++++++--- 6 files changed, 70 insertions(+), 11 deletions(-) diff --git a/Test/source/MainFrm.dfm b/Test/source/MainFrm.dfm index c15c481..61657c1 100644 --- a/Test/source/MainFrm.dfm +++ b/Test/source/MainFrm.dfm @@ -358,7 +358,7 @@ object MainForm: TMainForm Margins.Top = 8 Margins.Right = 8 Margins.Bottom = 0 - ActivePage = tsTimer + ActivePage = tsStructured Align = alTop TabOrder = 2 object tsText: TTabSheet @@ -609,7 +609,7 @@ object MainForm: TMainForm Left = 552 Top = 176 Bitmap = { - 494C0101020014005C000C000C00FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C01010200140060000C000C00FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000300000000C00000001002000000000000009 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/Test/source/MainFrm.pas b/Test/source/MainFrm.pas index c3e311b..e096835 100644 --- a/Test/source/MainFrm.pas +++ b/Test/source/MainFrm.pas @@ -476,7 +476,7 @@ procedure TMainForm.btnValueTypesClick(Sender: TObject); begin FLog.InfoS('Testing the various value types', ['String', 'Hello world!', - 'DateTime', Now, + 'DateTime', LogDT, 'Has the large hadron collider destroyed the world yet?', False, 'Float', 3.1415, 'Integer', 89740987342]); diff --git a/X2Log.Details.Default.pas b/X2Log.Details.Default.pas index 73c021e..9720ebf 100644 --- a/X2Log.Details.Default.pas +++ b/X2Log.Details.Default.pas @@ -331,6 +331,7 @@ var param: TVarRec; key: string; value: TX2LogDictionaryValue; + logDateTime: IX2LogDateTime; begin inherited Create; @@ -375,6 +376,12 @@ begin vtPWideChar: value := TX2LogDictionaryStringValue.Create(param.VPWideChar); vtAnsiString: value := TX2LogDictionaryStringValue.Create(PChar(param.VAnsiString)); vtCurrency: value := TX2LogDictionaryFloatValue.Create(param.VCurrency^); + vtInterface: + if Supports(IInterface(param.VInterface), IX2LogDateTime, logDateTime) then + value := TX2LogDictionaryDateTimeValue.Create(logDateTime.Value) + else + raise Exception.CreateFmt('Unsupported value type %d at index %d', [param.VType, paramIndex]); + vtWideString: value := TX2LogDictionaryStringValue.Create(WideString(param.VWideString)); vtInt64: value := TX2LogDictionaryIntValue.Create(param.VInt64^); {$IF CompilerVersion >= 23} diff --git a/X2Log.Intf.pas b/X2Log.Intf.pas index 739932b..43b95c7 100644 --- a/X2Log.Intf.pas +++ b/X2Log.Intf.pas @@ -109,7 +109,8 @@ type { Use this wrapper when passing a TDateTime to one of the structured logging methods, otherwise Delphi will pass it as a floating point value. } - function DT(AValue: TDateTime): IX2LogDateTime; + function LogDT: IX2LogDateTime; overload; + function LogDT(AValue: TDateTime): IX2LogDateTime; overload; implementation @@ -125,7 +126,13 @@ type -function DT(AValue: TDateTime): IX2LogDateTime; +function LogDT: IX2LogDateTime; +begin + Result := LogDT(Now); +end; + + +function LogDT(AValue: TDateTime): IX2LogDateTime; begin Result := TX2LogDateTime.Create(AValue); end; diff --git a/X2Log.Observer.MonitorForm.dfm b/X2Log.Observer.MonitorForm.dfm index bb49b40..3a51ad2 100644 --- a/X2Log.Observer.MonitorForm.dfm +++ b/X2Log.Observer.MonitorForm.dfm @@ -144,7 +144,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm Align = alClient Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goAlwaysShowEditor, goThumbTracking] TabOrder = 3 - ExplicitTop = 0 + OnKeyDown = vleDetailsDictionaryKeyDown ColWidths = ( 150 142) @@ -284,7 +284,7 @@ object X2LogObserverMonitorForm: TX2LogObserverMonitorForm Left = 448 Top = 48 Bitmap = { - 494C01010A004000FC0010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C01010A004000000110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000003000000001002000000000000030 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/X2Log.Observer.MonitorForm.pas b/X2Log.Observer.MonitorForm.pas index 65b4e1c..0ee67ec 100644 --- a/X2Log.Observer.MonitorForm.pas +++ b/X2Log.Observer.MonitorForm.pas @@ -5,21 +5,23 @@ uses System.Classes, System.Generics.Collections, System.Types, - Vcl.ActnList, + Vcl.ActnList, Vcl.ComCtrls, Vcl.Controls, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.Forms, + Vcl.Grids, Vcl.ImgList, Vcl.Menus, Vcl.StdCtrls, Vcl.ToolWin, + Vcl.ValEdit, VirtualTrees, Winapi.Messages, X2Log.Details.Intf, - X2Log.Intf, Vcl.Grids, Vcl.ValEdit; + X2Log.Intf; const @@ -34,6 +36,8 @@ type TX2LogObserverMonitorForm = class; TMonitorFormDictionary = TObjectDictionary; + TCopyHandler = procedure of object; + TX2LogObserverMonitorForm = class(TForm, IX2LogObserver) vstLog: TVirtualStringTree; @@ -103,6 +107,7 @@ type procedure vstLogGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure vstLogGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer); procedure vstLogFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); + procedure vleDetailsDictionaryKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure actCloseExecute(Sender: TObject); procedure actClearExecute(Sender: TObject); procedure actCopyDetailsExecute(Sender: TObject); @@ -129,6 +134,7 @@ type FVisibleLevels: TX2LogLevels; FMaxEntries: Cardinal; FWordWrap: Boolean; + FCopyHandler: TCopyHandler; protected class function GetInstance(ALog: IX2LogObservable; out AForm: TX2LogObserverMonitorForm): Boolean; class procedure RemoveInstance(AForm: TX2LogObserverMonitorForm); @@ -153,6 +159,7 @@ type procedure SetBinaryDetails(ADetails: IX2LogDetailsBinary); procedure SetGraphicDetails(ADetails: IX2LogDetailsGraphic); procedure SetDictionaryDetails(ADetails: IX2LogDetailsDictionary); + procedure CopyDictionaryDetails; procedure SetVisibleDetails(AControl: TControl); procedure SetWordWrap(AValue: Boolean); @@ -376,6 +383,7 @@ begin actShowError.Caption := GetLogLevelText(TX2LogLevel.Error); FVisibleLevels := [Low(TX2LogLevel)..High(TX2LogLevel)]; + SetVisibleDetails(nil); UpdateUI; end; @@ -597,6 +605,7 @@ var begin FDetails := ADetails; canWrap := False; + FCopyHandler := nil; if Assigned(Details) then begin @@ -619,7 +628,7 @@ begin SetVisibleDetails(nil); - actCopyDetails.Enabled := Supports(ADetails, IX2LogDetailsCopyable); + actCopyDetails.Enabled := Assigned(FCopyHandler) or Supports(ADetails, IX2LogDetailsCopyable); actSaveDetails.Enabled := Supports(ADetails, IX2LogDetailsStreamable); actWordWrap.Enabled := canWrap; actWordWrap.Checked := canWrap and FWordWrap; @@ -756,10 +765,33 @@ begin vleDetailsDictionary.Values[key] := displayValue; end; + FCopyHandler := CopyDictionaryDetails; SetVisibleDetails(vleDetailsDictionary); end; +procedure TX2LogObserverMonitorForm.CopyDictionaryDetails; +var + y: Integer; + x: Integer; + selectedText: TStringBuilder; + +begin + selectedText := TStringBuilder.Create; + try + for y := vleDetailsDictionary.Selection.Top to vleDetailsDictionary.Selection.Bottom do + begin + for x := vleDetailsDictionary.Selection.Left to vleDetailsDictionary.Selection.Right do + selectedText.Append(vleDetailsDictionary.Cells[x, y]); + end; + + Clipboard.AsText := selectedText.ToString; + finally + FreeAndNil(selectedText); + end; +end; + + procedure TX2LogObserverMonitorForm.SetVisibleDetails(AControl: TControl); begin if Assigned(AControl) then @@ -878,6 +910,16 @@ begin end; +procedure TX2LogObserverMonitorForm.vleDetailsDictionaryKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +begin + if (Shift = [ssCtrl]) and (Key = Ord('C')) then + begin + CopyDictionaryDetails; + Key := 0; + end; +end; + + procedure TX2LogObserverMonitorForm.actCloseExecute(Sender: TObject); begin Close; @@ -898,7 +940,10 @@ var logDetailsCopyable: IX2LogDetailsCopyable; begin - if Supports(Details, IX2LogDetailsCopyable, logDetailsCopyable) then + if Assigned(FCopyHandler) then + FCopyHandler + + else if Supports(Details, IX2LogDetailsCopyable, logDetailsCopyable) then logDetailsCopyable.CopyToClipboard; end;