Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6465997be9 |
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Root Type="DevExpress.CodeRush.Foundation.CodePlaces.Options.FavoritesListContainer">
|
||||
<Options Language="Neutral">
|
||||
<Groups />
|
||||
</Options>
|
||||
</Root>
|
||||
@@ -1,2 +0,0 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
+11
-147
@@ -1,163 +1,27 @@
|
||||
# Generated build outputs for all projects, including Debug/Release archives.
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
AppDiagnostic/bin/
|
||||
AppDiagnostic/obj/
|
||||
Common/bin/
|
||||
Common/obj/
|
||||
Config/bin/
|
||||
Config/obj/
|
||||
DataMatrix4Net/bin/
|
||||
DataMatrix4Net/obj/
|
||||
DataStreamInterface/bin/
|
||||
DataStreamInterface/obj/
|
||||
Decrypt/bin/
|
||||
Decrypt/obj/
|
||||
DeviceTest/bin/
|
||||
DeviceTest/obj/
|
||||
Dirichlet.Numerics/bin
|
||||
Dirichlet.Numerics/obj
|
||||
Encrypt/bin/
|
||||
Encrypt/obj/
|
||||
EventViewer/bin/
|
||||
EventViewer/obj/
|
||||
FeatureVectorCalculator/bin/
|
||||
FeatureVectorCalculator/obj/
|
||||
GemCard/bin/
|
||||
GemCard/obj/
|
||||
GenCode128/bin/
|
||||
GenCode128/obj/
|
||||
GenericTest/bin/
|
||||
GenericTest/obj/
|
||||
GraphLib/bin/
|
||||
GraphLib/obj/
|
||||
LabelPrinting/bin/
|
||||
LabelPrinting/obj/
|
||||
MergeResultsDBs/bin/
|
||||
MergeResultsDBs/obj/
|
||||
NfcC7_Dll/bin/
|
||||
NfcC7_Dll/obj/
|
||||
NfcC7_DLL.Tests/bin/
|
||||
NfcC7_DLL.Tests/obj/
|
||||
OrderManagement/bin/
|
||||
OrderManagement/obj/
|
||||
ProductionTracing/bin/
|
||||
ProductionTracing/obj/
|
||||
RecordProcessing/bin/
|
||||
RecordProcessing/obj/
|
||||
ResetBatchNr/bin/
|
||||
ResetBatchNr/obj/
|
||||
RestClient/bin/
|
||||
RestClient/obj/
|
||||
GemCard/bin
|
||||
GemCard/obj
|
||||
GraphLib/bin
|
||||
GraphLib/obj
|
||||
TracingDB/bin
|
||||
TracingDB/obj
|
||||
Results/bin/
|
||||
Results/obj/
|
||||
ResultsBrowser/bin/
|
||||
ResultsBrowser/obj/
|
||||
ResultsParser/bin/
|
||||
ResultsParser/obj/
|
||||
S640TestApp/bin/
|
||||
S640TestApp/obj/
|
||||
SharedComponents/bin/
|
||||
SharedComponents/obj/
|
||||
SharedDatabase/bin/
|
||||
SharedDatabase/obj/
|
||||
SchematicDrawing/bin/
|
||||
SchematicDrawing/obj/
|
||||
Statistics/bin/
|
||||
Statistics/obj/
|
||||
TBF/bin/
|
||||
TBF/obj/
|
||||
TBFTests/bin/
|
||||
TBFTests/obj/
|
||||
ToFirstMonitor/bin/
|
||||
ToFirstMonitor/obj/
|
||||
ToSecondMonitor/bin/
|
||||
ToSecondMonitor/obj/
|
||||
UserManagement/bin/
|
||||
UserManagement/obj/
|
||||
WorkflowConfigurator/bin/
|
||||
WorkflowConfigurator/obj/
|
||||
Workplace/bin/
|
||||
Workplace/obj/
|
||||
DataStreamInterfaceTest/bin/
|
||||
DataStreamInterfaceTest/obj/
|
||||
DataStreamMeter/bin/
|
||||
DataStreamMeter/obj/
|
||||
Events/bin/
|
||||
Events/obj/
|
||||
TracingDB/bin/
|
||||
TracingDB/obj/
|
||||
TBFSetup/Debug/
|
||||
TBFSetup/Release/
|
||||
Users/bin/
|
||||
Users/obj/
|
||||
.vs/
|
||||
.idea/
|
||||
UserManagement/bin/
|
||||
UserManagement/obj/
|
||||
Doc/
|
||||
*.suo
|
||||
*.bak
|
||||
TBF.sln.DotSettings.user
|
||||
/ExternalProjects
|
||||
/GenesisCordonelTester
|
||||
/packages/*
|
||||
!/packages/Common/
|
||||
/GenesisCordonelInterface/bin/Debug/GenesisCordonelInterfaceLogger.log
|
||||
/GenesisCordonelInterface/bin/Debug/GenesisCordonelTesterLogger.log
|
||||
/GenesisCordonelInterface/bin/Debug/SirtConfig.json
|
||||
/GenesisCordonelInterface/bin/Release
|
||||
/GenesisCordonelInterface/obj/Debug
|
||||
/GenesisCordonelInterface/obj/Release
|
||||
/ExternalProjects
|
||||
/AppDiagnostic.Logging/bin/Debug/net472/AppDiagnostic.Logging.dll
|
||||
/AppDiagnostic.Logging/bin/Debug/net472/AppDiagnostic.Logging.pdb
|
||||
/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfo.cs
|
||||
/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.AssemblyInfoInputs.cache
|
||||
/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.csproj.AssemblyReference.cache
|
||||
/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.dll
|
||||
/AppDiagnostic.Logging/obj/Debug/net472/AppDiagnostic.Logging.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Metrology.Measurements.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Metrology.Measurements.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Ui.CordonelPreadjustmentUi.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Ui.CordonelPreadjustmentUi.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Ui.GenesisToolBox.exe
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Ui.GenesisToolBox.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/XylemCommonUiLegacyGenCtl.dll
|
||||
/GenesisCordonelInterface/bin/Debug/XylemCommonUiLegacyGenCtl.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/de/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.resources.dll
|
||||
/GenesisCordonelInterface/bin/Debug/GenesisCordonelInterface.exe
|
||||
/GenesisCordonelInterface/bin/Debug/GenesisCordonelInterface.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/TempFlansh.exe
|
||||
/GenesisCordonelInterface/bin/Debug/TempFlansh.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.Interfaces.Protocols.ProtocolCore.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.Interfaces.Protocols.ProtocolCore.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.eRegister.eRegisterCore.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.eRegister.eRegisterCore.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxConfig.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxCore.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Hardware.WaterMeter.MagFlux.MagFluxCore.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Logic.RelatePcb.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Logic.RelatePcb.pdb
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Logic.ServiceCore.dll
|
||||
/GenesisCordonelInterface/bin/Debug/Xylem.Common.Logic.ServiceCore.pdb
|
||||
/GenesisCordonelInterface/RuntimePackage/Package
|
||||
/SharedComponents/obj/SharedComponents.csproj.nuget.g.props
|
||||
/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.AssemblyInfo.cs
|
||||
/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.AssemblyInfoInputs.cache
|
||||
/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.csproj.AssemblyReference.cache
|
||||
/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.dll
|
||||
/AppDiagnostic.Logging/obj/Release/net472/AppDiagnostic.Logging.pdb
|
||||
/AppDiagnostic.Logging/bin/Release/net472/AppDiagnostic.Logging.dll
|
||||
/AppDiagnostic.Logging/bin/Release/net472/AppDiagnostic.Logging.pdb
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<RootNamespace>AppDiagnostic.Logging</RootNamespace>
|
||||
<AssemblyName>AppDiagnostic.Logging</AssemblyName>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<ProjectGuid>{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.2.2" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,41 +0,0 @@
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Layouts;
|
||||
|
||||
namespace AppDiagnostic.Logging
|
||||
{
|
||||
public static class AppDiagnosticConnector
|
||||
{
|
||||
private static readonly object syncRoot = new object();
|
||||
|
||||
public static void Register()
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
LoggingConfiguration configuration = LogManager.Configuration ?? new LoggingConfiguration();
|
||||
NLog.Targets.Target existingTarget = configuration.FindTargetByName("appDiagnostic");
|
||||
|
||||
if (existingTarget != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var target = new AppDiagnosticTarget
|
||||
{
|
||||
Name = "appDiagnostic",
|
||||
PipeName = DiagnosticProtocol.DefaultPipeName,
|
||||
QueueLimit = DiagnosticProtocol.DefaultQueueLimit,
|
||||
ReconnectDelayMilliseconds = DiagnosticProtocol.DefaultReconnectDelayMilliseconds,
|
||||
ConnectTimeoutMilliseconds = DiagnosticProtocol.DefaultConnectTimeoutMilliseconds,
|
||||
Layout = new SimpleLayout("${message}")
|
||||
};
|
||||
|
||||
configuration.AddTarget(target.Name, target);
|
||||
configuration.AddRule(LogLevel.Trace, LogLevel.Fatal, target, "*");
|
||||
|
||||
LogManager.Configuration = configuration;
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AppDiagnostic.Logging
|
||||
{
|
||||
[Target("AppDiagnostic")]
|
||||
public sealed class AppDiagnosticTarget : TargetWithLayout
|
||||
{
|
||||
private readonly object connectionLock = new object();
|
||||
private readonly string applicationName;
|
||||
private readonly int processId;
|
||||
|
||||
private BlockingCollection<DiagnosticLogEntry> queue;
|
||||
private CancellationTokenSource cancellation;
|
||||
private Task senderTask;
|
||||
private NamedPipeClientStream pipeClient;
|
||||
|
||||
public AppDiagnosticTarget()
|
||||
{
|
||||
using (Process process = Process.GetCurrentProcess())
|
||||
{
|
||||
applicationName = process.ProcessName;
|
||||
processId = process.Id;
|
||||
}
|
||||
|
||||
PipeName = DiagnosticProtocol.DefaultPipeName;
|
||||
QueueLimit = DiagnosticProtocol.DefaultQueueLimit;
|
||||
ReconnectDelayMilliseconds =
|
||||
DiagnosticProtocol.DefaultReconnectDelayMilliseconds;
|
||||
ConnectTimeoutMilliseconds =
|
||||
DiagnosticProtocol.DefaultConnectTimeoutMilliseconds;
|
||||
}
|
||||
|
||||
public string PipeName { get; set; }
|
||||
|
||||
public int QueueLimit { get; set; }
|
||||
|
||||
public int ReconnectDelayMilliseconds { get; set; }
|
||||
|
||||
public int ConnectTimeoutMilliseconds { get; set; }
|
||||
|
||||
protected override void InitializeTarget()
|
||||
{
|
||||
base.InitializeTarget();
|
||||
|
||||
int queueLimit = QueueLimit > 0
|
||||
? QueueLimit
|
||||
: DiagnosticProtocol.DefaultQueueLimit;
|
||||
|
||||
queue = new BlockingCollection<DiagnosticLogEntry>(queueLimit);
|
||||
cancellation = new CancellationTokenSource();
|
||||
|
||||
senderTask = Task.Factory.StartNew(
|
||||
ProcessQueue,
|
||||
cancellation.Token,
|
||||
TaskCreationOptions.LongRunning,
|
||||
TaskScheduler.Default);
|
||||
}
|
||||
|
||||
protected override void Write(LogEventInfo logEvent)
|
||||
{
|
||||
if (logEvent == null || queue == null || queue.IsAddingCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var entry = new DiagnosticLogEntry
|
||||
{
|
||||
TimestampUtc = logEvent.TimeStamp.ToUniversalTime(),
|
||||
MachineName = Environment.MachineName,
|
||||
ApplicationName = applicationName,
|
||||
ProcessId = processId,
|
||||
LoggerName = logEvent.LoggerName ?? string.Empty,
|
||||
Level = logEvent.Level?.Name ?? string.Empty,
|
||||
Message = Layout != null
|
||||
? Layout.Render(logEvent)
|
||||
: logEvent.FormattedMessage,
|
||||
Exception = logEvent.Exception?.ToString() ?? string.Empty
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
queue.TryAdd(entry);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// A concurrent NLog shutdown may dispose the queue.
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// A concurrent NLog shutdown may complete the queue.
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CloseTarget()
|
||||
{
|
||||
BlockingCollection<DiagnosticLogEntry> currentQueue = queue;
|
||||
CancellationTokenSource currentCancellation = cancellation;
|
||||
|
||||
if (currentQueue != null)
|
||||
{
|
||||
currentQueue.CompleteAdding();
|
||||
}
|
||||
|
||||
if (currentCancellation != null)
|
||||
{
|
||||
currentCancellation.Cancel();
|
||||
}
|
||||
|
||||
CloseConnection();
|
||||
|
||||
try
|
||||
{
|
||||
senderTask?.Wait(2000);
|
||||
}
|
||||
catch (AggregateException)
|
||||
{
|
||||
// Cancellation during application shutdown is expected.
|
||||
}
|
||||
|
||||
currentQueue?.Dispose();
|
||||
currentCancellation?.Dispose();
|
||||
|
||||
queue = null;
|
||||
cancellation = null;
|
||||
senderTask = null;
|
||||
|
||||
base.CloseTarget();
|
||||
}
|
||||
|
||||
private void ProcessQueue()
|
||||
{
|
||||
CancellationToken token = cancellation.Token;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (DiagnosticLogEntry entry in
|
||||
queue.GetConsumingEnumerable(token))
|
||||
{
|
||||
SendWhenConnected(entry, token);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Target shutdown is expected to cancel the sender.
|
||||
}
|
||||
}
|
||||
|
||||
private void SendWhenConnected(
|
||||
DiagnosticLogEntry entry,
|
||||
CancellationToken token)
|
||||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
EnsureConnected();
|
||||
DiagnosticMessageSerializer.WriteFramed(pipeClient, entry);
|
||||
return;
|
||||
}
|
||||
catch (Exception exception) when (
|
||||
exception is IOException ||
|
||||
exception is TimeoutException ||
|
||||
exception is InvalidOperationException)
|
||||
{
|
||||
CloseConnection();
|
||||
|
||||
int delay = ReconnectDelayMilliseconds > 0
|
||||
? ReconnectDelayMilliseconds
|
||||
: DiagnosticProtocol.DefaultReconnectDelayMilliseconds;
|
||||
|
||||
if (token.WaitHandle.WaitOne(delay))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureConnected()
|
||||
{
|
||||
lock (connectionLock)
|
||||
{
|
||||
if (pipeClient != null && pipeClient.IsConnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CloseConnectionWithoutLock();
|
||||
|
||||
pipeClient = new NamedPipeClientStream(
|
||||
".",
|
||||
string.IsNullOrWhiteSpace(PipeName)
|
||||
? DiagnosticProtocol.DefaultPipeName
|
||||
: PipeName,
|
||||
PipeDirection.Out,
|
||||
PipeOptions.Asynchronous);
|
||||
|
||||
int timeout = ConnectTimeoutMilliseconds > 0
|
||||
? ConnectTimeoutMilliseconds
|
||||
: DiagnosticProtocol.DefaultConnectTimeoutMilliseconds;
|
||||
|
||||
pipeClient.Connect(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseConnection()
|
||||
{
|
||||
lock (connectionLock)
|
||||
{
|
||||
CloseConnectionWithoutLock();
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseConnectionWithoutLock()
|
||||
{
|
||||
if (pipeClient == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pipeClient.Dispose();
|
||||
pipeClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace AppDiagnostic.Logging
|
||||
{
|
||||
[DataContract]
|
||||
public sealed class DiagnosticLogEntry
|
||||
{
|
||||
[DataMember(Order = 1)]
|
||||
public DateTime TimestampUtc { get; set; }
|
||||
|
||||
[DataMember(Order = 2)]
|
||||
public string MachineName { get; set; }
|
||||
|
||||
[DataMember(Order = 3)]
|
||||
public string ApplicationName { get; set; }
|
||||
|
||||
[DataMember(Order = 4)]
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
[DataMember(Order = 5)]
|
||||
public string LoggerName { get; set; }
|
||||
|
||||
[DataMember(Order = 6)]
|
||||
public string Level { get; set; }
|
||||
|
||||
[DataMember(Order = 7)]
|
||||
public string Message { get; set; }
|
||||
|
||||
[DataMember(Order = 8)]
|
||||
public string Exception { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Json;
|
||||
|
||||
namespace AppDiagnostic.Logging
|
||||
{
|
||||
public static class DiagnosticMessageSerializer
|
||||
{
|
||||
private static readonly DataContractJsonSerializer Serializer =
|
||||
new DataContractJsonSerializer(typeof(DiagnosticLogEntry));
|
||||
|
||||
private static readonly object SerializerLock = new object();
|
||||
|
||||
public static byte[] Serialize(DiagnosticLogEntry entry)
|
||||
{
|
||||
if (entry == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(entry));
|
||||
}
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
lock (SerializerLock)
|
||||
{
|
||||
Serializer.WriteObject(stream, entry);
|
||||
}
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static DiagnosticLogEntry Deserialize(byte[] payload)
|
||||
{
|
||||
if (payload == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(payload));
|
||||
}
|
||||
|
||||
if (payload.Length == 0 ||
|
||||
payload.Length > DiagnosticProtocol.MaximumMessageSize)
|
||||
{
|
||||
throw new InvalidDataException("Invalid diagnostic message size.");
|
||||
}
|
||||
|
||||
using (var stream = new MemoryStream(payload, false))
|
||||
{
|
||||
lock (SerializerLock)
|
||||
{
|
||||
return (DiagnosticLogEntry)Serializer.ReadObject(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteFramed(Stream stream, DiagnosticLogEntry entry)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
byte[] payload = Serialize(entry);
|
||||
|
||||
if (payload.Length > DiagnosticProtocol.MaximumMessageSize)
|
||||
{
|
||||
throw new InvalidDataException("Diagnostic message is too large.");
|
||||
}
|
||||
|
||||
byte[] length = BitConverter.GetBytes(payload.Length);
|
||||
stream.Write(length, 0, length.Length);
|
||||
stream.Write(payload, 0, payload.Length);
|
||||
stream.Flush();
|
||||
}
|
||||
|
||||
public static DiagnosticLogEntry ReadFramed(Stream stream)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
byte[] lengthBuffer = ReadExactly(stream, sizeof(int));
|
||||
int payloadLength = BitConverter.ToInt32(lengthBuffer, 0);
|
||||
|
||||
if (payloadLength <= 0 ||
|
||||
payloadLength > DiagnosticProtocol.MaximumMessageSize)
|
||||
{
|
||||
throw new InvalidDataException("Invalid diagnostic message size.");
|
||||
}
|
||||
|
||||
return Deserialize(ReadExactly(stream, payloadLength));
|
||||
}
|
||||
|
||||
private static byte[] ReadExactly(Stream stream, int count)
|
||||
{
|
||||
byte[] buffer = new byte[count];
|
||||
int offset = 0;
|
||||
|
||||
while (offset < count)
|
||||
{
|
||||
int bytesRead = stream.Read(buffer, offset, count - offset);
|
||||
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
offset += bytesRead;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace AppDiagnostic.Logging
|
||||
{
|
||||
public static class DiagnosticProtocol
|
||||
{
|
||||
public const string DefaultPipeName = "Sensus.AppDiagnostic.LogPipe";
|
||||
public const int MaximumMessageSize = 1024 * 1024;
|
||||
public const int DefaultQueueLimit = 10000;
|
||||
public const int DefaultReconnectDelayMilliseconds = 500;
|
||||
public const int DefaultConnectTimeoutMilliseconds = 250;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AppDiagnostic.Logging
|
||||
|
||||
Reusable NLog target for sending structured diagnostic events from multiple
|
||||
.NET Framework processes to `AppDiagnostic.exe` through a local named pipe.
|
||||
|
||||
## Producer integration
|
||||
|
||||
Reference this project from the producer application and add the extension and
|
||||
target to its NLog configuration:
|
||||
|
||||
```xml
|
||||
<extensions>
|
||||
<add assembly="AppDiagnostic.Logging" />
|
||||
</extensions>
|
||||
|
||||
<targets>
|
||||
<target name="appDiagnostic"
|
||||
xsi:type="AppDiagnostic"
|
||||
layout="${message}" />
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="*" minlevel="Trace" writeTo="appDiagnostic" />
|
||||
</rules>
|
||||
```
|
||||
|
||||
The target writes to a bounded background queue. Producer threads are not
|
||||
blocked while the diagnostic viewer is unavailable. Queued messages are sent
|
||||
after the viewer becomes available; new messages are discarded when the queue
|
||||
limit is reached.
|
||||
|
||||
The receiver can read messages with:
|
||||
|
||||
```csharp
|
||||
DiagnosticLogEntry entry =
|
||||
DiagnosticMessageSerializer.ReadFramed(namedPipeServerStream);
|
||||
```
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
|
||||
"projectName": "AppDiagnostic.Logging",
|
||||
"projectPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
|
||||
"packagesPath": "C:\\Users\\MFRNIAK\\.nuget\\packages\\",
|
||||
"outputPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\MFRNIAK\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net472"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net472": {
|
||||
"framework": "net472",
|
||||
"targetAlias": "net472",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net472": {
|
||||
"framework": "net472",
|
||||
"targetAlias": "net472",
|
||||
"dependencies": {
|
||||
"NLog": {
|
||||
"target": "Package",
|
||||
"version": "[5.2.2, )"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.303\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\MFRNIAK\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\MFRNIAK\.nuget\packages\" />
|
||||
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = AppDiagnostic.Logging
|
||||
build_property.ProjectDir = C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.CsWinRTUseWindowsUIXamlProjections = false
|
||||
build_property.EffectiveAnalysisLevelStyle =
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
551ba94934db30a277a1a9cec2dacbe03f8393107e5d0b2436695f9bd62bd569
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\AppDiagnostic.Logging.dll
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\AppDiagnostic.Logging.pdb
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Debug\net472\NLog.dll
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.csproj.AssemblyReference.cache
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.GeneratedMSBuildEditorConfig.editorconfig
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.AssemblyInfoInputs.cache
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.AssemblyInfo.cs
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.csproj.CoreCompileInputs.cache
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagn.CFEA7AC0.Up2Date
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.dll
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Debug\net472\AppDiagnostic.Logging.pdb
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = AppDiagnostic.Logging
|
||||
build_property.ProjectDir = C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.CsWinRTUseWindowsUIXamlProjections = false
|
||||
build_property.EffectiveAnalysisLevelStyle =
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
a53d59482cad49b656138b1af5cf3e55edf2108969aedc574c362be6c671436b
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\AppDiagnostic.Logging.dll
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\AppDiagnostic.Logging.pdb
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\bin\Release\net472\NLog.dll
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.csproj.AssemblyReference.cache
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.GeneratedMSBuildEditorConfig.editorconfig
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.AssemblyInfoInputs.cache
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.AssemblyInfo.cs
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.csproj.CoreCompileInputs.cache
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagn.CFEA7AC0.Up2Date
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.dll
|
||||
C:\Sensus_projects\New\LocalBranch_start_at_6.3.2026\tbf-local\tbf\AppDiagnostic.Logging\obj\Release\net472\AppDiagnostic.Logging.pdb
|
||||
@@ -1,119 +0,0 @@
|
||||
{
|
||||
"version": 4,
|
||||
"targets": {
|
||||
"net472": {
|
||||
"NLog/5.2.2": {
|
||||
"type": "package",
|
||||
"frameworkAssemblies": [
|
||||
"System",
|
||||
"System.Configuration",
|
||||
"System.Core",
|
||||
"System.IO.Compression",
|
||||
"System.Xml"
|
||||
],
|
||||
"compile": {
|
||||
"lib/net46/NLog.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net46/NLog.dll": {
|
||||
"related": ".xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"NLog/5.2.2": {
|
||||
"sha512": "r6Q9740g29gTwmTWlsgdIFm0mhNsfNZmbvWKX/Fxmi8X89ZrpUowHM2T2X1lP7RVpND+ef+XnfKL5g6Q1iNGXA==",
|
||||
"type": "package",
|
||||
"path": "nlog/5.2.2",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"N.png",
|
||||
"lib/net35/NLog.dll",
|
||||
"lib/net35/NLog.xml",
|
||||
"lib/net45/NLog.dll",
|
||||
"lib/net45/NLog.xml",
|
||||
"lib/net46/NLog.dll",
|
||||
"lib/net46/NLog.xml",
|
||||
"lib/netstandard1.3/NLog.dll",
|
||||
"lib/netstandard1.3/NLog.xml",
|
||||
"lib/netstandard1.5/NLog.dll",
|
||||
"lib/netstandard1.5/NLog.xml",
|
||||
"lib/netstandard2.0/NLog.dll",
|
||||
"lib/netstandard2.0/NLog.xml",
|
||||
"nlog.5.2.2.nupkg.sha512",
|
||||
"nlog.nuspec"
|
||||
]
|
||||
}
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net472": [
|
||||
"NLog >= 5.2.2"
|
||||
]
|
||||
},
|
||||
"packageFolders": {
|
||||
"C:\\Users\\MFRNIAK\\.nuget\\packages\\": {},
|
||||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
|
||||
"projectName": "AppDiagnostic.Logging",
|
||||
"projectPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
|
||||
"packagesPath": "C:\\Users\\MFRNIAK\\.nuget\\packages\\",
|
||||
"outputPath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\MFRNIAK\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net472"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net472": {
|
||||
"framework": "net472",
|
||||
"targetAlias": "net472",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net472": {
|
||||
"framework": "net472",
|
||||
"targetAlias": "net472",
|
||||
"dependencies": {
|
||||
"NLog": {
|
||||
"target": "Package",
|
||||
"version": "[5.2.2, )"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.303\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "ezwKOPZAAXU=",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Sensus_projects\\New\\LocalBranch_start_at_6.3.2026\\tbf-local\\tbf\\AppDiagnostic.Logging\\AppDiagnostic.Logging.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\MFRNIAK\\.nuget\\packages\\nlog\\5.2.2\\nlog.5.2.2.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>AppDiagnostic</RootNamespace>
|
||||
<AssemblyName>AppDiagnostic</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ColorRuleEditorForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DiagnosticLogFormatter.cs" />
|
||||
<Compile Include="DiagnosticLogStore.cs" />
|
||||
<Compile Include="DiagnosticPipeServer.cs" />
|
||||
<Compile Include="LogColorizer.cs" />
|
||||
<Compile Include="LogColorRule.cs" />
|
||||
<Compile Include="LogColorRuleRepository.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AppDiagnostic.Logging\AppDiagnostic.Logging.csproj">
|
||||
<Project>{A7AF8ED2-362E-4DBB-B607-EBA2820719EC}</Project>
|
||||
<Name>AppDiagnostic.Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\TBF_icon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
public class BufferedListView : ListView
|
||||
{
|
||||
public BufferedListView()
|
||||
{
|
||||
// Zapne dvojité bufferovanie pre ListView
|
||||
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
|
||||
this.UpdateStyles();
|
||||
}
|
||||
}
|
||||
@@ -1,319 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public sealed class ColorRuleEditorForm : Form
|
||||
{
|
||||
private readonly List<LogColorRule> rules;
|
||||
private readonly ListBox ruleList = new ListBox();
|
||||
private readonly TextBox patternTextBox = new TextBox();
|
||||
private readonly CheckBox enabledCheckBox = new CheckBox();
|
||||
private readonly CheckBox boldCheckBox = new CheckBox();
|
||||
private readonly CheckBox backgroundCheckBox = new CheckBox();
|
||||
private readonly Button foregroundButton = new Button();
|
||||
private readonly Button backgroundButton = new Button();
|
||||
private readonly RichTextBox previewBox = new RichTextBox();
|
||||
private readonly Font previewBoldFont;
|
||||
private bool loadingRule;
|
||||
|
||||
public ColorRuleEditorForm(IEnumerable<LogColorRule> sourceRules)
|
||||
{
|
||||
rules = sourceRules.Select(rule => rule.Clone()).ToList();
|
||||
InitializeWindow();
|
||||
previewBoldFont = new Font(previewBox.Font, FontStyle.Bold);
|
||||
RefreshRuleList(0);
|
||||
RefreshPreview();
|
||||
}
|
||||
|
||||
public List<LogColorRule> Rules => rules.Select(rule => rule.Clone()).ToList();
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
previewBoldFont.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void InitializeWindow()
|
||||
{
|
||||
Text = "Log color rules";
|
||||
Icon = Properties.Resources.TBF_icon;
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
MinimumSize = new Size(760, 500);
|
||||
ClientSize = new Size(860, 560);
|
||||
|
||||
var root = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 1, RowCount = 3, Padding = new Padding(10) };
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 145F));
|
||||
root.RowStyles.Add(new RowStyle(SizeType.Absolute, 42F));
|
||||
|
||||
var split = new SplitContainer { Dock = DockStyle.Fill, SplitterDistance = 280 };
|
||||
split.Panel1.Padding = new Padding(0, 0, 8, 0);
|
||||
split.Panel2.Padding = new Padding(8, 0, 0, 0);
|
||||
|
||||
ruleList.Dock = DockStyle.Fill;
|
||||
ruleList.IntegralHeight = false;
|
||||
ruleList.SelectedIndexChanged += RuleList_SelectedIndexChanged;
|
||||
|
||||
var listButtons = new FlowLayoutPanel { Dock = DockStyle.Bottom, Height = 36, FlowDirection = FlowDirection.LeftToRight };
|
||||
listButtons.Controls.Add(CreateButton("Add", AddRule_Click));
|
||||
listButtons.Controls.Add(CreateButton("Delete", DeleteRule_Click));
|
||||
listButtons.Controls.Add(CreateButton("Up", MoveUp_Click));
|
||||
listButtons.Controls.Add(CreateButton("Down", MoveDown_Click));
|
||||
split.Panel1.Controls.Add(ruleList);
|
||||
split.Panel1.Controls.Add(listButtons);
|
||||
|
||||
var editor = new TableLayoutPanel { Dock = DockStyle.Top, AutoSize = true, ColumnCount = 2, Padding = new Padding(4) };
|
||||
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
|
||||
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
|
||||
enabledCheckBox.Text = "Rule enabled";
|
||||
enabledCheckBox.AutoSize = true;
|
||||
enabledCheckBox.CheckedChanged += EditorValueChanged;
|
||||
AddEditorRow(editor, "State", enabledCheckBox);
|
||||
|
||||
patternTextBox.Dock = DockStyle.Fill;
|
||||
patternTextBox.TextChanged += EditorValueChanged;
|
||||
AddEditorRow(editor, "Substring", patternTextBox);
|
||||
|
||||
foregroundButton.Text = "Choose text color...";
|
||||
foregroundButton.AutoSize = true;
|
||||
foregroundButton.Click += ForegroundButton_Click;
|
||||
AddEditorRow(editor, "Text color", foregroundButton);
|
||||
|
||||
var backgroundPanel = new FlowLayoutPanel { Dock = DockStyle.Fill, AutoSize = true };
|
||||
backgroundCheckBox.Text = "Use background";
|
||||
backgroundCheckBox.AutoSize = true;
|
||||
backgroundCheckBox.CheckedChanged += EditorValueChanged;
|
||||
backgroundButton.Text = "Choose...";
|
||||
backgroundButton.AutoSize = true;
|
||||
backgroundButton.Click += BackgroundButton_Click;
|
||||
backgroundPanel.Controls.Add(backgroundCheckBox);
|
||||
backgroundPanel.Controls.Add(backgroundButton);
|
||||
AddEditorRow(editor, "Background", backgroundPanel);
|
||||
|
||||
boldCheckBox.Text = "Bold text";
|
||||
boldCheckBox.AutoSize = true;
|
||||
boldCheckBox.CheckedChanged += EditorValueChanged;
|
||||
AddEditorRow(editor, "Font", boldCheckBox);
|
||||
|
||||
var resetButton = CreateButton("Restore default rules", RestoreDefaults_Click);
|
||||
resetButton.AutoSize = true;
|
||||
AddEditorRow(editor, string.Empty, resetButton);
|
||||
split.Panel2.Controls.Add(editor);
|
||||
|
||||
previewBox.Dock = DockStyle.Fill;
|
||||
previewBox.ReadOnly = true;
|
||||
previewBox.WordWrap = true;
|
||||
previewBox.Font = new Font("Consolas", 9F);
|
||||
previewBox.Text = "2026-09-10 14:25:31.042|DEBUG|TBF[14280]|TBF.UI.MainWnd|Device configuration loaded.\n2026-09-10 14:25:31.384|INFO |TBF[14280]|TBF.Rig.StateMachine|Test bench started.\n2026-09-10 14:25:32.018|WARN |TBF[14280]|TBF.Device|Pressure is approaching the limit.\n2026-09-10 14:25:32.611|ERROR|TBF[14280]|TBF.Device|Communication failed.";
|
||||
|
||||
var previewGroup = new GroupBox { Text = "Live preview", Dock = DockStyle.Fill, Padding = new Padding(8) };
|
||||
previewGroup.Controls.Add(previewBox);
|
||||
|
||||
var footer = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.RightToLeft, Padding = new Padding(0, 8, 0, 0) };
|
||||
var okButton = new Button { Text = "OK", DialogResult = DialogResult.OK, AutoSize = true };
|
||||
var cancelButton = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, AutoSize = true };
|
||||
footer.Controls.Add(okButton);
|
||||
footer.Controls.Add(cancelButton);
|
||||
|
||||
AcceptButton = okButton;
|
||||
CancelButton = cancelButton;
|
||||
root.Controls.Add(split, 0, 0);
|
||||
root.Controls.Add(previewGroup, 0, 1);
|
||||
root.Controls.Add(footer, 0, 2);
|
||||
Controls.Add(root);
|
||||
}
|
||||
|
||||
private static Button CreateButton(string text, EventHandler clickHandler)
|
||||
{
|
||||
var button = new Button { Text = text, AutoSize = true };
|
||||
button.Click += clickHandler;
|
||||
return button;
|
||||
}
|
||||
|
||||
private static void AddEditorRow(TableLayoutPanel panel, string labelText, Control control)
|
||||
{
|
||||
int row = panel.RowCount++;
|
||||
panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
var label = new Label { Text = labelText, AutoSize = true, Anchor = AnchorStyles.Left, Margin = new Padding(3, 8, 3, 3) };
|
||||
control.Margin = new Padding(3, 5, 3, 5);
|
||||
panel.Controls.Add(label, 0, row);
|
||||
panel.Controls.Add(control, 1, row);
|
||||
}
|
||||
|
||||
private void RefreshRuleList(int selectedIndex)
|
||||
{
|
||||
ruleList.BeginUpdate();
|
||||
ruleList.Items.Clear();
|
||||
foreach (LogColorRule rule in rules)
|
||||
{
|
||||
ruleList.Items.Add(rule);
|
||||
}
|
||||
ruleList.EndUpdate();
|
||||
|
||||
if (rules.Count > 0)
|
||||
{
|
||||
ruleList.SelectedIndex = Math.Max(0, Math.Min(selectedIndex, rules.Count - 1));
|
||||
}
|
||||
}
|
||||
|
||||
private void RuleList_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
|
||||
if (rule == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loadingRule = true;
|
||||
enabledCheckBox.Checked = rule.Enabled;
|
||||
patternTextBox.Text = rule.Pattern;
|
||||
foregroundButton.BackColor = rule.ForeColor;
|
||||
backgroundCheckBox.Checked = rule.UseBackColor;
|
||||
backgroundButton.Enabled = rule.UseBackColor;
|
||||
backgroundButton.BackColor = rule.UseBackColor ? rule.BackColor : SystemColors.Control;
|
||||
boldCheckBox.Checked = rule.Bold;
|
||||
loadingRule = false;
|
||||
}
|
||||
|
||||
private void EditorValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (loadingRule)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
|
||||
if (rule == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rule.Enabled = enabledCheckBox.Checked;
|
||||
rule.Pattern = patternTextBox.Text;
|
||||
rule.UseBackColor = backgroundCheckBox.Checked;
|
||||
rule.Bold = boldCheckBox.Checked;
|
||||
backgroundButton.Enabled = rule.UseBackColor;
|
||||
int index = ruleList.SelectedIndex;
|
||||
RefreshRuleList(index);
|
||||
RefreshPreview();
|
||||
}
|
||||
|
||||
private void ForegroundButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
|
||||
if (rule == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var dialog = new ColorDialog { Color = rule.ForeColor, FullOpen = true })
|
||||
{
|
||||
if (dialog.ShowDialog(this) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rule.ForeColorArgb = dialog.Color.ToArgb();
|
||||
foregroundButton.BackColor = dialog.Color;
|
||||
RefreshPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void BackgroundButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
LogColorRule rule = ruleList.SelectedItem as LogColorRule;
|
||||
if (rule == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color initialColor = rule.UseBackColor ? rule.BackColor : SystemColors.Window;
|
||||
using (var dialog = new ColorDialog { Color = initialColor, FullOpen = true })
|
||||
{
|
||||
if (dialog.ShowDialog(this) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rule.BackColorArgb = dialog.Color.ToArgb();
|
||||
rule.UseBackColor = true;
|
||||
backgroundCheckBox.Checked = true;
|
||||
backgroundButton.BackColor = dialog.Color;
|
||||
RefreshPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddRule_Click(object sender, EventArgs e)
|
||||
{
|
||||
rules.Add(new LogColorRule { Pattern = "NEW SUBSTRING", ForeColorArgb = Color.MediumPurple.ToArgb() });
|
||||
RefreshRuleList(rules.Count - 1);
|
||||
patternTextBox.Focus();
|
||||
patternTextBox.SelectAll();
|
||||
}
|
||||
|
||||
private void DeleteRule_Click(object sender, EventArgs e)
|
||||
{
|
||||
int index = ruleList.SelectedIndex;
|
||||
if (index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rules.RemoveAt(index);
|
||||
RefreshRuleList(Math.Min(index, rules.Count - 1));
|
||||
RefreshPreview();
|
||||
}
|
||||
|
||||
private void MoveUp_Click(object sender, EventArgs e)
|
||||
{
|
||||
MoveSelectedRule(-1);
|
||||
}
|
||||
|
||||
private void MoveDown_Click(object sender, EventArgs e)
|
||||
{
|
||||
MoveSelectedRule(1);
|
||||
}
|
||||
|
||||
private void MoveSelectedRule(int offset)
|
||||
{
|
||||
int index = ruleList.SelectedIndex;
|
||||
int newIndex = index + offset;
|
||||
if (index < 0 || newIndex < 0 || newIndex >= rules.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogColorRule rule = rules[index];
|
||||
rules.RemoveAt(index);
|
||||
rules.Insert(newIndex, rule);
|
||||
RefreshRuleList(newIndex);
|
||||
RefreshPreview();
|
||||
}
|
||||
|
||||
private void RestoreDefaults_Click(object sender, EventArgs e)
|
||||
{
|
||||
rules.Clear();
|
||||
rules.AddRange(LogColorRule.CreateDefaults());
|
||||
RefreshRuleList(0);
|
||||
RefreshPreview();
|
||||
}
|
||||
|
||||
private void RefreshPreview()
|
||||
{
|
||||
int selectionStart = previewBox.SelectionStart;
|
||||
int selectionLength = previewBox.SelectionLength;
|
||||
string text = previewBox.Text;
|
||||
LogColorizer.Apply(previewBox, 0, text.Length, text, rules, previewBox.Font, previewBoldFont);
|
||||
previewBox.Select(Math.Min(selectionStart, previewBox.TextLength), Math.Min(selectionLength, Math.Max(0, previewBox.TextLength - selectionStart)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public class DiagApi
|
||||
{
|
||||
private static MainForm diagWindow; // Udržiava referenciu na existujúce okno
|
||||
|
||||
public DiagApi()
|
||||
{
|
||||
if (diagWindow == null || diagWindow.IsDisposed) // Ak okno neexistuje, vytvoríme ho
|
||||
{
|
||||
diagWindow = new MainForm();
|
||||
diagWindow.FormClosing += (s, e) =>
|
||||
{
|
||||
diagWindow = null; // Keď sa zavrie, vyčistíme referenciu
|
||||
};
|
||||
diagWindow.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
diagWindow.BringToFront(); // Ak už beží, len ho presunieme na vrch
|
||||
diagWindow.WindowState = FormWindowState.Normal; // Ak je minimalizované, obnovíme ho
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using AppDiagnostic.Logging;
|
||||
using System;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public static class DiagnosticLogFormatter
|
||||
{
|
||||
public static string Format(DiagnosticLogEntry entry)
|
||||
{
|
||||
if (entry == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string level = (entry.Level ?? string.Empty).ToUpperInvariant().PadRight(5);
|
||||
string application = string.IsNullOrWhiteSpace(entry.ApplicationName) ? "Unknown" : entry.ApplicationName;
|
||||
string logger = entry.LoggerName ?? string.Empty;
|
||||
string message = entry.Message ?? string.Empty;
|
||||
string exception = string.IsNullOrWhiteSpace(entry.Exception) ? string.Empty : Environment.NewLine + entry.Exception;
|
||||
|
||||
return $"{entry.TimestampUtc.ToLocalTime():yyyy-MM-dd HH:mm:ss.fff}|{level}|{application}[{entry.ProcessId}]|{logger}|{message}{exception}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
using AppDiagnostic.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public sealed class DiagnosticLogStore
|
||||
{
|
||||
private const int MaximumLogCount = 10000;
|
||||
private static readonly DiagnosticLogStore instance = new DiagnosticLogStore();
|
||||
private readonly object syncRoot = new object();
|
||||
private readonly List<DiagnosticLogEntry> entries = new List<DiagnosticLogEntry>();
|
||||
private long totalReceived;
|
||||
private long version;
|
||||
|
||||
private DiagnosticLogStore()
|
||||
{
|
||||
}
|
||||
|
||||
public static DiagnosticLogStore Instance => instance;
|
||||
|
||||
public long TotalReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
return totalReceived;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long Version
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(DiagnosticLogEntry entry)
|
||||
{
|
||||
if (entry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (syncRoot)
|
||||
{
|
||||
entries.Add(entry);
|
||||
totalReceived++;
|
||||
version++;
|
||||
|
||||
int excessCount = entries.Count - MaximumLogCount;
|
||||
if (excessCount > 0)
|
||||
{
|
||||
entries.RemoveRange(0, excessCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<DiagnosticLogEntry> GetSnapshot()
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
return entries.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
entries.Clear();
|
||||
version++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
using AppDiagnostic.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public sealed class DiagnosticPipeServer : IDisposable
|
||||
{
|
||||
private readonly Action<DiagnosticLogEntry> messageReceived;
|
||||
private readonly CancellationTokenSource cancellation = new CancellationTokenSource();
|
||||
private readonly object syncRoot = new object();
|
||||
private readonly List<NamedPipeServerStream> connectedClients = new List<NamedPipeServerStream>();
|
||||
private NamedPipeServerStream waitingServer;
|
||||
private Task serverTask;
|
||||
|
||||
public DiagnosticPipeServer(Action<DiagnosticLogEntry> messageReceived)
|
||||
{
|
||||
this.messageReceived = messageReceived ?? throw new ArgumentNullException(nameof(messageReceived));
|
||||
}
|
||||
|
||||
public int ConnectedClientCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
return connectedClients.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (serverTask != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
serverTask = Task.Run((Action)AcceptConnections);
|
||||
}
|
||||
|
||||
private void AcceptConnections()
|
||||
{
|
||||
while (!cancellation.IsCancellationRequested)
|
||||
{
|
||||
NamedPipeServerStream server = null;
|
||||
|
||||
try
|
||||
{
|
||||
server = new NamedPipeServerStream(DiagnosticProtocol.DefaultPipeName, PipeDirection.In, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||
|
||||
lock (syncRoot)
|
||||
{
|
||||
waitingServer = server;
|
||||
}
|
||||
|
||||
server.WaitForConnection();
|
||||
|
||||
lock (syncRoot)
|
||||
{
|
||||
waitingServer = null;
|
||||
connectedClients.Add(server);
|
||||
}
|
||||
|
||||
NamedPipeServerStream connectedServer = server;
|
||||
server = null;
|
||||
Task.Run(() => ReadClient(connectedServer));
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
if (!cancellation.IsCancellationRequested)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
if (!cancellation.IsCancellationRequested)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
if (ReferenceEquals(waitingServer, server))
|
||||
{
|
||||
waitingServer = null;
|
||||
}
|
||||
}
|
||||
|
||||
server?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadClient(NamedPipeServerStream client)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (client.IsConnected && !cancellation.IsCancellationRequested)
|
||||
{
|
||||
DiagnosticLogEntry entry = DiagnosticMessageSerializer.ReadFramed(client);
|
||||
messageReceived(entry);
|
||||
}
|
||||
}
|
||||
catch (EndOfStreamException)
|
||||
{
|
||||
// The producer application was closed.
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// The producer application disconnected.
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// The diagnostic application is shutting down.
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
connectedClients.Remove(client);
|
||||
}
|
||||
|
||||
client.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
cancellation.Cancel();
|
||||
|
||||
lock (syncRoot)
|
||||
{
|
||||
waitingServer?.Dispose();
|
||||
waitingServer = null;
|
||||
|
||||
foreach (NamedPipeServerStream client in connectedClients.ToArray())
|
||||
{
|
||||
client.Dispose();
|
||||
}
|
||||
|
||||
connectedClients.Clear();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
serverTask?.Wait(2000);
|
||||
}
|
||||
catch (AggregateException)
|
||||
{
|
||||
// Cancellation during shutdown is expected.
|
||||
}
|
||||
|
||||
cancellation.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
using SharedComponents;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public class LogAdapter
|
||||
{
|
||||
private ListView _listView;
|
||||
public string _filterText = string.Empty;
|
||||
private bool _isUserScrolling = false; // Indikátor, že používateľ manuálne scrolluje
|
||||
private bool _autoScrollEnabled = true; // Indikátor, že automatické scrollovanie je povolené
|
||||
private Timer _refreshTimer;
|
||||
private const int RefreshInterval = 1000;
|
||||
|
||||
public LogAdapter(ListView listView)
|
||||
{
|
||||
_listView = listView;
|
||||
|
||||
// Nastavenie ListView
|
||||
_listView.View = View.Details;
|
||||
_listView.Columns.Clear();
|
||||
_listView.Columns.Add("Logs");
|
||||
|
||||
_listView.Scrollable = true;
|
||||
|
||||
// Nastavenie šírky stĺpca na celú šírku ListView
|
||||
AdjustColumnWidth();
|
||||
|
||||
// Udalosť pre dynamickú zmenu veľkosti stĺpca pri zmene veľkosti ListView
|
||||
_listView.Resize += (sender, args) => AdjustColumnWidth();
|
||||
|
||||
// Pridanie udalosti pre manuálne skrolovanie
|
||||
_listView.MouseWheel += ListView_MouseWheel;
|
||||
|
||||
// Inicializácia časovača na pravidelný refresh
|
||||
_refreshTimer = new Timer { Interval = RefreshInterval };
|
||||
_refreshTimer.Tick += (sender, args) => RefreshListView();
|
||||
_refreshTimer.Start();
|
||||
}
|
||||
|
||||
private void ListView_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
_isUserScrolling = true;
|
||||
|
||||
// Ak sa manuálnym scrollovaním používateľ dostane na koniec, obnovíme automatické scrollovanie
|
||||
if (IsOnLastItem())
|
||||
{
|
||||
_isUserScrolling = false;
|
||||
_autoScrollEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_autoScrollEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshListView()
|
||||
{
|
||||
//LiveLogCache.Instance.AddLog(string.Format("-------------------------------RunDeviceAfter()-------------------------------"));
|
||||
|
||||
if (_listView.InvokeRequired)
|
||||
{
|
||||
_listView.Invoke(new Action(RefreshListView));
|
||||
return;
|
||||
}
|
||||
|
||||
_listView.BeginUpdate();
|
||||
try
|
||||
{
|
||||
// Získanie pozície prvého viditeľného prvku pre stabilizáciu scrollovania
|
||||
int topIndexBeforeRefresh = _listView.TopItem?.Index ?? 0;
|
||||
|
||||
// Pred pridaním nových položiek si pamätáme, či bol používateľ na poslednej položke
|
||||
bool wasOnLastItem = IsOnLastItem();
|
||||
|
||||
// Uchovanie aktuálne označených položiek (indexov)
|
||||
var selectedIndices = _listView.SelectedIndices.Cast<int>().ToList();
|
||||
|
||||
// Načítanie logov
|
||||
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.GetCount())
|
||||
.Where(log => string.IsNullOrEmpty(_filterText) ||
|
||||
log.IndexOf(_filterText, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
.ToList();
|
||||
|
||||
// Vymazanie existujúcich položiek a pridanie nových
|
||||
_listView.Items.Clear();
|
||||
|
||||
foreach (var log in logs)
|
||||
{
|
||||
var item = new ListViewItem(log)
|
||||
{
|
||||
BackColor = _listView.Items.Count % 2 == 0 ? Color.White : Color.FromArgb(240, 240, 240)
|
||||
};
|
||||
_listView.Items.Add(item);
|
||||
}
|
||||
|
||||
// Obnovenie označených položiek
|
||||
foreach (var index in selectedIndices)
|
||||
{
|
||||
if (index < _listView.Items.Count)
|
||||
{
|
||||
_listView.Items[index].Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Ak bol používateľ na poslednom prvku, nastavíme focus a scroll na posledný prvok
|
||||
if (_autoScrollEnabled && wasOnLastItem && _listView.Items.Count > 0)
|
||||
{
|
||||
var lastItemIndex = _listView.Items.Count - 1;
|
||||
_listView.EnsureVisible(lastItemIndex);
|
||||
_listView.Items[lastItemIndex].Focused = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ak používateľ nebol na spodku, vrátime sa na predchádzajúcu pozíciu scrollu
|
||||
if (topIndexBeforeRefresh < _listView.Items.Count)
|
||||
{
|
||||
_listView.TopItem = _listView.Items[topIndexBeforeRefresh];
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listView.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ApplyFilter(string filterText)
|
||||
{
|
||||
_filterText = filterText?.Trim() ?? string.Empty;
|
||||
RefreshListView();
|
||||
}
|
||||
|
||||
private bool IsOnLastItem()
|
||||
{
|
||||
if (_listView.Items.Count == 0)
|
||||
return false;
|
||||
|
||||
// Získame poslednú položku
|
||||
int lastItemIndex = _listView.Items.Count - 1;
|
||||
var lastItem = _listView.Items[lastItemIndex];
|
||||
|
||||
// Overíme, či je posledná položka úplne viditeľná
|
||||
return lastItem.Bounds.Bottom <= _listView.ClientRectangle.Bottom;
|
||||
}
|
||||
|
||||
public void EnableAutoScroll()
|
||||
{
|
||||
_autoScrollEnabled = true;
|
||||
}
|
||||
|
||||
public void DisableAutoScroll()
|
||||
{
|
||||
_autoScrollEnabled = false;
|
||||
}
|
||||
|
||||
private void AdjustColumnWidth()
|
||||
{
|
||||
if (_listView.Columns.Count > 0)
|
||||
{
|
||||
_listView.Columns[0].Width = _listView.ClientSize.Width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class LogColorRule
|
||||
{
|
||||
public bool Enabled { get; set; } = true;
|
||||
public string Pattern { get; set; } = string.Empty;
|
||||
public int ForeColorArgb { get; set; } = Color.Black.ToArgb();
|
||||
public int BackColorArgb { get; set; }
|
||||
public bool UseBackColor { get; set; }
|
||||
public bool Bold { get; set; }
|
||||
|
||||
public Color ForeColor => Color.FromArgb(ForeColorArgb);
|
||||
public Color BackColor => Color.FromArgb(BackColorArgb);
|
||||
|
||||
public LogColorRule Clone()
|
||||
{
|
||||
return new LogColorRule
|
||||
{
|
||||
Enabled = Enabled,
|
||||
Pattern = Pattern,
|
||||
ForeColorArgb = ForeColorArgb,
|
||||
BackColorArgb = BackColorArgb,
|
||||
UseBackColor = UseBackColor,
|
||||
Bold = Bold
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string state = Enabled ? string.Empty : "[disabled] ";
|
||||
return state + Pattern;
|
||||
}
|
||||
|
||||
public static List<LogColorRule> CreateDefaults()
|
||||
{
|
||||
return new List<LogColorRule>
|
||||
{
|
||||
Create("|TRACE|", Color.DimGray, false),
|
||||
Create("|DEBUG|", Color.RoyalBlue, false),
|
||||
Create("|INFO |", Color.ForestGreen, false),
|
||||
Create("|WARN |", Color.DarkOrange, true),
|
||||
Create("|ERROR|", Color.Crimson, true),
|
||||
Create("|FATAL|", Color.White, true, Color.DarkRed)
|
||||
};
|
||||
}
|
||||
|
||||
private static LogColorRule Create(string pattern, Color foreground, bool bold, Color? background = null)
|
||||
{
|
||||
return new LogColorRule
|
||||
{
|
||||
Enabled = true,
|
||||
Pattern = pattern,
|
||||
ForeColorArgb = foreground.ToArgb(),
|
||||
BackColorArgb = background?.ToArgb() ?? Color.Empty.ToArgb(),
|
||||
UseBackColor = background.HasValue,
|
||||
Bold = bold
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public static class LogColorRuleRepository
|
||||
{
|
||||
private static readonly string settingsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Sensus", "AppDiagnostic");
|
||||
private static readonly string settingsPath = Path.Combine(settingsFolder, "color-rules.xml");
|
||||
|
||||
public static List<LogColorRule> Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(settingsPath))
|
||||
{
|
||||
return LogColorRule.CreateDefaults();
|
||||
}
|
||||
|
||||
var serializer = new XmlSerializer(typeof(List<LogColorRule>));
|
||||
using (FileStream stream = File.OpenRead(settingsPath))
|
||||
{
|
||||
var rules = serializer.Deserialize(stream) as List<LogColorRule>;
|
||||
return rules == null || rules.Count == 0 ? LogColorRule.CreateDefaults() : rules;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return LogColorRule.CreateDefaults();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save(IEnumerable<LogColorRule> rules)
|
||||
{
|
||||
Directory.CreateDirectory(settingsFolder);
|
||||
|
||||
var serializer = new XmlSerializer(typeof(List<LogColorRule>));
|
||||
using (FileStream stream = File.Create(settingsPath))
|
||||
{
|
||||
serializer.Serialize(stream, new List<LogColorRule>(rules));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public static class LogColorizer
|
||||
{
|
||||
public static void Apply(RichTextBox target, int startIndex, int length, string text, IEnumerable<LogColorRule> rules, Font regularFont, Font boldFont)
|
||||
{
|
||||
if (target == null || length <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
target.Select(startIndex, length);
|
||||
target.SelectionColor = target.ForeColor;
|
||||
target.SelectionBackColor = target.BackColor;
|
||||
target.SelectionFont = regularFont;
|
||||
|
||||
foreach (LogColorRule rule in rules)
|
||||
{
|
||||
if (rule == null || !rule.Enabled || string.IsNullOrEmpty(rule.Pattern))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int searchIndex = 0;
|
||||
while (searchIndex < text.Length)
|
||||
{
|
||||
int matchIndex = text.IndexOf(rule.Pattern, searchIndex, StringComparison.OrdinalIgnoreCase);
|
||||
if (matchIndex < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
target.Select(startIndex + matchIndex, rule.Pattern.Length);
|
||||
target.SelectionColor = rule.ForeColor;
|
||||
target.SelectionBackColor = rule.UseBackColor ? rule.BackColor : target.BackColor;
|
||||
target.SelectionFont = rule.Bold ? boldFont : regularFont;
|
||||
searchIndex = matchIndex + rule.Pattern.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
using SharedComponents;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public class LogFilter
|
||||
{
|
||||
private ListView _listView;
|
||||
private string _filterText = string.Empty; // Pre uloženie aktuálneho filtrovaného reťazca
|
||||
|
||||
// Konstruktor
|
||||
public LogFilter(ListView listView)
|
||||
{
|
||||
_listView = listView;
|
||||
}
|
||||
|
||||
// Metóda na aplikovanie filtra na ListView
|
||||
public void ApplyFilter(string filterText)
|
||||
{
|
||||
_filterText = filterText.ToLower(); // Ukladáme text filtra bez ohľadu na veľkosť písmen
|
||||
|
||||
// Po aplikovaní filtra obnovíme zobrazenie
|
||||
RefreshListView();
|
||||
}
|
||||
|
||||
public void RefreshListView()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skontrolujeme, či sme na hlavnom vlákne a v prípade potreby použijeme Invoke
|
||||
if (_listView.InvokeRequired)
|
||||
{
|
||||
// Použijeme Invoke, ak nie sme na hlavnom vlákne
|
||||
_listView.Invoke(new Action(RefreshListView));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vymazanie existujúcich položiek
|
||||
_listView.Items.Clear();
|
||||
|
||||
// Načítame všetky logy (ideálne z cache alebo databázy)
|
||||
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.Logs.Count);
|
||||
|
||||
// Pridáme len tie logy, ktoré spĺňajú filter
|
||||
foreach (var log in logs)
|
||||
{
|
||||
if (log.ToLower().Contains(_filterText)) // Kontrola, či log obsahuje filter text
|
||||
{
|
||||
var listViewItem = new ListViewItem(log);
|
||||
|
||||
// Striedanie farieb riadkov
|
||||
if (_listView.Items.Count % 2 == 0) // Párny index => biela
|
||||
{
|
||||
listViewItem.BackColor = Color.White;
|
||||
}
|
||||
else // Nepárny index => svetlá sivá
|
||||
{
|
||||
listViewItem.BackColor = Color.FromArgb(240, 240, 240); // Veľmi svetlá sivá
|
||||
}
|
||||
|
||||
// Pridanie efektu pre novú položku
|
||||
ApplyNewItemEffect(listViewItem);
|
||||
|
||||
// Pridanie položky do ListView
|
||||
_listView.Items.Add(listViewItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Zachytíme výnimku, ak sa niečo pokazí, a zobrazíme ju užívateľovi
|
||||
MessageBox.Show($"An error occurred while refreshing the log view: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
// Môžete pridať ďalšie metódy na zobrazenie alebo efekt pre nové položky, ak je to potrebné
|
||||
private void ApplyNewItemEffect(ListViewItem item)
|
||||
{
|
||||
// Prípadný efekt pre nový pridaný log
|
||||
// Môžete pridať animáciu alebo zmenu farby atď.
|
||||
item.ForeColor = Color.Green; // Napríklad zmeníme farbu písma na zelenú
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
-309
@@ -1,309 +0,0 @@
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
private System.Windows.Forms.ToolStrip mainToolStrip;
|
||||
private System.Windows.Forms.ToolStripButton pauseButton;
|
||||
private System.Windows.Forms.ToolStripButton refreshButton;
|
||||
private System.Windows.Forms.ToolStripButton clearButton;
|
||||
private System.Windows.Forms.ToolStripButton saveButton;
|
||||
private System.Windows.Forms.ToolStripButton copyButton;
|
||||
private System.Windows.Forms.ToolStripButton copyAllButton;
|
||||
private System.Windows.Forms.ToolStripButton wrapButton;
|
||||
private System.Windows.Forms.ToolStripButton autoScrollButton;
|
||||
private System.Windows.Forms.ToolStripButton alwaysOnTopButton;
|
||||
private System.Windows.Forms.ToolStripButton colorRulesButton;
|
||||
private System.Windows.Forms.ToolStripButton closeButton;
|
||||
private System.Windows.Forms.TableLayoutPanel filterPanel;
|
||||
private System.Windows.Forms.Label filterLabel;
|
||||
private System.Windows.Forms.TextBox filterTextBox;
|
||||
private System.Windows.Forms.Label levelLabel;
|
||||
private System.Windows.Forms.ComboBox levelComboBox;
|
||||
private System.Windows.Forms.Label applicationLabel;
|
||||
private System.Windows.Forms.ComboBox applicationComboBox;
|
||||
private System.Windows.Forms.Button applyFilterButton;
|
||||
private System.Windows.Forms.Button clearFilterButton;
|
||||
private System.Windows.Forms.RichTextBox logView;
|
||||
private System.Windows.Forms.StatusStrip statusStrip;
|
||||
private System.Windows.Forms.ToolStripStatusLabel receiverStatusLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel statusSpacer;
|
||||
private System.Windows.Forms.ToolStripStatusLabel countStatusLabel;
|
||||
private System.Windows.Forms.ContextMenuStrip logContextMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem copySelectionMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem copyLineMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem copyAllMenuItem;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.mainToolStrip = new System.Windows.Forms.ToolStrip();
|
||||
this.pauseButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.refreshButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.clearButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.saveButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.copyButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.copyAllButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.wrapButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.autoScrollButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.alwaysOnTopButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.colorRulesButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.closeButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.filterPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.filterLabel = new System.Windows.Forms.Label();
|
||||
this.filterTextBox = new System.Windows.Forms.TextBox();
|
||||
this.levelLabel = new System.Windows.Forms.Label();
|
||||
this.levelComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.applicationLabel = new System.Windows.Forms.Label();
|
||||
this.applicationComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.applyFilterButton = new System.Windows.Forms.Button();
|
||||
this.clearFilterButton = new System.Windows.Forms.Button();
|
||||
this.logContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.copySelectionMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.copyLineMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.copyAllMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.logView = new System.Windows.Forms.RichTextBox();
|
||||
this.statusStrip = new System.Windows.Forms.StatusStrip();
|
||||
this.receiverStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.statusSpacer = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.countStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.mainToolStrip.SuspendLayout();
|
||||
this.filterPanel.SuspendLayout();
|
||||
this.logContextMenu.SuspendLayout();
|
||||
this.statusStrip.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// mainToolStrip
|
||||
//
|
||||
this.mainToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.mainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.pauseButton,
|
||||
this.refreshButton,
|
||||
this.clearButton,
|
||||
this.saveButton,
|
||||
new System.Windows.Forms.ToolStripSeparator(),
|
||||
this.copyButton,
|
||||
this.copyAllButton,
|
||||
new System.Windows.Forms.ToolStripSeparator(),
|
||||
this.wrapButton,
|
||||
this.autoScrollButton,
|
||||
this.alwaysOnTopButton,
|
||||
this.colorRulesButton,
|
||||
this.closeButton});
|
||||
this.mainToolStrip.Location = new System.Drawing.Point(0, 0);
|
||||
this.mainToolStrip.Name = "mainToolStrip";
|
||||
this.mainToolStrip.Padding = new System.Windows.Forms.Padding(6, 3, 6, 3);
|
||||
this.mainToolStrip.Size = new System.Drawing.Size(1184, 31);
|
||||
this.mainToolStrip.TabIndex = 0;
|
||||
//
|
||||
// pauseButton
|
||||
//
|
||||
this.pauseButton.CheckOnClick = true;
|
||||
this.pauseButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.pauseButton.Text = "Pause";
|
||||
this.pauseButton.ToolTipText = "Pause screen updates while continuing to receive logs";
|
||||
this.pauseButton.Click += new System.EventHandler(this.pauseButton_Click);
|
||||
//
|
||||
// refreshButton
|
||||
//
|
||||
this.refreshButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.refreshButton.Text = "Refresh";
|
||||
this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click);
|
||||
//
|
||||
// clearButton
|
||||
//
|
||||
this.clearButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.clearButton.Text = "Clear";
|
||||
this.clearButton.Click += new System.EventHandler(this.clearButton_Click);
|
||||
//
|
||||
// saveButton
|
||||
//
|
||||
this.saveButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.saveButton.Text = "Save...";
|
||||
this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
|
||||
//
|
||||
// copyButton
|
||||
//
|
||||
this.copyButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.copyButton.Text = "Copy";
|
||||
this.copyButton.ToolTipText = "Copy selected text or the current log line";
|
||||
this.copyButton.Click += new System.EventHandler(this.copyButton_Click);
|
||||
//
|
||||
// copyAllButton
|
||||
//
|
||||
this.copyAllButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.copyAllButton.Text = "Copy all";
|
||||
this.copyAllButton.Click += new System.EventHandler(this.copyAllButton_Click);
|
||||
//
|
||||
// wrapButton
|
||||
//
|
||||
this.wrapButton.Checked = true;
|
||||
this.wrapButton.CheckOnClick = true;
|
||||
this.wrapButton.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.wrapButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.wrapButton.Text = "Wrap lines";
|
||||
this.wrapButton.Click += new System.EventHandler(this.wrapButton_Click);
|
||||
//
|
||||
// autoScrollButton
|
||||
//
|
||||
this.autoScrollButton.Checked = true;
|
||||
this.autoScrollButton.CheckOnClick = true;
|
||||
this.autoScrollButton.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.autoScrollButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.autoScrollButton.Text = "Auto-scroll";
|
||||
//
|
||||
// alwaysOnTopButton
|
||||
//
|
||||
this.alwaysOnTopButton.CheckOnClick = true;
|
||||
this.alwaysOnTopButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.alwaysOnTopButton.Text = "Always on top";
|
||||
this.alwaysOnTopButton.Click += new System.EventHandler(this.alwaysOnTopButton_Click);
|
||||
//
|
||||
// colorRulesButton
|
||||
//
|
||||
this.colorRulesButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.colorRulesButton.Text = "Color rules...";
|
||||
this.colorRulesButton.Click += new System.EventHandler(this.colorRulesButton_Click);
|
||||
//
|
||||
// closeButton
|
||||
//
|
||||
this.closeButton.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
|
||||
this.closeButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.closeButton.Text = "Close";
|
||||
this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
|
||||
//
|
||||
// filterPanel
|
||||
//
|
||||
this.filterPanel.ColumnCount = 8;
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 42F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 42F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 105F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 72F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 180F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F));
|
||||
this.filterPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 66F));
|
||||
this.filterPanel.Controls.Add(this.filterLabel, 0, 0);
|
||||
this.filterPanel.Controls.Add(this.filterTextBox, 1, 0);
|
||||
this.filterPanel.Controls.Add(this.levelLabel, 2, 0);
|
||||
this.filterPanel.Controls.Add(this.levelComboBox, 3, 0);
|
||||
this.filterPanel.Controls.Add(this.applicationLabel, 4, 0);
|
||||
this.filterPanel.Controls.Add(this.applicationComboBox, 5, 0);
|
||||
this.filterPanel.Controls.Add(this.applyFilterButton, 6, 0);
|
||||
this.filterPanel.Controls.Add(this.clearFilterButton, 7, 0);
|
||||
this.filterPanel.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.filterPanel.Location = new System.Drawing.Point(0, 31);
|
||||
this.filterPanel.Name = "filterPanel";
|
||||
this.filterPanel.Padding = new System.Windows.Forms.Padding(6, 5, 6, 5);
|
||||
this.filterPanel.RowCount = 1;
|
||||
this.filterPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.filterPanel.Size = new System.Drawing.Size(1184, 38);
|
||||
this.filterPanel.TabIndex = 1;
|
||||
//
|
||||
// filter controls
|
||||
//
|
||||
this.filterLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.filterLabel.AutoSize = true;
|
||||
this.filterLabel.Text = "Filter";
|
||||
this.filterTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.filterTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.filterTextBox_KeyDown);
|
||||
this.levelLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.levelLabel.AutoSize = true;
|
||||
this.levelLabel.Text = "Level";
|
||||
this.levelComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.levelComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.levelComboBox.SelectedIndexChanged += new System.EventHandler(this.filterValueChanged);
|
||||
this.applicationLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.applicationLabel.AutoSize = true;
|
||||
this.applicationLabel.Text = "Application";
|
||||
this.applicationComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.applicationComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.applicationComboBox.SelectedIndexChanged += new System.EventHandler(this.filterValueChanged);
|
||||
this.applyFilterButton.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.applyFilterButton.Text = "Apply";
|
||||
this.applyFilterButton.Click += new System.EventHandler(this.applyFilterButton_Click);
|
||||
this.clearFilterButton.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.clearFilterButton.Text = "Reset";
|
||||
this.clearFilterButton.Click += new System.EventHandler(this.clearFilterButton_Click);
|
||||
//
|
||||
// logContextMenu
|
||||
//
|
||||
this.logContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.copySelectionMenuItem,
|
||||
this.copyLineMenuItem,
|
||||
this.copyAllMenuItem});
|
||||
this.copySelectionMenuItem.Text = "Copy selection";
|
||||
this.copySelectionMenuItem.Click += new System.EventHandler(this.copySelectionMenuItem_Click);
|
||||
this.copyLineMenuItem.Text = "Copy current line";
|
||||
this.copyLineMenuItem.Click += new System.EventHandler(this.copyLineMenuItem_Click);
|
||||
this.copyAllMenuItem.Text = "Copy all visible logs";
|
||||
this.copyAllMenuItem.Click += new System.EventHandler(this.copyAllButton_Click);
|
||||
//
|
||||
// logView
|
||||
//
|
||||
this.logView.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.logView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.logView.ContextMenuStrip = this.logContextMenu;
|
||||
this.logView.DetectUrls = false;
|
||||
this.logView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.logView.Font = new System.Drawing.Font("Consolas", 9F);
|
||||
this.logView.HideSelection = false;
|
||||
this.logView.Location = new System.Drawing.Point(0, 69);
|
||||
this.logView.Name = "logView";
|
||||
this.logView.ReadOnly = true;
|
||||
this.logView.Size = new System.Drawing.Size(1184, 554);
|
||||
this.logView.TabIndex = 2;
|
||||
this.logView.Text = "";
|
||||
this.logView.WordWrap = true;
|
||||
//
|
||||
// statusStrip
|
||||
//
|
||||
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.receiverStatusLabel,
|
||||
this.statusSpacer,
|
||||
this.countStatusLabel});
|
||||
this.statusStrip.Location = new System.Drawing.Point(0, 623);
|
||||
this.statusStrip.Name = "statusStrip";
|
||||
this.statusStrip.Size = new System.Drawing.Size(1184, 22);
|
||||
this.statusStrip.TabIndex = 3;
|
||||
this.receiverStatusLabel.Text = "Listening";
|
||||
this.statusSpacer.Spring = true;
|
||||
this.countStatusLabel.Text = "Received: 0 | Visible: 0";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1184, 645);
|
||||
this.Controls.Add(this.logView);
|
||||
this.Controls.Add(this.filterPanel);
|
||||
this.Controls.Add(this.mainToolStrip);
|
||||
this.Controls.Add(this.statusStrip);
|
||||
this.KeyPreview = true;
|
||||
this.MinimumSize = new System.Drawing.Size(860, 480);
|
||||
this.Name = "MainForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Application live diagnostic";
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown);
|
||||
this.mainToolStrip.ResumeLayout(false);
|
||||
this.mainToolStrip.PerformLayout();
|
||||
this.filterPanel.ResumeLayout(false);
|
||||
this.filterPanel.PerformLayout();
|
||||
this.logContextMenu.ResumeLayout(false);
|
||||
this.statusStrip.ResumeLayout(false);
|
||||
this.statusStrip.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,446 +0,0 @@
|
||||
using AppDiagnostic.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
private readonly Func<int> connectedClientCountProvider;
|
||||
private readonly Func<bool> activationRequestProvider;
|
||||
private readonly Timer refreshTimer;
|
||||
private readonly Font regularLogFont;
|
||||
private readonly Font boldLogFont;
|
||||
private List<LogColorRule> colorRules;
|
||||
private long lastRenderedVersion = -1;
|
||||
private int observedEntryCount;
|
||||
private int visibleEntryCount;
|
||||
private bool loadingFilters;
|
||||
|
||||
public MainForm() : this(null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public MainForm(Func<int> connectedClientCountProvider, Func<bool> activationRequestProvider)
|
||||
{
|
||||
this.connectedClientCountProvider = connectedClientCountProvider;
|
||||
this.activationRequestProvider = activationRequestProvider;
|
||||
InitializeComponent();
|
||||
Icon = Properties.Resources.TBF_icon;
|
||||
|
||||
regularLogFont = new Font(logView.Font, FontStyle.Regular);
|
||||
boldLogFont = new Font(logView.Font, FontStyle.Bold);
|
||||
colorRules = LogColorRuleRepository.Load();
|
||||
|
||||
InitializeFilters();
|
||||
|
||||
refreshTimer = new Timer { Interval = 250 };
|
||||
refreshTimer.Tick += refreshTimer_Tick;
|
||||
refreshTimer.Start();
|
||||
|
||||
RefreshView(true);
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
refreshTimer.Stop();
|
||||
refreshTimer.Dispose();
|
||||
regularLogFont.Dispose();
|
||||
boldLogFont.Dispose();
|
||||
base.OnFormClosing(e);
|
||||
}
|
||||
|
||||
private void InitializeFilters()
|
||||
{
|
||||
loadingFilters = true;
|
||||
levelComboBox.Items.AddRange(new object[] { "All levels", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" });
|
||||
levelComboBox.SelectedIndex = 0;
|
||||
applicationComboBox.Items.Add("All applications");
|
||||
applicationComboBox.SelectedIndex = 0;
|
||||
loadingFilters = false;
|
||||
}
|
||||
|
||||
private void refreshTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
ProcessActivationRequest();
|
||||
RefreshView(false);
|
||||
}
|
||||
|
||||
private void ProcessActivationRequest()
|
||||
{
|
||||
if (activationRequestProvider == null || !activationRequestProvider())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (WindowState == FormWindowState.Minimized)
|
||||
{
|
||||
WindowState = FormWindowState.Normal;
|
||||
}
|
||||
|
||||
Show();
|
||||
BringToFront();
|
||||
Activate();
|
||||
}
|
||||
|
||||
private void RefreshView(bool forceFullRefresh)
|
||||
{
|
||||
List<DiagnosticLogEntry> snapshot = DiagnosticLogStore.Instance.GetSnapshot();
|
||||
UpdateApplicationFilter(snapshot);
|
||||
|
||||
if (pauseButton.Checked)
|
||||
{
|
||||
UpdateStatus(snapshot.Count);
|
||||
return;
|
||||
}
|
||||
|
||||
long currentVersion = DiagnosticLogStore.Instance.Version;
|
||||
if (!forceFullRefresh && currentVersion == lastRenderedVersion)
|
||||
{
|
||||
UpdateStatus(snapshot.Count);
|
||||
return;
|
||||
}
|
||||
|
||||
bool canAppend = !forceFullRefresh && snapshot.Count > observedEntryCount;
|
||||
if (canAppend)
|
||||
{
|
||||
AppendEntries(snapshot.Skip(observedEntryCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
RebuildView(snapshot);
|
||||
}
|
||||
|
||||
observedEntryCount = snapshot.Count;
|
||||
lastRenderedVersion = currentVersion;
|
||||
UpdateStatus(snapshot.Count);
|
||||
}
|
||||
|
||||
private void RebuildView(IEnumerable<DiagnosticLogEntry> entries)
|
||||
{
|
||||
logView.SuspendLayout();
|
||||
logView.Clear();
|
||||
visibleEntryCount = 0;
|
||||
AppendEntries(entries, false);
|
||||
logView.ResumeLayout();
|
||||
|
||||
if (autoScrollButton.Checked)
|
||||
{
|
||||
ScrollToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendEntries(IEnumerable<DiagnosticLogEntry> entries, bool scrollAfterAppend = true)
|
||||
{
|
||||
int originalSelectionStart = logView.SelectionStart;
|
||||
int originalSelectionLength = logView.SelectionLength;
|
||||
|
||||
foreach (DiagnosticLogEntry entry in entries)
|
||||
{
|
||||
if (!MatchesFilter(entry))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AppendEntry(entry);
|
||||
visibleEntryCount++;
|
||||
}
|
||||
|
||||
if (scrollAfterAppend && autoScrollButton.Checked)
|
||||
{
|
||||
ScrollToEnd();
|
||||
}
|
||||
else if (!autoScrollButton.Checked)
|
||||
{
|
||||
int safeStart = Math.Min(originalSelectionStart, logView.TextLength);
|
||||
int safeLength = Math.Min(originalSelectionLength, logView.TextLength - safeStart);
|
||||
logView.Select(safeStart, safeLength);
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendEntry(DiagnosticLogEntry entry)
|
||||
{
|
||||
string text = DiagnosticLogFormatter.Format(entry);
|
||||
|
||||
if (logView.TextLength > 0)
|
||||
{
|
||||
logView.AppendText(Environment.NewLine);
|
||||
}
|
||||
|
||||
int startIndex = logView.TextLength;
|
||||
logView.AppendText(text);
|
||||
LogColorizer.Apply(logView, startIndex, text.Length, text, colorRules, regularLogFont, boldLogFont);
|
||||
logView.Select(logView.TextLength, 0);
|
||||
}
|
||||
|
||||
private bool MatchesFilter(DiagnosticLogEntry entry)
|
||||
{
|
||||
string selectedLevel = levelComboBox.SelectedItem as string;
|
||||
if (!string.IsNullOrEmpty(selectedLevel) && selectedLevel != "All levels" && !string.Equals(entry.Level, selectedLevel, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string selectedApplication = applicationComboBox.SelectedItem as string;
|
||||
if (!string.IsNullOrEmpty(selectedApplication) && selectedApplication != "All applications" && !string.Equals(entry.ApplicationName, selectedApplication, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string filter = filterTextBox.Text.Trim();
|
||||
return filter.Length == 0 || DiagnosticLogFormatter.Format(entry).IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
private void UpdateApplicationFilter(IEnumerable<DiagnosticLogEntry> entries)
|
||||
{
|
||||
string selectedApplication = applicationComboBox.SelectedItem as string ?? "All applications";
|
||||
List<string> applications = entries.Select(entry => entry.ApplicationName).Where(name => !string.IsNullOrWhiteSpace(name)).Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(name => name).ToList();
|
||||
List<string> currentApplications = applicationComboBox.Items.Cast<string>().Skip(1).ToList();
|
||||
|
||||
if (applications.SequenceEqual(currentApplications, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loadingFilters = true;
|
||||
applicationComboBox.BeginUpdate();
|
||||
applicationComboBox.Items.Clear();
|
||||
applicationComboBox.Items.Add("All applications");
|
||||
applicationComboBox.Items.AddRange(applications.Cast<object>().ToArray());
|
||||
applicationComboBox.SelectedItem = applicationComboBox.Items.Cast<string>().FirstOrDefault(item => string.Equals(item, selectedApplication, StringComparison.OrdinalIgnoreCase)) ?? "All applications";
|
||||
applicationComboBox.EndUpdate();
|
||||
loadingFilters = false;
|
||||
}
|
||||
|
||||
private void UpdateStatus(int storedCount)
|
||||
{
|
||||
int clients = connectedClientCountProvider?.Invoke() ?? 0;
|
||||
receiverStatusLabel.Text = pauseButton.Checked ? $"Paused | Connected sources: {clients}" : $"Listening | Connected sources: {clients}";
|
||||
countStatusLabel.Text = $"Received: {DiagnosticLogStore.Instance.TotalReceived:N0} | Stored: {storedCount:N0} | Visible: {visibleEntryCount:N0}";
|
||||
}
|
||||
|
||||
private void ScrollToEnd()
|
||||
{
|
||||
logView.Select(logView.TextLength, 0);
|
||||
logView.ScrollToCaret();
|
||||
}
|
||||
|
||||
private void pauseButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
pauseButton.Text = pauseButton.Checked ? "Resume" : "Pause";
|
||||
|
||||
if (!pauseButton.Checked)
|
||||
{
|
||||
RefreshView(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus(DiagnosticLogStore.Instance.GetSnapshot().Count);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
RefreshView(true);
|
||||
}
|
||||
|
||||
private void clearButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
DiagnosticLogStore.Instance.Clear();
|
||||
observedEntryCount = 0;
|
||||
visibleEntryCount = 0;
|
||||
RefreshView(true);
|
||||
}
|
||||
|
||||
private void saveButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
using (var dialog = new SaveFileDialog())
|
||||
{
|
||||
dialog.Filter = "Text files (*.txt)|*.txt|Log files (*.log)|*.log|All files (*.*)|*.*";
|
||||
dialog.Title = "Save visible diagnostic logs";
|
||||
dialog.DefaultExt = "log";
|
||||
dialog.FileName = $"AppDiagnostic_{DateTime.Now:yyyyMMdd_HHmmss}.log";
|
||||
|
||||
if (dialog.ShowDialog(this) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(dialog.FileName, logView.Text);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MessageBox.Show(this, $"Unable to save diagnostic logs: {exception.Message}", "Save error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
CopySelectionOrCurrentLine();
|
||||
}
|
||||
|
||||
private void copySelectionMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (logView.SelectionLength > 0)
|
||||
{
|
||||
CopyText(logView.SelectedText);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyLineMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
CopyCurrentLine();
|
||||
}
|
||||
|
||||
private void copyAllButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
CopyText(logView.Text);
|
||||
}
|
||||
|
||||
private void CopySelectionOrCurrentLine()
|
||||
{
|
||||
if (logView.SelectionLength > 0)
|
||||
{
|
||||
CopyText(logView.SelectedText);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyCurrentLine();
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyCurrentLine()
|
||||
{
|
||||
if (logView.Lines.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int lineIndex = logView.GetLineFromCharIndex(logView.SelectionStart);
|
||||
if (lineIndex >= 0 && lineIndex < logView.Lines.Length)
|
||||
{
|
||||
CopyText(logView.Lines[lineIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyText(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(text);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MessageBox.Show(this, $"Unable to copy text: {exception.Message}", "Clipboard error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void wrapButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
logView.WordWrap = wrapButton.Checked;
|
||||
}
|
||||
|
||||
private void alwaysOnTopButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
TopMost = alwaysOnTopButton.Checked;
|
||||
}
|
||||
|
||||
private void colorRulesButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
using (var editor = new ColorRuleEditorForm(colorRules))
|
||||
{
|
||||
if (editor.ShowDialog(this) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
colorRules = editor.Rules;
|
||||
|
||||
try
|
||||
{
|
||||
LogColorRuleRepository.Save(colorRules);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MessageBox.Show(this, $"Unable to save color rules: {exception.Message}", "Settings error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
RefreshView(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyFilterButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
RefreshView(true);
|
||||
}
|
||||
|
||||
private void clearFilterButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
loadingFilters = true;
|
||||
filterTextBox.Clear();
|
||||
levelComboBox.SelectedIndex = 0;
|
||||
applicationComboBox.SelectedIndex = 0;
|
||||
loadingFilters = false;
|
||||
RefreshView(true);
|
||||
}
|
||||
|
||||
private void filterValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!loadingFilters)
|
||||
{
|
||||
RefreshView(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void filterTextBox_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
{
|
||||
RefreshView(true);
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
else if (e.KeyCode == Keys.Escape)
|
||||
{
|
||||
clearFilterButton_Click(sender, EventArgs.Empty);
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void closeButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void MainForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Control && e.KeyCode == Keys.F)
|
||||
{
|
||||
filterTextBox.Focus();
|
||||
filterTextBox.SelectAll();
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
else if (e.Control && e.KeyCode == Keys.S)
|
||||
{
|
||||
saveButton_Click(sender, EventArgs.Empty);
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
else if (e.KeyCode == Keys.F5)
|
||||
{
|
||||
RefreshView(true);
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
bool isFirstInstance;
|
||||
|
||||
using (var instanceMutex = new Mutex(true, "Sensus.AppDiagnostic.SingleInstance", out isFirstInstance))
|
||||
using (var activationEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Sensus.AppDiagnostic.Activate"))
|
||||
{
|
||||
if (!isFirstInstance)
|
||||
{
|
||||
activationEvent.Set();
|
||||
return;
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
using (var diagnosticServer = new DiagnosticPipeServer(DiagnosticLogStore.Instance.Add))
|
||||
{
|
||||
diagnosticServer.Start();
|
||||
Application.Run(new MainForm(() => diagnosticServer.ConnectedClientCount, () => activationEvent.WaitOne(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AppDiagnostic")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AppDiagnostic")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2024")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("fa9abad1-7184-4295-ade8-d44f2e3de6b2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AppDiagnostic.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AppDiagnostic.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon TBF_icon {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("TBF_icon", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="TBF_icon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\TBF_icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AppDiagnostic.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="log4net" version="3.0.3" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -1,37 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public class BackgroundBeep
|
||||
{
|
||||
static Thread beepThread;
|
||||
static AutoResetEvent signalBeep;
|
||||
|
||||
static BackgroundBeep()
|
||||
{
|
||||
signalBeep = new AutoResetEvent(false);
|
||||
beepThread = new Thread(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
signalBeep.WaitOne(); /// waits for an event
|
||||
Console.Beep(500, 400); /// frequency (Hz), duration (ms)
|
||||
}
|
||||
}, 1);
|
||||
beepThread.IsBackground = true;
|
||||
beepThread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes one beep in a separate thread (non-blocking function)
|
||||
/// </summary>
|
||||
public static void Beep()
|
||||
{
|
||||
signalBeep.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C8939821-BA5C-4988-A3D0-BF53B74865C7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Common</RootNamespace>
|
||||
<AssemblyName>Common</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.5.2.2\lib\net46\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackgroundBeep.cs" />
|
||||
<Compile Include="DatabaseSettings.cs" />
|
||||
<Compile Include="DBSettings.cs" />
|
||||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="Forms\ListViewEx.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ListViewExtensions.cs" />
|
||||
<Compile Include="Forms\LviDateTimeColumnComparer.cs" />
|
||||
<Compile Include="Forms\LviIntColumnComparer.cs" />
|
||||
<Compile Include="Forms\LviNameSurnameColumnComparer.cs" />
|
||||
<Compile Include="Forms\LviTextColumnComparer.cs" />
|
||||
<Compile Include="Forms\MessageEventArgs.cs" />
|
||||
<Compile Include="Forms\ModelessForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ModelessForm.designer.cs">
|
||||
<DependentUpon>ModelessForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Formulas.cs" />
|
||||
<Compile Include="CurrentUser.cs" />
|
||||
<Compile Include="GlobalData.cs" />
|
||||
<Compile Include="IMeasurementCorrection.cs" />
|
||||
<Compile Include="IOrderInfo.cs" />
|
||||
<Compile Include="IParamsProvider.cs" />
|
||||
<Compile Include="Iperl\OptoTelegramRaw.cs" />
|
||||
<Compile Include="IUncertainty.cs" />
|
||||
<Compile Include="IUser.cs" />
|
||||
<Compile Include="Printers\PrintersCommon.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="QuitAppException.cs" />
|
||||
<Compile Include="SerializableDictionary.cs" />
|
||||
<Compile Include="StatisticalMetrics.cs" />
|
||||
<Compile Include="Telegram.cs" />
|
||||
<Compile Include="UIControls\CoolButtonCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UIControls\CoolButtonCtrl.Designer.cs">
|
||||
<DependentUpon>CoolButtonCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UIControls\RoundedRectangle.cs" />
|
||||
<Compile Include="Units.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Forms\ListViewEx.resx">
|
||||
<DependentUpon>ListViewEx.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\ModelessForm.resx">
|
||||
<DependentUpon>ModelessForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,132 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021-2022 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
class UserAndForm
|
||||
{
|
||||
public readonly IUser User;
|
||||
public readonly Form Form;
|
||||
|
||||
public UserAndForm(IUser user, Form form)
|
||||
{
|
||||
User = user;
|
||||
Form = form;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CurrentUser
|
||||
{
|
||||
public const string AdminUsername = "admin";
|
||||
public const string AdminPassword = "staratura";
|
||||
|
||||
public static int MinPasswdLength = 0;
|
||||
public static int PasswdExpirationPeriodDays = 0;
|
||||
|
||||
public static DBSettings RemoteUsersDB = null;
|
||||
public static DBSettings LocalUsersDB = null;
|
||||
|
||||
|
||||
static readonly Stack<UserAndForm> userStack = new Stack<UserAndForm>();
|
||||
|
||||
public static Common.AuthorizedAs AuthorizedAs;
|
||||
public static DateTime LastAuthorization = DateTime.Now;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Push a new user into the stack of users and form references.
|
||||
/// Prevent double user stack entry for the same Windows form.
|
||||
/// </summary>
|
||||
/// <param name="newUser">New user</param>
|
||||
/// <param name="currentForm">Reference to the current form</param>
|
||||
public static void Change(IUser newUser, Form currentForm)
|
||||
{
|
||||
if (userStack.Count > 0 && userStack.Peek().Form == currentForm)
|
||||
{
|
||||
userStack.Pop();
|
||||
}
|
||||
|
||||
userStack.Push(new UserAndForm(newUser, currentForm));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore an original user from the stack of users - remove user at the top of the stack.
|
||||
/// Prevent restoring when there is no entry for the form currently being closed.
|
||||
/// </summary>
|
||||
/// <param name="formBeingClosed">Reference to the form currently being closed</param>
|
||||
/// <returns>true = current user was restored, false = no current user change</returns>
|
||||
public static bool Restore(Form formBeingClosed)
|
||||
{
|
||||
if (userStack.Count > 0 && userStack.Peek().Form == formBeingClosed)
|
||||
{
|
||||
userStack.Pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the user currenty at the top of the stack of users.
|
||||
/// </summary>
|
||||
public static IUser User()
|
||||
{
|
||||
return (userStack.Count > 0) ? userStack.Peek().User : null; /// TODO: Return default user when stack is empty
|
||||
}
|
||||
|
||||
public static IUser User2;
|
||||
public static IUser User3;
|
||||
|
||||
/// <summary>
|
||||
/// Return the current user name or an empty string
|
||||
/// </summary>
|
||||
public static string UserName()
|
||||
{
|
||||
if (User() == null || User().UserName == null)
|
||||
return string.Empty;
|
||||
else if (User2 == null || User2.UserName == null)
|
||||
return User().UserName;
|
||||
else if (User3 == null || User3.UserName == null)
|
||||
return string.Format("{0},{1}", User().UserName, User2.UserName);
|
||||
else
|
||||
return string.Format("{0},{1},{2}", User().UserName, User2.UserName, User3.UserName);
|
||||
}
|
||||
|
||||
public static string GetEncodedString(string legalizator)
|
||||
{
|
||||
if (User() == null || User().UserName == null) return string.Empty;
|
||||
return string.Format("{0}~{1}~{2}",
|
||||
User().UserName,
|
||||
User().FullName == null ? string.Empty : User().FullName,
|
||||
legalizator == null ? string.Empty : legalizator);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return the current user number or 0
|
||||
/// </summary>
|
||||
public static int Number()
|
||||
{
|
||||
return (User() != null) ? User().Number : 0;
|
||||
}
|
||||
|
||||
public static bool IsPowerUser()
|
||||
{
|
||||
return (User() != null) ? User().IsPowerUser() : false;
|
||||
}
|
||||
|
||||
public static bool IsMemberOf(GID groupId)
|
||||
{
|
||||
return (User() != null) ? User().IsMemberOf(groupId) : false;
|
||||
}
|
||||
|
||||
public static bool IsMemberOf(GID[] groupIds)
|
||||
{
|
||||
return (User() != null) ? User().IsMemberOf(groupIds) : (groupIds == null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Database settings required to make a connection
|
||||
/// </summary>
|
||||
public class DBSettings : ICloneable
|
||||
{
|
||||
public DBType DbType;
|
||||
public string ConnectionString;
|
||||
|
||||
public DBSettings()
|
||||
{
|
||||
}
|
||||
|
||||
public DBSettings(DBType dbType, string connectionString)
|
||||
{
|
||||
this.DbType = dbType;
|
||||
this.ConnectionString = connectionString;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new DBSettings(DbType, ConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Test bench database settings, contains bench name and settings od several databases
|
||||
/// </summary>
|
||||
public class DatabaseSettings : ICloneable, IComparable
|
||||
{
|
||||
// Public fields
|
||||
public string BenchName;
|
||||
public bool IsRealBench;
|
||||
public DBSettings ProceduresDBSettings; /// Configuration database settings
|
||||
public DBSettings WaterMetersDBSettings; /// Results database settings
|
||||
public DBSettings EventsDBSettings; /// Events database settings
|
||||
public DBSettings UsersDBSettings; /// Shared configuration database settings
|
||||
|
||||
// Constructor
|
||||
public DatabaseSettings()
|
||||
{
|
||||
BenchName = String.Empty; /// Empty string (avoid null)
|
||||
IsRealBench = false;
|
||||
ProceduresDBSettings = new DBSettings(DBType.MySql, string.Empty);
|
||||
WaterMetersDBSettings = new DBSettings(DBType.MySql, string.Empty);
|
||||
EventsDBSettings = new DBSettings(DBType.MySql, string.Empty);
|
||||
UsersDBSettings = new DBSettings(DBType.MySql, string.Empty);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
DatabaseSettings result = new DatabaseSettings();
|
||||
|
||||
result.BenchName = BenchName;
|
||||
result.IsRealBench = IsRealBench;
|
||||
result.ProceduresDBSettings = (DBSettings)ProceduresDBSettings.Clone();
|
||||
result.WaterMetersDBSettings = (DBSettings)WaterMetersDBSettings.Clone();
|
||||
result.EventsDBSettings = (DBSettings)EventsDBSettings.Clone();
|
||||
result.UsersDBSettings = (DBSettings)UsersDBSettings.Clone();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int CompareTo(object dbs2)
|
||||
{
|
||||
if (!(dbs2 is DatabaseSettings)) return 0;
|
||||
return String.Compare(BenchName, (dbs2 as DatabaseSettings).BenchName);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Extract and return a DB server from a MySQL connection string.
|
||||
/// </summary>
|
||||
public static string GetDBServer(string connectionString)
|
||||
{
|
||||
return GetFromConnectionString(connectionString, new string[] { "SERVER=" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract and return a DB name from a MySQL connection string.
|
||||
/// </summary>
|
||||
public static string GetDBName(string connectionString)
|
||||
{
|
||||
return GetFromConnectionString(connectionString, new string[] { "DATABASE=" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract and return a username from a MySQL connection string
|
||||
/// </summary>
|
||||
public static string GetDBUser(string connectionString)
|
||||
{
|
||||
return GetFromConnectionString(connectionString, new string[] { "USER=", "UID=" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract and return a password from a MySQL connection string
|
||||
/// </summary>
|
||||
public static string GetDBPassword(string connectionString)
|
||||
{
|
||||
return GetFromConnectionString(connectionString, new string[] { "PASSWORD=", "PWD=" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract and return an element of a MySQL connection string
|
||||
/// (a host, a database, a user name or a password).
|
||||
/// Return an empty string on any error.
|
||||
/// </summary>
|
||||
public static string GetFromConnectionString(string connectionString, string[] patterns)
|
||||
{
|
||||
foreach (var pattern in patterns)
|
||||
{
|
||||
int startIx = connectionString.IndexOf(pattern);
|
||||
if (startIx >= 0)
|
||||
{
|
||||
/// pattern found, extract the subsequent element
|
||||
startIx += pattern.Length;
|
||||
int endIx = connectionString.IndexOf(';', startIx);
|
||||
return (endIx > 0) ? connectionString.Substring(startIx, endIx - startIx) : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// pattern NOT found
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} config={1} results={2} events={3} users={4}",
|
||||
BenchName,
|
||||
ProceduresDBSettings.ConnectionString,
|
||||
WaterMetersDBSettings.ConnectionString,
|
||||
EventsDBSettings.ConnectionString,
|
||||
UsersDBSettings.ConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
-890
@@ -1,890 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to assign descriptions to enum values
|
||||
/// </summary>
|
||||
public class Description : Attribute
|
||||
{
|
||||
public string Text;
|
||||
public Description(string t)
|
||||
{
|
||||
Text = t;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetDescription
|
||||
{
|
||||
/// Extension method for enum-s
|
||||
public static string ToDescription(this Enum en)
|
||||
{
|
||||
Type type = en.GetType();
|
||||
MemberInfo[] memInfo = type.GetMember(en.ToString());
|
||||
|
||||
if (memInfo != null && memInfo.Length > 0)
|
||||
{
|
||||
object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description), false);
|
||||
if (attrs != null && attrs.Length > 0)
|
||||
return ((Description)attrs[0]).Text;
|
||||
}
|
||||
|
||||
return en.ToString(); /// Return ToString() value in case there is no description
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the type of a database
|
||||
/// </summary>
|
||||
public enum DBType
|
||||
{
|
||||
None, /// Database disabled
|
||||
MySql, /// MySQL database
|
||||
SQLite, /// SQLite
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Identifies the database based on the content </summary>
|
||||
public enum DBKind
|
||||
{
|
||||
Config,
|
||||
Results,
|
||||
RemoteConfig,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum ProcedureSelection
|
||||
{
|
||||
#if LANG_CS
|
||||
[Description("Žádné")] None,
|
||||
[Description("Lokální postupy")] FromLocalDB,
|
||||
[Description("Postupy ze sdílené databázy")] FromSharedDB,
|
||||
[Description("Zakázky z Oracle databázy")] OrderNrFromOracleDB,
|
||||
[Description("Zakázky ze sledovací databázy")] OrderNrFromTracingDB,
|
||||
#else
|
||||
[Description("None")] None,
|
||||
[Description("Local procedures")] FromLocalDB,
|
||||
[Description("Shared procedures")] FromSharedDB,
|
||||
[Description("Orders from Oracle DB")] OrderFromOracleDB,
|
||||
[Description("Orders from Tracing DB")] OrderFromTracingDB,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum LoginMethod
|
||||
{
|
||||
UserName, /// = alias, abbreviation
|
||||
FullName, /// = description
|
||||
Number,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum AuthorizedAs
|
||||
{
|
||||
PowerUser,
|
||||
LocalUser,
|
||||
RemoteUser,
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GID-s of user groups, each user is member of one or more groups.
|
||||
/// </summary>
|
||||
public enum GID
|
||||
{
|
||||
Testers,
|
||||
TestingSpecialists,
|
||||
HeadOfLab,
|
||||
MaintenanceSpecialists,
|
||||
Metrologists,
|
||||
CalibrationSpecialists,
|
||||
Administrators, /// application / network / database administrator
|
||||
TraceabilityManagement,
|
||||
MetrologicalAuthority,
|
||||
WaterMeterAuthority,
|
||||
NrOfGroups, /// Number of groups (this is not a GroupID)
|
||||
None,
|
||||
}
|
||||
|
||||
public enum MySortOrder
|
||||
{
|
||||
None,
|
||||
Ascending, /// The same like SortOrder.Ascending
|
||||
Descending, /// The same like SortOrder.Descending
|
||||
Ascending2, /// Sorts by a surname in ascending order in case or 'Name Surname' column
|
||||
Descending2, /// Sorts by a surname in descending order in case or 'Name Surname' column
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flags returned by each device configuration control Verify(...) function.
|
||||
/// </summary>
|
||||
public enum CfgUpdateFlags
|
||||
{
|
||||
None = 0,
|
||||
Error = 0x1, /// Some settings in the user control are invalid and cannot be set
|
||||
Warning = 0x02, /// Some settings in the user control are suspicious, can be set after user confirmation
|
||||
RestartRqrd = 0x04, /// TBF program restart is required to apply all changed parameters
|
||||
AnyChange = 0x08, /// At least one parameter have changed
|
||||
VolatileChange = 0x10,
|
||||
InvokeCfgChange = 0x20, /// Invoke CfgChange handler of the component
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event severity
|
||||
/// </summary>
|
||||
public enum Severity
|
||||
{
|
||||
Undefined,
|
||||
Notification,
|
||||
Warning,
|
||||
Error,
|
||||
FatalError,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum EventClass
|
||||
{
|
||||
Undefined,
|
||||
EquipmentHW,
|
||||
Metrology,
|
||||
TestingProcess,
|
||||
BadResults,
|
||||
ComputerResources,
|
||||
Network,
|
||||
Other,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum SubscriberGroup : long
|
||||
{
|
||||
None = 0,
|
||||
Metrology = 1,
|
||||
Maintenance = 2,
|
||||
Production = 4,
|
||||
Management = 8,
|
||||
Finish = 16,
|
||||
}
|
||||
|
||||
public enum EViewerOption
|
||||
{
|
||||
Undefined,
|
||||
AllEvents,
|
||||
RecentEvents,
|
||||
UnreadEvents,
|
||||
}
|
||||
|
||||
public enum ProcedureState
|
||||
{
|
||||
Active,
|
||||
History,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum FlowNames
|
||||
{
|
||||
QnQtQmin = 0,
|
||||
Q3Q2Q1 = 1,
|
||||
QpQi = 2,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ProfileType
|
||||
{
|
||||
Q3R,
|
||||
QnClassColdWater,
|
||||
QnClassHotWater,
|
||||
QpQi,
|
||||
CompoundQ3RQ3R,
|
||||
CompoundQnClassQnClass,
|
||||
CompoundQ3RQnClass,
|
||||
CompoundQnClassQ3R,
|
||||
CompoundQpQiQpQi,
|
||||
Manual,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum FlowId
|
||||
{
|
||||
Any,
|
||||
Q4,
|
||||
Q3,
|
||||
Q2,
|
||||
Q1,
|
||||
Q4Main,
|
||||
Q3Main,
|
||||
Q2Main,
|
||||
Q1Main,
|
||||
Q4Aux,
|
||||
Q3Aux,
|
||||
Q2Aux,
|
||||
Q1Aux,
|
||||
Qmax,
|
||||
Qn,
|
||||
Qt,
|
||||
Qmin,
|
||||
QmaxMain,
|
||||
QnMain,
|
||||
QtMain,
|
||||
QminMain,
|
||||
QmaxAux,
|
||||
QnAux,
|
||||
QtAux,
|
||||
QminAux,
|
||||
Qp,
|
||||
Qp10,
|
||||
Qi,
|
||||
QpMain,
|
||||
Qp10Main,
|
||||
QiMain,
|
||||
QpAux,
|
||||
Qp10Aux,
|
||||
QiAux,
|
||||
Qdetected,
|
||||
Qfall,
|
||||
Qrise,
|
||||
}
|
||||
|
||||
public enum ErrorLimitType
|
||||
{
|
||||
Manual,
|
||||
QpClass,
|
||||
Count,
|
||||
}
|
||||
|
||||
/// <summary> Kind of meters for the procedure / test </summary>
|
||||
public enum MetersKind
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Wasserzähler")] Single,
|
||||
[Description("Verbundwasserzähler")] Combined,
|
||||
[Description("Wärmezähler")] HeatMeter,
|
||||
#elif LANG_FR
|
||||
[Description("Compteurs eau")] Single,
|
||||
[Description("Mètres composés")] Combined,
|
||||
[Description("Thermomètres")] HeatMeter,
|
||||
#elif LANG_CS
|
||||
[Description("Vodoměry")] Single,
|
||||
[Description("Kombinované vodoměry")] Combined,
|
||||
[Description("Měřiče tepla")] HeatMeter,
|
||||
#elif LANG_RU
|
||||
[Description("Счетчик")] Single,
|
||||
[Description("Комбинированный счетчик")] Combined,
|
||||
[Description("Счетчик тепла")] HeatMeter,
|
||||
#else
|
||||
[Description("Water meters")] Single,
|
||||
[Description("Compound water meters")] Combined,
|
||||
[Description("Heat meters")] HeatMeter,
|
||||
#endif
|
||||
}
|
||||
|
||||
public enum CompoundMeterId : byte
|
||||
{
|
||||
Single,
|
||||
CompoundMain,
|
||||
CompoundAux,
|
||||
Compound,
|
||||
HeatMeterVolume,
|
||||
HeatMeterMass,//...MF
|
||||
HeatMeterEnergy,
|
||||
SingleOrCompound, /// Only used when querying results
|
||||
}
|
||||
|
||||
public enum PulsesTypeByQuantity : short
|
||||
{
|
||||
[Description("dm3")] Volume_dm3,
|
||||
[Description("kg")] Mass_kg,
|
||||
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Medium
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
#if LANG_PL
|
||||
[Description("zimna")] ColdWater,
|
||||
[Description("ciepła")] HotWater,
|
||||
#elif LANG_IT
|
||||
[Description("freddo")] ColdWater,
|
||||
[Description("caldo")] HotWater,
|
||||
#elif LANG_FR
|
||||
[Description("eau froide")] ColdWater,
|
||||
[Description("eau chaude")] HotWater,
|
||||
#else
|
||||
[Description("cold")] ColdWater,
|
||||
[Description("hot")] HotWater,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Mounting
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
#if LANG_DE
|
||||
[Description("H")] H, /// horizontal
|
||||
[Description("V")] V, /// vertical
|
||||
[Description("STR")] S, /// standrohre
|
||||
[Description("F")] F, /// fall
|
||||
[Description("H/V")] HV, /// horizontal / vertical
|
||||
#else
|
||||
[Description("H")] H, /// horizontal
|
||||
[Description("V")] V, /// vertical
|
||||
[Description("S")] S, /// steig
|
||||
[Description("F")] F, /// fall
|
||||
[Description("H/V")] HV, /// horizontal / vertical
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum TemperatureClass
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("T30")] T30,
|
||||
[Description("T50")] T50,
|
||||
[Description("T70")] T70,
|
||||
[Description("T90")] T90,
|
||||
[Description("T130")] T130,
|
||||
[Description("T180")] T180,
|
||||
[Description("T30/70")] T30_70,
|
||||
[Description("T30/90")] T30_90,
|
||||
[Description("T30/130")] T30_130,
|
||||
[Description("T30/180")] T30_180,
|
||||
[Description("30")] t30,
|
||||
[Description("50")] t50,
|
||||
[Description("70")] t70,
|
||||
[Description("90")] t90,
|
||||
[Description("130")] t130,
|
||||
[Description("180")] t180,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum FlowProfileSensitivityClass
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("U0")] U0, /// ?
|
||||
[Description("D0")] D0, /// ?
|
||||
Count
|
||||
}
|
||||
|
||||
public enum PressureLossClass
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("dp63")] dp63, /// 0.063 MPa = 0.63 bar, TODO: Change to "Δp63"
|
||||
[Description("dp40")] dp40, /// 0.040 MPa = 0.40 bar
|
||||
[Description("dp25")] dp25, /// 0.025 MPa = 0.25 bar
|
||||
[Description("dp16")] dp16, /// 0.016 MPa = 0.16 bar
|
||||
[Description("dp10")] dp10, /// 0.010 MPa = 0.10 bar
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Maximum Admissible Pressure </summary>
|
||||
public enum MaxAdmissiblePressure
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("MAP6")] MAP6,
|
||||
[Description("MAP10")] MAP10,
|
||||
[Description("MAP16")] MAP16,
|
||||
[Description("MAP25")] MAP25,
|
||||
[Description("MAP40")] MAP40,
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Register reader type </summary>
|
||||
public enum RegisterReaderType
|
||||
{
|
||||
Unknown,
|
||||
Pulses, /// Sick, optical and similar
|
||||
Camera, /// CLP1611
|
||||
DataStream, /// iPerl
|
||||
Manual, /// Entered by human via form (also from camera images)
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Transition step is finished when this condition is fulfilled </summary>
|
||||
public enum StepCondition
|
||||
{
|
||||
None,
|
||||
Scale1Empty,
|
||||
Scale2Empty,
|
||||
Scale3Empty,
|
||||
AllScalesEmpty,
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State of water filled in the test bench.
|
||||
/// </summary>
|
||||
public enum FillState
|
||||
{
|
||||
Unknown, /// Test bench fill state is unknown
|
||||
Empty, /// Test bench is empty, no water
|
||||
Full, /// Test bench is full of water
|
||||
Count
|
||||
}
|
||||
|
||||
public enum MeretProtocol
|
||||
{
|
||||
[Description("<undefined>")] Undefined,
|
||||
[Description("Meret (obsolete)")] Meret,
|
||||
[Description("Modbus")] Modbus,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Publish : sbyte
|
||||
{
|
||||
#if LANG_DE
|
||||
/// german
|
||||
[Description("nie")] Never = 0,
|
||||
[Description("immer")] Always = 1,
|
||||
[Description("Bildschirm")] OnScreen = 2,
|
||||
[Description("intern")] Internal = 3,
|
||||
#elif LANG_FR
|
||||
[Description("jamais")] Never = 0,
|
||||
[Description("toujours")] Always = 1,
|
||||
[Description("À l'écran")] OnScreen = 2,
|
||||
[Description("interne")] Internal = 3,
|
||||
#elif LANG_CS
|
||||
/// czech
|
||||
[Description("nikdy")] Never = 0,
|
||||
[Description("vždy")] Always = 1,
|
||||
[Description("na obrazovku")] OnScreen = 2,
|
||||
[Description("interně")] Internal = 3,
|
||||
#elif LANG_SK
|
||||
/// slovak
|
||||
[Description("nikdy")] Never = 0,
|
||||
[Description("vždy")] Always = 1,
|
||||
[Description("na obrazovku")] OnScreen = 2,
|
||||
[Description("interne")] Internal = 3,
|
||||
#elif LANG_PL
|
||||
/// polish
|
||||
[Description("nigdy")] Never = 0,
|
||||
[Description("zawsze")] Always = 1,
|
||||
[Description("na ekranie")] OnScreen = 2,
|
||||
[Description("wewnętrznie")] Internal = 3,
|
||||
#elif LANG_RU
|
||||
/// russian
|
||||
[Description("никогда")] Never = 0,
|
||||
[Description("всегда")] Always = 1,
|
||||
[Description("толька экран")] OnScreen = 2,
|
||||
[Description("внутренно")] Internal = 3,
|
||||
#else
|
||||
/// english
|
||||
[Description("Never")] Never = 0,
|
||||
[Description("Always")] Always = 1,
|
||||
[Description("On screen")] OnScreen = 2,
|
||||
[Description("Internal")] Internal = 3,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum MassMethod : byte
|
||||
{
|
||||
#if LANG_DE
|
||||
/// nemecky
|
||||
[Description("Waage")] Scale,
|
||||
[Description("Spanne")] Spread,
|
||||
[Description("Standardabw.")] StdDev,
|
||||
#elif LANG_FR
|
||||
[Description("Balance")] Scale,
|
||||
[Description("Envergure")] Spread,
|
||||
[Description("Déviation std.")] StdDev,
|
||||
#elif LANG_CS
|
||||
/// cesky
|
||||
[Description("váhou")] Scale,
|
||||
[Description("max.rozdíl")] Spread,
|
||||
[Description("std.dev.")] StdDev,
|
||||
#else
|
||||
[Description("Scale")] Scale,
|
||||
[Description("Spread")] Spread,
|
||||
[Description("Std.dev.")] StdDev,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Three state test results and/or water meter result (Algeria PT25 requirement).
|
||||
/// NearlyOK means error is within error limits not narrowed by uncertainty
|
||||
/// OK: Uncertainty + ErrLimLo <= error <= ErrLimHi - Uncertainty
|
||||
/// NearlyOK: not OK but stil ErrLimLo <= error <= ErrLimHi
|
||||
/// Nok: otherwise
|
||||
/// </summary>
|
||||
public enum ThreeState
|
||||
{
|
||||
#if LANG_FR
|
||||
[Description("NC")] Nok, /// Totally failed: not OK and not NearlyOK
|
||||
[Description("2e/Ff")] NearlyOK, /// Nearly OK, not OK but not totally failed
|
||||
[Description("***")] OK, /// OK
|
||||
#else
|
||||
[Description("NOK")] Nok, /// Totally failed: not OK and not NearlyOK
|
||||
[Description("Nearly OK")] NearlyOK, /// Nearly OK, not OK but not totally failed
|
||||
[Description("OK")] OK, /// OK
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum TestProfile
|
||||
{
|
||||
UserDefined,
|
||||
UserDefinedCompound,
|
||||
UserDefinedHeatMeter,
|
||||
Protected, /// The first protected one
|
||||
ProtectedCompound,
|
||||
ProtectedHeatMeter,
|
||||
}
|
||||
|
||||
public enum Progress
|
||||
{
|
||||
JustStarted,
|
||||
TransitionBefore,
|
||||
SwitchingFlowDetection,
|
||||
FlowSetting,
|
||||
Aborted, /// Use as an argument when a test was aborted
|
||||
Test,
|
||||
TransitionAfter,
|
||||
Completed,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum Device
|
||||
{
|
||||
Screen,
|
||||
Printer,
|
||||
Disk,
|
||||
}
|
||||
|
||||
public enum PageOrientation
|
||||
{
|
||||
Portrait,
|
||||
Landscape,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ItemCategory
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Allgemein")] Other,
|
||||
[Description("Prüfstanddaten")] BenchData,
|
||||
[Description("Prüfstandergebnisse")] BenchResult,
|
||||
[Description("Prüfpunktdaten")] TestData,
|
||||
[Description("Prüfpunktergebnisse")] TestResult,
|
||||
[Description("Wasserzelledaten")] MeterData,
|
||||
[Description("Wasserzelleergebnisse")] MeterResult,
|
||||
#elif LANG_FR
|
||||
[Description("Autres")] Other,
|
||||
[Description("Données de banc")] BenchData,
|
||||
[Description("Résultats du banc")] BenchResult,
|
||||
[Description("Données de test")] TestData,
|
||||
[Description("Résultats de test")] TestResult,
|
||||
[Description("Données du compteur d'eau")] MeterData,
|
||||
[Description("Résultats du compteur d'eau")] MeterResult,
|
||||
#else
|
||||
[Description("Other")] Other,
|
||||
[Description("Bench data")] BenchData,
|
||||
[Description("Bench result")] BenchResult,
|
||||
[Description("Test data")] TestData,
|
||||
[Description("Test result")] TestResult,
|
||||
[Description("Meter data")] MeterData,
|
||||
[Description("Meter result")] MeterResult,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
/// <summary> Possible modes of operation of components and devices. </summary>
|
||||
public enum DebugMode
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Erkennen-aus")] DetectedOff = -2,
|
||||
[Description("Erkennen-ein")] DetectedOn = -1,
|
||||
[Description("Normal")] Normal = 0, /// Normal operation
|
||||
[Description("Auto-erkennen")] AutoDetect, /// The component (device) will be auto-detected
|
||||
[Description("Fehler")] FailureDuringOperation, /// Failure during operation -> disabled
|
||||
[Description("Aus")] Off, /// The component is off
|
||||
[Description("Aufzeichnen")] Record,
|
||||
[Description("Abspielen")] Replay,
|
||||
[Description("Simuliert")] Simulate, /// Test bench simulation, this mode does not require any hardware
|
||||
[Description("Geerbt")] Inherit,
|
||||
#elif LANG_FR
|
||||
[Description("Détection automatique: Éteindre")] DetectedOff = -2,
|
||||
[Description("Détection automatique: Allumé")] DetectedOn = -1,
|
||||
[Description("Ordinaire")] Normal = 0,
|
||||
[Description("Détection automatique")] AutoDetect,
|
||||
[Description("Erreur d'exécution")] FailureDuringOperation,
|
||||
[Description("Éteindre")] Off,
|
||||
[Description("Record")] Record,
|
||||
[Description("Répondre")] Replay,
|
||||
[Description("Simuler")] Simulate,
|
||||
[Description("Hériter")] Inherit,
|
||||
#else
|
||||
[Description("Detected off")] DetectedOff = -2,
|
||||
[Description("Detected on")] DetectedOn = -1,
|
||||
[Description("Normal")] Normal = 0, /// Normal operation
|
||||
[Description("Auto detect")] AutoDetect, /// The component (device) will be auto-detected
|
||||
[Description("Run-time error")] FailureDuringOperation, /// Failure during operation -> disabled
|
||||
[Description("Off")] Off, /// The component is off
|
||||
[Description("Record")] Record,
|
||||
[Description("Replay")] Replay,
|
||||
[Description("Simulate")] Simulate, /// Test bench simulation, this mode does not require any hardware
|
||||
[Description("Inherit")] Inherit,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Aus")] Off,
|
||||
[Description("Schwerwiegend")] Fatal,
|
||||
[Description("Fehler")] Error,
|
||||
[Description("Warnung")] Warn,
|
||||
[Description("Info")] Info,
|
||||
[Description("Debug")] Debug,
|
||||
[Description("Alles")] All,
|
||||
#else
|
||||
[Description("Off")] Off,
|
||||
[Description("Fatal")] Fatal,
|
||||
[Description("Error")] Error,
|
||||
[Description("Warn")] Warn,
|
||||
[Description("Info")] Info,
|
||||
[Description("Debug")] Debug,
|
||||
[Description("All")] All,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Arrangement of tests </summary>
|
||||
public enum TestsArrangement
|
||||
{
|
||||
Rows,
|
||||
Columns,
|
||||
}
|
||||
|
||||
/// <summary> Arrangement of meters </summary>
|
||||
public enum MetersArrangement
|
||||
{
|
||||
Vertically,
|
||||
Horizontally,
|
||||
}
|
||||
|
||||
public enum Alignment
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("links")] Left,
|
||||
[Description("zentriert")] Center,
|
||||
[Description("rechts")] Right,
|
||||
[Description("angepasst")] Justified,
|
||||
#elif LANG_FR
|
||||
[Description("gauche")] Left,
|
||||
[Description("centré")] Center,
|
||||
[Description("droit")] Right,
|
||||
[Description("justifié")] Justified,
|
||||
#else
|
||||
[Description("Left")] Left,
|
||||
[Description("Center")] Center,
|
||||
[Description("Right")] Right,
|
||||
[Description("Justified")] Justified,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum VertAlignment
|
||||
{
|
||||
[Description("Top")] Top,
|
||||
[Description("Middle")] Middle,
|
||||
[Description("Bottom")] Bottom,
|
||||
}
|
||||
|
||||
public enum TableForm
|
||||
{
|
||||
None,
|
||||
Rows,
|
||||
Columns,
|
||||
ColumnsPL,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum DivResolution : int
|
||||
{
|
||||
[Description("1 ms (0.25 s)")] _1ms = 0,
|
||||
[Description("2 ms (0.5 s)")] _2ms = 1,
|
||||
[Description("4 ms (1 s)")] _4ms = 2,
|
||||
[Description("8 ms (2 s)")] _8ms = 3,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ImageRotation
|
||||
{
|
||||
[Description("0 deg")] None,
|
||||
[Description("90 deg")] Deg90,
|
||||
[Description("180 deg")] Deg180,
|
||||
[Description("270 deg")] Deg270,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum CameraDisplayResolution
|
||||
{
|
||||
Small,
|
||||
Medium,
|
||||
Large,
|
||||
// FullScreen,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ErrorFlagsMode : sbyte
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("aus")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("ein")] On,
|
||||
[Description("stopp")] Stop,
|
||||
#elif LANG_FR
|
||||
[Description("éteindre")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("allumé")] On,
|
||||
[Description("arrêter")] Stop,
|
||||
#elif LANG_CS
|
||||
[Description("vypnuto")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("zapnuto")] On,
|
||||
[Description("stop")] Stop,
|
||||
#elif LANG_RU
|
||||
[Description("выкл")] Off,
|
||||
[Description("инфо")] Info,
|
||||
[Description("вкл")] On,
|
||||
[Description("останов")] Stop,
|
||||
#elif LANG_PL
|
||||
[Description("nie")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("tak")] On,
|
||||
[Description("przestać")] Stop,
|
||||
#else // LANG_EN
|
||||
[Description("off")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("on")] On,
|
||||
[Description("stop")] Stop,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
|
||||
public enum ErrorFlagMask : long
|
||||
{
|
||||
E1 = (1L << 0), /// shift = 0, E1 = 1L
|
||||
E2 = (1L << 1),
|
||||
E3 = (1L << 2),
|
||||
E4 = (1L << 3),
|
||||
E5 = (1L << 4),
|
||||
E6 = (1L << 5),
|
||||
E7 = (1L << 6),
|
||||
E8 = (1L << 7),
|
||||
E9 = (1L << 8),
|
||||
E10 = (1L << 9),
|
||||
E11 = (1L << 10),
|
||||
E12 = (1L << 11),
|
||||
E13 = (1L << 12),
|
||||
E14 = (1L << 13),
|
||||
E15 = (1L << 14),
|
||||
E16 = (1L << 15),
|
||||
E17 = (1L << 16),
|
||||
E18 = (1L << 17),
|
||||
E19 = (1L << 18),
|
||||
E20 = (1L << 19),
|
||||
E21 = (1L << 20),
|
||||
E22 = (1L << 21),
|
||||
E23 = (1L << 22),
|
||||
E24 = (1L << 23),
|
||||
E25 = (1L << 24),
|
||||
E26 = (1L << 25), /// iPERL: Invalid Q2 correction factors, mismatch between factors in the water meter and in DB
|
||||
E27 = (1L << 26), /// iPERL: Wrong counting direction
|
||||
E28 = (1L << 27), /// iPERL: Missing workflow step (assembly or test)
|
||||
E29 = (1L << 28),
|
||||
E30 = (1L << 29),
|
||||
E31 = (1L << 30),
|
||||
E32 = (1L << 31),
|
||||
E33 = (1L << 32),
|
||||
E34 = (1L << 33),
|
||||
E35 = (1L << 34),
|
||||
E36 = (1L << 35),
|
||||
E37 = (1L << 36),
|
||||
E38 = (1L << 37),
|
||||
E39 = (1L << 38),
|
||||
E40 = (1L << 39),
|
||||
E41 = (1L << 40),
|
||||
E42 = (1L << 41),
|
||||
E43 = (1L << 42),
|
||||
E44 = (1L << 43),
|
||||
E45 = (1L << 44),
|
||||
E46 = (1L << 45),
|
||||
E47 = (1L << 46),
|
||||
E48 = (1L << 47),
|
||||
E49 = (1L << 48),
|
||||
E50 = (1L << 49),
|
||||
E51 = (1L << 50),
|
||||
E52 = (1L << 51),
|
||||
E53 = (1L << 52),
|
||||
E54 = (1L << 53),
|
||||
E55 = (1L << 54),
|
||||
E56 = (1L << 55),
|
||||
E57 = (1L << 56),
|
||||
E58 = (1L << 57),
|
||||
E59 = (1L << 58),
|
||||
E60 = (1L << 59),
|
||||
E61 = (1L << 60),
|
||||
E62 = (1L << 61),
|
||||
E63 = (1L << 62),
|
||||
}
|
||||
|
||||
//...MF
|
||||
public enum FlowType : int
|
||||
{
|
||||
none,
|
||||
volume,
|
||||
mass,
|
||||
Count,
|
||||
}
|
||||
|
||||
#region iPERL enums
|
||||
|
||||
public enum Side
|
||||
{
|
||||
#if LANG_CS
|
||||
[Description("Levá")] Left,
|
||||
[Description("Pravá")] Right,
|
||||
#else
|
||||
[Description("Left")] Left,
|
||||
[Description("Right")] Right,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum FlowDir
|
||||
{
|
||||
R_L,
|
||||
L_R,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Counting
|
||||
{
|
||||
Arbitrary,
|
||||
Positive,
|
||||
Negative,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum OptoHeadState
|
||||
{
|
||||
Disabled,
|
||||
OptoAndDirOK,
|
||||
OptoNok,
|
||||
DirNok,
|
||||
Count
|
||||
}
|
||||
|
||||
#endregion iPERL enums
|
||||
}
|
||||
@@ -1,495 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Event Handler for SubItem events
|
||||
/// </summary>
|
||||
public delegate void SubItemEventHandler(object sender, SubItemEventArgs e);
|
||||
/// <summary>
|
||||
/// Event Handler for SubItemEndEditing events
|
||||
/// </summary>
|
||||
public delegate void SubItemEndEditingEventHandler(object sender, SubItemEndEditingEventArgs e);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Inherited ListView to allow in-place editing of subitems
|
||||
/// </summary>
|
||||
public class ListViewEx : System.Windows.Forms.ListView
|
||||
{
|
||||
#region Interop structs, imports and constants
|
||||
/// <summary>
|
||||
/// MessageHeader for WM_NOTIFY
|
||||
/// </summary>
|
||||
private struct NMHDR
|
||||
{
|
||||
#pragma warning disable
|
||||
public IntPtr hwndFrom;
|
||||
public Int32 idFrom;
|
||||
public Int32 code;
|
||||
#pragma warning restore
|
||||
}
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wPar, IntPtr lPar);
|
||||
[DllImport("user32.dll", CharSet=CharSet.Ansi)]
|
||||
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int len, ref int [] order);
|
||||
|
||||
// ListView messages
|
||||
private const int LVM_FIRST = 0x1000;
|
||||
private const int LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + 59);
|
||||
|
||||
// Windows Messages that will abort editing
|
||||
private const int WM_HSCROLL = 0x114;
|
||||
private const int WM_VSCROLL = 0x115;
|
||||
private const int WM_SIZE = 0x05;
|
||||
private const int WM_NOTIFY = 0x4E;
|
||||
|
||||
private const int HDN_FIRST = -300;
|
||||
private const int HDN_BEGINDRAG = (HDN_FIRST-10);
|
||||
private const int HDN_ITEMCHANGINGA = (HDN_FIRST-0);
|
||||
private const int HDN_ITEMCHANGINGW = (HDN_FIRST-20);
|
||||
#endregion
|
||||
|
||||
public MySortOrder SortOrder = MySortOrder.None;
|
||||
public int SortColumn = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
public event SubItemEventHandler SubItemClicked;
|
||||
public event SubItemEventHandler SubItemRightClicked;
|
||||
public event SubItemEventHandler SubItemBeginEditing;
|
||||
public event SubItemEndEditingEventHandler SubItemEndEditing;
|
||||
|
||||
public ListViewEx()
|
||||
{
|
||||
// This call is required by the Windows.Forms Form Designer.
|
||||
InitializeComponent();
|
||||
|
||||
base.FullRowSelect = true;
|
||||
base.View = View.Details;
|
||||
base.AllowColumnReorder = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if( components != null )
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private bool _doubleClickActivation = false;
|
||||
/// <summary>
|
||||
/// Is a double click required to start editing a cell?
|
||||
/// </summary>
|
||||
public bool DoubleClickActivation
|
||||
{
|
||||
get { return _doubleClickActivation; }
|
||||
set { _doubleClickActivation = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the order in which columns appear
|
||||
/// </summary>
|
||||
/// <returns>Current display order of column indices</returns>
|
||||
public int[] GetColumnOrder()
|
||||
{
|
||||
IntPtr lPar = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * Columns.Count);
|
||||
|
||||
IntPtr res = SendMessage(Handle, LVM_GETCOLUMNORDERARRAY, new IntPtr(Columns.Count), lPar);
|
||||
if (res.ToInt32() == 0) // Something went wrong
|
||||
{
|
||||
Marshal.FreeHGlobal(lPar);
|
||||
return null;
|
||||
}
|
||||
|
||||
int [] order = new int[Columns.Count];
|
||||
Marshal.Copy(lPar, order, 0, Columns.Count);
|
||||
|
||||
Marshal.FreeHGlobal(lPar);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Find ListViewItem and SubItem Index at position (x,y)
|
||||
/// </summary>
|
||||
/// <param name="x">relative to ListView</param>
|
||||
/// <param name="y">relative to ListView</param>
|
||||
/// <param name="item">Item at position (x,y)</param>
|
||||
/// <returns>SubItem index</returns>
|
||||
public int GetSubItemAt(int x, int y, out ListViewItem item)
|
||||
{
|
||||
item = this.GetItemAt(x, y);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
int[] order = GetColumnOrder();
|
||||
Rectangle lviBounds;
|
||||
int subItemX;
|
||||
|
||||
lviBounds = item.GetBounds(ItemBoundsPortion.Entire);
|
||||
subItemX = lviBounds.Left;
|
||||
for (int i=0; i<order.Length; i++)
|
||||
{
|
||||
ColumnHeader h = this.Columns[order[i]];
|
||||
if (x < subItemX+h.Width)
|
||||
{
|
||||
return h.Index;
|
||||
}
|
||||
subItemX += h.Width;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get bounds for a SubItem
|
||||
/// </summary>
|
||||
/// <param name="Item">Target ListViewItem</param>
|
||||
/// <param name="SubItem">Target SubItem index</param>
|
||||
/// <returns>Bounds of SubItem (relative to ListView)</returns>
|
||||
public Rectangle GetSubItemBounds(ListViewItem Item, int SubItem)
|
||||
{
|
||||
int[] order = GetColumnOrder();
|
||||
|
||||
Rectangle subItemRect = Rectangle.Empty;
|
||||
if (SubItem >= order.Length)
|
||||
throw new IndexOutOfRangeException("SubItem "+SubItem+" out of range");
|
||||
|
||||
if (Item == null)
|
||||
throw new ArgumentNullException("Item");
|
||||
|
||||
Rectangle lviBounds = Item.GetBounds(ItemBoundsPortion.Entire);
|
||||
int subItemX = lviBounds.Left;
|
||||
|
||||
ColumnHeader col;
|
||||
int i;
|
||||
for (i=0; i<order.Length; i++)
|
||||
{
|
||||
col = this.Columns[order[i]];
|
||||
if (col.Index == SubItem)
|
||||
break;
|
||||
subItemX += col.Width;
|
||||
}
|
||||
subItemRect = new Rectangle(subItemX, lviBounds.Top, this.Columns[order[i]].Width, lviBounds.Height);
|
||||
return subItemRect;
|
||||
}
|
||||
|
||||
|
||||
protected override void WndProc(ref Message msg)
|
||||
{
|
||||
switch (msg.Msg)
|
||||
{
|
||||
// Look for WM_VSCROLL,WM_HSCROLL or WM_SIZE messages.
|
||||
case WM_VSCROLL:
|
||||
case WM_HSCROLL:
|
||||
case WM_SIZE:
|
||||
EndEditing(false);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
// Look for WM_NOTIFY of events that might also change the
|
||||
// editor's position/size: Column reordering or resizing
|
||||
NMHDR h = (NMHDR)Marshal.PtrToStructure(msg.LParam, typeof(NMHDR));
|
||||
if (h.code == HDN_BEGINDRAG ||
|
||||
h.code == HDN_ITEMCHANGINGA ||
|
||||
h.code == HDN_ITEMCHANGINGW)
|
||||
EndEditing(false);
|
||||
break;
|
||||
}
|
||||
|
||||
base.WndProc(ref msg);
|
||||
}
|
||||
|
||||
|
||||
#region Initialize editing depending of DoubleClickActivation property
|
||||
protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
|
||||
MouseEventArgs me = (MouseEventArgs)e;
|
||||
if (me.Button == MouseButtons.Right)
|
||||
{
|
||||
/// Right mouse button click function
|
||||
RightClickFunctionSubitemAt(new Point(e.X, e.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Normal function (=edit item)
|
||||
if (DoubleClickActivation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditSubitemAt(new Point(e.X, e.Y));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDoubleClick(EventArgs e)
|
||||
{
|
||||
base.OnDoubleClick (e);
|
||||
|
||||
if (!DoubleClickActivation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Point pt = this.PointToClient(Cursor.Position);
|
||||
|
||||
EditSubitemAt(pt);
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Fire SubItemClicked
|
||||
///</summary>
|
||||
///<param name="p">Point of click/doubleclick</param>
|
||||
private void EditSubitemAt(Point p)
|
||||
{
|
||||
ListViewItem item;
|
||||
int idx = GetSubItemAt(p.X, p.Y, out item);
|
||||
if (idx >= 0)
|
||||
{
|
||||
OnSubItemClicked(new SubItemEventArgs(item, idx));
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Fire SubItemRightClicked
|
||||
///</summary>
|
||||
///<param name="p">Point of click/doubleclick</param>
|
||||
private void RightClickFunctionSubitemAt(Point p)
|
||||
{
|
||||
ListViewItem item;
|
||||
int idx = GetSubItemAt(p.X, p.Y, out item);
|
||||
if (idx >= 0)
|
||||
{
|
||||
OnSubItemRightClicked(new SubItemEventArgs(item, idx));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region In-place editing functions
|
||||
// The control performing the actual editing
|
||||
private Control _editingControl;
|
||||
// The LVI being edited
|
||||
private ListViewItem _editItem;
|
||||
// The SubItem being edited
|
||||
private int _editSubItem;
|
||||
|
||||
protected void OnSubItemBeginEditing(SubItemEventArgs e)
|
||||
{
|
||||
if (SubItemBeginEditing != null) SubItemBeginEditing(this, e);
|
||||
}
|
||||
|
||||
protected void OnSubItemEndEditing(SubItemEndEditingEventArgs e)
|
||||
{
|
||||
if (SubItemEndEditing != null) SubItemEndEditing(this, e);
|
||||
}
|
||||
|
||||
protected void OnSubItemClicked(SubItemEventArgs e)
|
||||
{
|
||||
if (SubItemClicked != null) SubItemClicked(this, e);
|
||||
}
|
||||
|
||||
protected void OnSubItemRightClicked(SubItemEventArgs e)
|
||||
{
|
||||
if (SubItemRightClicked != null) SubItemRightClicked(this, e);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Begin in-place editing of given cell
|
||||
/// </summary>
|
||||
/// <param name="c">Control used as cell editor</param>
|
||||
/// <param name="Item">ListViewItem to edit</param>
|
||||
/// <param name="SubItem">SubItem index to edit</param>
|
||||
public void StartEditing(Control c, ListViewItem Item, int SubItem)
|
||||
{
|
||||
OnSubItemBeginEditing(new SubItemEventArgs(Item, SubItem));
|
||||
|
||||
Rectangle rcSubItem = GetSubItemBounds(Item, SubItem);
|
||||
|
||||
if (rcSubItem.X < 0)
|
||||
{
|
||||
// Left edge of SubItem not visible - adjust rectangle position and width
|
||||
rcSubItem.Width += rcSubItem.X;
|
||||
rcSubItem.X=0;
|
||||
}
|
||||
if (rcSubItem.X+rcSubItem.Width > this.Width)
|
||||
{
|
||||
// Right edge of SubItem not visible - adjust rectangle width
|
||||
rcSubItem.Width = this.Width-rcSubItem.Left;
|
||||
}
|
||||
|
||||
// Subitem bounds are relative to the location of the ListView!
|
||||
rcSubItem.Offset(Left, Top);
|
||||
|
||||
// In case the editing control and the listview are on different parents,
|
||||
// account for different origins
|
||||
Point origin = new Point(0,0);
|
||||
Point lvOrigin = this.Parent.PointToScreen(origin);
|
||||
Point ctlOrigin = c.Parent.PointToScreen(origin);
|
||||
|
||||
rcSubItem.Offset(lvOrigin.X-ctlOrigin.X, lvOrigin.Y-ctlOrigin.Y);
|
||||
|
||||
// Position and show editor
|
||||
c.Bounds = rcSubItem;
|
||||
c.Text = Item.SubItems[SubItem].Text;
|
||||
c.Visible = true;
|
||||
c.BringToFront();
|
||||
c.Focus();
|
||||
|
||||
_editingControl = c;
|
||||
_editingControl.Leave += new EventHandler(_editControl_Leave);
|
||||
_editingControl.KeyPress += new KeyPressEventHandler(_editControl_KeyPress);
|
||||
|
||||
_editItem = Item;
|
||||
_editSubItem = SubItem;
|
||||
}
|
||||
|
||||
|
||||
private void _editControl_Leave(object sender, EventArgs e)
|
||||
{
|
||||
// cell editor losing focus
|
||||
EndEditing(true);
|
||||
}
|
||||
|
||||
private void _editControl_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
|
||||
{
|
||||
switch (e.KeyChar)
|
||||
{
|
||||
case (char)(int)Keys.Escape:
|
||||
{
|
||||
EndEditing(false);
|
||||
break;
|
||||
}
|
||||
|
||||
case (char)(int)Keys.Enter:
|
||||
{
|
||||
EndEditing(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accept or discard current value of cell editor control
|
||||
/// </summary>
|
||||
/// <param name="AcceptChanges">Use the _editingControl's Text as new SubItem text or discard changes?</param>
|
||||
public void EndEditing(bool AcceptChanges)
|
||||
{
|
||||
if (_editingControl == null)
|
||||
return;
|
||||
|
||||
SubItemEndEditingEventArgs e = new SubItemEndEditingEventArgs(
|
||||
_editItem, // The item being edited
|
||||
_editSubItem, // The subitem index being edited
|
||||
AcceptChanges ?
|
||||
_editingControl.Text : // Use editControl text if changes are accepted
|
||||
_editItem.SubItems[_editSubItem].Text, // or the original subitem's text, if changes are discarded
|
||||
!AcceptChanges // Cancel?
|
||||
);
|
||||
|
||||
OnSubItemEndEditing(e);
|
||||
|
||||
if (_editSubItem >= 0 && _editSubItem < _editItem.SubItems.Count)
|
||||
{
|
||||
_editItem.SubItems[_editSubItem].Text = e.DisplayText;
|
||||
}
|
||||
|
||||
if (_editingControl != null)
|
||||
{
|
||||
_editingControl.Leave -= new EventHandler(_editControl_Leave);
|
||||
_editingControl.KeyPress -= new KeyPressEventHandler(_editControl_KeyPress);
|
||||
|
||||
_editingControl.Visible = false;
|
||||
}
|
||||
|
||||
_editingControl = null;
|
||||
_editItem = null;
|
||||
_editSubItem = -1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event Args for SubItemClicked event
|
||||
/// </summary>
|
||||
public class SubItemEventArgs : EventArgs
|
||||
{
|
||||
int subItem = -1; /// Sub-item index
|
||||
ListViewItem item = null;
|
||||
|
||||
public int SubItem { get { return subItem; } }
|
||||
public ListViewItem Item { get { return item; } }
|
||||
|
||||
public SubItemEventArgs(ListViewItem item, int subItem)
|
||||
{
|
||||
this.subItem = subItem;
|
||||
this.item = item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event Args for SubItemEndEditingClicked event
|
||||
/// </summary>
|
||||
public class SubItemEndEditingEventArgs : SubItemEventArgs
|
||||
{
|
||||
string displayText = string.Empty;
|
||||
bool cancel = true;
|
||||
|
||||
public SubItemEndEditingEventArgs(ListViewItem item, int subItem, string displayText, bool cancel) :
|
||||
base(item, subItem)
|
||||
{
|
||||
this.displayText = displayText;
|
||||
this.cancel = cancel;
|
||||
}
|
||||
public string DisplayText
|
||||
{
|
||||
get { return displayText; }
|
||||
set { displayText = value; }
|
||||
}
|
||||
public bool Cancel
|
||||
{
|
||||
get { return cancel; }
|
||||
set { cancel = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class ListViewExtensions
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct HDITEM
|
||||
{
|
||||
public Mask mask;
|
||||
public int cxy;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string pszText;
|
||||
public IntPtr hbm;
|
||||
public int cchTextMax;
|
||||
public Format fmt;
|
||||
public IntPtr lParam;
|
||||
// _WIN32_IE >= 0x0300
|
||||
public int iImage;
|
||||
public int iOrder;
|
||||
// _WIN32_IE >= 0x0500
|
||||
public uint type;
|
||||
public IntPtr pvFilter;
|
||||
// _WIN32_WINNT >= 0x0600
|
||||
public uint state;
|
||||
|
||||
[Flags]
|
||||
public enum Mask
|
||||
{
|
||||
Format = 0x4, // HDI_FORMAT
|
||||
};
|
||||
|
||||
[Flags]
|
||||
public enum Format
|
||||
{
|
||||
SortDown = 0x200, // HDF_SORTDOWN
|
||||
SortUp = 0x400, // HDF_SORTUP
|
||||
};
|
||||
};
|
||||
|
||||
public const int LVM_FIRST = 0x1000;
|
||||
public const int LVM_GETHEADER = LVM_FIRST + 31;
|
||||
|
||||
public const int HDM_FIRST = 0x1200;
|
||||
public const int HDM_GETITEM = HDM_FIRST + 11;
|
||||
public const int HDM_SETITEM = HDM_FIRST + 12;
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref HDITEM lParam);
|
||||
|
||||
public static void SetSortIcon(this ListViewEx listViewControl, int columnIndex, MySortOrder order)
|
||||
{
|
||||
IntPtr columnHeader = SendMessage(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
|
||||
for (int columnNumber = 0; columnNumber <= listViewControl.Columns.Count - 1; columnNumber++)
|
||||
{
|
||||
var columnPtr = new IntPtr(columnNumber);
|
||||
var item = new HDITEM
|
||||
{
|
||||
mask = HDITEM.Mask.Format
|
||||
};
|
||||
|
||||
if (SendMessage(columnHeader, HDM_GETITEM, columnPtr, ref item) == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
if (order != MySortOrder.None && columnNumber == columnIndex)
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case MySortOrder.Ascending:
|
||||
case MySortOrder.Ascending2:
|
||||
item.fmt &= ~HDITEM.Format.SortDown;
|
||||
item.fmt |= HDITEM.Format.SortUp;
|
||||
break;
|
||||
|
||||
case MySortOrder.Descending:
|
||||
case MySortOrder.Descending2:
|
||||
item.fmt &= ~HDITEM.Format.SortUp;
|
||||
item.fmt |= HDITEM.Format.SortDown;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.fmt &= ~HDITEM.Format.SortDown & ~HDITEM.Format.SortUp;
|
||||
}
|
||||
|
||||
if (SendMessage(columnHeader, HDM_SETITEM, columnPtr, ref item) == IntPtr.Zero)
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
public class LviDateTimeColumnComparer : IComparer
|
||||
{
|
||||
int column;
|
||||
MySortOrder order;
|
||||
|
||||
public LviDateTimeColumnComparer()
|
||||
{
|
||||
column = 0;
|
||||
order = MySortOrder.Ascending;
|
||||
}
|
||||
|
||||
public LviDateTimeColumnComparer(int column, MySortOrder order)
|
||||
{
|
||||
this.column = column;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
DateTime valX = DateTime.Parse(((ListViewItem)x).SubItems[column].Text);
|
||||
DateTime valY = DateTime.Parse(((ListViewItem)y).SubItems[column].Text);
|
||||
|
||||
if (valX == valY)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if ((order == MySortOrder.Descending || order == MySortOrder.Descending2))
|
||||
{
|
||||
return (valY > valX) ? 1 : -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (valX > valY) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
public class LviIntColumnComparer : IComparer
|
||||
{
|
||||
int column;
|
||||
MySortOrder order;
|
||||
|
||||
public LviIntColumnComparer()
|
||||
{
|
||||
column = 0;
|
||||
order = MySortOrder.Ascending;
|
||||
}
|
||||
|
||||
public LviIntColumnComparer(int column, MySortOrder order)
|
||||
{
|
||||
this.column = column;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
int valX = int.Parse(((ListViewItem)x).SubItems[column].Text);
|
||||
int valY = int.Parse(((ListViewItem)y).SubItems[column].Text);
|
||||
return (order == MySortOrder.Descending || order == MySortOrder.Descending2) ? (valY - valX) : (valX - valY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
public class LviTextColumnComparer : IComparer
|
||||
{
|
||||
private int column;
|
||||
MySortOrder order;
|
||||
|
||||
public LviTextColumnComparer()
|
||||
{
|
||||
column = 0;
|
||||
order = MySortOrder.Ascending;
|
||||
}
|
||||
|
||||
public LviTextColumnComparer(int column, MySortOrder order)
|
||||
{
|
||||
this.column = column;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
string txtX = ((ListViewItem)x).SubItems[column].Text;
|
||||
string txtY = ((ListViewItem)y).SubItems[column].Text;
|
||||
return (order == MySortOrder.Descending || order == MySortOrder.Descending2) ? String.Compare(txtY, txtX) : String.Compare(txtX, txtY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
public class MessageEventArgs : EventArgs
|
||||
{
|
||||
public string Message;
|
||||
public MessageEventArgs(string message) { Message = message; }
|
||||
}
|
||||
}
|
||||
Generated
-63
@@ -1,63 +0,0 @@
|
||||
namespace Common.Forms
|
||||
{
|
||||
partial class ModelessForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(47, 29);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(35, 13);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "label1";
|
||||
//
|
||||
// ModelessForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(191, 56);
|
||||
this.Controls.Add(this.label1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Name = "ModelessForm";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "ModelessForm";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common.Forms
|
||||
{
|
||||
public partial class ModelessForm : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor to be used by the application
|
||||
/// </summary>
|
||||
/// <param name="title">Window title</param>
|
||||
/// <param name="message">Displayed message</param>
|
||||
public ModelessForm(string message, int backArgb = 0, int textArgb = 0, Font textFont = null, string title = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
ControlBox = false;
|
||||
|
||||
label1.Text = (message != null) ? message : "Please wait";
|
||||
BackColor = (backArgb != 0) ? Color.FromArgb(backArgb) : Color.LightGreen;
|
||||
ForeColor = (textArgb != 0) ? Color.FromArgb(textArgb) : Color.Black;
|
||||
label1.Font = (textFont != null) ? textFont : new Font("Arial", 14, FontStyle.Regular);
|
||||
Text = (title != null) ? title : string.Empty;
|
||||
|
||||
float textWidth = Graphics.FromImage(new Bitmap(1, 1)).MeasureString(label1.Text, label1.Font).Width;
|
||||
float textHeight = Graphics.FromImage(new Bitmap(1, 1)).MeasureString(label1.Text, label1.Font).Height;
|
||||
Width = (int)textWidth + 120; /// Form width calculated from the text width
|
||||
Height += (int)textHeight; /// Form height calculated from the text height
|
||||
|
||||
UpdateMessageHandler += delegate(object sender, MessageEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<MessageEventArgs>(OnUpdateMessage), sender, args); }
|
||||
else OnUpdateMessage(sender, args);
|
||||
};
|
||||
|
||||
CloseFormHandler += delegate(object sender, EventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<EventArgs>(OnCloseForm), sender, args); }
|
||||
else OnCloseForm(sender, args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called from the state machine when an operation forces a modeless dialog close.
|
||||
/// </summary>
|
||||
public void UpdateMessage(MessageEventArgs args)
|
||||
{
|
||||
if (UpdateMessageHandler == null) return;
|
||||
try { UpdateMessageHandler(null, args); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
public event EventHandler<MessageEventArgs> UpdateMessageHandler;
|
||||
void OnUpdateMessage(object sender, MessageEventArgs args)
|
||||
{
|
||||
if (args != null && args.Message != null) label1.Text = args.Message;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called from the state machine when an operation forces a modeless dialog close.
|
||||
/// </summary>
|
||||
public void CloseForm()
|
||||
{
|
||||
if (CloseFormHandler == null) return;
|
||||
try { CloseFormHandler(null, null); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
public event EventHandler<EventArgs> CloseFormHandler;
|
||||
void OnCloseForm(object sender, EventArgs args)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public static class Formulas
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Formulas));
|
||||
|
||||
|
||||
///
|
||||
/// Wrappers
|
||||
///
|
||||
public static double RealDensity() { return GlobalData.SampleDensity; }
|
||||
public static double AtTemperature() { return GlobalData.SampleTemp; }
|
||||
public static double Buoyancy() { return GlobalData.Buoyancy; }
|
||||
|
||||
|
||||
/// Private tables with coeficients to calculate specific enthalpy
|
||||
static readonly int[] Ii;
|
||||
static readonly int[] Ji;
|
||||
static readonly double[] ni;
|
||||
|
||||
/// Private table with coeficients to calculate temperature of a platinum thermometer
|
||||
static readonly double[] Di;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
static Formulas()
|
||||
{
|
||||
///
|
||||
/// Initialize tables to calculate specific enthalpies
|
||||
///
|
||||
Ii = new int[34] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 8, 8, 21, 23, 29, 30, 31, 32 };
|
||||
Ji = new int[34] { -2, -1, 0, 1, 2, 3, 4, 5, -9, -7, -1, 0, 1, 3, -3, 0, 1, 3, 17, -4, 0, 6, -5, -2, 10, -8, -11, -6, -29, -31, -38, -39, -40, -41 };
|
||||
ni = new double[34] {
|
||||
0.14632971213167, /// 1
|
||||
-0.84548187169114, /// 2
|
||||
-0.37563603672040E1, /// 3
|
||||
0.33855169168385E1, /// 4
|
||||
-0.95791963387872, /// 5
|
||||
0.15772038513228, /// 6
|
||||
-0.16616417199501E-1, /// 7
|
||||
0.81214629983568E-3, /// 8
|
||||
0.28319080123804E-3, /// 9
|
||||
-0.60706301565874E-3, /// 10
|
||||
-0.18990068218419E-1, /// 11
|
||||
-0.32529748770505E-1, /// 12
|
||||
-0.21841717175414E-1, /// 13
|
||||
-0.52838357969930E-4, /// 14
|
||||
-0.47184321073267E-3, /// 15
|
||||
-0.30001780793026E-3, /// 16
|
||||
0.47661393906987E-4, /// 17
|
||||
-0.44141845330846E-5, /// 18
|
||||
-0.72694996297594E-15, /// 19
|
||||
-0.31679644845054E-4, /// 20
|
||||
-0.28270797985312E-5, /// 21
|
||||
-0.85205128120103E-9, /// 22
|
||||
-0.22425281908000E-5, /// 23
|
||||
-0.65171222895601E-6, /// 24
|
||||
-0.14341729937924E-12, /// 25
|
||||
-0.40516996860117E-6, /// 26
|
||||
-0.12734301741641E-8, /// 27
|
||||
-0.17424871230634E-9, /// 28
|
||||
-0.68762131295531E-18, /// 29
|
||||
0.14478307828521E-19, /// 30
|
||||
0.26335781662795E-22, /// 31
|
||||
-0.11947622640071E-22, /// 32
|
||||
0.18228094581404E-23, /// 33
|
||||
-0.93537087292458E-25, /// 34
|
||||
};
|
||||
|
||||
///
|
||||
/// Initialize a table to calculate temperature of a platinum thermometer from resistance
|
||||
///
|
||||
Di = new double[]
|
||||
{
|
||||
439.932854,
|
||||
472.418020,
|
||||
37.684494,
|
||||
7.472018,
|
||||
2.920828,
|
||||
0.005184,
|
||||
-0.963864,
|
||||
-0.188732,
|
||||
0.191203,
|
||||
0.049025,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate density of distilled water from temperature
|
||||
/// </summary>
|
||||
/// <param name="t">ITS-90 temperature in [°C]</param>
|
||||
/// <returns>Density in [kg/m3]</returns>
|
||||
public static double DistilledWaterDensityFromTemp(double t)
|
||||
{
|
||||
if (t <= 40)
|
||||
{
|
||||
const double c0 = 999.839564;
|
||||
const double c1 = 0.067998613;
|
||||
const double c2 = -0.0091101468;
|
||||
const double c3 = 0.00010058299;
|
||||
const double c4 = -0.0000011275659;
|
||||
const double c5 = 6.5985371e-09;
|
||||
|
||||
return ((((c5 * t + c4) * t + c3) * t + c2) * t + c1) * t + c0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const double a0 = 9.9983952E2;
|
||||
const double a1 = 1.6952577E1;
|
||||
const double a2 = -7.9905127E-3;
|
||||
const double a3 = -4.6241757E-5;
|
||||
const double a4 = 1.0584601E-7;
|
||||
const double a5 = -2.8103006E-10;
|
||||
const double b = 1.6887236E-2;
|
||||
|
||||
return (((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t + a0) / (1.0 + b * t);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate density of distilled water from temperature (obsolete)
|
||||
/// </summary>
|
||||
/// <param name="t">IPTS-68 temperature in [°C]</param>
|
||||
/// <returns>Density in [kg/m3]</returns>
|
||||
public static double DistilledWaterDensityFromTempIPTS68(double t)
|
||||
{
|
||||
const double a0 = 999.842594;
|
||||
const double a1 = 0.06793952;
|
||||
const double a2 = -0.009095290;
|
||||
const double a3 = 0.0001001685;
|
||||
const double a4 = -0.000001120083;
|
||||
const double a5 = 6.536332e-09;
|
||||
|
||||
return ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t + a0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate density by comparing calculated data and data from a certificate
|
||||
/// </summary>
|
||||
/// <param name="realDensity">Density from a certificate in [kg/m3]</param>
|
||||
/// <param name="atTemperature">Temperature from a certificate in [°C]</param>
|
||||
/// <returns>Density correction in [kg/m3]</returns>
|
||||
public static double DensityCorrection(double realDensity, double atTemperature)
|
||||
{
|
||||
/// Calculated data
|
||||
double calculatedDensity = DistilledWaterDensityFromTemp(atTemperature);
|
||||
|
||||
return realDensity - calculatedDensity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate corrected (real) water density from temperature
|
||||
/// </summary>
|
||||
/// <param name="t">Temperature in [°C]</param>
|
||||
/// <returns>Density in [kg/m3]</returns>
|
||||
public static double WaterDensityFromTemp(double t)
|
||||
{
|
||||
return DistilledWaterDensityFromTemp(t) + DensityCorrection(RealDensity(), AtTemperature());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate corrected (real) water density from temperature
|
||||
/// </summary>
|
||||
/// <param name="t">Temperature in [°C]</param>
|
||||
/// <returns>Density in [kg/m3]</returns>
|
||||
public static double WaterDensityFromTempPress(double temp, double pressure)
|
||||
{
|
||||
double x0 = 5.08821E-10;
|
||||
double x1 = 1.2639418;
|
||||
double x2 = 0.2660269;
|
||||
double x3 = 0.3734838;
|
||||
double x4 = 2.0205242;
|
||||
double theta = temp / 100.0;
|
||||
double B = x0 * (((x3 * theta + x2) * theta + x1) * theta + 1) / (1 + x4 * theta);
|
||||
|
||||
return WaterDensityFromTemp(temp) * (1 + B * Common.Units.ConvertTo(Common.Unit.Pa, pressure));
|
||||
}
|
||||
|
||||
|
||||
public static float AirDensityFromAmbientVales(float tempC, float pressureBar, float humiPct)
|
||||
{
|
||||
double pressurePa = 100000.0 * (double)pressureBar; /// [Pa]
|
||||
double tempKelvin = 273.15 + (double)tempC;
|
||||
double coef1 = 1.2811805 / 10000.0 * tempKelvin * tempKelvin
|
||||
- 1.950987 / 100.0 * tempKelvin
|
||||
+ 34.04926034
|
||||
- 6.353631 * 1000.0 / tempKelvin;
|
||||
double coef3 = humiPct / 100.0 * System.Math.Exp(coef1) / pressurePa;
|
||||
double airDensityKgm3 = 0.00348353 * pressurePa * (1.0 - 0.378 * coef3) / tempKelvin; /// kg/m3
|
||||
return (float)airDensityKgm3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert 'pulses' to 'volume', prevent division by zero
|
||||
/// </summary>
|
||||
public static double VolumeFromPulses(int pulses, double pulsesPerLiter)
|
||||
{
|
||||
if (pulsesPerLiter <= double.Epsilon) return 0;
|
||||
return Convert.ToDouble(pulses) / pulsesPerLiter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the error in % from 'measured' and 'true' volume, prevent division by zero
|
||||
/// </summary>
|
||||
public static double ErrorFromVolumes(double measuredVolume, double trueVolume)
|
||||
{
|
||||
if (Math.Abs(trueVolume) <= float.Epsilon)
|
||||
{
|
||||
if (Math.Abs(measuredVolume) <= float.Epsilon)
|
||||
{
|
||||
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, -100.0);
|
||||
return -100.0;
|
||||
}
|
||||
|
||||
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, 99.0);
|
||||
return 99.0;
|
||||
}
|
||||
|
||||
double error = 100.0 * (measuredVolume - trueVolume) / trueVolume;
|
||||
log.InfoFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Converts a measurement error to a correction (used when preparing correction tables).
|
||||
/// </summary>
|
||||
/// <param name="measuredValue">Measured value (in arbitrary units)</param>
|
||||
/// <param name="error">Measurement error in %</param>
|
||||
/// <returns>Correction in the same units as the measured value</returns>
|
||||
public static double CorrectionFromError(double measuredValue, double error)
|
||||
{
|
||||
double trueValue = measuredValue / (1 + error/100);
|
||||
double correction = trueValue - measuredValue;
|
||||
return correction;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the heat coefficient for water
|
||||
/// </summary>
|
||||
/// <param name="pressure">Pressure [bar]</param>
|
||||
/// <param name="T_in">Inlet temperature [°C]</param>
|
||||
/// <param name="T_out">Outlet temperature [°C]</param>
|
||||
/// <param name="flowMeasuredAtInlet">true = flow measured @inlet, false = flow measured @outlet</param>
|
||||
/// <returns> Heat coefficient for water [J/(m3 K)]</returns>
|
||||
public static double HeatCoefficientWater(double pressure, double T_in, double T_out, bool flowMeasuredAtInlet)
|
||||
{
|
||||
if (T_in == T_out) return 0;
|
||||
|
||||
const double R = 461.526; /// [J kg^-1 K^-1]
|
||||
const double p_star_Pa = 16.53E6; /// [Pa] (=16.53 MPa)
|
||||
const double T_star = 1386.0; /// [K]
|
||||
|
||||
double T_in_K = Common.Units.ConvertTo(Common.Unit.K, T_in);
|
||||
double T_out_K = Common.Units.ConvertTo(Common.Unit.K, T_out);
|
||||
double tau_in = T_star / T_in_K;
|
||||
double tau_out = T_star / T_out_K;
|
||||
double pi = Common.Units.ConvertTo(Common.Unit.Pa, pressure) / p_star_Pa;
|
||||
|
||||
double h_in = tau_in * GammaTau(pi, tau_in) * R * T_in_K;
|
||||
double h_out = tau_out * GammaTau(pi, tau_out) * R * T_out_K;
|
||||
|
||||
double ni = flowMeasuredAtInlet ? GammaPi(pi, tau_in) * R * T_in_K / p_star_Pa
|
||||
: GammaPi(pi, tau_out) * R * T_out_K / p_star_Pa;
|
||||
|
||||
return (h_in - h_out) / (ni * (T_in - T_out));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gamma(pi) see also STN EN 1434-1 Annex A (A.4)
|
||||
/// </summary>
|
||||
/// <param name="pi">pi = p / p* where p* = 16.53 MPa</param>
|
||||
/// <param name="tau">tau = T* / T where T* = 1386 K</param>
|
||||
/// <returns>gamma(pi)</returns>
|
||||
static double GammaPi(double pi, double tau)
|
||||
{
|
||||
double result = 0;
|
||||
for (int i = 0; i < 34; i++)
|
||||
{
|
||||
result -= ni[i] * Ii[i] * Math.Pow(7.1 - pi, Ii[i] - 1) * Math.Pow(tau - 1.222, Ji[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gamma(tau) see also STN EN 1434-1 Annex A (A.7)
|
||||
/// </summary>
|
||||
/// <param name="pi">pi = p / p* where p* = 16.53 MPa</param>
|
||||
/// <param name="tau">tau = T* / T where T* = 1386 K</param>
|
||||
/// <returns>gamma(tau)</returns>
|
||||
static double GammaTau(double pi, double tau)
|
||||
{
|
||||
double result = 0;
|
||||
for (int i = 0; i < 34; i++)
|
||||
{
|
||||
result += ni[i] * Math.Pow(7.1 - pi, Ii[i]) * Ji[i] * Math.Pow(tau - 1.222, Ji[i] - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conversion of measured resistance of a platinum thermometer to temperature according to ITS-90
|
||||
/// </summary>
|
||||
/// <param name="R">Measured resistance in [°C]</param>
|
||||
/// <param name="R001C">Calibrated resistance in Ohm at 0.01°C</param>
|
||||
/// <param name="a7">Calibrated ITS-90 coefficient a7</param>
|
||||
/// <param name="b7">Calibrated ITS-90 coefficient b7</param>
|
||||
/// <param name="c7">Calibrated ITS-90 coefficient c7</param>
|
||||
/// <returns>Temperature in [°C]</returns>
|
||||
public static double PlatinumResistanceTM_ITS90_R2T(double R, double R001C, double a7, double b7, double c7)
|
||||
{
|
||||
double w = R / R001C; /// ratio
|
||||
double r1 = w - 1.0;
|
||||
double dw = r1 * (a7 + r1 * (b7 + r1 * c7)); /// = a7*r1 + b7*r1^2 + c7*r1^3
|
||||
double wr = w - dw;
|
||||
double x = (wr - 2.64) / 1.64;
|
||||
|
||||
double sum = 0;
|
||||
for (int i = Di.Length - 1; i >= 0; i--)
|
||||
{
|
||||
sum = sum * x + Di[i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conversion of measured resistance of a platinum thermometer to temperature using Callendar-Van Dusen equations
|
||||
/// </summary>
|
||||
/// <param name="R">Measured resistance in [°C]</param>
|
||||
/// <param name="R0">Calibrated resistance in Ohm at 0°C</param>
|
||||
/// <param name="A">Calibration coefficient a</param>
|
||||
/// <param name="B">Calibration coefficient b</param>
|
||||
/// <returns>Temperature in [°C]</returns>
|
||||
public static double PlatinumResistanceTM_ITS27_R2T(double R, double R0, double A, double B)
|
||||
{
|
||||
if (R0 * R0 * A * A - 4 * R0 * B * (R0 - R) <= 0) return 0; /// Out of range
|
||||
|
||||
return (-(R0 * A) + Math.Sqrt(R0 * R0 * A * A - 4 * R0 * B * (R0 - R))) / (2 * R0 * B);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public static class GlobalData
|
||||
{
|
||||
public static double SampleDensity = 0; /// sample water density measured in an accredited labo [kg/m3]
|
||||
public static double SampleTemp = 0; /// sample temperature when density measured in an accredited labo [°C]
|
||||
public static double Buoyancy = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public interface IMeasurementCorrection
|
||||
{
|
||||
int RangeIx { get; set; }
|
||||
double Measurement { get; set; }
|
||||
double Correction { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public interface IOrderInfo
|
||||
{
|
||||
string POName { get; }
|
||||
string VariantCode { get; }
|
||||
string ModuleParam { get; }
|
||||
int PiecesCount { get; }
|
||||
string SNPrefix { get; }
|
||||
int SNFirst { get; }
|
||||
int SNDigitsCount { get; }
|
||||
string SNSuffix { get; }
|
||||
string RAPrefix { get; }
|
||||
int RAFirst { get; }
|
||||
string RASuffix { get; }
|
||||
string Remark { get; }
|
||||
int CurrentPcsCount { get; set; }
|
||||
int CurrentSN { get; set; }
|
||||
int CurrentRA { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public interface IUncertainty
|
||||
{
|
||||
float Measurement { get; }
|
||||
float MainUncertainty { get; }
|
||||
float Resolution { get; }
|
||||
float DriftPerYr { get; }
|
||||
float Conditions { get; }
|
||||
float UncertaintyOfCorrection { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public interface IUser
|
||||
{
|
||||
string UserName { get; } /// = name, alias, abbreviation
|
||||
string FullName { get; } /// = description
|
||||
string Tag { get; }
|
||||
int Number { get; }
|
||||
|
||||
/// Access rights
|
||||
bool IsPowerUser();
|
||||
bool IsMemberOf(GID group);
|
||||
bool IsMemberOf(GID[] groups);
|
||||
bool IsCorrectPassword(string password);
|
||||
|
||||
/// Password complexity, history, etc.
|
||||
bool IsPasswordExpired();
|
||||
bool IsPasswordUsedInPast(string passwordCandidate);
|
||||
void SetPassword(string password);
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2021 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Common.Iperl
|
||||
{
|
||||
public enum OptoTelegramFlags : byte
|
||||
{
|
||||
OK = 0,
|
||||
OK_TestStart,
|
||||
OK_TestEnd,
|
||||
InvalidTelegram, /// Wrong telegram format of checksum error
|
||||
SyncError,
|
||||
}
|
||||
|
||||
public class OptoTelegramRaw
|
||||
{
|
||||
public static readonly int Length = 42;
|
||||
private static CultureInfo culture;
|
||||
|
||||
|
||||
///
|
||||
/// Strobed value
|
||||
///
|
||||
public static decimal TestStartTimestampDec;
|
||||
|
||||
///
|
||||
/// Stored values
|
||||
///
|
||||
public OptoTelegramFlags Flags;
|
||||
|
||||
public DateTime DateTime; /// From PC
|
||||
public float RefFlow; /// [m3/h]
|
||||
public int Counter;
|
||||
|
||||
public Int32 EmfRaw; /// Signed EMF from iPerl opto data
|
||||
public Int16 MagneticFieldRaw;
|
||||
public Int16 FlowRaw;
|
||||
public UInt32 VolumeRaw;
|
||||
public Int64 VolumeRawExt;
|
||||
public Int16 Impedance;
|
||||
public UInt32 Timestamp;
|
||||
public Int64 TimestampExt;
|
||||
public byte CheckSum;
|
||||
|
||||
///
|
||||
/// Calculated values
|
||||
///
|
||||
public double EMF()
|
||||
{
|
||||
return 0.000000333 * (double)EmfRaw;
|
||||
}
|
||||
public double MagneticField() { return (double)MagneticFieldRaw; }
|
||||
public double Flow(double scalingFactor) { return 0.225 * scalingFactor * (double)FlowRaw; }
|
||||
public double Volume(double scalingFactor) { return 0.0000625 * scalingFactor * (double)VolumeRawExt; }
|
||||
public Int32 FlipTime() { return Impedance; }
|
||||
public decimal TimestampDec() { return (decimal)TimestampExt; }
|
||||
public double VolumeDelta(double scalingFactor, OptoTelegramRaw previous) { return (previous == null) ? 0 : Volume(scalingFactor) - previous.Volume(scalingFactor); }
|
||||
public decimal TimeDelta() { return TimestampDec() - TestStartTimestampDec; }
|
||||
public string Label()
|
||||
{
|
||||
if (Flags == OptoTelegramFlags.OK_TestStart) return "#### start test ####";
|
||||
else if (Flags == OptoTelegramFlags.OK_TestEnd) return "#### end of test ####";
|
||||
else return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
static OptoTelegramRaw()
|
||||
{
|
||||
culture = CultureInfo.CreateSpecificCulture("DE"); /// This is to use comma as decimal number separator
|
||||
}
|
||||
|
||||
public OptoTelegramRaw()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses optical telegram and returns OptoTelegramRaw object
|
||||
/// </summary>
|
||||
/// <description>
|
||||
/// Create a configuration structure from a complete byte array
|
||||
///
|
||||
/// Telegram description:
|
||||
///
|
||||
/// AAAAAA[tab]BBBB[tab]CCCC[tab]DDDDDD[tab]EEEE[tab]FFFFFFFF[tab]GG[cr][lf] (42 bytes)
|
||||
///
|
||||
/// Data Comment Type Calculate to decimal
|
||||
/// ----------------------------------------------------------------
|
||||
/// AAAAAA EMF Int24 Value * 0.000000333
|
||||
/// BBBB Magnetic field Int16 Value
|
||||
/// CCCC Flow Int16 Value * 0.225 * Scalig factor
|
||||
/// DDDDDD Volume Int24 Value / 16000 * Scaling factor
|
||||
/// EEEE Impedance Int16 Value
|
||||
/// FFFFFFFF Timestamp Uint32 Value / 8192
|
||||
/// GG Checksum Byte
|
||||
/// ----------------------------------------------------------------
|
||||
///
|
||||
/// Example:
|
||||
/// FFFFFE 51EA 0000 65324E 0087 F6319DFF 86
|
||||
/// FFDD3A 51F9 0000 65324E 0088 F631A60B 45
|
||||
/// ...
|
||||
/// </description>
|
||||
/// <param name="data">A complete byte array data</param>
|
||||
/// <returns>true = telegram OK, false = telegram NOK</returns>
|
||||
public bool UpdateFromString(string telegram, int counter, float refFlow, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast, bool isLog = false)
|
||||
{
|
||||
DateTime = DateTime.Now;
|
||||
Counter = counter;
|
||||
RefFlow = refFlow;
|
||||
|
||||
if ((telegram == null) || (telegram.Length < Length) ||
|
||||
(telegram[6] != '\t') || (telegram[11] != '\t') || (telegram[16] != '\t') ||
|
||||
(telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') ||
|
||||
(!isLog && (telegram[40] != '\r' || telegram[41] != '\n')))
|
||||
{
|
||||
Flags = OptoTelegramFlags.InvalidTelegram;
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt32 uEmfRaw;
|
||||
bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uEmfRaw);
|
||||
EmfRaw = (uEmfRaw > 0x7FFFFF) ? ((int)uEmfRaw - 0x1000000) : (int)uEmfRaw;
|
||||
|
||||
bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticFieldRaw);
|
||||
bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw);
|
||||
bool f4 = UInt32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
|
||||
bool f5 = Int16.TryParse(telegram.Substring(24, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Impedance);
|
||||
bool f6 = UInt32.TryParse(telegram.Substring(29, 8), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
|
||||
bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
|
||||
|
||||
byte calculatedCheckSum = 0;
|
||||
for (int i = 0; i < Length - 4; i++)
|
||||
{
|
||||
calculatedCheckSum += (byte)telegram[i];
|
||||
}
|
||||
|
||||
bool allOk = f1 && f2 && f3 && f4 && f5 && f6 && f7 && (calculatedCheckSum == CheckSum);
|
||||
|
||||
if (allOk)
|
||||
{
|
||||
///
|
||||
/// Cope with 'VolumeRaw' overflow
|
||||
///
|
||||
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & 0xFFFFFFFFFF000000UL) | VolumeRaw);
|
||||
if (Math.Abs(uncorrected - volumeRawExtLast) <= 0x800000L)
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected;
|
||||
}
|
||||
else if (Math.Abs(uncorrected + 0x1000000L - volumeRawExtLast) <= 0x800000L)
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected + 0x1000000L;
|
||||
}
|
||||
else if (Math.Abs(uncorrected - 0x1000000L - volumeRawExtLast) <= 0x800000L)
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected - 0x1000000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected;
|
||||
}
|
||||
|
||||
///
|
||||
/// Cope with 'Timestamp' overflow
|
||||
///
|
||||
uncorrected = (Int64)(((UInt64)timestampExtLast & 0xFFFFFFFF00000000UL) | Timestamp);
|
||||
if (Math.Abs(uncorrected - timestampExtLast) <= 0x80000000L)
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected;
|
||||
}
|
||||
else if (Math.Abs(uncorrected + 0x100000000L - timestampExtLast) <= 0x80000000L)
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected + 0x100000000L;
|
||||
}
|
||||
else if (Math.Abs(uncorrected - 0x100000000L - timestampExtLast) <= 0x80000000L)
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected - 0x100000000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected;
|
||||
}
|
||||
}
|
||||
|
||||
Flags = allOk ? OptoTelegramFlags.OK : OptoTelegramFlags.InvalidTelegram;
|
||||
|
||||
return allOk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alternative to UpdateFromString(...) when data are flushed
|
||||
/// </summary>
|
||||
public bool UpdateFromStringDummy(string telegram)
|
||||
{
|
||||
DateTime = DateTime.Now;
|
||||
RefFlow = 0;
|
||||
|
||||
if ((telegram == null) || (telegram.Length < Length) ||
|
||||
(telegram[6] != '\t') || (telegram[11] != '\t') || (telegram[16] != '\t') ||
|
||||
(telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') ||
|
||||
(telegram[40] != '\r') || (telegram[41] != '\n'))
|
||||
{
|
||||
Flags = OptoTelegramFlags.InvalidTelegram;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
|
||||
|
||||
byte calculatedCheckSum = 0;
|
||||
for (int i = 0; i < Length - 4; i++)
|
||||
{
|
||||
calculatedCheckSum += (byte)telegram[i];
|
||||
}
|
||||
|
||||
bool allOk = f7 && (calculatedCheckSum == CheckSum);
|
||||
|
||||
Flags = allOk ? OptoTelegramFlags.OK : OptoTelegramFlags.InvalidTelegram;
|
||||
|
||||
return allOk;
|
||||
}
|
||||
|
||||
|
||||
public void SetFlags(OptoTelegramFlags flags)
|
||||
{
|
||||
this.Flags = flags;
|
||||
}
|
||||
|
||||
|
||||
public string ToString(double scalingFactor, OptoTelegramRaw previous)
|
||||
{
|
||||
if (Flags == OptoTelegramFlags.SyncError)
|
||||
{
|
||||
return "Sychronization error";
|
||||
}
|
||||
else if (Flags == OptoTelegramFlags.InvalidTelegram)
|
||||
{
|
||||
return "Invalid telegram";
|
||||
}
|
||||
else /// if (flags == OptoTelegramFlags.OK / OptoTelegramFlags.OK_TestStart / OptoTelegramFlags.OK_TestEnd)
|
||||
{
|
||||
return string.Format("{0}:{1}:{2}.{3}\t{4} :\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}\t{16}\t{17}\t{18}\t{19}\t{20}\t{21}\t{22}",
|
||||
DateTime.Hour.ToString("D2"),
|
||||
DateTime.Minute.ToString("D2"),
|
||||
DateTime.Second.ToString("D2"),
|
||||
DateTime.Millisecond.ToString("D4"),
|
||||
Counter,
|
||||
(EmfRaw & 0x00FFFFFF).ToString("X6"),
|
||||
MagneticFieldRaw.ToString("X4"),
|
||||
FlowRaw.ToString("X4"),
|
||||
VolumeRaw.ToString("X6"),
|
||||
Impedance.ToString("X4"),
|
||||
Timestamp.ToString("X8"),
|
||||
CheckSum.ToString("X2"),
|
||||
EMF().ToString("F4", culture),
|
||||
MagneticField().ToString("F0", culture),
|
||||
Flow(scalingFactor).ToString("F2", culture),
|
||||
Volume(scalingFactor).ToString("F4", culture),
|
||||
FlipTime().ToString("F0", culture),
|
||||
TimestampDec().ToString("F4", culture),
|
||||
(RefFlow * 1000).ToString("F2", culture),
|
||||
VolumeDelta(scalingFactor, previous).ToString("F4", culture),
|
||||
TimeDelta().ToString("F3", culture),
|
||||
scalingFactor.ToString("F1", culture),
|
||||
Label());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Printing;
|
||||
|
||||
namespace Common.Printers
|
||||
{
|
||||
public class PrintersCommon : PrintDocument
|
||||
{
|
||||
static Font lastFont = null;
|
||||
static float lastSpacing = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Measure the size of a paragraph of text, lines are separated by '~'.
|
||||
/// </summary>
|
||||
/// <param name="e">PrintPageEventArgs</param>
|
||||
/// <param name="text">Text, lines are separated by '~'</param>
|
||||
/// <param name="font">Font</param>
|
||||
/// <returns>Size of the paragraph of text</returns>
|
||||
public static SizeF Measure(System.Drawing.Printing.PrintPageEventArgs e, string text, Font font)
|
||||
{
|
||||
if (font != lastFont)
|
||||
{
|
||||
lastFont = font;
|
||||
lastSpacing = e.Graphics.MeasureString("Abcgq", font).Height;
|
||||
}
|
||||
|
||||
string[] lines = text.Split(new char[] { '~' });
|
||||
float width = 0;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
float lineWid = e.Graphics.MeasureString(line, font).Width;
|
||||
if (lineWid > width) width = lineWid;
|
||||
}
|
||||
|
||||
return new SizeF(width, 0.8f * lines.Length * lastSpacing + 0.2f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print a paragraph of text, lines are separated by '~'.
|
||||
/// </summary>
|
||||
/// <param name="e">PrintPageEventArgs</param>
|
||||
/// <param name="text">Text, lines are separated by '~'</param>
|
||||
/// <param name="font">Font</param>
|
||||
/// <param name="x">Position x</param>
|
||||
/// <param name="y">Position y</param>
|
||||
/// <param name="width">Width (required when alignment=Alignment.Center or alignment=Aligmenr.Right</param>
|
||||
/// <param name="height">Height, 0 = no vertical centering</param>
|
||||
/// <param name="horizAlignment">Horizontal alignment</param>
|
||||
/// <param name="vertAlignment">Vertical alignment</param>
|
||||
public static void PrintAt(System.Drawing.Printing.PrintPageEventArgs e, string text, Font font,
|
||||
float x, float y, float width, float height,
|
||||
Alignment horizAlignment, VertAlignment vertAlignment)
|
||||
{
|
||||
SizeF size = PrintersCommon.Measure(e, text, font);
|
||||
|
||||
string[] lines = text.Split(new char[] { '~' });
|
||||
|
||||
if (height <= size.Height) vertAlignment = VertAlignment.Top;
|
||||
float y0;
|
||||
switch (vertAlignment)
|
||||
{
|
||||
default:
|
||||
case VertAlignment.Top: y0 = y; break;
|
||||
case VertAlignment.Middle: y0 = y + (height - size.Height) / 2; break;
|
||||
case VertAlignment.Bottom: y0 = y + (height - size.Height); break;
|
||||
}
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
float x0;
|
||||
switch (horizAlignment)
|
||||
{
|
||||
default:
|
||||
case Alignment.Left: x0 = x; break;
|
||||
case Alignment.Center: x0 = x + (width - e.Graphics.MeasureString(line, font).Width) / 2; break;
|
||||
case Alignment.Right: x0 = x + width - e.Graphics.MeasureString(line, font).Width; break;
|
||||
}
|
||||
e.Graphics.DrawString(line, font, Brushes.Black, new PointF(x0, y0));
|
||||
y0 += 0.8f * lastSpacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Common")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Common")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4e3e3538-fd80-47d5-9417-2268afa590cf")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,338 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Common.Iperl;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static float[] SubArray(this float[] array, int offset, int length)
|
||||
{
|
||||
float[] result = new float[length];
|
||||
Array.Copy(array, offset, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class StatisticalMetrics
|
||||
{
|
||||
const int VectorSize = 7;
|
||||
const int MinLength = 100;
|
||||
const float AdcBit = (float)57e-9;
|
||||
const int NeighbourhoodSize = 30; /// To determine extended outliers
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a 7-dimensional vector with these components:
|
||||
/// x[0] = X1 = Number of outliers
|
||||
/// x[1] = X2 = Relative cal-factor shift due to outliers
|
||||
/// x[2] = X3 = Standard deviation of high-pass filteres ++++ demodulation of EMF (cut-off at Nyquist frequency)
|
||||
/// x[3] = X4 = Robust standard deviation of high-pass filtered ++++ demodulation
|
||||
/// x[4] = X5 = Peak-to-peak of low-pass filtered ++++ demodulation of EMF (cut-off TBD)
|
||||
/// x[5] = X6 = Peak-to-peak of reference flow rate
|
||||
/// x[6] = X7 = Mean impedance (++-- demodulation)
|
||||
/// </summary>
|
||||
/// <param name="optoData"></param>
|
||||
/// <param name="optoDataCount"></param>
|
||||
/// <param name="startIx"></param>
|
||||
/// <param name="endIx"></param>
|
||||
/// <returns></returns>
|
||||
public static float[] Calculate(OptoTelegramRaw[] optoData, int optoDataCount, int startIx, int endIx, bool downsample,
|
||||
out float[] offsetV, out float[] kOhmsR, out float[] kOhmsC, out float[] dutFlow,
|
||||
out float[] refFlow, out float[] flowRatio, out float[] magField, out float[] emfV,
|
||||
out PointF[] outliers, out PointF[] extendedOutliers)
|
||||
{
|
||||
offsetV = kOhmsR = kOhmsC = dutFlow = refFlow = flowRatio = magField = emfV = null;
|
||||
outliers = extendedOutliers = null;
|
||||
|
||||
if (optoData == null || optoData.Length < optoDataCount ||
|
||||
startIx < 0 || endIx >= optoDataCount || endIx <= startIx + MinLength + 3) return null;
|
||||
|
||||
float[] modulatedData = GetModulatedEmf(optoData, optoDataCount, AdcBit);
|
||||
|
||||
FindShiftAndDemodulate(modulatedData, downsample,
|
||||
new float[] { +1, +1, +1, +1 }, out offsetV,
|
||||
new float[] { +1, +1, -1, -1 }, out kOhmsR,
|
||||
new float[] { +1, -1, -1, +1 }, out kOhmsC,
|
||||
new float[] { +1, -1, +1, -1 }, out dutFlow);
|
||||
//offsetV = FirFilter(modulatedData, new float[] { 1, 3, 4, 4, 3, 1}, 0.0625F);
|
||||
|
||||
magField = GetMagField(optoData, optoDataCount, downsample, new float[] { 1, 1, 1, 1 });
|
||||
|
||||
refFlow = GetRefFlow(optoData, optoDataCount, downsample, new float[] { 1, 1, 1, 1 });
|
||||
|
||||
flowRatio = new float[Math.Min(dutFlow.Length, refFlow.Length)];
|
||||
for (int i = 0; i < flowRatio.Length; i++)
|
||||
{
|
||||
flowRatio[i] = (refFlow[i] != 0) ? dutFlow[i] / refFlow[i] : 1;
|
||||
}
|
||||
|
||||
|
||||
float[] x = new float[VectorSize];
|
||||
|
||||
/// X1 = Number of outliers
|
||||
int outliersCount = GetOutliers(flowRatio, out outliers, out extendedOutliers);
|
||||
|
||||
|
||||
/// X2 = Relative cal-factor shift due to outliers
|
||||
|
||||
/// X3 = Standard deviation of high-pass filteres ++++ demodulation of EMF (cut-off at Nyquist frequency)
|
||||
|
||||
/// X4 = Robust standard deviation of high-pass filtered ++++ demodulation
|
||||
|
||||
/// X5 = Peak-to-peak of low-pass filtered ++++ demodulation of EMF (cut-off TBD)
|
||||
|
||||
/// X6 = Peak-to-peak of reference flow rate
|
||||
|
||||
/// X7 = Mean impedance (++-- demodulation)
|
||||
double sum = 0;
|
||||
foreach (var z in kOhmsR) sum += z;
|
||||
x[6] = Convert.ToSingle(sum / kOhmsR.Length);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
static float[] GetModulatedEmf(OptoTelegramRaw[] optoData, int optoDataCount, float factor)
|
||||
{
|
||||
if (optoData == null || optoDataCount < 0) return null;
|
||||
|
||||
float[] result = new float[optoDataCount];
|
||||
for (int i = 0; i < optoDataCount; i++)
|
||||
{
|
||||
result[i] = optoData[i].EmfRaw * factor;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static float[] GetMagField(OptoTelegramRaw[] optoData, int optoDataCount, bool downsample, float[] kernel)
|
||||
{
|
||||
if (optoData == null || optoDataCount < 0 || (downsample && (kernel == null || kernel.Length < 4))) return null;
|
||||
|
||||
int resultLen = downsample ? (optoDataCount / 4) : optoDataCount;
|
||||
float[] result = new float[resultLen];
|
||||
|
||||
if (downsample)
|
||||
{
|
||||
float ksum = 0;
|
||||
for (int j = 0; j < kernel.Length; j++) ksum += kernel[j];
|
||||
for (int j = 0; j < kernel.Length; j++) kernel[j] /= ksum;
|
||||
|
||||
for (int i = 0; (4 * i) + kernel.Length - 1 < optoDataCount; i++)
|
||||
{
|
||||
float sum = 0;
|
||||
for (int j = 0; j < kernel.Length; j++) sum += Convert.ToSingle(optoData[4 * i + j].MagneticFieldRaw) * kernel[j];
|
||||
result[i] = sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < optoDataCount; i++) result[i] = optoData[i].MagneticFieldRaw;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static float[] GetRefFlow(OptoTelegramRaw[] optoData, int optoDataCount, bool downsample, float[] kernel)
|
||||
{
|
||||
if (optoData == null || optoDataCount < 0 || (downsample && (kernel == null || kernel.Length < 4))) return null;
|
||||
|
||||
int resultLen = downsample ? (optoDataCount / 4) : optoDataCount;
|
||||
float[] result = new float[resultLen];
|
||||
|
||||
if (downsample)
|
||||
{
|
||||
float ksum = 0;
|
||||
for (int j = 0; j < kernel.Length; j++) ksum += kernel[j];
|
||||
for (int j = 0; j < kernel.Length; j++) kernel[j] /= ksum;
|
||||
|
||||
for (int i = 0; (4 * i) + kernel.Length - 1 < optoDataCount; i++)
|
||||
{
|
||||
float sum = 0;
|
||||
for (int j = 0; j < kernel.Length; j++) sum += Convert.ToSingle(optoData[4 * i + j].RefFlow) * kernel[j];
|
||||
result[i] = sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < optoDataCount; i++) result[i] = optoData[i].RefFlow;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static void FindShiftAndDemodulate(float[] modulatedData, bool downsample,
|
||||
float[] kernel1, out float[] data1,
|
||||
float[] kernel2, out float[] data2,
|
||||
float[] kernel3, out float[] data3,
|
||||
float[] kernel4, out float[] data4)
|
||||
{
|
||||
int shift = GetShift(modulatedData.SubArray(0, MinLength));
|
||||
|
||||
data1 = (kernel1 != null) ? Demodulate(modulatedData, kernel1, shift, downsample) : null;
|
||||
data2 = (kernel2 != null) ? Demodulate(modulatedData, kernel2, shift, downsample) : null;
|
||||
data3 = (kernel3 != null) ? Demodulate(modulatedData, kernel3, shift, downsample) : null;
|
||||
data4 = (kernel4 != null) ? Demodulate(modulatedData, kernel4, shift, downsample) : null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unlike FIR filtering, demodulation shifts the kernel in 4 phases
|
||||
/// </summary>
|
||||
/// <param name="data">Input data</param>
|
||||
/// <param name="kernel">Demodulation kernel</param>
|
||||
/// <param name="shift">shift 0..3</param>
|
||||
/// <returns>Output data</returns>
|
||||
static float[] Demodulate(float[] data, float[] kernel, int shift, bool downsample)
|
||||
{
|
||||
if (data == null || data.Length < MinLength || kernel == null || kernel.Length != 4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
float ksum = 0;
|
||||
for (int i = 0; i < 4; i++) ksum += Math.Abs(kernel[i]);
|
||||
for (int i = 0; i < 4; i++) kernel[i] /= ksum;
|
||||
|
||||
int rsltLen = downsample ? (data.Length - 3) / 4 : data.Length - 3;
|
||||
float[] result = new float[rsltLen];
|
||||
|
||||
if (downsample)
|
||||
{
|
||||
for (int i = shift; i < 4 * rsltLen; i += 4)
|
||||
{
|
||||
float sum = 0;
|
||||
for (int j = 0; j < 4; j++) sum += data[i + j] * kernel[(i + j + 4 - shift) % 4];
|
||||
result[i / 4] = sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < rsltLen; i++)
|
||||
{
|
||||
float sum = 0;
|
||||
for (int j = 0; j < 4; j++) sum += data[i + j] * kernel[(i + j + 4 - shift) % 4];
|
||||
result[i] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determine modulation phase by maximizing ++-- demodulation result.
|
||||
/// </summary>
|
||||
/// <param name="modulatedEmf">Input data</param>
|
||||
/// <returns>0..3 = modulation phase or, -1 = error</returns>
|
||||
static int GetShift(float[] modulatedData)
|
||||
{
|
||||
float[] kernel = new float[4] { 1, 1, -1, -1 };
|
||||
int maximizingShift = -1;
|
||||
float maximum = float.MinValue;
|
||||
|
||||
for (int shift = 0; shift <= 3; shift++)
|
||||
{
|
||||
var demodulatedCandidate = Demodulate(modulatedData, kernel, shift, false);
|
||||
float sum = 0;
|
||||
foreach (var d in demodulatedCandidate) sum += d;
|
||||
if (sum > maximum)
|
||||
{
|
||||
maximum = sum;
|
||||
maximizingShift = shift;
|
||||
}
|
||||
}
|
||||
|
||||
return maximizingShift;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// FIR filtering = convolution with a kernel
|
||||
/// </summary>
|
||||
/// <param name="data">Input data</param>
|
||||
/// <param name="kernel">Convolution kernel</param>
|
||||
/// <returns>Output data</returns>
|
||||
static float[] FirFilter(float[] data, float[] kernel, float factor)
|
||||
{
|
||||
if (data == null || kernel == null) return null;
|
||||
|
||||
int kernelLen = kernel.Length;
|
||||
int rsltLen = data.Length - kernelLen + 1;
|
||||
if (rsltLen < 0) return null;
|
||||
|
||||
float[] result = new float[rsltLen];
|
||||
for (int i = 0; i < rsltLen; i++)
|
||||
{
|
||||
float sum = 0;
|
||||
for (int j = 0; j < kernelLen; j++) sum += data[i + j] * kernel[j];
|
||||
result[i] = sum * factor;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int GetOutliers(float[] flowRatio, out PointF[] outliers, out PointF[] extendedOutliers)
|
||||
{
|
||||
float mean = Enumerable.Average(flowRatio);
|
||||
var fr = new float[flowRatio.Length];
|
||||
for (int i = 0; i < fr.Length; i++) fr[i] = flowRatio[i] - mean;
|
||||
|
||||
Array.Sort(fr);
|
||||
float qLo = fr[fr.Length / 4];
|
||||
float qHi = fr[3 * fr.Length / 4];
|
||||
|
||||
int N = fr.Length / 2;
|
||||
float sumY = 0;
|
||||
float sumYY = 0;
|
||||
for (int i = fr.Length / 4; i < 3 * fr.Length / 4; i++)
|
||||
{
|
||||
sumY += fr[i];
|
||||
sumYY += fr[i] * fr[i];
|
||||
}
|
||||
float std = (float)Math.Sqrt(sumYY / N - (sumY / N) * (sumY / N));
|
||||
float robustStd = std * 5.1812824F;
|
||||
float threshold = 7 * robustStd;
|
||||
|
||||
/// Restore fr as it was before sorting
|
||||
for (int i = 0; i < fr.Length; i++) fr[i] = flowRatio[i] - mean;
|
||||
|
||||
IList<PointF> listOfOutliers = new List<PointF>();
|
||||
bool[] boolExtendedOutliers = new bool[fr.Length];
|
||||
int outliersCount = 0;
|
||||
for (int i = 0; i < fr.Length; i++)
|
||||
{
|
||||
if (fr[i] < -threshold || fr[i] > threshold)
|
||||
{
|
||||
/// This is an outlier
|
||||
listOfOutliers.Add(new PointF(Convert.ToSingle(i), fr[i] + mean));
|
||||
outliersCount++;
|
||||
for (int j = Math.Max(0, i - NeighbourhoodSize); j <= Math.Min(i + NeighbourhoodSize, fr.Length - 1); j++)
|
||||
{
|
||||
boolExtendedOutliers[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IList<PointF> listOfExtendedOutliers = new List<PointF>();
|
||||
for (int i = 0; i < fr.Length; i++)
|
||||
{
|
||||
if (boolExtendedOutliers[i])
|
||||
{
|
||||
listOfExtendedOutliers.Add(new PointF(Convert.ToSingle(i), fr[i] + mean));
|
||||
}
|
||||
}
|
||||
|
||||
outliers = listOfOutliers.ToArray<PointF>();
|
||||
extendedOutliers = listOfExtendedOutliers.ToArray<PointF>();
|
||||
|
||||
return outliersCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public static class Telegram
|
||||
{
|
||||
const UInt16 crcSeed = 0xFFFF; // Initial crc value
|
||||
const UInt16 crcGP = 0xA001; // Generating polynomial
|
||||
|
||||
/// <summary>
|
||||
/// For standard CRC16 (remainder of division)
|
||||
/// to start a new crc, set CRC16 = SEED
|
||||
/// then for each byte call UpdateCRC(byte, &CRC16);
|
||||
/// CRC16 will contain the result
|
||||
/// (if you calculate all of the incoming data
|
||||
/// INCLUDING the crc, the result should be 0x0000
|
||||
/// and if you are sending the crc be sure to
|
||||
/// send the bytes in the correct order)
|
||||
/// <summary>
|
||||
static void UpdateCRC(byte b, ref UInt16 crc)
|
||||
{
|
||||
crc ^= (UInt16)b;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bool carry = (crc & 0x0001) != 0;
|
||||
crc >>= 1;
|
||||
if (carry) crc ^= crcGP;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the CRC from a data telegram (an array of bytes).
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateTelegramCRC(byte[] data, int enforcedLen = 0)
|
||||
{
|
||||
int len = (enforcedLen != 0) ? Math.Min(enforcedLen, data.Length) : data.Length;
|
||||
UInt16 crc = crcSeed;
|
||||
for (int i = 0; i < len - 2; i++) UpdateCRC(data[i], ref crc);
|
||||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the CRC from a data telegram (an array of bytes).
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateTelegramCRC(int offset, byte[] data, int enforcedLen = 0)
|
||||
{
|
||||
int len = (enforcedLen != 0) ? Math.Min(enforcedLen, data.Length - offset) : data.Length - offset;
|
||||
UInt16 crc = crcSeed;
|
||||
for (int i = 0; i < len - 2; i++) UpdateCRC(data[offset + i], ref crc);
|
||||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function modifies the last 2 bytes in the message buffer
|
||||
/// by the CRC calculated from the remaining first (Lenght - 2) bytes.
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
public static void UpdateTelegramCRC(byte[] data)
|
||||
{
|
||||
int len = data.Length;
|
||||
if (len < 2) return;
|
||||
|
||||
UInt16 crc = CalculateTelegramCRC(data);
|
||||
|
||||
data[len - 2] = (byte)(crc & 0xFF);
|
||||
data[len - 1] = (byte)(crc >> 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function compares the last 2 bytes in the message buffer
|
||||
/// with the CRC calculated from the remaining first (Lenght - 2) bytes.
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>true if the CRC in the telegram is correct</returns>
|
||||
public static bool VerifyTelegramCRC(byte[] data, int enforcedLen = 0)
|
||||
{
|
||||
if (data == null || data.Length == 0 || enforcedLen > data.Length) return false;
|
||||
|
||||
int len = (enforcedLen != 0) ? enforcedLen : data.Length;
|
||||
if (len < 2) return false;
|
||||
|
||||
UInt16 crc = CalculateTelegramCRC(data, len);
|
||||
|
||||
return (data[len - 2] == (byte)(crc & 0xFF)) && (data[len - 1] == (byte)(crc >> 8));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function compares the last 2 bytes in the message buffer
|
||||
/// with the CRC calculated from the remaining first (Lenght - 2) bytes.
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>true if the CRC in the telegram is correct</returns>
|
||||
public static bool VerifyTelegramCRC(int offset, byte[] data, int enforcedLen = 0)
|
||||
{
|
||||
if (data == null || data.Length == 0 || enforcedLen > data.Length - offset) return false;
|
||||
|
||||
int len = (enforcedLen != 0) ? enforcedLen : data.Length - offset;
|
||||
if (len < 2) return false;
|
||||
|
||||
UInt16 crc = CalculateTelegramCRC(offset, data, len);
|
||||
|
||||
return (data[offset + len - 2] == (byte)(crc & 0xFF)) && (data[offset + len - 1] == (byte)(crc >> 8));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the checksum from a data telegram (an array of bytes).
|
||||
/// A complete telegram including one byte reserved for the checksum
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>Calculated checksum</returns>
|
||||
public static byte CalculateTelegramChecksum(byte[] data)
|
||||
{
|
||||
byte checksum = 0;
|
||||
for (int i = 0; i < data.Length - 1; i++) checksum = (byte)(checksum ^ data[i]);
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the checksum from a data telegram (an array of bytes).
|
||||
/// A complete telegram including one bytes reserved for the checksum
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="hartPreambLen">Length of HART telegram preamble (FF bytes)</param>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>Calculated checksum</returns>
|
||||
public static byte CalculateTelegramChecksum(int hartPreambLen, byte[] data)
|
||||
{
|
||||
byte checksum = 0;
|
||||
for (int i = hartPreambLen; i < data.Length - 1; i++) checksum = (byte)(checksum ^ data[i]);
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function modifies the last byte in the message buffer
|
||||
/// by the checksum calculated from the remaining first (Lenght - 1) bytes.
|
||||
/// A complete telegram including one bytes reserved for the checksum
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
public static void UpdateTelegramChecksum(byte[] data)
|
||||
{
|
||||
int len = data.Length;
|
||||
if (len < 1) return;
|
||||
data[len - 1] = CalculateTelegramChecksum(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function modifies the last byte in the message buffer
|
||||
/// by the checksum calculated from the preceeding (Lenght - hartPreambLen - 1) bytes.
|
||||
/// First hartPreambLen bytes in the telegram are skipped.
|
||||
/// A complete telegram including preamble and one bytes reserved for the checksum
|
||||
/// after data bytes must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="hartPreambLen">Length of HART telegram preamble (FF bytes)</param>
|
||||
/// <param name="data">Data telegram</param>
|
||||
public static void UpdateTelegramChecksum(int hartPreambLen, byte[] data)
|
||||
{
|
||||
if (data.Length - hartPreambLen < 1) return;
|
||||
data[data.Length - 1] = CalculateTelegramChecksum(hartPreambLen, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function compares the last byte in the message buffer
|
||||
/// with the checksum calculated from the remaining first (Lenght - 1) bytes.
|
||||
/// A complete telegram including two bytes reserved for the checksum
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>true if the checksum in the telegram is correct</returns>
|
||||
public static bool VerifyTelegramChecksum(byte[] data)
|
||||
{
|
||||
int len = data.Length;
|
||||
if (len < 1) return false;
|
||||
return (data[len - 1] == CalculateTelegramChecksum(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function compares the last byte in the message buffer
|
||||
/// with the checksum calculated from the remaining first (Lenght - 1) bytes.
|
||||
/// A complete telegram including two bytes reserved for the checksum
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="hartPreambLen">Length of HART telegram preamble (FF bytes)</param>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>true if the checksum in the telegram is correct</returns>
|
||||
public static bool VerifyTelegramChecksum(int hartPreambLen, byte[] data)
|
||||
{
|
||||
if (data.Length - hartPreambLen < 1) return false;
|
||||
return (data[data.Length - 1] == CalculateTelegramChecksum(hartPreambLen, data));
|
||||
}
|
||||
|
||||
|
||||
public static string LogTelegram(string intro, byte[] data, int from = 0, int len = -1)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
|
||||
|
||||
int length = (len >= 0) ? len : (data.Length - from);
|
||||
|
||||
sb.Append(intro);
|
||||
sb.Append(length.ToString());
|
||||
sb.Append(" bytes:");
|
||||
|
||||
for (int i = from; i < from + length; i++)
|
||||
{
|
||||
byte b = data[i];
|
||||
sb.Append(" ");
|
||||
sb.Append(((int)b).ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static string LogTelegram(string intro, IList<byte> data, int from = 0, int len = -1)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
|
||||
|
||||
int length = (len >= 0) ? len : (data.Count - from);
|
||||
|
||||
sb.Append(intro);
|
||||
sb.Append(length.ToString());
|
||||
sb.Append(" bytes:");
|
||||
|
||||
for (int i = from; i < from + length; i++)
|
||||
{
|
||||
byte b = data[i];
|
||||
sb.Append(" ");
|
||||
sb.Append(((int)b).ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static string LogTelegram(string intro, string data)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder(80);
|
||||
|
||||
sb.Append(intro);
|
||||
sb.Append(data.Length.ToString());
|
||||
sb.Append(" bytes:");
|
||||
foreach (var d in data)
|
||||
{
|
||||
sb.Append(" ");
|
||||
sb.Append(((int)d).ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
namespace Common.UIControls
|
||||
{
|
||||
partial class CoolButtonCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// CoolButton
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Transparent;
|
||||
this.DoubleBuffered = true;
|
||||
this.Name = "CoolButton";
|
||||
this.Size = new System.Drawing.Size(72, 29);
|
||||
this.Load += new System.EventHandler(this.CoolButtonLoad);
|
||||
this.SizeChanged += new System.EventHandler(this.CoolButtonSizeChanged);
|
||||
this.Paint += new System.Windows.Forms.PaintEventHandler(this.CoolButtonPaint);
|
||||
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CoolButtonMouseDown);
|
||||
this.MouseEnter += new System.EventHandler(this.CoolButtonMouseEnter);
|
||||
this.MouseLeave += new System.EventHandler(this.CoolButtonMouseLeave);
|
||||
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CoolButtonMouseUp);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Common.UIControls
|
||||
{
|
||||
public partial class CoolButtonCtrl : UserControl
|
||||
{
|
||||
private Color _buttonColor;
|
||||
private Color _textColor;
|
||||
private Color _focusColor;
|
||||
private Color _borderColor;
|
||||
private Color _highlightBorderColor;
|
||||
private Color _highlightButtonColor;
|
||||
private Font _buttonFont;
|
||||
private string _buttonText;
|
||||
private bool _mouseOver;
|
||||
private bool _mouseDown;
|
||||
|
||||
public delegate void ButtonClickedArgs(object sender);
|
||||
|
||||
public event ButtonClickedArgs ButtonClicked;
|
||||
|
||||
public Color FocusColor
|
||||
{
|
||||
get { return _focusColor; }
|
||||
set
|
||||
{
|
||||
_focusColor = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public Color TextColor
|
||||
{
|
||||
get { return _textColor; }
|
||||
set
|
||||
{
|
||||
_textColor = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public Color HighlightBorderColor
|
||||
{
|
||||
get { return _highlightBorderColor; }
|
||||
set
|
||||
{
|
||||
_highlightBorderColor = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public Color HighlightButtonColor
|
||||
{
|
||||
get { return _highlightButtonColor; }
|
||||
set
|
||||
{
|
||||
_highlightButtonColor = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public string ButtonText
|
||||
{
|
||||
get { return _buttonText; }
|
||||
set
|
||||
{
|
||||
_buttonText = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public Font ButtonFont
|
||||
{
|
||||
get { return _buttonFont; }
|
||||
set
|
||||
{
|
||||
_buttonFont = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public Color BorderColor
|
||||
{
|
||||
get { return _borderColor; }
|
||||
set
|
||||
{
|
||||
_borderColor = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public Color ButtonColor
|
||||
{
|
||||
get { return _buttonColor; }
|
||||
set
|
||||
{
|
||||
_buttonColor = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public CoolButtonCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_buttonColor = Color.FromArgb(243, 243, 243);
|
||||
_borderColor = Color.FromArgb(220, 220, 220);
|
||||
_highlightBorderColor = Color.FromArgb(198, 198, 198);
|
||||
_highlightButtonColor = Color.FromArgb(246, 246, 246);
|
||||
_focusColor = Color.FromArgb(77, 144, 254);
|
||||
_buttonFont = new Font("Arial", 8, FontStyle.Bold);
|
||||
_buttonText = "button";
|
||||
_textColor = Color.Black;
|
||||
|
||||
_mouseOver = false;
|
||||
_mouseDown = false;
|
||||
|
||||
LostFocus += CoolButtonFocus;
|
||||
GotFocus += CoolButtonFocus;
|
||||
}
|
||||
|
||||
void CoolButtonFocus(object sender, EventArgs e)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void CoolButtonLoad(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void CoolButtonPaint(object sender, PaintEventArgs e)
|
||||
{
|
||||
var bmp = new Bitmap(ClientSize.Width, ClientSize.Height);
|
||||
Graphics g = Graphics.FromImage(bmp);
|
||||
|
||||
if (!_mouseOver)
|
||||
{
|
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
|
||||
GraphicsPath path = RoundedRectangle.Create(0, 0, ClientSize.Width - 4, ClientSize.Height - 4);
|
||||
SizeF fontSize = g.MeasureString(_buttonText, _buttonFont);
|
||||
int horWidth = ((ClientSize.Width - 4 - (int)fontSize.Width) / 2);
|
||||
int verHeight = ((ClientSize.Height - 4 - (int)fontSize.Height) / 2);
|
||||
|
||||
g.FillPath(new SolidBrush(_buttonColor), path);
|
||||
g.DrawPath(Focused ? new Pen(_focusColor) : new Pen(_borderColor), path);
|
||||
g.DrawString(_buttonText, _buttonFont, new SolidBrush(_textColor), horWidth, verHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
|
||||
GraphicsPath path = RoundedRectangle.Create(0, 0, ClientSize.Width - 4, ClientSize.Height - 4);
|
||||
SizeF fontSize = g.MeasureString(_buttonText, _buttonFont);
|
||||
int horWidth = ((ClientSize.Width - 4 - (int)fontSize.Width) / 2);
|
||||
int verHeight = ((ClientSize.Height - 4 - (int)fontSize.Height) / 2);
|
||||
|
||||
g.FillPath(new SolidBrush(_highlightButtonColor), path);
|
||||
g.DrawPath(ContainsFocus ? new Pen(_focusColor) : new Pen(_borderColor), path);
|
||||
g.DrawString(_buttonText, _buttonFont, new SolidBrush(_textColor), horWidth, verHeight);
|
||||
|
||||
Color a1 = Color.FromArgb(255, 198, 198, 198);
|
||||
Color a2 = Color.FromArgb(128, 198, 198, 198);
|
||||
Color a3 = Color.FromArgb(64, 198, 198, 198);
|
||||
|
||||
var shadowBmp = new Bitmap(1, 3);
|
||||
var shadowBmp2 = new Bitmap(3, 1);
|
||||
shadowBmp.SetPixel(0, 0, a1);
|
||||
shadowBmp.SetPixel(0, 1, a2);
|
||||
shadowBmp.SetPixel(0, 2, a3);
|
||||
|
||||
shadowBmp2.SetPixel(0, 0, a1);
|
||||
shadowBmp2.SetPixel(1, 0, a2);
|
||||
shadowBmp2.SetPixel(2, 0, a3);
|
||||
|
||||
for (int z = 4; z < ClientSize.Width - 4; z++)
|
||||
{
|
||||
g.DrawImage(shadowBmp, z, ClientSize.Height - 4, 1, 3);
|
||||
}
|
||||
for (int z = 4; z < ClientSize.Height - 4; z++)
|
||||
{
|
||||
g.DrawImage(shadowBmp2, ClientSize.Width - 4, z, 3, 1);
|
||||
}
|
||||
g.DrawPath(Focused ? new Pen(_focusColor) : new Pen(_borderColor), path);
|
||||
}
|
||||
|
||||
e.Graphics.DrawImage(bmp, 0, 0, ClientSize.Width, ClientSize.Height);
|
||||
//bmp.Dispose();
|
||||
}
|
||||
|
||||
private void CoolButtonMouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
_mouseOver = true;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void CoolButtonMouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
_mouseOver = false;
|
||||
_mouseDown = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void CoolButtonSizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void CoolButtonMouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
_mouseDown = true;
|
||||
}
|
||||
|
||||
private void CoolButtonMouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button != MouseButtons.Left)
|
||||
return;
|
||||
if (_mouseDown)
|
||||
{
|
||||
if (ButtonClicked != null)
|
||||
{
|
||||
ButtonClicked(this);
|
||||
}
|
||||
}
|
||||
_mouseDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -1,107 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Common.UIControls
|
||||
{
|
||||
public abstract class RoundedRectangle
|
||||
{
|
||||
[Flags]
|
||||
public enum RectangleCorners
|
||||
{
|
||||
None = 0, TopLeft = 1, TopRight = 2, BottomLeft = 4, BottomRight = 8,
|
||||
All = TopLeft | TopRight | BottomLeft | BottomRight
|
||||
}
|
||||
|
||||
public static GraphicsPath Create(int x, int y, int width, int height,
|
||||
int radius, RectangleCorners corners)
|
||||
{
|
||||
int xw = x + width;
|
||||
int yh = y + height;
|
||||
int xwr = xw - radius;
|
||||
int yhr = yh - radius;
|
||||
int xr = x + radius;
|
||||
int yr = y + radius;
|
||||
int r2 = radius * 2;
|
||||
int xwr2 = xw - r2;
|
||||
int yhr2 = yh - r2;
|
||||
|
||||
var p = new GraphicsPath();
|
||||
p.StartFigure();
|
||||
|
||||
//Top Left Corner
|
||||
if ((RectangleCorners.TopLeft & corners) == RectangleCorners.TopLeft)
|
||||
{
|
||||
p.AddArc(x, y, r2, r2, 180, 90);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.AddLine(x, yr, x, y);
|
||||
p.AddLine(x, y, xr, y);
|
||||
}
|
||||
|
||||
//Top Edge
|
||||
p.AddLine(xr, y, xwr, y);
|
||||
|
||||
//Top Right Corner
|
||||
if ((RectangleCorners.TopRight & corners) == RectangleCorners.TopRight)
|
||||
{
|
||||
p.AddArc(xwr2, y, r2, r2, 270, 90);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.AddLine(xwr, y, xw, y);
|
||||
p.AddLine(xw, y, xw, yr);
|
||||
}
|
||||
|
||||
//Right Edge
|
||||
p.AddLine(xw, yr, xw, yhr);
|
||||
|
||||
//Bottom Right Corner
|
||||
if ((RectangleCorners.BottomRight & corners) == RectangleCorners.BottomRight)
|
||||
{
|
||||
p.AddArc(xwr2, yhr2, r2, r2, 0, 90);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.AddLine(xw, yhr, xw, yh);
|
||||
p.AddLine(xw, yh, xwr, yh);
|
||||
}
|
||||
|
||||
//Bottom Edge
|
||||
p.AddLine(xwr, yh, xr, yh);
|
||||
|
||||
//Bottom Left Corner
|
||||
if ((RectangleCorners.BottomLeft & corners) == RectangleCorners.BottomLeft)
|
||||
{
|
||||
p.AddArc(x, yhr2, r2, r2, 90, 90);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.AddLine(xr, yh, x, yh);
|
||||
p.AddLine(x, yh, x, yhr);
|
||||
}
|
||||
|
||||
//Left Edge
|
||||
p.AddLine(x, yhr, x, yr);
|
||||
|
||||
p.CloseFigure();
|
||||
return p;
|
||||
}
|
||||
|
||||
public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners c)
|
||||
{ return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c); }
|
||||
|
||||
public static GraphicsPath Create(int x, int y, int width, int height, int radius)
|
||||
{ return Create(x, y, width, height, radius, RectangleCorners.All); }
|
||||
|
||||
public static GraphicsPath Create(Rectangle rect, int radius)
|
||||
{ return Create(rect.X, rect.Y, rect.Width, rect.Height, radius); }
|
||||
|
||||
public static GraphicsPath Create(int x, int y, int width, int height)
|
||||
{ return Create(x, y, width, height, 5); }
|
||||
|
||||
public static GraphicsPath Create(Rectangle rect)
|
||||
{ return Create(rect.X, rect.Y, rect.Width, rect.Height); }
|
||||
}
|
||||
}
|
||||
-672
@@ -1,672 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2016-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
[Description("---")] None,
|
||||
|
||||
[Description("imp.")] pulse,
|
||||
#if LANG_PL
|
||||
[Description("stopień")] degree,
|
||||
#else
|
||||
[Description("degree")] degree,
|
||||
#endif
|
||||
[Description("ml")] ml, /// 1 ml = 0.001 l
|
||||
[Description("l")] l, /// * 1 liter
|
||||
[Description("dm3")] dm3, /// 1 dm3 = 1 l
|
||||
[Description("US gal")] USgal, /// 1 US gallon = 3.78541178 l
|
||||
[Description("imper.gal")] UKgal, /// 1 imperial gallon = 4.54609 l
|
||||
[Description("cf")] cf, /// 1 cubic foot = 28.316846592 l
|
||||
[Description("m3")] m3, /// 1 m3 = 1000 l
|
||||
|
||||
[Description("l/h")] lph, /// 1 l/h = 0.001 m3/h
|
||||
[Description("cf/h")] cfph, /// 1 cf/h = 0.028316846592 m3/h
|
||||
[Description("l/m")] lpm, /// 1 l/m = 60 l/h = 0.06 m3/h
|
||||
[Description("US gal/m")] USgalpm, /// 1 US gallon per minute = 0.2271247068 m3/h
|
||||
[Description("m3/h")] m3ph, /// * 1 m3/h
|
||||
[Description("l/s")] lps, /// 1 liter/s = 3.6 m3/h
|
||||
[Description("US gal/s")] USgalps, /// 1 US gallon per second = 13.627482408 m3/h
|
||||
[Description("m3/m")] m3pm, /// 1 m3/m = 60 m3/h
|
||||
[Description("cf/s")] cfs, /// 1 cubic foot per second = 101.9406477312 m3/h
|
||||
|
||||
|
||||
[Description("g/s")] gps, /// 1 g/s = 0.0036 t/h
|
||||
[Description("g/min")] gpm, /// 1 g/min = 0.00006 t/h
|
||||
[Description("g/h")] gph, /// 1 g/h = 0.000001 t/h
|
||||
[Description("kg/s")] kgps, /// 1 kg/s = 3.6 t/h
|
||||
[Description("kg/min")] kgpm, /// 1 kg/min = 0.06 t/h
|
||||
[Description("kg/h")] kgph, /// 1 kg/h = 0.001 t/h
|
||||
[Description("t/s")] tps, /// 1 t/s = 3600 t/h
|
||||
[Description("t/min")] tpm, /// 1 t/min = 60 t/h
|
||||
[Description("t/h")] tph, /// 1 t/h = 1 t/h
|
||||
[Description("lb/s")] lbps, /// 1 lb/s ≈ 1.633 t/h
|
||||
[Description("lb/min")] lbpm, /// 1 lb/min ≈ 0.027216 t/h
|
||||
[Description("lb/h")] lbph, /// 1 lb/h ≈ 0.0004536 t/h
|
||||
|
||||
[Description("g")] g, /// 0.001 kg
|
||||
[Description("oz")] oz, /// 0.0283495231 kg
|
||||
[Description("lb")] lb, /// 0.45359237 kg
|
||||
[Description("kg")] kg, /// * 1 kilogram
|
||||
[Description("t")] t, /// 1000 kg
|
||||
|
||||
[Description("ms")] ms, /// 1 ms = 0.001 s
|
||||
[Description("s")] s, /// * 1 second
|
||||
[Description("min")] min, /// 1 min = 60 s
|
||||
[Description("hr")] hour, /// 1 hour = 60 min = 3600 s
|
||||
|
||||
[Description("°C")] C, /// * degree Celsius (°C)
|
||||
[Description("°F")] F, /// degree Fahrenheit
|
||||
[Description("K")] K, /// degree Kelvin
|
||||
|
||||
[Description("Pa")] Pa, /// 1 Pa = 0.01 hPa
|
||||
[Description("hPa")] hPa, /// 1 hPa = 100 Pa
|
||||
[Description("mbar")] mbar, /// 1 mbar = 1 hPa = 100 Pa
|
||||
[Description("kPa")] kPa, /// 1 kPa = 10 hPa = 1000 Pa
|
||||
[Description("inHg")] inHg, /// 1 inHg = 33.864 hPa
|
||||
[Description("psi")] psi, /// 1 psi = 0.0689475729 bar
|
||||
[Description("bar")] bar, /// * 1 Bar = 1000 mbar = 0.1 MPa = 100000 Pa
|
||||
[Description("MPa")] MPa, /// 1 MPa = 10000 hPa
|
||||
|
||||
[Description("R%")] RPct, /// * 1 R%
|
||||
|
||||
[Description("promile")] Promile, /// 1 promile = 0.1 %
|
||||
[Description("%")] Pct, /// * 1 %
|
||||
|
||||
[Description("mm")] mm, /// * 1 millimeter
|
||||
[Description("cm")] cm, /// 1 cm = 10 mm
|
||||
[Description("in")] inch, /// 1 inch = 25.4 mm
|
||||
[Description("dm")] dm, /// 1 dm = 100 mm
|
||||
[Description("ft")] foot, /// 1 foot = 304.8 mm
|
||||
[Description("yd")] yard, /// 1 yard = 914.4 mm
|
||||
[Description("m")] m, /// 1 m = 1000 mm
|
||||
|
||||
[Description("kg/m3")] kgpm3, /// * 1 kg/m3 = 0.001 kg/l
|
||||
[Description("kg/l")] kgpl, /// 1 kg/l = 1000 kg/m3
|
||||
|
||||
[Description("J")] J, /// * 1 Joul
|
||||
[Description("kJ")] kJ, /// 1 kJ = 1000 J
|
||||
[Description("MJ")] MJ, /// 1 MJ = 1000000 J
|
||||
[Description("Wh")] Wh, /// 1 Wh = 3600 J
|
||||
[Description("kWh")] kWh, /// 1 kWh = 3600000 J
|
||||
[Description("MWh")] MWh, /// 1 MWh = 3600000000 J
|
||||
|
||||
[Description("uS/cm")] uSpcm, /// * 1 uS/cm
|
||||
[Description("mS/m")] mSpm, /// 1 mS/m = 10 uS/cm
|
||||
|
||||
#if LANG_PL
|
||||
[Description("imp/l")] ppl, /// * 1 pulse/l
|
||||
[Description("imp/dm3")] ppdm3, /// * 1 pulse/dm3
|
||||
[Description("stopień/l")] degpl, /// * 1 degree/l
|
||||
[Description("stopień/dm3")] degpdm3, /// * 1 degree/dm3
|
||||
[Description("l/imp")] lpp, /// * 1 l/pulse
|
||||
[Description("dm3/imp")] dm3pp, /// * 1 dm3/pulse
|
||||
[Description("l/stopień")] lpdeg, /// * 1 l/degree
|
||||
[Description("dm3/stopień")] dm3pdeg, /// * 1 dm3/degree
|
||||
#else
|
||||
[Description("pulse/l")] ppl, /// * 1 pulse/l
|
||||
[Description("pulse/dm3")] ppdm3, /// 1 pulse/dm3
|
||||
[Description("degree/l")] degpl, /// 1 degree/l
|
||||
[Description("degree/dm3")] degpdm3, /// 1 degree/dm3
|
||||
[Description("l/pulse")] lpp, /// 1 l/pulse
|
||||
[Description("dm3/pulse")] dm3pp, /// 1 dm3/pulse
|
||||
[Description("l/degree")] lpdeg, /// 1 l/degree
|
||||
[Description("dm3/degree")] dm3pdeg, /// 1 dm3/degree
|
||||
#endif
|
||||
///
|
||||
[Description("pulse/kWh")] ppkWh, /// * 1 pulse/kWh
|
||||
[Description("kWh/pulse")] kWhpp, /// 1 kWh/pulse
|
||||
|
||||
///
|
||||
[Description("A")] A, /// *1 A
|
||||
[Description("mA")] mA, /// 1 mA = 0.001 A
|
||||
///
|
||||
[Description("V")] V, /// *1 V
|
||||
[Description("mV")] mV, /// 1 mV = 0.001 V
|
||||
|
||||
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Quantity
|
||||
{
|
||||
/// Quantities with units and conversions (double -> double)
|
||||
#if LANG_DE
|
||||
[Description("Volumen")] Volume,
|
||||
[Description("Durchfluss")] Flow,
|
||||
[Description("Masse")] Mass,
|
||||
[Description("Zeit")] Time,
|
||||
[Description("Temperatur")] Temperature,
|
||||
[Description("Druck")] Pressure,
|
||||
[Description("Feuchtigkeit")] Humidity,
|
||||
[Description("Fehler")] Error,
|
||||
[Description("Länge")] Length,
|
||||
[Description("Dichte")] Density,
|
||||
[Description("Energie")] Energy,
|
||||
[Description("Impulse")] Pulses,
|
||||
[Description("Impulse/l")] PulsePerLtr,
|
||||
[Description("Impulse/kWh")] PulsePerKWh,
|
||||
[Description("Leitfähigkeit")] Conductivity,
|
||||
|
||||
/// Quantities without units and conversions
|
||||
[Description("Nummer")] Number,
|
||||
[Description("Text")] String,
|
||||
[Description("Boolean")] Boolean,
|
||||
[Description("Datum und Uhrzeit")] DateTime,
|
||||
[Description("Aufgezählt")] Enumerated,
|
||||
[Description("Strom")] Current,
|
||||
[Description("Spannung")] Voltage,
|
||||
#elif LANG_PL
|
||||
[Description("Objętość")] Volume,
|
||||
[Description("Przepływ")] Flow,
|
||||
[Description("Masa")] Mass,
|
||||
[Description("Czas")] Time,
|
||||
[Description("Temperatura")] Temperature,
|
||||
[Description("Ciśnienie")] Pressure,
|
||||
[Description("Wilgotność")] Humidity,
|
||||
[Description("Błąd")] Error,
|
||||
[Description("Długość")] Length,
|
||||
[Description("Gęstość")] Density,
|
||||
[Description("Energia")] Energy,
|
||||
[Description("Impulsy")] Pulses,
|
||||
[Description("Impulsy/litr")] PulsePerLtr,
|
||||
[Description("Impulsy/kWh")] PulsePerKWh,
|
||||
[Description("Przewodność")] Conductivity,
|
||||
|
||||
/// Quantities without units and conversions
|
||||
[Description("Numer")] Number,
|
||||
[Description("Tekst")] String,
|
||||
[Description("Boolean")] Boolean,
|
||||
[Description("Data i czas")] DateTime,
|
||||
[Description("Wyliczone")] Enumerated,
|
||||
[Description("Prąd")] Current,
|
||||
[Description("Napięcie")] Voltage,
|
||||
#elif LANG_CS
|
||||
[Description("Objem")] Volume,
|
||||
[Description("Průtok")] Flow,
|
||||
[Description("Hmotnost")] Mass,
|
||||
[Description("Čas")] Time,
|
||||
[Description("Teplota")] Temperature,
|
||||
[Description("Tlak")] Pressure,
|
||||
[Description("Vlhkost")] Humidity,
|
||||
[Description("Chyba")] Error,
|
||||
[Description("Délka")] Length,
|
||||
[Description("Hustota")] Density,
|
||||
[Description("Energie")] Energy,
|
||||
[Description("Pulzy")] Pulses,
|
||||
[Description("Pulzy/litr")] PulsePerLtr,
|
||||
[Description("Pulzy/kWh")] PulsePerKWh,
|
||||
[Description("Vodivost")] Conductivity,
|
||||
|
||||
/// Quantities without units and conversions
|
||||
[Description("Počet")] Number,
|
||||
[Description("Text")] String,
|
||||
[Description("Boolean")] Boolean,
|
||||
[Description("Datum a čas")] DateTime,
|
||||
[Description("Vyjmenované")] Enumerated,
|
||||
[Description("Proud")] Current,
|
||||
[Description("Napětí")] Voltage,
|
||||
#elif LANG_IT
|
||||
[Description("Volume")] Volume,
|
||||
[Description("Flusso")] Flow,
|
||||
[Description("Massa")] Mass,
|
||||
[Description("Tempo")] Time,
|
||||
[Description("Temperatura")] Temperature,
|
||||
[Description("Pressione")] Pressure,
|
||||
[Description("Umidità")] Humidity,
|
||||
[Description("Errore")] Error,
|
||||
[Description("Lungezza")] Length,
|
||||
[Description("Densità")] Density,
|
||||
[Description("Energia")] Energy,
|
||||
[Description("Impulso")] Pulses,
|
||||
[Description("Impulso/litro")] PulsePerLtr,
|
||||
[Description("Impulso/kWh")] PulsePerKWh,
|
||||
[Description("Conduttività")] Conductivity,
|
||||
|
||||
/// Quantities without units and conversions
|
||||
[Description("Numero")] Number,
|
||||
[Description("Stringa")] String,
|
||||
[Description("Boolean")] Boolean,
|
||||
[Description("Data e ora")] DateTime,
|
||||
[Description("Enumerato")] Enumerated,
|
||||
[Description("Corrente")] Current,
|
||||
[Description("Voltaggio")] Voltage,
|
||||
#else
|
||||
[Description("RegisterReader")] RegisterReader,
|
||||
[Description("MultiFunctionalVariables")] MultiFunctionalVariables,
|
||||
[Description("VolumeFlow")] VolumeFlow,
|
||||
[Description("Volume")] Volume,
|
||||
[Description("Flow")] Flow,
|
||||
[Description("MassFlow")] MassFlow,
|
||||
[Description("Mass")] Mass,
|
||||
[Description("Time")] Time,
|
||||
[Description("Temperature")] Temperature,
|
||||
[Description("Pressure")] Pressure,
|
||||
[Description("Humidity")] Humidity,
|
||||
[Description("Error")] Error,
|
||||
[Description("Length")] Length,
|
||||
[Description("Density")] Density,
|
||||
[Description("Energy")] Energy,
|
||||
[Description("Pulses")] Pulses,
|
||||
[Description("Pulses/liter")] PulsePerLtr,
|
||||
[Description("Pulses/kg")] PulsePerKilogram, //...MF
|
||||
[Description("Pulses/Unit")] PulsePerUnit,//...MF
|
||||
[Description("Pulses/kWh")] PulsePerKWh,
|
||||
[Description("Conductivity")] Conductivity,
|
||||
|
||||
/// Quantities without units and conversions
|
||||
[Description("Number")] Number,
|
||||
[Description("String")] String,
|
||||
[Description("Boolean")] Boolean,
|
||||
[Description("Date and time")] DateTime,
|
||||
[Description("Enumerated")] Enumerated,
|
||||
[Description("Current")] Current,
|
||||
[Description("Voltage")] Voltage,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
public static class Units
|
||||
{
|
||||
public static bool IsUnitless(Quantity quantity)
|
||||
{
|
||||
return quantity >= Quantity.Number;
|
||||
}
|
||||
|
||||
public static bool IsDefaultUnit(Unit unit)
|
||||
{
|
||||
return unit == Unit.l || unit == Unit.m3ph || unit == Unit.kg || unit == Unit.s || unit == Unit.C ||
|
||||
unit == Unit.bar || unit == Unit.RPct || unit == Unit.Pct || unit == Unit.mm || unit == Unit.kgpm3 ||
|
||||
unit == Unit.J || unit == Unit.uSpcm || unit == Unit.ppl || unit == Unit.ppkWh || unit == Unit.A ||
|
||||
unit == Unit.V;
|
||||
}
|
||||
|
||||
public static bool IsQuantity(Unit unit, Quantity quantity)
|
||||
{
|
||||
return GetQuantity(unit).Contains(quantity);
|
||||
}
|
||||
|
||||
public static Quantity[] GetQuantity(Unit unit)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case Unit.pulse:
|
||||
case Unit.degree:
|
||||
return new[] { Quantity.Pulses };
|
||||
|
||||
case Unit.ml:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
case Unit.l:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
case Unit.dm3:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
case Unit.USgal:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
case Unit.UKgal:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
case Unit.cf:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
case Unit.m3:
|
||||
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
|
||||
|
||||
case Unit.lph:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.cfph:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.lpm:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.USgalpm:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.m3ph:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.lps:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.USgalps:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.m3pm:
|
||||
return new[] { Quantity.Flow };
|
||||
case Unit.cfs:
|
||||
return new[] { Quantity.Flow };
|
||||
|
||||
case Unit.gps:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.gpm:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.gph:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.kgps:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.kgpm:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.kgph:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.tps:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.tpm:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.tph:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.lbps:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.lbpm:
|
||||
return new[] { Quantity.MassFlow};
|
||||
case Unit.lbph:
|
||||
return new[] { Quantity.MassFlow};
|
||||
|
||||
case Unit.g:
|
||||
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
|
||||
case Unit.oz:
|
||||
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
|
||||
case Unit.lb:
|
||||
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
|
||||
case Unit.kg:
|
||||
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
|
||||
case Unit.t:
|
||||
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
|
||||
|
||||
case Unit.ms:
|
||||
case Unit.s:
|
||||
case Unit.min:
|
||||
case Unit.hour:
|
||||
return new[] { Quantity.Time };
|
||||
|
||||
case Unit.C:
|
||||
case Unit.F:
|
||||
case Unit.K:
|
||||
return new[] { Quantity.Temperature };
|
||||
|
||||
case Unit.Pa:
|
||||
case Unit.hPa:
|
||||
case Unit.mbar:
|
||||
case Unit.kPa:
|
||||
case Unit.inHg:
|
||||
case Unit.psi:
|
||||
case Unit.bar:
|
||||
case Unit.MPa:
|
||||
return new[] { Quantity.Pressure };
|
||||
|
||||
case Unit.RPct:
|
||||
return new[] { Quantity.Humidity };
|
||||
|
||||
case Unit.Promile:
|
||||
case Unit.Pct:
|
||||
return new[] { Quantity.Error };
|
||||
|
||||
case Unit.mm:
|
||||
case Unit.cm:
|
||||
case Unit.inch:
|
||||
case Unit.dm:
|
||||
case Unit.foot:
|
||||
case Unit.yard:
|
||||
case Unit.m:
|
||||
return new[] { Quantity.Length };
|
||||
|
||||
case Unit.kgpm3:
|
||||
case Unit.kgpl:
|
||||
return new[] { Quantity.Density };
|
||||
|
||||
case Unit.J:
|
||||
case Unit.kJ:
|
||||
case Unit.MJ:
|
||||
case Unit.Wh:
|
||||
case Unit.kWh:
|
||||
case Unit.MWh:
|
||||
return new[] { Quantity.Energy };
|
||||
|
||||
case Unit.uSpcm:
|
||||
case Unit.mSpm:
|
||||
return new[] { Quantity.Conductivity };
|
||||
|
||||
case Unit.ppl:
|
||||
case Unit.ppdm3:
|
||||
case Unit.degpl:
|
||||
case Unit.degpdm3:
|
||||
case Unit.lpp:
|
||||
case Unit.dm3pp:
|
||||
case Unit.lpdeg:
|
||||
case Unit.dm3pdeg:
|
||||
return new[] { Quantity.PulsePerLtr };
|
||||
|
||||
case Unit.ppkWh:
|
||||
case Unit.kWhpp:
|
||||
return new[] { Quantity.PulsePerKWh };
|
||||
|
||||
case Unit.A:
|
||||
case Unit.mA:
|
||||
return new[] { Quantity.Current };
|
||||
|
||||
case Unit.V:
|
||||
case Unit.mV:
|
||||
return new[] { Quantity.Voltage };
|
||||
|
||||
default:
|
||||
return new[] { Quantity.Number };
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsVolumeFlow(Unit unit) { return IsQuantity(unit, Quantity.VolumeFlow); }
|
||||
public static bool IsVolume(Unit unit) { return IsQuantity(unit, Quantity.Volume); }
|
||||
public static bool IsFlow(Unit unit) { return IsQuantity(unit, Quantity.Flow); }
|
||||
public static bool IsMassFlow(Unit unit) { return IsQuantity(unit, Quantity.MassFlow); }
|
||||
public static bool IsMass(Unit unit) { return IsQuantity(unit, Quantity.Mass); }
|
||||
public static bool IsTime(Unit unit) { return IsQuantity(unit, Quantity.Time); }
|
||||
public static bool IsTemperature(Unit unit) { return IsQuantity(unit, Quantity.Temperature); }
|
||||
public static bool IsPressure(Unit unit) { return IsQuantity(unit, Quantity.Pressure); }
|
||||
public static bool IsHumidity(Unit unit) { return IsQuantity(unit, Quantity.Humidity); }
|
||||
public static bool IsError(Unit unit) { return IsQuantity(unit, Quantity.Error); }
|
||||
public static bool IsLength(Unit unit) { return IsQuantity(unit, Quantity.Length); }
|
||||
public static bool IsDensity(Unit unit) { return IsQuantity(unit, Quantity.Density); }
|
||||
public static bool IsEnergy(Unit unit) { return IsQuantity(unit, Quantity.Energy); }
|
||||
public static bool IsPulses(Unit unit) { return IsQuantity(unit, Quantity.Pulses); }
|
||||
public static bool IsPulsePerLtr(Unit unit) { return IsQuantity(unit, Quantity.PulsePerLtr); }
|
||||
public static bool IsPulsePerKWh(Unit unit) { return IsQuantity(unit, Quantity.PulsePerKWh); }
|
||||
public static bool IsConductivity(Unit unit) { return IsQuantity(unit, Quantity.Conductivity); }
|
||||
public static bool IsCurrent(Unit unit) { return IsQuantity(unit, Quantity.Current); }
|
||||
public static bool IsVoltage(Unit unit) { return IsQuantity(unit, Quantity.Voltage); }
|
||||
|
||||
|
||||
|
||||
public static float ConvertTo(Unit unit, float v)
|
||||
{
|
||||
return (float)ConvertTo(unit, (double)v);
|
||||
}
|
||||
|
||||
public static double ConvertTo(Unit unit, double v)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
/// Volume: internal representation in l
|
||||
case Unit.ml: return 1000 * v; /// 1 ml = 0.001 l
|
||||
case Unit.USgal: return 0.26417205 * v; /// 1 gal(US) = 3.78541178 l
|
||||
case Unit.UKgal: return 0.21996925 * v; /// 1 gal(UK) = 4.54609 l
|
||||
case Unit.cf: return 0.0353146667215 * v; /// 1 cubic foot = 28.316846592 l
|
||||
case Unit.m3: return 0.001 * v; /// 1 m3 = 1000 l
|
||||
|
||||
/// Flow: internal representation in m3/h
|
||||
case Unit.lph: return 1000 * v; /// 1 l/h
|
||||
case Unit.cfph: return 35.3146667214886 * v;/// 1 cf/h
|
||||
case Unit.lpm: return v / 0.06; /// 1 l/m
|
||||
case Unit.USgalpm: return 4.40286754395493 * v;/// 1 US gallon per minute
|
||||
case Unit.lps: return v / 3.6; /// 1 l/s
|
||||
case Unit.USgalps: return 0.0733811257326 * v; /// 1 US gallon per second
|
||||
case Unit.m3pm: return v / 60; /// 1 m3/m
|
||||
case Unit.cfs: return 0.009809629644858 * v; /// 1 cubic foot per second
|
||||
|
||||
/// Mass: internal representation in kg
|
||||
case Unit.g: return 1000 * v; /// 1 g = 0.001 kg
|
||||
case Unit.oz: return 35.273962 * v; /// 1 oz = 0.0283495231 kg
|
||||
case Unit.lb: return 2.2046226 * v; /// 1 lb = 0.45359237 kg
|
||||
case Unit.t: return 0.001 * v; /// 1 t = 1000 kg
|
||||
|
||||
/// Time or duration: internal representation in seconds [s]
|
||||
case Unit.ms: return 1000 * v;
|
||||
case Unit.min: return v / 60;
|
||||
case Unit.hour: return v / 3600;
|
||||
|
||||
/// Temperature: internal representation in °C
|
||||
case Unit.F: return 1.8 * v + 32; /// degree Fahrenheit
|
||||
case Unit.K: return v + 273.15; /// degree Kelvin
|
||||
|
||||
/// Pressure: internal representation in bar = 0.1 MPa
|
||||
case Unit.Pa: return 100000 * v; /// 1 hPa = 100 Pa
|
||||
case Unit.hPa: return 1000 * v; /// 1 hPa = 100 Pa
|
||||
case Unit.mbar: return 1000 * v; /// 1 mbar = 1 hPa = 100 Pa
|
||||
case Unit.kPa: return 100 * v; /// 1 kPa = 10 HPa
|
||||
case Unit.inHg: return 29.53 * v; /// 1 inHg =
|
||||
case Unit.psi: return 14.5037738 * v; /// 1 psi =
|
||||
case Unit.MPa: return 0.1 * v; /// 1 MPa = 10000 hPa
|
||||
|
||||
/// Relative error: internal representation in %
|
||||
case Unit.Promile: return 10 * v; /// 1 promile = 0.1 %
|
||||
|
||||
/// Diameter, length: internal representation in mm
|
||||
case Unit.cm: return 0.1 * v; /// 1 cm = 10 mm
|
||||
case Unit.inch: return v / 25.4; /// 1 inch = 25.4 mm
|
||||
case Unit.dm: return 0.01 * v; /// 1 dm = 100 mm
|
||||
case Unit.foot: return v / 304.8; /// 1 foot = 304.8 mm
|
||||
case Unit.yard: return v / 914.4; /// 1 yard = 914,4 mm
|
||||
case Unit.m: return 0.001 * v; /// 1 m = 1000 mm
|
||||
|
||||
/// Density: internal representation in kg/m3
|
||||
case Unit.kgpl: return 0.001 * v;
|
||||
|
||||
/// Energy, internal representation in Joul
|
||||
case Unit.kJ: return 0.001 * v; /// 1 kJ = 1000 J
|
||||
case Unit.MJ: return 0.000001 * v; /// 1 kJ = 1000000 J
|
||||
case Unit.Wh: return v / 3600.0; /// 1 Wh = 3600 J
|
||||
case Unit.kWh: return v / 3600000.0; /// 1 kWh = 3600000 J
|
||||
case Unit.MWh: return v / 3600000000.0; /// 1 MWh = 3600000000 J
|
||||
|
||||
/// Electrical conductivity
|
||||
case Unit.mSpm: return 0.1 * v;
|
||||
|
||||
/// Invert pulses
|
||||
case Unit.kWhpp:
|
||||
case Unit.lpp:
|
||||
case Unit.dm3pp:
|
||||
case Unit.lpdeg:
|
||||
case Unit.dm3pdeg: return (v <= float.Epsilon) ? 0 : 1/v;
|
||||
|
||||
/// Current: internal representation in A
|
||||
case Unit.mA: return 1000 * v; /// 1000 mA = 1 A
|
||||
|
||||
/// Voltage: internal representation in V
|
||||
case Unit.mV: return 1000 * v; /// 1000 mV = 1 V
|
||||
|
||||
|
||||
default: return v; /// Do not convert
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static float ConvertFrom(Unit unit, float v)
|
||||
{
|
||||
return (float)ConvertFrom(unit, (double)v);
|
||||
}
|
||||
|
||||
public static double ConvertFrom(Unit unit, double v)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
/// Volume: internal representation in l
|
||||
case Unit.ml: return 0.001 * v; /// 0.001 l
|
||||
case Unit.USgal: return 3.78541178 * v; /// 1 gal(US) = 3.78541178 l
|
||||
case Unit.UKgal: return 4.54609 * v; /// 1 gal(UK) = 4.54609 l
|
||||
case Unit.cf: return 28.316846592 * v; /// 1 cubic foot = 28.316846592 l
|
||||
case Unit.m3: return 1000 * v; /// 1000 l
|
||||
|
||||
/// Flow: internal representation in m3/h
|
||||
case Unit.lph: return 0.001 * v; /// 1 l/h
|
||||
case Unit.cfph: return 0.028316846592 * v; /// 1 cf/h
|
||||
case Unit.lpm: return 0.06 * v; /// 1 l/m
|
||||
case Unit.USgalpm: return 0.2271247068 * v; /// 1 US gallon per minute
|
||||
case Unit.lps: return 3.6 * v; /// 1 l/s
|
||||
case Unit.USgalps: return 13.627482408 * v; /// 1 US gallon per second
|
||||
case Unit.m3pm: return 60 * v; /// 1 m3/m
|
||||
case Unit.cfs: return 101.9406477312 * v; /// 1 cubic foot per second
|
||||
|
||||
/// Mass: internal representation in kg
|
||||
case Unit.g: return 0.001 * v; /// 1 g = 0.001 kg
|
||||
case Unit.oz: return 0.0283495231 * v; /// 1 oz = 0.0283495231 kg
|
||||
case Unit.lb: return 0.45359237 * v; /// 1 lb = 0.45359237 kg
|
||||
case Unit.t: return 1000 * v; /// 1 t = 1000 kg
|
||||
|
||||
/// Time or duration: internal representation in seconds [s]
|
||||
case Unit.ms: return 0.001 * v;
|
||||
case Unit.min: return 60 * v;
|
||||
case Unit.hour: return 3600 * v;
|
||||
|
||||
/// Temperature: internal representation in °C
|
||||
case Unit.F: return 5 * (v - 32) / 9; /// degree Fahrenheit
|
||||
case Unit.K: return v - 273.15; /// degree Kelvin
|
||||
|
||||
/// Pressure: internal representation in bar = 0.1 MPa
|
||||
case Unit.Pa: return 0.00001 * v; /// 1 hPa = 100 Pa
|
||||
case Unit.hPa: return 0.001 * v; /// 1 hPa = 100 Pa
|
||||
case Unit.mbar: return 0.001 * v; /// 1 mbar = 1 hPa = 100 Pa
|
||||
case Unit.kPa: return 0.01 * v; /// 1 kPa = 10 HPa
|
||||
case Unit.inHg: return 0.033864 * v; /// 1 inHg = 33.864 hPa
|
||||
case Unit.psi: return 0.0689475729 * v; /// 1 psi = 0.0689475729 bar
|
||||
case Unit.MPa: return 10 * v; /// 1 MPa = 10000 hPa
|
||||
|
||||
/// Relative error: internal representation in %
|
||||
case Unit.Promile: return 0.1 * v; /// 1 promile = 0.1 %
|
||||
|
||||
/// Diameter, length: internal representation in mm
|
||||
case Unit.cm: return 10 * v; /// 1 cm = 10 mm
|
||||
case Unit.inch: return 25.4 * v; /// 1 inch = 25.4 mm
|
||||
case Unit.dm: return 100 * v; /// 1 dm = 100 mm
|
||||
case Unit.foot: return 304.8 * v; /// 1 foot = 304.8 mm
|
||||
case Unit.yard: return 914.4 * v; /// 1 yard = 914,4 mm
|
||||
case Unit.m: return 1000 * v; /// 1 m = 1000 mm
|
||||
|
||||
/// Density: internal representation in kg/m3
|
||||
case Unit.kgpl: return 1000 * v;
|
||||
|
||||
/// Energy, internal representation in Joul
|
||||
case Unit.kJ: return 1000 * v; /// 1 kJ = 1000 J
|
||||
case Unit.MJ: return 1000000 * v; /// 1 kJ = 1000000 J
|
||||
case Unit.Wh: return 3600 * v; /// 1 Wh = 3600 J
|
||||
case Unit.kWh: return 3600000 * v; /// 1 kWh = 3600000 J
|
||||
case Unit.MWh: return 3600000000 * v; /// 1 kWh = 3600000000 J
|
||||
|
||||
/// Electrical conductivity
|
||||
case Unit.mSpm: return 10 * v;
|
||||
|
||||
/// Current: internal representation in A
|
||||
case Unit.mA: return 0.001 * v; /// 1 mA = 0.001 A
|
||||
|
||||
/// Voltage: internal representation in V
|
||||
case Unit.mV: return 0.001 * v; /// 1 mV = 0.001 V
|
||||
|
||||
/// Invert
|
||||
case Unit.kWhpp:
|
||||
case Unit.lpp:
|
||||
case Unit.dm3pp:
|
||||
case Unit.lpdeg:
|
||||
case Unit.dm3pdeg: return (v <= float.Epsilon) ? 0 : 1/v;
|
||||
|
||||
default: return v; /// Do not convert
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a unit
|
||||
/// </summary>
|
||||
/// <param name="description">Unit description string</param>
|
||||
/// <returns>Converted unit or Unit.None if not recognized</returns>
|
||||
public static Unit FromDescription(string description)
|
||||
{
|
||||
for (Unit unit = 0; unit < Unit.Count; unit++)
|
||||
{
|
||||
if (unit.ToDescription() == description) return unit;
|
||||
}
|
||||
|
||||
return Unit.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
-363
@@ -1,363 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace Common
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
public static string GetTestName(string name, int repeats, int repetitionNr)
|
||||
{
|
||||
if (name == null) return null;
|
||||
if (repeats == 1) return name;
|
||||
return string.Format("{0} ({1}/{2})", name, repetitionNr, repeats);
|
||||
}
|
||||
|
||||
public static string ToNiceString(double value, int sigDigits)
|
||||
{
|
||||
string format = SignificantDigitsToFmt(value, sigDigits);
|
||||
return (format == "F0") ? value.ToString("F0") : value.ToString(format).TrimEnd(new char[] { '0' });
|
||||
}
|
||||
|
||||
public static FlowNames ProfileType2FlowNames(ProfileType pt, bool isAux = false)
|
||||
{
|
||||
switch (pt)
|
||||
{
|
||||
case ProfileType.Q3R:
|
||||
case ProfileType.CompoundQ3RQ3R:
|
||||
return FlowNames.Q3Q2Q1;
|
||||
case ProfileType.CompoundQ3RQnClass:
|
||||
return isAux ? FlowNames.QnQtQmin : FlowNames.Q3Q2Q1;
|
||||
case ProfileType.QnClassColdWater:
|
||||
case ProfileType.QnClassHotWater:
|
||||
case ProfileType.CompoundQnClassQnClass:
|
||||
return FlowNames.QnQtQmin;
|
||||
case ProfileType.CompoundQnClassQ3R:
|
||||
return isAux ? FlowNames.Q3Q2Q1 : FlowNames.QnQtQmin;
|
||||
case ProfileType.QpQi:
|
||||
case ProfileType.CompoundQpQiQpQi:
|
||||
return FlowNames.QpQi;
|
||||
default:
|
||||
return FlowNames.Q3Q2Q1;
|
||||
}
|
||||
}
|
||||
|
||||
public static string SignificantDigitsToFmt(double value, int sigDigits)
|
||||
{
|
||||
if (sigDigits == 6)
|
||||
{
|
||||
if (value >= 99999.5 || value < -99999.5) return "F0";
|
||||
else if (value >= 9999.95 || value < -9999.95) return "F1";
|
||||
else if (value >= 999.995 || value < -999.995) return "F2";
|
||||
else if (value >= 99.9995 || value < -99.9995) return "F3";
|
||||
else if (value >= 9.99995 || value < -9.99995) return "F4";
|
||||
else if (value >= 0.999995 || value < -0.999995) return "F5";
|
||||
else if (value >= 0.0999995 || value < -0.0999995) return "F6";
|
||||
else if (value >= 0.00999995 || value < -0.00999995) return "F7";
|
||||
else if (value >= 0.000999995 || value < -0.000999995) return "F8";
|
||||
else if (value >= 0.0000999995 || value < -0.0000999995) return "F9";
|
||||
else return "F10";
|
||||
}
|
||||
else if (sigDigits == 5)
|
||||
{
|
||||
if (value >= 9999.5 || value < -9999.5) return "F0";
|
||||
else if (value >= 999.95 || value < -999.95) return "F1";
|
||||
else if (value >= 99.995 || value < -99.995) return "F2";
|
||||
else if (value >= 9.9995 || value < -9.9995) return "F3";
|
||||
else if (value >= 0.99995 || value < -0.99995) return "F4";
|
||||
else if (value >= 0.099995 || value < -0.099995) return "F5";
|
||||
else if (value >= 0.0099995 || value < -0.0099995) return "F6";
|
||||
else if (value >= 0.00099995 || value < -0.00099995) return "F7";
|
||||
else if (value >= 0.000099995 || value < -0.000099995) return "F8";
|
||||
else return "F9";
|
||||
}
|
||||
else if (sigDigits == 4)
|
||||
{
|
||||
if (value >= 999.5 || value < -999.5) return "F0";
|
||||
else if (value >= 99.95 || value < -99.95) return "F1";
|
||||
else if (value >= 9.995 || value < -9.995) return "F2";
|
||||
else if (value >= 0.9995 || value < -0.9995) return "F3";
|
||||
else if (value >= 0.09995 || value < -0.09995) return "F4";
|
||||
else if (value >= 0.009995 || value < -0.009995) return "F5";
|
||||
else if (value >= 0.0009995 || value < -0.0009995) return "F6";
|
||||
else if (value >= 0.00009995 || value < -0.00009995) return "F7";
|
||||
else return "F8";
|
||||
}
|
||||
else if (sigDigits == 3)
|
||||
{
|
||||
if (value >= 99.5 || value < -99.5) return "F0";
|
||||
else if (value >= 9.95 || value < -9.95) return "F1";
|
||||
else if (value >= 0.995 || value < -0.995) return "F2";
|
||||
else if (value >= 0.0995 || value < -0.0995) return "F3";
|
||||
else if (value >= 0.00995 || value < -0.00995) return "F4";
|
||||
else if (value >= 0.000995 || value < -0.000995) return "F5";
|
||||
else if (value >= 0.0000995 || value < -0.0000995) return "F6";
|
||||
else return "F7";
|
||||
}
|
||||
else if (sigDigits == 2)
|
||||
{
|
||||
if (value >= 9.5 || value < -9.5) return "F0";
|
||||
else if (value >= 0.95 || value < -0.95) return "F1";
|
||||
else if (value >= 0.095 || value < -0.095) return "F2";
|
||||
else if (value >= 0.0095 || value < -0.0095) return "F3";
|
||||
else if (value >= 0.00095 || value < -0.00095) return "F4";
|
||||
else if (value >= 0.000095 || value < -0.000095) return "F5";
|
||||
else return "F6";
|
||||
}
|
||||
else /// if (sigDigits == 1)
|
||||
{
|
||||
if (value >= 0.95 || value < -0.95) return "F0";
|
||||
else if (value >= 0.095 || value < -0.095) return "F1";
|
||||
else if (value >= 0.0095 || value < -0.0095) return "F2";
|
||||
else if (value >= 0.00095 || value < -0.00095) return "F3";
|
||||
else if (value >= 0.000095 || value < -0.000095) return "F4";
|
||||
else return "F5";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get either Q1 or Qmin flow for a given Qn and metrological class
|
||||
/// </summary>
|
||||
/// <param name="Qn">Nominal flow in m3/h</param>
|
||||
/// <param name="metroClass">Metrological class ("A" ,"B", "C" or "R#")</param>
|
||||
/// <param name="medium">NotSpecified, ColdWater or HotWater</param>
|
||||
/// <param name="Qdflt">Default flow when metrologic does not match pattern</param>
|
||||
/// <returns>Q1 or Qmin flow in m3/h</returns>
|
||||
public static double GetQ1Qmin(double Qn, string metroClass, Medium medium = Medium.ColdWater, double Qdflt = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(metroClass)) return Qdflt;
|
||||
|
||||
int metroClassRatio;
|
||||
if ((metroClass[0] == 'R') && int.TryParse(metroClass.Substring(1), out metroClassRatio) && (metroClassRatio > 0))
|
||||
{
|
||||
return Qn / (double)metroClassRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (medium == Medium.HotWater)
|
||||
{
|
||||
switch (metroClass)
|
||||
{
|
||||
case "A": return (Qn < 15) ? (0.04 * Qn) : (0.08 * Qn);
|
||||
case "B": return (Qn < 15) ? (0.02 * Qn) : (0.04 * Qn);
|
||||
case "C": return (Qn < 15) ? (0.01 * Qn) : (0.02 * Qn);
|
||||
case "D": return (Qn < 15) ? (0.01 * Qn) : Qdflt;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (metroClass)
|
||||
{
|
||||
case "A": return (Qn < 15) ? (0.04 * Qn) : (0.08 * Qn);
|
||||
case "B": return (Qn < 15) ? (0.02 * Qn) : (0.03 * Qn);
|
||||
case "C": return (Qn < 15) ? (0.01 * Qn) : (0.006 * Qn);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Qdflt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get either Q2 or Qt flow for a given Qn and metrological class
|
||||
/// </summary>
|
||||
/// <param name="Qn">Nominal flow in m3/h</param>
|
||||
/// <param name="metroClass">Metrological class ("A" ,"B", "C" or "R#")</param>
|
||||
/// <param name="medium">NotSpecified, ColdWater or HotWater</param>
|
||||
/// <param name="Qdflt">Default flow when metrologic does not match pattern</param>
|
||||
/// <returns>Q2 or Qt flow in m3/h</returns>
|
||||
public static double GetQ2Qt(double Qn, string metroClass, Medium medium = Medium.ColdWater, double Qdflt = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(metroClass)) return Qdflt;
|
||||
|
||||
int metroClassRatio;
|
||||
if ((metroClass[0] == 'R') && int.TryParse(metroClass.Substring(1), out metroClassRatio) && (metroClassRatio > 0))
|
||||
{
|
||||
return 1.6 * Qn / (double)metroClassRatio;
|
||||
}
|
||||
|
||||
if (medium == Medium.HotWater)
|
||||
{
|
||||
switch (metroClass)
|
||||
{
|
||||
case "A": return (Qn < 15) ? (0.1 * Qn) : (0.2 * Qn);
|
||||
case "B": return (Qn < 15) ? (0.08 * Qn) : (0.15 * Qn);
|
||||
case "C": return (Qn < 15) ? (0.06 * Qn) : (0.1 * Qn);
|
||||
case "D": return (Qn < 15) ? (0.015 * Qn) : Qdflt;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (metroClass)
|
||||
{
|
||||
case "A": return (Qn < 15) ? (0.1 * Qn) : (0.3 * Qn);
|
||||
case "B": return (Qn < 15) ? (0.08 * Qn) : (0.2 * Qn);
|
||||
case "C": return (Qn < 15) ? (0.015 * Qn) : (0.015 * Qn);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return Qdflt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get either Q4 or Qmax flow for a given Qn and metrological class
|
||||
/// </summary>
|
||||
/// <param name="Qn">Nominal flow in m3/h</param>
|
||||
/// <param name="metroClass">Metrological class ("A" ,"B", "C" or "R#")</param>
|
||||
/// <param name="medium">NotSpecified, ColdWater or HotWater</param>
|
||||
/// <param name="Qdflt">Default flow when metrologic does not match pattern</param>
|
||||
/// <returns>Q4 or Qmax flow in m3/h</returns>
|
||||
public static double GetQ4Qmax(double Qn, string metroClass, Medium medium = Medium.ColdWater, double Qdflt = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(metroClass)) return Qdflt;
|
||||
|
||||
switch (metroClass[0])
|
||||
{
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
return 2 * Qn;
|
||||
case 'R':
|
||||
return 1.25 * Qn;
|
||||
default:
|
||||
return Qdflt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks requirements on the password regardless of the password history
|
||||
/// </summary>
|
||||
/// <param name="password">Password</param>
|
||||
/// <returns>true when the password is OK</returns>
|
||||
public static bool IsPasswordMeetsRequirements(string password, out string explanation)
|
||||
{
|
||||
int length = string.IsNullOrEmpty(password) ? 0 : password.Length;
|
||||
|
||||
/// Password length must be at least 6
|
||||
if (length < CurrentUser.MinPasswdLength)
|
||||
{
|
||||
explanation = string.Format("Password must have at least {0} characters", CurrentUser.MinPasswdLength);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
explanation = string.Empty;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getHash encrypts a string
|
||||
/// </summary>
|
||||
/// <param name="text">the string to encrypt</param>
|
||||
/// <returns></returns>
|
||||
public static string GetHash(string text)
|
||||
{
|
||||
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(text);
|
||||
System.Security.Cryptography.SHA512Managed hashstring = new System.Security.Cryptography.SHA512Managed();
|
||||
byte[] hash = hashstring.ComputeHash(bytes);
|
||||
string hashString = string.Empty;
|
||||
foreach (byte x in hash)
|
||||
{
|
||||
hashString += String.Format("{0:x2}", x);
|
||||
}
|
||||
return hashString;
|
||||
}
|
||||
|
||||
public static string EncodedStrToUserName(string encodedStr)
|
||||
{
|
||||
string[] subStrings = encodedStr.Split(new char[] { '~' });
|
||||
return (subStrings.Length >= 1) ? subStrings[0] : string.Empty;
|
||||
}
|
||||
|
||||
public static string EncodedStrToFullName(string encodedStr)
|
||||
{
|
||||
string[] subStrings = encodedStr.Split(new char[] { '~' });
|
||||
return (subStrings.Length >= 2) ? subStrings[1] : string.Empty;
|
||||
}
|
||||
|
||||
public static string EncodedStrToLegalizator(string encodedStr)
|
||||
{
|
||||
string[] subStrings = encodedStr.Split(new char[] { '~' });
|
||||
return (subStrings.Length >= 3) ? subStrings[2] : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns 'true' when authentication data are valid for a power user.
|
||||
/// </summary>
|
||||
/// <param name="userName">User name</param>
|
||||
/// <param name="password">Password</param>
|
||||
/// <returns>true = authenticated, false = refused</returns>
|
||||
public static bool IsPowerUser(string userName, string password)
|
||||
{
|
||||
DateTime date = DateTime.Now.Date;
|
||||
int number = (date.Year % 10) + 10 * (date.Month - 1) + 120 * date.Day;
|
||||
string passwordOfDay = Convert.ToString(number, 8);
|
||||
|
||||
return (userName.Equals("milan") && password.Equals("kraken")) ||
|
||||
(userName.Equals("bumi") && password.Equals("70630")) ||
|
||||
(userName.Equals("igor") && password.Equals("mojronko8")) ||
|
||||
(userName.Equals("lubo1212") && password.Equals("Tatry52")) ||
|
||||
(userName.Equals("Michal") && password.Equals("Plok789456123")) ||
|
||||
(userName.Equals("martin") && password.Equals("vaclavek84")) ||
|
||||
(userName.Equals("pakan") && password.Equals("kuriatko")) ||
|
||||
(userName.Equals("jan") && password.Equals("jaugust")) ||
|
||||
(userName.Equals("JCermak") && password.Equals("Zt6911")) ||
|
||||
(userName.Equals("gilles") && password.Equals("alibaba")) ||
|
||||
(userName.Equals("michal") && password.Equals("mojnelson8")) ||
|
||||
(userName.Equals("marek") && password.Equals("mareciino")) ||
|
||||
#if DEBUG
|
||||
(userName.Equals("Sensus Developers") && password.Equals("5fbg12gf5hn8nhy1fr")) ||
|
||||
#endif
|
||||
(userName.Equals(passwordOfDay) && password.Equals(passwordOfDay));
|
||||
}
|
||||
|
||||
public static void CalculateFeatureVector(Iperl.OptoTelegramRaw[] optoData, int optoDataCount, int startIx, int endIx, ref float[] x)
|
||||
{
|
||||
if (startIx < 0 || endIx >= optoDataCount || startIx >= endIx) return;
|
||||
|
||||
int n = 0;
|
||||
Int64 sumFlow = 0;
|
||||
Int64 sumFlow2 = 0;
|
||||
Int64 sumEmf = 0;
|
||||
Int64 sumEmf2 = 0;
|
||||
Int64 sumMagF = 0;
|
||||
Int64 sumMagF2 = 0;
|
||||
Int64 sumImp = 0;
|
||||
Int64 sumImp2 = 0;
|
||||
|
||||
for (int ix = startIx; ix <= endIx; ix++)
|
||||
{
|
||||
if (optoData[ix].Flags == Iperl.OptoTelegramFlags.OK ||
|
||||
optoData[ix].Flags == Iperl.OptoTelegramFlags.OK_TestStart ||
|
||||
optoData[ix].Flags == Iperl.OptoTelegramFlags.OK_TestEnd)
|
||||
{
|
||||
n++;
|
||||
sumFlow += optoData[ix].FlowRaw;
|
||||
sumFlow2 += ((int)optoData[ix].FlowRaw * (int)optoData[ix].FlowRaw);
|
||||
sumEmf += (int)optoData[ix].EmfRaw;
|
||||
sumEmf2 += ((Int64)optoData[ix].EmfRaw * (Int64)optoData[ix].EmfRaw);
|
||||
sumMagF += optoData[ix].MagneticFieldRaw;
|
||||
sumMagF2 += ((int)optoData[ix].MagneticFieldRaw * (int)optoData[ix].MagneticFieldRaw);
|
||||
sumImp += optoData[ix].Impedance;
|
||||
sumImp2 += ((int)optoData[ix].Impedance * (int)optoData[ix].Impedance);
|
||||
}
|
||||
}
|
||||
|
||||
if (n >= 2)
|
||||
{
|
||||
if (x.Length > 0) x[0] = ((float)sumFlow2 - (float)sumFlow * (float)sumFlow / n) / (n - 1);
|
||||
if (x.Length > 1) x[1] = ((float)sumEmf2 - (float)sumEmf * (float)sumEmf / n) / (n - 1);
|
||||
if (x.Length > 2) x[2] = ((float)sumMagF2 - (float)sumMagF * (float)sumMagF / n) / (n - 1);
|
||||
if (x.Length > 3) x[3] = ((float)sumImp2 - (float)sumImp * (float)sumImp / n) / (n - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="log4net" version="2.0.15" targetFramework="net472" />
|
||||
<package id="NLog" version="5.2.2" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Config.CalendarEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for creating event types
|
||||
/// </summary>
|
||||
public interface ICalendarEvent
|
||||
{
|
||||
DateTime Date { get; set; } /// The Date that the event occurs
|
||||
Frequency Frequency { get; set; } /// A value indicating how often the event occurs
|
||||
bool AllDay { get; set; } /// True if the time component of DateTime value can be ignored
|
||||
bool TriggerOnExactDayOnly { get; set; } /// If this is a recurring event, set this to true to make the event show up only from the day specified forward
|
||||
string Source { get; set; } /// Source of this calendar event (becomes the source of the triggered event)
|
||||
string Title { get; set; } /// The name of the event (becomes the text of the triggered event)
|
||||
AutoAction AutoAction { get; set; } /// Automated action to be done or event to be triggered (triggered event Severity)
|
||||
string Parameters { get; set; } /// Automated action parameters (e.g. name of a procedure to start)
|
||||
int Rank { get; set; } /// The ranking of the event that determines the order in which it is displayed on a particular day
|
||||
bool Hidden { get; set; } /// True if the event is hidden/invisible, otherwise false
|
||||
bool ReadOnly { get; set; } /// True if the event details cannot be modified
|
||||
int BackColor { get; set; } /// The color that the event show up in on the calendar
|
||||
int TextColor { get; set; } /// The text color of the event
|
||||
bool TooltipEnabled { get; set; } /// True if a tooltip should be displayed when hovering over the event
|
||||
|
||||
/// <summary>
|
||||
/// Set this to a custom function that will automatically determine if the event should be rendered on a given day.
|
||||
/// This is only executed if <see cref="Frequency"/> is set to custom.
|
||||
/// </summary>
|
||||
CustomRecurringFrequenciesHandler CustomRecurringFunction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A function for cloning an event instance
|
||||
/// </summary>
|
||||
/// <returns>A cloned <see cref="ICalendarEvent"/></returns>
|
||||
ICalendarEvent Clone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A delegate for creating custom recurring frequencies
|
||||
/// </summary>
|
||||
/// <param name="evnt">The <see cref="ICalendarEvent"/> in question</param>
|
||||
/// <param name="day">The day in question</param>
|
||||
/// <returns>Should return a boolean value that indicates if the event should be rendered on the day passed in</returns>
|
||||
public delegate bool CustomRecurringFrequenciesHandler(ICalendarEvent evnt, DateTime day);
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Config.Resources;
|
||||
|
||||
namespace Config.CalendarEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of calendar event actions
|
||||
/// </summary>
|
||||
public enum AutoAction
|
||||
{
|
||||
Undefined,
|
||||
None, /// No action at all
|
||||
Notification, /// Trigger a notification event
|
||||
Warning, /// Trigger a warning event
|
||||
Error, /// Trigger an error event and stop test bench function
|
||||
FatalErr, /// Trigger a fatal error and stop test bench function
|
||||
InvokeBeforeCycle, /// Invoke a maintenance procedure before a cycle after entering order number
|
||||
InvokeInsideCycle, /// Invoke conditional tests inside a cycle (if any)
|
||||
InvokeAfterCycle, /// Invoke a maintenance procedure after a cycle after saving results
|
||||
BackupData,
|
||||
Count,
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of built-in recurring event frequencies
|
||||
/// </summary>
|
||||
public enum Frequency
|
||||
{
|
||||
Undefined,
|
||||
Once, /// Indicates that the event is non recurring will occur only one time
|
||||
Yearly, /// Indicates that the event will occur once a year, on the month and day specified
|
||||
Monthly, /// Indicates that the event will occur every month
|
||||
Weekly, /// Indicates that the event will occur every week
|
||||
EveryTuTh, /// Indicates that the event will occur every Tuesday and Thursday
|
||||
EveryMoWeFr, /// Indicates that the event will occur every Mon, Wed and Fri
|
||||
EveryWkday, /// Indicates that the event will occur every week day (Mon - Fri)
|
||||
Daily, /// Indicates that the event will occur every day
|
||||
EveryShift,
|
||||
Custom, /// Indicates that the recuring schedule of this event is unique
|
||||
Count
|
||||
}
|
||||
|
||||
public class Utils
|
||||
{
|
||||
public static string Action2String(AutoAction action)
|
||||
{
|
||||
return action.ToString();
|
||||
}
|
||||
|
||||
public static AutoAction String2Action(string astr)
|
||||
{
|
||||
for (AutoAction a = AutoAction.None; a < AutoAction.Count; a++)
|
||||
{
|
||||
if (Action2String(a) == astr) return a;
|
||||
}
|
||||
return AutoAction.Undefined;
|
||||
}
|
||||
|
||||
public static string Freq2String(Frequency f)
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
case Frequency.Custom: return Strings.Custom;
|
||||
case Frequency.Daily: return Strings.Daily;
|
||||
case Frequency.EveryMoWeFr: return Strings.Every_Mon_Wed_and_Fri;
|
||||
case Frequency.EveryTuTh: return Strings.Every_Tue_and_Thu;
|
||||
case Frequency.EveryWkday: return Strings.Every_Week_Day;
|
||||
case Frequency.EveryShift: return Strings.Every_shift;
|
||||
case Frequency.Monthly: return Strings.Every_Month;
|
||||
case Frequency.Once: return Strings.Once;
|
||||
case Frequency.Weekly: return Strings.Every_week;
|
||||
case Frequency.Yearly: return Strings.Every_year;
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static Frequency String2Freq(string fstr)
|
||||
{
|
||||
for (Frequency f = Frequency.Once; f < Frequency.Count; f++)
|
||||
{
|
||||
if (Freq2String(f) == fstr) return f;
|
||||
}
|
||||
return Frequency.Undefined;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether an event date matches given day and time (dt)
|
||||
/// (whether an event needs to be rendered on a specific day).
|
||||
/// </summary>
|
||||
/// <param name="evnt">Calendar event</param>
|
||||
/// <param name="dt">Day and time</param>
|
||||
/// <returns>true = needs to be rendered</returns>
|
||||
public static bool DayMatchesExactly(ICalendarEvent evnt, DateTime dt)
|
||||
{
|
||||
DayOfWeek dow = dt.DayOfWeek;
|
||||
|
||||
switch (evnt.Frequency)
|
||||
{
|
||||
case Frequency.EveryShift: return (dow == DayOfWeek.Sunday && evnt.Date.Hour >= 22) ||
|
||||
dow == DayOfWeek.Monday ||
|
||||
dow == DayOfWeek.Tuesday ||
|
||||
dow == DayOfWeek.Wednesday ||
|
||||
dow == DayOfWeek.Thursday ||
|
||||
(dow == DayOfWeek.Friday && evnt.Date.Hour < 22);
|
||||
|
||||
case Frequency.Daily: return true;
|
||||
case Frequency.EveryMoWeFr: return (dow == DayOfWeek.Monday) || (dow == DayOfWeek.Wednesday) || (dow == DayOfWeek.Friday);
|
||||
case Frequency.EveryTuTh: return (dow == DayOfWeek.Tuesday) || (dow == DayOfWeek.Thursday);
|
||||
case Frequency.EveryWkday: return (dow != DayOfWeek.Sunday) && (dow != DayOfWeek.Saturday);
|
||||
case Frequency.Weekly: return evnt.Date.DayOfWeek == dow;
|
||||
case Frequency.Monthly: return evnt.Date.Day == dt.Day;
|
||||
case Frequency.Yearly: return evnt.Date.Month == dt.Month && evnt.Date.Day == dt.Day;
|
||||
case Frequency.Once: return evnt.Date.Year == dt.Year && evnt.Date.Month == dt.Month && evnt.Date.Day == dt.Day;
|
||||
case Frequency.Custom: return (evnt.CustomRecurringFunction != null) && evnt.CustomRecurringFunction(evnt, dt);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool IsCalendarEventTrigerred(ICalendarEvent evnt, DateTime currentDate)
|
||||
{
|
||||
DateTime evntDT = evnt.AllDay
|
||||
? new DateTime(evnt.Date.Year, evnt.Date.Month, evnt.Date.Day, 0, 0, 0)
|
||||
: evnt.Date;
|
||||
|
||||
if (evnt.Frequency == Frequency.EveryShift)
|
||||
{
|
||||
DateTime dt1 = evntDT;
|
||||
DateTime dt2 = evntDT + new TimeSpan(8, 0, 0);
|
||||
DateTime dt3 = evntDT + new TimeSpan(16, 0, 0);
|
||||
return (currentDate >= dt1) || (currentDate >= dt1) || (currentDate >= dt3);
|
||||
}
|
||||
else if (!evnt.TriggerOnExactDayOnly)
|
||||
{
|
||||
/// Trigger after event expires
|
||||
return (currentDate >= evntDT);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Trigger event on exact date only
|
||||
return (currentDate >= evntDT) && DayMatchesExactly(evnt, currentDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called to update event.Date after an event was trigerred and a required action was done.
|
||||
/// </summary>
|
||||
/// <param name="evnt">Calendar event</param>
|
||||
/// <param name="currentDate">Current date and time which triggered the event</param>
|
||||
/// <returns>true when event.Date was updated</returns>
|
||||
public static bool UpdateRecurringDate(ICalendarEvent evnt, DateTime currentDate)
|
||||
{
|
||||
switch (evnt.Frequency)
|
||||
{
|
||||
case Frequency.Yearly:
|
||||
do {
|
||||
evnt.Date = evnt.Date.AddYears(1);
|
||||
}
|
||||
while (evnt.Date <= currentDate);
|
||||
return true;
|
||||
|
||||
case Frequency.Monthly:
|
||||
do {
|
||||
evnt.Date = evnt.Date.AddMonths(1);
|
||||
}
|
||||
while (evnt.Date <= currentDate);
|
||||
return true;
|
||||
|
||||
case Frequency.Weekly:
|
||||
do {
|
||||
evnt.Date += new TimeSpan(7, 0, 0, 0); /// add one week
|
||||
}
|
||||
while (evnt.Date <= currentDate);
|
||||
return true;
|
||||
|
||||
case Frequency.EveryTuTh:
|
||||
do {
|
||||
evnt.Date += new TimeSpan(1, 0, 0, 0); /// add one day
|
||||
}
|
||||
while ((evnt.Date <= currentDate) || ((evnt.Date.DayOfWeek != DayOfWeek.Tuesday) &&
|
||||
(evnt.Date.DayOfWeek != DayOfWeek.Thursday)));
|
||||
return true;
|
||||
|
||||
case Frequency.EveryMoWeFr:
|
||||
do {
|
||||
evnt.Date += new TimeSpan(1, 0, 0, 0); /// add one day
|
||||
}
|
||||
while ((evnt.Date <= currentDate) || ((currentDate.DayOfWeek != DayOfWeek.Monday) &&
|
||||
(currentDate.DayOfWeek != DayOfWeek.Wednesday) &&
|
||||
(currentDate.DayOfWeek != DayOfWeek.Friday)));
|
||||
return true;
|
||||
|
||||
case Frequency.EveryWkday:
|
||||
do {
|
||||
evnt.Date += new TimeSpan(1, 0, 0, 0); /// add one day
|
||||
}
|
||||
while ((evnt.Date <= currentDate) || (currentDate.DayOfWeek == DayOfWeek.Saturday) || (currentDate.DayOfWeek == DayOfWeek.Sunday));
|
||||
return true;
|
||||
|
||||
case Frequency.Daily:
|
||||
do {
|
||||
evnt.Date += new TimeSpan(1, 0, 0, 0); /// add one day
|
||||
}
|
||||
while (evnt.Date <= currentDate);
|
||||
return true;
|
||||
|
||||
case Frequency.EveryShift:
|
||||
do {
|
||||
evnt.Date += new TimeSpan(8, 0, 0); /// add eight hours
|
||||
}
|
||||
while (evnt.Date <= currentDate);
|
||||
return true;
|
||||
|
||||
default:
|
||||
/// This is not a recurring calendar event, 'Date' was not updated
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-27
@@ -10,30 +10,27 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Config</RootNamespace>
|
||||
<AssemblyName>Config</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;SLM_END;HEAT_METERS;LANG_SK</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;JUZNA_AFRIKA_NEW;</DefineConstants>
|
||||
<DefineConstants>TRACE;SLM_END;HEAT_METERS;LANG_SK</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentNHibernate">
|
||||
@@ -43,7 +40,7 @@
|
||||
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net">
|
||||
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
|
||||
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data">
|
||||
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
|
||||
@@ -67,41 +64,39 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CalendarEvent\ICalendarEvent.cs" />
|
||||
<Compile Include="Data.cs" />
|
||||
<Compile Include="DatabaseSettings.cs" />
|
||||
<Compile Include="Entities\BenchPath.cs" />
|
||||
<Compile Include="Entities\CustomEvent.cs" />
|
||||
<Compile Include="Entities\Component.cs" />
|
||||
<Compile Include="Entities\ComponentProcedure.cs" />
|
||||
<Compile Include="Entities\ComponentTest.cs" />
|
||||
<Compile Include="Entities\Enums.cs" />
|
||||
<Compile Include="Entities\FeedingPath.cs" />
|
||||
<Compile Include="Entities\Group.cs" />
|
||||
<Compile Include="Entities\HeatMetersPath.cs" />
|
||||
<Compile Include="Entities\IHasItemNr.cs" />
|
||||
<Compile Include="Entities\IHasName.cs" />
|
||||
<Compile Include="Entities\IHasValves.cs" />
|
||||
<Compile Include="Entities\IParamsProvider.cs" />
|
||||
<Compile Include="Entities\MeasurementCorrection.cs" />
|
||||
<Compile Include="Entities\MetersPath.cs" />
|
||||
<Compile Include="Entities\OutputPath.cs" />
|
||||
<Compile Include="Entities\Procedure.cs" />
|
||||
<Compile Include="Entities\Profile.cs" />
|
||||
<Compile Include="Entities\PTest.cs" />
|
||||
<Compile Include="Entities\ProcedureHistory.cs" />
|
||||
<Compile Include="Entities\Test.cs" />
|
||||
<Compile Include="Entities\TestInstance.cs" />
|
||||
<Compile Include="Entities\TransitionSequence.cs" />
|
||||
<Compile Include="Entities\TransitionStep.cs" />
|
||||
<Compile Include="Entities\Uncertainty.cs" />
|
||||
<Compile Include="Entities\User.cs" />
|
||||
<Compile Include="Entities\VirtualBenchSequence.cs" />
|
||||
<Compile Include="Entities\VirtualBenchStep.cs" />
|
||||
<Compile Include="CalendarEvent\Utils.cs" />
|
||||
<Compile Include="Entities\Watermeter.cs" />
|
||||
<Compile Include="Entities\WMType.cs" />
|
||||
<Compile Include="FluentCommon.cs" />
|
||||
<Compile Include="Formulas.cs" />
|
||||
<Compile Include="Mappings\BenchPathMap.cs" />
|
||||
<Compile Include="Mappings\ComponentMap.cs" />
|
||||
<Compile Include="Mappings\ComponentProcedureMap.cs" />
|
||||
<Compile Include="Mappings\ComponentTestMap.cs" />
|
||||
<Compile Include="Mappings\CustomEventMap.cs" />
|
||||
<Compile Include="Mappings\FeedingPathMap.cs" />
|
||||
<Compile Include="Mappings\GroupMap.cs" />
|
||||
<Compile Include="Mappings\HeatMetersPathMap.cs" />
|
||||
@@ -109,27 +104,26 @@
|
||||
<Compile Include="Mappings\MetersPathMap.cs" />
|
||||
<Compile Include="Mappings\OutputPathMap.cs" />
|
||||
<Compile Include="Mappings\ProcedureMap.cs" />
|
||||
<Compile Include="Mappings\ProfileMap.cs" />
|
||||
<Compile Include="Mappings\PTestMap.cs" />
|
||||
<Compile Include="Mappings\TestMap.cs" />
|
||||
<Compile Include="Mappings\TransitionSequenceMap.cs" />
|
||||
<Compile Include="Mappings\TransitionStepMap.cs" />
|
||||
<Compile Include="Mappings\UncertaintyMap.cs" />
|
||||
<Compile Include="Mappings\UserMap.cs" />
|
||||
<Compile Include="Mappings\VirtualBenchSequenceMap.cs" />
|
||||
<Compile Include="Mappings\VirtualBenchStepMap.cs" />
|
||||
<Compile Include="Mappings\WatermeterMap.cs" />
|
||||
<Compile Include="Mappings\WMTypeMap.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PurchaseResources.cs" />
|
||||
<Compile Include="Resources\Strings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Units.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Strings.cs.resx" />
|
||||
<EmbeddedResource Include="Resources\Strings.de.resx">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources\Strings.fr.resx" />
|
||||
<EmbeddedResource Include="Resources\Strings.de.resx" />
|
||||
<EmbeddedResource Include="Resources\Strings.it.resx" />
|
||||
<EmbeddedResource Include="Resources\Strings.pl.resx" />
|
||||
<EmbeddedResource Include="Resources\Strings.resx">
|
||||
@@ -139,9 +133,9 @@
|
||||
<EmbeddedResource Include="Resources\Strings.zh-CN.resx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.csproj">
|
||||
<Project>{c8939821-ba5c-4988-a3d0-bf53b74865c7}</Project>
|
||||
<Name>Common</Name>
|
||||
<ProjectReference Include="..\Users\Users.csproj">
|
||||
<Project>{6E5CB0E9-E1B6-4E5D-AC6E-B1049E180F2B}</Project>
|
||||
<Name>Users</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
+70
-71
@@ -1,103 +1,102 @@
|
||||
using System;
|
||||
|
||||
//formulas.cs has been added cause iPerl from master-2 ...MF
|
||||
using System;
|
||||
|
||||
namespace Config
|
||||
{
|
||||
public class Data
|
||||
public class Data : Users.GlobalData
|
||||
{
|
||||
public const string AdminUsername = "admin";
|
||||
public const string AdminPassword = "staratura";
|
||||
public const string SQLiteDbFName = "SQLite.db";
|
||||
|
||||
#if DN100 || BADGER_STREDNA_TRAT || BADGER_VELKA_TRAT || CEVAK_200
|
||||
#if MUNICH
|
||||
public const int WMsCount = 3;
|
||||
public const int LineSize = 1;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 3;
|
||||
#elif DN100 || BADGER_STREDNA_TRAT || BADGER_VELKA_TRAT || CEVAK_200
|
||||
public const int WMsCount = 3;
|
||||
public const int LineSize = 3;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 1;
|
||||
#elif MUNICH
|
||||
public const int WMsCount = 3;
|
||||
public const int LineSize = 3;
|
||||
public const int CompoundWMsCount = 3;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 3;
|
||||
#elif MALTA_WSD25
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 0;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 1;
|
||||
#elif BADGER_MALA_TRAT || BERLIN || FUZHOU_150 || FUZHOU_300 || GELSENWASSER || GENESIS || IZRAEL_200 || PETERSBURG_200 || SENTEC || SLM_150 || TORINO_50
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 1;
|
||||
#elif PUCHONG_200
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif FUZHOU_300 || FUZHOU_150 || IZRAEL_200 || PUCHONG_200 || GENESIS || SLM_150 || PETERSBURG_200
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 3;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 3;
|
||||
#elif RUM_MOB
|
||||
public const int WMsCount = 8;
|
||||
public const int LineSize = 8;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif TURA_SPECIAL
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif DEWA_300 || FUZHOU_100 || ROMA_200 || LUXEMBURG_40
|
||||
public const int WMsCount = 10;
|
||||
public const int LineSize = 10;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif DUBAJ_50
|
||||
public const int WMsCount = 10;
|
||||
public const int LineSize = 5;
|
||||
public const int CompoundWMsCount = 0;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif SLM_END || WARSAW_END
|
||||
public const int WMsCount = 10;
|
||||
public const int LineSize = 5;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 4;
|
||||
#elif SLM_50
|
||||
public const int WMsCount = 12;
|
||||
public const int LineSize = 12;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 6;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif ALZIR_25 || BAHRAIN_50 || CEVAK_40 || FEWA_50 || FILIPINY_50 || FUZHOU_50 || HONGKONG_50 || IZRAEL_25 || JUZNA_AFRIKA_50 || KEMPNO_50 || KRAKOW_50 || MILWAUKEE || MURES_40 || PETERSBURG_50 || TORUN_50 || WARSAW_50 || ZAMBIA || ZODINO
|
||||
public const int WMsCount = 20;
|
||||
public const int LineSize = 10;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif TURA_IPERL || TURA_IPERL_NEW
|
||||
public const int WMsCount = 40;
|
||||
public const int LineSize = 20;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif IZRAEL_50
|
||||
public const int WMsCount = 40;
|
||||
public const int LineSize = 10;
|
||||
public const int CompoundWMsCount = 0;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif FUZHOU_100
|
||||
public const int WMsCount = 10;
|
||||
public const int LineSize = 10;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif TORINO_50 || BADGER_MALA_TRAT || BERLIN
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 1;
|
||||
#elif TORUN_50 || CEVAK_40 || MURES_40 || FUZHOU_50 || PETERSBURG_50 || KEMPNO_50 || BAHRAIN_50 || KRAKOW_50 || JUZNA_AFRIKA_50 || ZAMBIA || FEWA_50
|
||||
public const int WMsCount = 20;
|
||||
public const int LineSize = 10;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif RUM_MOB
|
||||
public const int WMsCount = 8;
|
||||
public const int LineSize = 8;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif TURA_IPERL
|
||||
public const int WMsCount = 40;
|
||||
public const int LineSize = 20;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif TURA_SPECIAL || SENTEC
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif SLM_50
|
||||
public const int WMsCount = 12;
|
||||
public const int LineSize = 12;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 6;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#elif SLM_END || WARSAW_END
|
||||
public const int WMsCount = 10;
|
||||
public const int LineSize = 5;
|
||||
public const int CompoundWMsCount = 1;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = 4;
|
||||
#elif MALTA_WSD25
|
||||
public const int WMsCount = 6;
|
||||
public const int LineSize = 6;
|
||||
public const int CompoundWMsCount = 0;
|
||||
public const int HeatMetersCount = 0;
|
||||
public const int MaxPartNr = WMsCount / LineSize;
|
||||
#endif
|
||||
|
||||
public static double RealDensity = 0; /// true water density [kg/m3]
|
||||
public static double AtTemperature = 0; /// measured at temperature [°C]
|
||||
public static double Buoyancy = 0;
|
||||
}
|
||||
///
|
||||
/// Database related: This object reference is set after a successful user login
|
||||
///
|
||||
public static DatabaseSettings CurrentBench;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Test bench database settings, contains bench name and settings od several databases
|
||||
/// </summary>
|
||||
public class DatabaseSettings : ICloneable
|
||||
{
|
||||
// Public fields
|
||||
public string BenchName;
|
||||
public bool IsRealBench;
|
||||
public Users.DBSettings ProceduresDBSettings; /// Config database settings
|
||||
public Users.DBSettings WaterMetersDBSettings; /// Results database settings
|
||||
public Users.DBSettings UsersDBSettings; /// Users database settings
|
||||
|
||||
// Constructor
|
||||
public DatabaseSettings()
|
||||
{
|
||||
BenchName = String.Empty; /// Empty string (avoid null)
|
||||
IsRealBench = false;
|
||||
ProceduresDBSettings = new Users.DBSettings(Users.Entities.DBType.MySql, string.Empty);
|
||||
WaterMetersDBSettings = new Users.DBSettings(Users.Entities.DBType.MySql, string.Empty);
|
||||
UsersDBSettings = new Users.DBSettings(Users.Entities.DBType.MySql, string.Empty);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
DatabaseSettings result = new DatabaseSettings();
|
||||
|
||||
result.BenchName = BenchName;
|
||||
result.IsRealBench = IsRealBench;
|
||||
result.ProceduresDBSettings = (Users.DBSettings)ProceduresDBSettings.Clone();
|
||||
result.WaterMetersDBSettings = (Users.DBSettings)WaterMetersDBSettings.Clone();
|
||||
result.UsersDBSettings = (Users.DBSettings)UsersDBSettings.Clone();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} config={1} results={2} users={3}",
|
||||
BenchName,
|
||||
ProceduresDBSettings.ConnectionString,
|
||||
WaterMetersDBSettings.ConnectionString,
|
||||
UsersDBSettings.ConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
@@ -13,34 +12,26 @@ namespace Config.Entities
|
||||
public virtual int ItemNr { get; set; }
|
||||
public virtual string Name { get; set; }
|
||||
public virtual string OriName { get; set; } /// Not mapped to database
|
||||
public virtual double Qfrom { get; set; } /// Water flow in [m3/h]
|
||||
public virtual double Qto { get; set; } /// Water flow in [m3/h]
|
||||
public virtual Unit FlowUnit { get; set; } /// Not mapped to database, used in UI
|
||||
public virtual string Selector { get; set; }
|
||||
public virtual float Qfrom { get; set; } /// Water flow in [m3/h]
|
||||
public virtual float Qto { get; set; } /// Water flow in [m3/h]
|
||||
public virtual string TempMtrUp { get; set; }
|
||||
public virtual string TempMtrDown { get; set; }
|
||||
public virtual string PressMtrUp { get; set; }
|
||||
public virtual string PressMtrDown { get; set; }
|
||||
public virtual string PressMtrDelta { get; set; }
|
||||
public virtual string ElectricMtrUp { get; set; }
|
||||
public virtual string ElectricMtrDown { get; set; }
|
||||
public virtual string ElectricMtrDelta { get; set; }
|
||||
public virtual string StopBFValve { get; set; }
|
||||
|
||||
/// Valves
|
||||
public virtual string ValvesOpen { get; set; }
|
||||
public virtual string ValvesClose { get; set; }
|
||||
|
||||
public virtual bool QfromTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
|
||||
public virtual bool QtoTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
|
||||
|
||||
/// ------------- Additional stuff not mapped into the database -------------
|
||||
|
||||
public BenchPath()
|
||||
{
|
||||
ValvesOpen = string.Empty;
|
||||
ValvesClose = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public BenchPath(string name, int itemNr)
|
||||
: this()
|
||||
@@ -55,16 +46,11 @@ namespace Config.Entities
|
||||
|
||||
result.Qfrom = Qfrom;
|
||||
result.Qto = Qto;
|
||||
result.FlowUnit = FlowUnit;
|
||||
result.Selector = Selector;
|
||||
result.TempMtrUp = TempMtrUp;
|
||||
result.TempMtrUp = TempMtrUp;
|
||||
result.TempMtrDown = TempMtrDown;
|
||||
result.PressMtrUp = PressMtrUp;
|
||||
result.PressMtrDown = PressMtrDown;
|
||||
result.PressMtrDelta = PressMtrDelta;
|
||||
result.ElectricMtrUp = ElectricMtrUp;
|
||||
result.ElectricMtrDown = ElectricMtrDown;
|
||||
result.ElectricMtrDelta = ElectricMtrDelta;
|
||||
result.StopBFValve = StopBFValve;
|
||||
result.ValvesOpen = ValvesOpen;
|
||||
result.ValvesClose = ValvesClose;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using Common;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
@@ -14,12 +14,11 @@ namespace Config.Entities
|
||||
public virtual int ItemNr { get; set; }
|
||||
public virtual string Name { get; set; }
|
||||
public virtual string ClassName { get; set; }
|
||||
public virtual string Parent { get; set; }
|
||||
public virtual DebugMode DebugMode { get; set; }
|
||||
public virtual LogLevel LogLevel { get; set; }
|
||||
public virtual string ParentName { get; set; }
|
||||
public virtual DebugMode Mode { get; set; }
|
||||
public virtual LogLevel Logging { get; set; }
|
||||
public virtual string Parameters { get; set; }
|
||||
public virtual IList<MeasurementCorrection> Corrections { get; set; }
|
||||
public virtual IList<Uncertainty> Uncertainties { get; set; }
|
||||
public virtual IList<MeasurementCorrection> Corrections { get; set; }
|
||||
|
||||
/// ------------- Additional stuff not mapped into the database -------------
|
||||
|
||||
@@ -28,7 +27,6 @@ namespace Config.Entities
|
||||
Name = string.Empty;
|
||||
ClassName = string.Empty;
|
||||
Corrections = new List<MeasurementCorrection>();
|
||||
Uncertainties = new List<Uncertainty>();
|
||||
}
|
||||
|
||||
public static Component CreateFromCfg(string name, string className, string parentName, int itemNr,
|
||||
@@ -38,9 +36,9 @@ namespace Config.Entities
|
||||
result.ItemNr = itemNr;
|
||||
result.Name = name;
|
||||
result.ClassName = className;
|
||||
result.Parent = parentName;
|
||||
result.DebugMode = debugLevel;
|
||||
result.LogLevel = logLevel;
|
||||
result.ParentName = parentName;
|
||||
result.Mode = debugLevel;
|
||||
result.Logging = logLevel;
|
||||
result.Parameters = parameters;
|
||||
return result;
|
||||
}
|
||||
@@ -52,9 +50,9 @@ namespace Config.Entities
|
||||
result.ItemNr = ItemNr;
|
||||
result.Name = Name;
|
||||
result.ClassName = ClassName;
|
||||
result.Parent = Parent;
|
||||
result.DebugMode = DebugMode;
|
||||
result.LogLevel = LogLevel;
|
||||
result.ParentName = ParentName;
|
||||
result.Mode = Mode;
|
||||
result.Logging = Logging;
|
||||
result.Parameters = Parameters;
|
||||
return result;
|
||||
}
|
||||
@@ -63,9 +61,9 @@ namespace Config.Entities
|
||||
{
|
||||
output.WriteLine(Name);
|
||||
output.WriteLine(ClassName);
|
||||
output.WriteLine(Parent);
|
||||
output.WriteLine(DebugMode.ToString());
|
||||
output.WriteLine(LogLevel.ToString());
|
||||
output.WriteLine(ParentName);
|
||||
output.WriteLine(Mode.ToString());
|
||||
output.WriteLine(Logging.ToString());
|
||||
output.Write(Parameters);
|
||||
|
||||
output.Close();
|
||||
@@ -77,28 +75,28 @@ namespace Config.Entities
|
||||
|
||||
result.Name = input.ReadLine();
|
||||
result.ClassName = input.ReadLine();
|
||||
result.Parent = input.ReadLine();
|
||||
result.ParentName = input.ReadLine();
|
||||
|
||||
string line = input.ReadLine();
|
||||
if (line.Equals(DebugMode.DetectedOff.ToString())) result.DebugMode = DebugMode.DetectedOff;
|
||||
else if (line.Equals(DebugMode.DetectedOn.ToString())) result.DebugMode = DebugMode.DetectedOn;
|
||||
else if (line.Equals(DebugMode.Normal.ToString())) result.DebugMode = DebugMode.Normal;
|
||||
else if (line.Equals(DebugMode.AutoDetect.ToString())) result.DebugMode = DebugMode.AutoDetect;
|
||||
else if (line.Equals(DebugMode.FailureDuringOperation.ToString())) result.DebugMode = DebugMode.FailureDuringOperation;
|
||||
else if (line.Equals(DebugMode.Off.ToString())) result.DebugMode = DebugMode.Off;
|
||||
else if (line.Equals(DebugMode.Record.ToString())) result.DebugMode = DebugMode.Record;
|
||||
else if (line.Equals(DebugMode.Replay.ToString())) result.DebugMode = DebugMode.Replay;
|
||||
else if (line.Equals(DebugMode.Simulate.ToString())) result.DebugMode = DebugMode.Simulate;
|
||||
else if (line.Equals(DebugMode.Inherit.ToString())) result.DebugMode = DebugMode.Inherit;
|
||||
if (line.Equals(DebugMode.DetectedOff.ToString())) result.Mode = DebugMode.DetectedOff;
|
||||
else if (line.Equals(DebugMode.DetectedOn.ToString())) result.Mode = DebugMode.DetectedOn;
|
||||
else if (line.Equals(DebugMode.Normal.ToString())) result.Mode = DebugMode.Normal;
|
||||
else if (line.Equals(DebugMode.AutoDetect.ToString())) result.Mode = DebugMode.AutoDetect;
|
||||
else if (line.Equals(DebugMode.FailureDuringOperation.ToString())) result.Mode = DebugMode.FailureDuringOperation;
|
||||
else if (line.Equals(DebugMode.Off.ToString())) result.Mode = DebugMode.Off;
|
||||
else if (line.Equals(DebugMode.Record.ToString())) result.Mode = DebugMode.Record;
|
||||
else if (line.Equals(DebugMode.Reply.ToString())) result.Mode = DebugMode.Reply;
|
||||
else if (line.Equals(DebugMode.Simulate.ToString())) result.Mode = DebugMode.Simulate;
|
||||
else if (line.Equals(DebugMode.Inherit.ToString())) result.Mode = DebugMode.Inherit;
|
||||
|
||||
line = input.ReadLine();
|
||||
if (line.Equals(LogLevel.Off.ToString())) result.LogLevel = LogLevel.Off;
|
||||
else if (line.Equals(LogLevel.Fatal.ToString())) result.LogLevel = LogLevel.Fatal;
|
||||
else if (line.Equals(LogLevel.Error.ToString())) result.LogLevel = LogLevel.Error;
|
||||
else if (line.Equals(LogLevel.Warn.ToString())) result.LogLevel = LogLevel.Warn;
|
||||
else if (line.Equals(LogLevel.Info.ToString())) result.LogLevel = LogLevel.Info;
|
||||
else if (line.Equals(LogLevel.Debug.ToString())) result.LogLevel = LogLevel.Debug;
|
||||
else if (line.Equals(LogLevel.All.ToString())) result.LogLevel = LogLevel.All;
|
||||
if (line.Equals(LogLevel.Off.ToString())) result.Logging = LogLevel.Off;
|
||||
else if (line.Equals(LogLevel.Fatal.ToString())) result.Logging = LogLevel.Fatal;
|
||||
else if (line.Equals(LogLevel.Error.ToString())) result.Logging = LogLevel.Error;
|
||||
else if (line.Equals(LogLevel.Warn.ToString())) result.Logging = LogLevel.Warn;
|
||||
else if (line.Equals(LogLevel.Info.ToString())) result.Logging = LogLevel.Info;
|
||||
else if (line.Equals(LogLevel.Debug.ToString())) result.Logging = LogLevel.Debug;
|
||||
else if (line.Equals(LogLevel.All.ToString())) result.Logging = LogLevel.All;
|
||||
|
||||
result.Parameters = string.Empty;
|
||||
line = input.ReadLine();
|
||||
@@ -119,12 +117,12 @@ namespace Config.Entities
|
||||
result += indent + "ItemNr = " + (ItemNr + 1).ToString() + Environment.NewLine;
|
||||
result += indent + "Name = " + Name + Environment.NewLine;
|
||||
result += indent + "ClassName = " + ClassName + Environment.NewLine;
|
||||
if (Parent != null)
|
||||
if (ParentName != null)
|
||||
{
|
||||
result += indent + "ParentName = " + Parent + Environment.NewLine;
|
||||
result += indent + "ParentName = " + ParentName + Environment.NewLine;
|
||||
}
|
||||
result += indent + "DebugLevel = " + DebugMode.ToString() + Environment.NewLine;
|
||||
result += indent + "LogLevel = " + LogLevel.ToString() + Environment.NewLine;
|
||||
result += indent + "DebugLevel = " + Mode.ToString() + Environment.NewLine;
|
||||
result += indent + "LogLevel = " + Logging.ToString() + Environment.NewLine;
|
||||
result += indent + "Parameters = " + Parameters + Environment.NewLine;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.IO;
|
||||
using Common;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.IO;
|
||||
using Common;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Config.CalendarEvent;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
public class CustomEvent : Config.CalendarEvent.ICalendarEvent
|
||||
{
|
||||
public virtual int Id { get; protected set; }
|
||||
public virtual DateTime Date { get; set; } /// The Date that the event occurs
|
||||
public virtual Frequency Frequency { get; set; } /// A value indicating how often the event occurs
|
||||
public virtual bool AllDay { get; set; } /// True if the time component of the date can be ignored
|
||||
public virtual bool TriggerOnExactDayOnly { get; set; } /// If this is a recurring event, set this to true to make the event show up only from the day specified forward
|
||||
public virtual string Source { get; set; } /// Source of this calendar event (becomes the source of the triggered event)
|
||||
public virtual string Title { get; set; } /// The name of the event (becomes the text of the triggered event)
|
||||
public virtual AutoAction AutoAction { get; set; } /// Automated action to be done or event to be triggered
|
||||
public virtual string Parameters { get; set; } /// Automated action parameters (e.g. name of a procedure to start)
|
||||
public virtual int Rank { get; set; } /// The ranking of the event that determines the order in which it is displayed on a particular day
|
||||
public virtual bool Hidden { get; set; } /// True if the event is enabled, otherwise false
|
||||
public virtual bool ReadOnly { get; set; } /// True if the event details cannot be modified
|
||||
public virtual int BackColor { get; set; } /// The color that the event show up in on the calendar: (MSB)AARRGGBB(LSB)
|
||||
public virtual int TextColor { get; set; } /// The text color of the event: (MSB)AARRGGBB(LSB)
|
||||
public virtual bool TooltipEnabled { get; set; } /// True if a tooltip should be displayed when hovering over the event
|
||||
public virtual CustomRecurringFrequenciesHandler
|
||||
CustomRecurringFunction { get; set; } /// Not mapped to DB, always null
|
||||
|
||||
/// <summary>
|
||||
/// CustomEvent Constructor
|
||||
/// </summary>
|
||||
public CustomEvent()
|
||||
{
|
||||
}
|
||||
|
||||
public CustomEvent(DateTime dateTime, string text)
|
||||
{
|
||||
Date = dateTime;
|
||||
Frequency = Config.CalendarEvent.Frequency.Once;
|
||||
AllDay = false;
|
||||
TriggerOnExactDayOnly = false;
|
||||
Source = "Calendar";
|
||||
Title = text;
|
||||
AutoAction = AutoAction.None;
|
||||
Parameters = string.Empty;
|
||||
Rank = 2;
|
||||
Hidden = false;
|
||||
ReadOnly = false;
|
||||
BackColor = unchecked((int)0xFFFF5050);
|
||||
TextColor = unchecked((int)0xFFFFFFFF);
|
||||
TooltipEnabled = true;
|
||||
CustomRecurringFunction = null;
|
||||
}
|
||||
|
||||
public virtual Config.CalendarEvent.ICalendarEvent Clone()
|
||||
{
|
||||
return new CustomEvent
|
||||
{
|
||||
Date = this.Date,
|
||||
Frequency = this.Frequency,
|
||||
AllDay = this.AllDay,
|
||||
TriggerOnExactDayOnly = this.TriggerOnExactDayOnly,
|
||||
Source = this.Source,
|
||||
Title = this.Title,
|
||||
AutoAction = this.AutoAction,
|
||||
Parameters = this.Parameters,
|
||||
Rank = this.Rank,
|
||||
Hidden = this.Hidden,
|
||||
ReadOnly = this.ReadOnly,
|
||||
BackColor = this.BackColor,
|
||||
TextColor = this.TextColor,
|
||||
TooltipEnabled = this.TooltipEnabled,
|
||||
CustomRecurringFunction = this.CustomRecurringFunction,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when updated
|
||||
/// </summary>
|
||||
/// <param name="currentDate">Current date and time</param>
|
||||
/// <returns>true when the entity was updated</returns>
|
||||
public virtual bool UpdateRecurringDate(DateTime currentDate)
|
||||
{
|
||||
return Config.CalendarEvent.Utils.UpdateRecurringDate(this, currentDate);
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to assign descriptions to enum values
|
||||
/// </summary>
|
||||
public class Description : Attribute
|
||||
{
|
||||
public string Text;
|
||||
public Description(string t)
|
||||
{
|
||||
Text = t;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetDescription
|
||||
{
|
||||
/// Extension method for enum-s
|
||||
public static string ToDescription(this Enum en)
|
||||
{
|
||||
Type type = en.GetType();
|
||||
MemberInfo[] memInfo = type.GetMember(en.ToString());
|
||||
|
||||
if (memInfo != null && memInfo.Length > 0)
|
||||
{
|
||||
object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description), false);
|
||||
if (attrs != null && attrs.Length > 0)
|
||||
return ((Description)attrs[0]).Text;
|
||||
}
|
||||
|
||||
return en.ToString(); /// Return ToString() value in case there is no description
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flags returned by each device configuration control Verify(...) function.
|
||||
/// </summary>
|
||||
public enum CfgUpdateFlags
|
||||
{
|
||||
None = 0,
|
||||
Error = 0x1, /// Some settings in the user control are invalid and cannot be set
|
||||
Warning = 0x02, /// Some settings in the user control are suspicious, can be set after user confirmation
|
||||
RestartRqrd = 0x04, /// TBF program restart is required to apply all changed parameters
|
||||
AnyChange = 0x08, /// At least one parameter have changed
|
||||
VolatileChange = 0x10,
|
||||
InvokeCfgChange = 0x20, /// Invoke CfgChange handler of the component
|
||||
}
|
||||
|
||||
public enum RemoteDBUse
|
||||
{
|
||||
[Description("Local DB only")] LocalDBOnly,
|
||||
[Description("Remote DB only")] RemoteDBOnly,
|
||||
[Description("Both DB-s, local 1st")] BothDBsLocalFirst,
|
||||
[Description("Both DB-s, remote 1st")] BothDBsRemoteFirst,
|
||||
Count,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains a procedure name and a database specification (local/remote).
|
||||
/// </summary>
|
||||
public class ProcedureInfo
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly Users.Entities.DBKind DBKind;
|
||||
|
||||
public ProcedureInfo(string name, Users.Entities.DBKind dbKind)
|
||||
{
|
||||
Name = name;
|
||||
DBKind = dbKind;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ProcedureState
|
||||
{
|
||||
Active,
|
||||
History,
|
||||
Count,
|
||||
}
|
||||
|
||||
/// <summary> Kind of meters for the procedure / test </summary>
|
||||
public enum MetersKind
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Wasserzähler")] Single,
|
||||
[Description("Verbundwasserzähler")] Combined,
|
||||
[Description("Wärmezähler")] HeatMeter,
|
||||
#elif LANG_CS
|
||||
[Description("Vodoměry")] Single,
|
||||
[Description("Kombinované vodoměry")] Combined,
|
||||
[Description("Měřiče tepla")] HeatMeter,
|
||||
#elif LANG_RU
|
||||
[Description("Счетчик")] Single,
|
||||
[Description("Комбинированный счетчик")] Combined,
|
||||
[Description("Счетчик тепла")] HeatMeter,
|
||||
#else
|
||||
[Description("Water meters")] Single,
|
||||
[Description("Compound water meters")] Combined,
|
||||
[Description("Heat meters")] HeatMeter,
|
||||
#endif
|
||||
}
|
||||
|
||||
public enum CompoundMeterId : byte
|
||||
{
|
||||
Single,
|
||||
CompoundMain,
|
||||
CompoundAux,
|
||||
Compound,
|
||||
HeatMeterVolume,
|
||||
HeatMeterEnergy,
|
||||
SingleOrCompound, /// Only used when querying results
|
||||
}
|
||||
|
||||
public enum Medium
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
#if LANG_PL
|
||||
[Description("zimna")] ColdWater,
|
||||
[Description("ciepła")] HotWater,
|
||||
#elif LANG_IT
|
||||
[Description("freddo")] ColdWater,
|
||||
[Description("caldo")] HotWater,
|
||||
#else
|
||||
[Description("cold")] ColdWater,
|
||||
[Description("hot")] HotWater,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Mounting
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
#if LANG_DE
|
||||
[Description("H")] H, /// horizontal
|
||||
[Description("V")] V, /// vertical
|
||||
[Description("STR")] S, /// standrohre
|
||||
[Description("F")] F, /// fall
|
||||
#else
|
||||
[Description("H")] H, /// horizontal
|
||||
[Description("V")] V, /// vertical
|
||||
[Description("S")] S, /// steig
|
||||
[Description("F")] F, /// fall
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum TemperatureClass
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("T30")] T30,
|
||||
[Description("T50")] T50,
|
||||
[Description("T70")] T70,
|
||||
[Description("T90")] T90,
|
||||
[Description("T130")] T130,
|
||||
[Description("T180")] T180,
|
||||
[Description("T30/70")] T30_70,
|
||||
[Description("T30/90")] T30_90,
|
||||
[Description("T30/130")] T30_130,
|
||||
[Description("T30/180")] T30_180,
|
||||
[Description("30")] t30,
|
||||
[Description("50")] t50,
|
||||
[Description("70")] t70,
|
||||
[Description("90")] t90,
|
||||
[Description("130")] t130,
|
||||
[Description("180")] t180,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum FlowProfileSensitivityClass
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("U0")] U0, /// ?
|
||||
[Description("D0")] D0, /// ?
|
||||
Count
|
||||
}
|
||||
|
||||
public enum PressureLossClass
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("dp63")] dp63, /// 0.063 MPa = 0.63 bar, TODO: Change to "Δp63"
|
||||
[Description("dp40")] dp40, /// 0.040 MPa = 0.40 bar
|
||||
[Description("dp25")] dp25, /// 0.025 MPa = 0.25 bar
|
||||
[Description("dp16")] dp16, /// 0.016 MPa = 0.16 bar
|
||||
[Description("dp10")] dp10, /// 0.010 MPa = 0.10 bar
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Maximum Admissible Pressure </summary>
|
||||
public enum MaxAdmissiblePressure
|
||||
{
|
||||
[Description("")] NotSpecified,
|
||||
[Description("MAP6")] MAP6,
|
||||
[Description("MAP10")] MAP10,
|
||||
[Description("MAP16")] MAP16,
|
||||
[Description("MAP25")] MAP25,
|
||||
[Description("MAP40")] MAP40,
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Register reader type </summary>
|
||||
public enum RegisterReaderType
|
||||
{
|
||||
Unknown,
|
||||
Pulses, /// Sick, optical and similar
|
||||
Camera, /// CLP1611
|
||||
DataStream, /// iPerl
|
||||
Manual, /// Entered by human via form (also from camera images)
|
||||
Count
|
||||
}
|
||||
|
||||
/// <summary> Transition step is finished when this condition is fulfilled </summary>
|
||||
public enum StepCondition
|
||||
{
|
||||
None,
|
||||
Scale1Empty,
|
||||
Scale2Empty,
|
||||
Scale3Empty,
|
||||
AllScalesEmpty,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum Publish : sbyte
|
||||
{
|
||||
#if LANG_DE
|
||||
/// german
|
||||
[Description("nie")] Never = 0,
|
||||
[Description("immer")] Always = 1,
|
||||
[Description("Bildschirm")] OnScreen = 2,
|
||||
[Description("intern")] Internal = 3,
|
||||
#elif LANG_CS
|
||||
/// czech
|
||||
[Description("nikdy")] Never = 0,
|
||||
[Description("vždy")] Always = 1,
|
||||
[Description("na obrazovku")] OnScreen = 2,
|
||||
[Description("interně")] Internal = 3,
|
||||
#elif LANG_SK
|
||||
/// slovak
|
||||
[Description("nikdy")] Never = 0,
|
||||
[Description("vždy")] Always = 1,
|
||||
[Description("na obrazovku")] OnScreen = 2,
|
||||
[Description("interne")] Internal = 3,
|
||||
#elif LANG_PL
|
||||
/// polish
|
||||
[Description("nigdy")] Never = 0,
|
||||
[Description("zawsze")] Always = 1,
|
||||
[Description("na ekranie")] OnScreen = 2,
|
||||
[Description("wewnętrznie")] Internal = 3,
|
||||
#elif LANG_RU
|
||||
/// russian
|
||||
[Description("никогда")] Never = 0,
|
||||
[Description("всегда")] Always = 1,
|
||||
[Description("толька экран")] OnScreen = 2,
|
||||
[Description("внутренно")] Internal = 3,
|
||||
#else
|
||||
/// english
|
||||
[Description("Never")] Never = 0,
|
||||
[Description("Always")] Always = 1,
|
||||
[Description("On screen")] OnScreen = 2,
|
||||
[Description("Internal")] Internal = 3,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum MassMethod : byte
|
||||
{
|
||||
#if LANG_DE
|
||||
/// nemecky
|
||||
[Description("Waage")] Scale,
|
||||
[Description("Spanne")] Spread,
|
||||
[Description("Standardabw.")] StdDev,
|
||||
#elif LANG_CS
|
||||
/// cesky
|
||||
[Description("váhou")] Scale,
|
||||
[Description("max.rozdíl")] Spread,
|
||||
[Description("std.dev.")] StdDev,
|
||||
#else
|
||||
[Description("Scale")] Scale,
|
||||
[Description("Spread")] Spread,
|
||||
[Description("Std.dev.")] StdDev,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum TestRedType
|
||||
{
|
||||
Fix,
|
||||
/// etc.
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum FQC1
|
||||
{
|
||||
FQC1,
|
||||
FQP1,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum Progress
|
||||
{
|
||||
JustStarted,
|
||||
TransitionBefore,
|
||||
SwitchingFlowDetection,
|
||||
FlowSetting,
|
||||
Aborted, /// Use as an argument when a test was aborted
|
||||
Test,
|
||||
TransitionAfter,
|
||||
Completed,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum Device
|
||||
{
|
||||
Screen,
|
||||
Printer,
|
||||
Disk,
|
||||
}
|
||||
|
||||
public enum PageOrientation
|
||||
{
|
||||
Portrait,
|
||||
Landscape,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ItemCategory
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Allgemein")] Other,
|
||||
[Description("Prüfstanddaten")] BenchData,
|
||||
[Description("Prüfstandergebnisse")] BenchResult,
|
||||
[Description("Prüfpunktdaten")] TestData,
|
||||
[Description("Prüfpunktergebnisse")] TestResult,
|
||||
[Description("Wasserzelledaten")] MeterData,
|
||||
[Description("Wasserzelleergebnisse")] MeterResult,
|
||||
#else
|
||||
[Description("Other")] Other,
|
||||
[Description("Bench data")] BenchData,
|
||||
[Description("Bench result")] BenchResult,
|
||||
[Description("Test data")] TestData,
|
||||
[Description("Test result")] TestResult,
|
||||
[Description("Meter data")] MeterData,
|
||||
[Description("Meter result")] MeterResult,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
/// <summary> Possible modes of operation of components and devices. </summary>
|
||||
public enum DebugMode
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Erkennen-aus")] DetectedOff = -2,
|
||||
[Description("Erkennen-ein")] DetectedOn = -1,
|
||||
[Description("Normal")] Normal = 0, /// Normal operation
|
||||
[Description("Auto-erkennen")] AutoDetect, /// The component (device) will be auto-detected
|
||||
[Description("Fehler")] FailureDuringOperation, /// Failure during operation -> disabled
|
||||
[Description("Aus")] Off, /// The component is off
|
||||
[Description("Aufzeichnen")] Record,
|
||||
[Description("Reply")] Reply,
|
||||
[Description("Simuliert")] Simulate, /// Test bench simulation, this mode does not require any hardware
|
||||
[Description("Geerbt")] Inherit,
|
||||
#else
|
||||
[Description("Detected off")] DetectedOff = -2,
|
||||
[Description("Detected on")] DetectedOn = -1,
|
||||
[Description("Normal")] Normal = 0, /// Normal operation
|
||||
[Description("Auto detect")] AutoDetect, /// The component (device) will be auto-detected
|
||||
[Description("Run-time error")] FailureDuringOperation, /// Failure during operation -> disabled
|
||||
[Description("Off")] Off, /// The component is off
|
||||
[Description("Record")] Record,
|
||||
[Description("Reply")] Reply,
|
||||
[Description("Simulate")] Simulate, /// Test bench simulation, this mode does not require any hardware
|
||||
[Description("Inherit")] Inherit,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("Aus")] Off,
|
||||
[Description("Schwerwiegend")] Fatal,
|
||||
[Description("Fehler")] Error,
|
||||
[Description("Warnung")] Warn,
|
||||
[Description("Info")] Info,
|
||||
[Description("Debug")] Debug,
|
||||
[Description("Alles")] All,
|
||||
#else
|
||||
[Description("Off")] Off,
|
||||
[Description("Fatal")] Fatal,
|
||||
[Description("Error")] Error,
|
||||
[Description("Warn")] Warn,
|
||||
[Description("Info")] Info,
|
||||
[Description("Debug")] Debug,
|
||||
[Description("All")] All,
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Arrangement of tests </summary>
|
||||
public enum TestsArrangement
|
||||
{
|
||||
Rows,
|
||||
Columns,
|
||||
}
|
||||
|
||||
/// <summary> Arrangement of meters </summary>
|
||||
public enum MetersArrangement
|
||||
{
|
||||
Vertically,
|
||||
Horizontally,
|
||||
}
|
||||
|
||||
public enum Alignment
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("links")] Left,
|
||||
[Description("zentriert")] Center,
|
||||
[Description("rechts")] Right,
|
||||
[Description("angepasst")] Justified,
|
||||
#else
|
||||
[Description("Left")] Left,
|
||||
[Description("Center")] Center,
|
||||
[Description("Right")] Right,
|
||||
[Description("Justified")] Justified,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
|
||||
public enum VertAlignment
|
||||
{
|
||||
[Description("Top")] Top,
|
||||
[Description("Middle")] Middle,
|
||||
[Description("Bottom")] Bottom,
|
||||
}
|
||||
|
||||
public enum TableForm
|
||||
{
|
||||
None,
|
||||
Rows,
|
||||
Columns,
|
||||
ColumnsPL,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ImageRotation
|
||||
{
|
||||
[Description("0 deg")] None,
|
||||
[Description("90 deg")] Deg90,
|
||||
[Description("180 deg")] Deg180,
|
||||
[Description("270 deg")] Deg270,
|
||||
Count
|
||||
}
|
||||
|
||||
public enum CameraDisplayResolution
|
||||
{
|
||||
Small,
|
||||
Medium,
|
||||
Large,
|
||||
// FullScreen,
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ErrorFlagsMode : sbyte
|
||||
{
|
||||
#if LANG_DE
|
||||
[Description("aus")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("ein")] On,
|
||||
#elif LANG_CS
|
||||
[Description("vypnuto")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("zapnuto")] On,
|
||||
#elif LANG_RU
|
||||
[Description("выкл")] Off,
|
||||
[Description("инфо")] Info,
|
||||
[Description("вкл")] On,
|
||||
#elif LANG_PL
|
||||
[Description("nie")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("tak")] On,
|
||||
#else // LANG_EN
|
||||
[Description("off")] Off,
|
||||
[Description("info")] Info,
|
||||
[Description("on")] On,
|
||||
#endif
|
||||
Count
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,26 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
public class FeedingPath : IHasName, IHasItemNr, IHasValves
|
||||
{
|
||||
public virtual int Id { get; protected set; }
|
||||
public virtual int ItemNr { get; set; }
|
||||
public virtual int Id { get; protected set; }
|
||||
public virtual int ItemNr { get; set; }
|
||||
public virtual string Name { get; set; }
|
||||
public virtual string OriName { get; set; } /// Not mapped to database
|
||||
public virtual double Qfrom { get; set; } /// Water flow in [m3/h]
|
||||
public virtual double Qto { get; set; } /// Water flow in [m3/h]
|
||||
public virtual Unit FlowUnit { get; set; } /// Not mapped to database, used in UI
|
||||
public virtual string Selector { get; set; }
|
||||
public virtual float Qfrom { get; set; } /// Water flow in [m3/h]
|
||||
public virtual float Qto { get; set; } /// Water flow in [m3/h]
|
||||
public virtual string Pump { get; set; }
|
||||
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in Category.Feeding in % separated by ';'
|
||||
public virtual string RegulValvesPct { get; set; } /// Positions of regulation valves in % separated by ';'
|
||||
|
||||
/// Valves
|
||||
public virtual string ValvesOpen { get; set; }
|
||||
public virtual string ValvesClose { get; set; }
|
||||
|
||||
public virtual bool QfromTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
|
||||
public virtual bool QtoTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
|
||||
|
||||
/// ------------- Additional stuff not mapped into the database -------------
|
||||
|
||||
public FeedingPath()
|
||||
@@ -46,14 +40,12 @@ namespace Config.Entities
|
||||
{
|
||||
FeedingPath result = new FeedingPath(name, itemNr);
|
||||
|
||||
result.Qfrom = Qfrom;
|
||||
result.Qto = Qto;
|
||||
result.FlowUnit = FlowUnit;
|
||||
result.Selector = Selector;
|
||||
result.Pump = Pump;
|
||||
result.RegVPositions = RegVPositions;
|
||||
result.ValvesOpen = ValvesOpen;
|
||||
result.ValvesClose = ValvesClose;
|
||||
result.Qfrom = Qfrom;
|
||||
result.Qto = Qto;
|
||||
result.Pump = Pump;
|
||||
result.RegulValvesPct = RegulValvesPct;
|
||||
result.ValvesOpen = ValvesOpen;
|
||||
result.ValvesClose = ValvesClose;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,24 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
|
||||
namespace Config.Entities
|
||||
{
|
||||
public class Group
|
||||
{
|
||||
public virtual int Id { get; protected set; }
|
||||
public virtual GID GID { get; set; }
|
||||
public virtual long AccessFlags { get; set; } /// Bitfield of access flags: bit0 .. bit62
|
||||
public virtual IList<User> Users { get; set; } /// Group can be a member of a list of users
|
||||
public virtual int Gid { get; set; }
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
public Group()
|
||||
{
|
||||
Users = new List<User>();
|
||||
}
|
||||
|
||||
public Group(GID gid)
|
||||
: this()
|
||||
{
|
||||
GID = gid;
|
||||
public Group(int gid, string name)
|
||||
{
|
||||
Gid = gid;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Common
|
||||
namespace Config.Entities
|
||||
{
|
||||
public interface IParamsProvider
|
||||
{
|
||||
@@ -31,7 +31,7 @@ namespace Common
|
||||
/// Returns a list of possible values of one parameter (ComboBox when editing) or null (Textbox when editing).
|
||||
/// </summary>
|
||||
/// <param name="ix">Zero based index of the parameter</param>
|
||||
ICollection<string> ParamValues(int ix);
|
||||
IList<string> ParamValues(int ix);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a parameter value in the string form
|
||||
@@ -60,11 +60,7 @@ namespace Common
|
||||
/// <param name="strValue">String representation of the parameter</param>
|
||||
CfgUpdateFlags UpdateParam(int ix, string strValue);
|
||||
|
||||
/// <summary>
|
||||
/// Updates DB entities for related parameters
|
||||
/// </summary>
|
||||
/// <returns>true when successful</returns>
|
||||
bool UpdateEmbeddedDbEntity();
|
||||
void UpdateEmbeddedDbEntity();
|
||||
|
||||
/// <summary>
|
||||
/// Creates an object copy
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user