Update output printer OnePerMeter - 1. printer configuration in PrintResultsSelectionDlg, 2. document preview, 3. edit document name, 4. enable more save destinations

This commit is contained in:
Marek Frniak 2026-03-04 13:21:45 +01:00
parent 8fffb9e366
commit 4bfd5c8e11
9 changed files with 1369 additions and 423 deletions

View File

@ -1,14 +1,18 @@
///
using Common;
using log4net;
using Results.Entities;
using Results.Output.Printers.OnePerMeter;
///
/// Copyright (c) 2017-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.Globalization;
using System.IO;
using System.Threading;
using Results.Entities;
using Results.Output.Printers.OnePerMeter;
using log4net;
using Common;
using System.Windows.Forms;
using TBF.Rig.Output.FileWriters;
namespace TBF.Rig.Output.Printers.OnePerMeter
{
@ -135,27 +139,106 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
printerCfg.ImgWid = newCfg.ImgWid;
printerCfg.ImgHgh = newCfg.ImgHgh;
printerCfg.ImgName = newCfg.ImgName;
printerCfg.DocName = newCfg.DocName;
//printerCfg.DocName = newCfg.DocName;
printerCfg.BarcodeType = newCfg.BarcodeType;
printerCfg.BarcodeLeft = newCfg.BarcodeLeft;
printerCfg.BarcodeTop = newCfg.BarcodeTop;
printerCfg.BarcodeWidth = newCfg.BarcodeWidth;
printerCfg.BarcodeHeight = newCfg.BarcodeHeight;
printerCfg.YearFolders = newCfg.YearFolders;
printerCfg.MonthFolders = newCfg.MonthFolders;
printerCfg.DayFolders = newCfg.DayFolders;
ApplyConfig();
ApplyConfig();
}
}
};
}
#endregion Configuration Change Handling
#endregion Configuration Change Handling
/// <summary>
/// Returns a file name derived from a DateTime structure.
/// Creates directories on this path as a side effect.
/// </summary>
/// <param name="time">Date and time</param>
/// <returns>File name</returns>
string GetFilename(string destinationPath, DateTime time)
{
string directory = destinationPath; /// Ends with "\\";
/// <summary>
/// Prints the test cycle results, Events: Event.ResultsPrinted
/// </summary>
/// <param name="batch">Batch results to print</param>
/// <returns>Reference to the operation</returns>
switch (printerCfg.YearFolders)
{
case YearFolders.FourDigit:
directory = string.Format("{0}{1:yyyy}\\", directory, time);
break;
case YearFolders.TwoDigit:
directory = string.Format("{0}{1:yy}\\", directory, time);
break;
}
switch (printerCfg.MonthFolders)
{
case MonthFolders.Name:
{
string monthStr;
switch (time.Month)
{
default:
case 1: monthStr = "January"; break;
case 2: monthStr = "February"; break;
case 3: monthStr = "March"; break;
case 4: monthStr = "April"; break;
case 5: monthStr = "May"; break;
case 6: monthStr = "June"; break;
case 7: monthStr = "July"; break;
case 8: monthStr = "August"; break;
case 9: monthStr = "September"; break;
case 10: monthStr = "October"; break;
case 11: monthStr = "November"; break;
case 12: monthStr = "December"; break;
}
directory = string.Format("{0}{1}\\", directory, monthStr);
break;
}
case MonthFolders.Digit:
directory = string.Format("{0}{1}\\", directory, time.Month.ToString());
break;
case MonthFolders.TwoDigit:
directory = string.Format("{0}{1:MM}\\", directory, time);
break;
}
switch (printerCfg.DayFolders)
{
case DayFolders.Digit:
directory = string.Format("{0}{1}\\", directory, time.Day.ToString());
break;
case DayFolders.TwoDigit:
directory = string.Format("{0}{1:dd}\\", directory, time);
break;
}
Directory.CreateDirectory(directory);
return directory;
/*try
{
if (string.IsNullOrEmpty(printerCfg.FileNameFormat)) throw new Exception();
return directory + string.Format(printerCfg.FileNameFormat, time);
}
catch
{
return string.Format("{0}{1:yyMMdd-HHmm}.txt", directory, time);
}*/
}
/// <summary>
/// Prints the test cycle results, Events: Event.ResultsPrinted
/// </summary>
/// <param name="batch">Batch results to print</param>
/// <returns>Reference to the operation</returns>
public IOperation ProcessResultsOp(Batch batch)
{
this.batch = batch;
@ -181,15 +264,19 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
string documentName;
try
{
if (string.IsNullOrEmpty(printerCfg.DocName)) throw (new Exception());
documentName = string.Format(printerCfg.DocName, wm.StartTime(), wm.EndTime(), wm.BatchNr(), wm.WMPosition, wm.SerialNr);
if (string.IsNullOrEmpty(printerCfg.FileNameFormat)) throw (new Exception());
documentName = string.Format(printerCfg.FileNameFormat, wm.StartTime(), wm.EndTime(), wm.BatchNr(), wm.WMPosition, wm.SerialNr, wm.BenchId());
}
catch
{
documentName = string.Format("{0}-{1}", batch.BatchNr, wm.WMPosition);
}
PrintResults(batch, wm, documentName);
if (string.IsNullOrEmpty(printerCfg.DestinationPath)) throw (new Exception());
PrintResults(batch, wm, documentName, printerCfg.DestinationPath, "print");
if (!string.IsNullOrEmpty(printerCfg.DestinationPath2))
PrintResults(batch, wm, documentName, printerCfg.DestinationPath2, "print");
}
}
@ -209,8 +296,17 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
{
}
string UpdatePathAndCreateFolderByEndTime(Batch batch, string destination)
{
if (!string.IsNullOrEmpty(destination))
{
return GetFilename(destination, batch.EndTime);
}
void PrintResults(Batch batch, WaterMeter wm, string documentName)
return "";
}
public void PrintResults(Batch batch, WaterMeter wm, string documentName, string destination, string whoCall)
{
OnePerMeterPrinterCfg cfg = new OnePerMeterPrinterCfg {
PageOrientation = printerCfg.PageOrientation,
@ -269,8 +365,177 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
};
var pd = new OnePerMeterPrintDocument(batch, cfg, wm, documentName);
//...MF
string destinationFolder = destination;
//if (!string.IsNullOrEmpty(printerCfg.PrinterName)) pd.PrinterSettings.PrinterName = printerCfg.PrinterName;
//pd.Print();
// If you already have printer name in config, keep this
if (!string.IsNullOrEmpty(printerCfg.PrinterName))
pd.PrinterSettings.PrinterName = printerCfg.PrinterName;
if (IsMicrosoftPdfPrinter(pd.PrinterSettings))
{
// Validate destination folder text
if (string.IsNullOrWhiteSpace(destinationFolder))
{
MessageBox.Show(
"Destination folder for PDF is not set.\n\nPlease select a folder before printing to PDF.",
"PDF destination not set",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
try
{
destinationFolder = UpdatePathAndCreateFolderByEndTime(batch, destinationFolder);
// Ensure destination folder exists (create if missing)
if (!Directory.Exists(destinationFolder))
Directory.CreateDirectory(destinationFolder);
}
catch (Exception ex)
{
MessageBox.Show(
"Failed to create or access the destination folder:\n" +
destinationFolder + "\n\n" +
"Error: " + ex.Message,
"Destination folder error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
// Build full PDF path: Destination\DocumentName.pdf
string fileName = documentName;
if (!fileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
fileName += ".pdf";
printerCfg.DocName = fileName;
if (fileName.Contains(" "))
{
MessageBox.Show(
"The generated PDF file name contains spaces:\n\n" +
fileName + "\n\n" +
"Microsoft Print to PDF may not be able to save the file correctly " +
"when the file name contains spaces.\n" +
"Please remove spaces from the file name.",
"Invalid PDF file name",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
string fullPath = Path.Combine(destinationFolder, fileName);
// Extra validation: path must be absolute and with .pdf extension
if (!Path.IsPathRooted(fullPath))
{
MessageBox.Show(
"The generated PDF file path is not valid:\n" + fullPath,
"Invalid PDF path",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
// Tell printer to print directly to file (no Save dialog)
pd.PrinterSettings.PrintToFile = true;
pd.PrinterSettings.PrintFileName = fullPath;
// Suppress default print status dialog
//pd.PrintController = new StandardPrintController();
try
{
// 1) Show preview
if (whoCall.Equals("preview"))
ShowPreview(batch, cfg, wm, documentName);
else
pd.Print();
}
catch (Exception ex)
{
MessageBox.Show(
"Printing to PDF failed.\n\n" +
"Target file:\n" + fullPath + "\n\n" +
"Error: " + ex.Message,
"PDF printing error - target folder not exists.",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
else
{
// Non-PDF printer normal printing
try
{
// 1) Show preview
if (whoCall.Equals("preview"))
ShowPreview(batch, cfg, wm, documentName);
else
// 2) If you want an extra confirmation before real printing:
if (MessageBox.Show("Print this report to PDF?",
"Confirm printing",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
pd.Print();
}
}
catch (Exception ex)
{
MessageBox.Show(
"Print() failed.\n\nError: " + ex.Message,
"Printing error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
/*var pd = new OnePerMeterPrintDocument(batch, cfg, wm, documentName);
if (!string.IsNullOrEmpty(printerCfg.PrinterName)) pd.PrinterSettings.PrinterName = printerCfg.PrinterName;
pd.Print();
pd.Print();*/
}
}
private bool IsMicrosoftPdfPrinter(PrinterSettings settings)
{
if (settings == null) return false;
// Check if the printer name contains "Microsoft Print to PDF"
return settings.PrinterName.IndexOf("Microsoft Print to PDF",
StringComparison.OrdinalIgnoreCase) >= 0;
}
private void ShowPreview(Results.Entities.Batch batch,
OnePerMeterPrinterCfg cfg,
Results.Entities.WaterMeter wm,
string documentName)
{
using (var pd = new OnePerMeterPrintDocument(batch, cfg, wm, documentName))
using (var preview = new PrintPreviewDialog())
{
preview.Document = pd;
preview.WindowState = FormWindowState.Maximized; // fullscreen preview
preview.ShowIcon = false;
preview.Text = "Preview " + documentName;
preview.ShowDialog(); // user can zoom, scroll, print from toolbar
}
}
private void PrintToPdf(Results.Entities.Batch batch,
OnePerMeterPrinterCfg cfg,
Results.Entities.WaterMeter wm,
string documentName,
string destinationFolder)
{
}
}
}

View File

@ -1,11 +1,12 @@
///
using Common;
using Config.Entities;
///
/// Copyright (c) 2017-2023 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Rig.Output.FileWriters;
namespace TBF.Rig.Output.Printers.OnePerMeter
{
@ -16,9 +17,15 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new PrinterCfgCtrl(); }
///
/// Serialized parameters
///
///
/// Serialized parameters
///
public string DestinationPath; /// Directory path into which the results will be saved
public string DestinationPath2; /// Directory path into which the 2nd copy of results will be saved
public YearFolders YearFolders;
public MonthFolders MonthFolders;
public DayFolders DayFolders;
public string FileNameFormat;
public string PrinterName;
public PageOrientation PageOrientation;
public string Template;
@ -83,8 +90,8 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
[XmlIgnore]
public MetersKind MetersKind;
/// Private parameterless constructor invoked by all other (public) constructors
PrinterCfg()
/// Private parameterless constructor invoked by all other (public) constructors
PrinterCfg()
{
}

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,24 @@
///
using Common;
using Config.Entities;
using log4net;
using NHibernate;
using Renci.SshNet;
using Results.Output.Printers;
///
/// Copyright (c) 2017-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using log4net;
using Common;
using Results.Output.Printers;
using TBF.Resources;
using TBF.Rig.Configs;
using TBF.Rig.Configs.ParamsProvider;
using TBF.Rig.Generic;
using TBF.Rig.Output.FileWriters;
using TBF.UI.Bench.Components;
using TBF.UI.ResultsMI;
namespace TBF.Rig.Output.Printers.OnePerMeter
{
@ -41,12 +50,23 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
string[] belowItems3;
string footer;
public PrinterCfgCtrl()
{
InitializeComponent();
string whoCall = "";
Printer metaPrinter = null;
ComponentParametersDlg pf1 = null;
PrintResultsSelectionDlg pf2 = null;
CfgUpdateFlags flags; /// Or-ed from particular Flags from ComponentParametersDlg
IList<Config.Entities.Component> cmpntEntities;
ISession session;
public PrinterCfgCtrl()
{
InitializeComponent();
Localize();
orientationComboBox.Items.Add(PageOrientation.Portrait.ToString());
flags = CfgUpdateFlags.None;
orientationComboBox.Items.Add(PageOrientation.Portrait.ToString());
orientationComboBox.Items.Add(PageOrientation.Landscape.ToString());
foreach (var ff in System.Drawing.FontFamily.Families)
@ -75,12 +95,34 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
private void PrinterCfgCtrl_Load(object sender, EventArgs e)
{
for (Culture s = 0; s < Culture.Count; s++) cultureComboBox.Items.Add(s.ToString());
pf1 = (ComponentParametersDlg)ParentForm;
pf2 = pf1.SharedButtonsParentForm as PrintResultsSelectionDlg;
if (pf2 != null)
{
metaPrinter = new Printer(config);
whoCall = "preview";
generateDocNameButton.Enabled = true;
previewButton.Enabled = true;
documentNameLabel.Enabled = true;
documentNameTextBox.Enabled = true;
saveComponentButton.Enabled = true;
generateDocumentName();
}
for (Culture s = 0; s < Culture.Count; s++) cultureComboBox.Items.Add(s.ToString());
printerComboBox.Items.Add(Strings.default_printer);
foreach (var p in PrinterSettings.InstalledPrinters) printerComboBox.Items.Add(p);
header = config.Header;
for (YearFolders s = 0; s < YearFolders.Count; s++) yearFoldersComboBox.Items.Add(s.ToString());
for (MonthFolders s = 0; s < MonthFolders.Count; s++) monthFoldersComboBox.Items.Add(s.ToString());
for (DayFolders s = 0; s < DayFolders.Count; s++) dayFoldersComboBox.Items.Add(s.ToString());
for (Culture s = 0; s < Culture.Count; s++) cultureComboBox.Items.Add(s.ToString());
header = config.Header;
commonItems1 = config.CommonItems1;
commonItems2 = config.CommonItems2;
commonItems3 = config.CommonItems3;
@ -91,14 +133,25 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
belowItems3 = config.BelowItems3;
footer = config.Footer;
Redraw();
session = TBF.DB.CreateSession(DBKind.Config);
cmpntEntities = session.QueryOver<Component>()
.OrderBy(x => x.ItemNr).Asc
.List<Component>();
Redraw();
}
void Localize()
{
nameLabel.Text = Strings.Name;
destinationLabel.Text = "Destination";
destination2Label.Text = "Destination" + " 2";
yearFoldersLabel.Text = "Year folders";
monthFoldersLabel.Text = "Month folders";
dayFoldersLabel.Text = "Day folders";
fileNameFmtLabel.Text = "File name format";
templateLabel.Text = "Template";
cultureLabel.Text = "Culture";
cultureLabel.Text = "Culture";
headerButton.Text = Strings.Header;
footerButton.Text = Strings.Footer;
}
@ -109,8 +162,16 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
nameTextBox.Text = config.Name;
if (config == null) return; /// Control was not loaded, settings were not changed
metaPrinter = new Printer(config);
nameTextBox.Text = config.Name;
destinationTextBox.Text = config.DestinationPath;
destination2TextBox.Text = config.DestinationPath2;
yearFoldersComboBox.Text = config.YearFolders.ToString();
monthFoldersComboBox.Text = config.MonthFolders.ToString();
dayFoldersComboBox.Text = config.DayFolders.ToString();
fileNameFmtTextBox.Text = config.FileNameFormat;
//documentNameTextBox.Text = config.DocName;
printerComboBox.Text = string.IsNullOrEmpty(config.PrinterName) ? Strings.default_printer : config.PrinterName;
templateTextBox.Text = config.Template;
orientationComboBox.Text = config.PageOrientation.ToString();
@ -161,7 +222,7 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
imageWidthTextBox.Text = config.ImgWid.ToString();
imageHeightTextBox.Text = config.ImgHgh.ToString();
imageNameTextBox.Text = config.ImgName;
docNameTextBox.Text = config.DocName;
//docNameTextBox.Text = config.DocName;
tableFormComboBox.Text = config.Form.ToString();
tableAlignmentComboBox.Text = config.Alignment.ToDescription();
@ -176,6 +237,15 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
public void Unlock()
{
nameTextBox.Enabled = true;
destinationTextBox.Enabled = true;
destinationButton.Enabled = true;
destination2TextBox.Enabled = true;
destination2Button.Enabled = true;
yearFoldersComboBox.Enabled = true;
monthFoldersComboBox.Enabled = true;
dayFoldersComboBox.Enabled = true;
fileNameFmtTextBox.Enabled = true;
posibleParams1ComboBox.Enabled = true;
printerComboBox.Enabled = true;
selectPrinterButton.Enabled = true;
templateTextBox.Enabled = true;
@ -229,7 +299,6 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
imageWidthTextBox.Enabled = true;
imageHeightTextBox.Enabled = true;
imageNameTextBox.Enabled = true;
docNameTextBox.Enabled = true;
barcodeTypeComboBox.Enabled = true;
barcodeLeftTextBox.Enabled = true;
barcodeTopTextBox.Enabled = true;
@ -241,7 +310,25 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if ((int)GetOrientation(orientationComboBox.Text) < 0)
if (!yearFoldersComboBox.Items.Contains(yearFoldersComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid year folders selection";
}
if (!monthFoldersComboBox.Items.Contains(monthFoldersComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid month folders selection";
}
if (!dayFoldersComboBox.Items.Contains(dayFoldersComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid day folder selection";
}
if ((int)GetOrientation(orientationComboBox.Text) < 0)
{
message += Environment.NewLine + "Invalid 'Page orientation'";
flags |= CfgUpdateFlags.Error;
@ -438,6 +525,56 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
flags |= CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange;
}
if (config.DestinationPath != destinationTextBox.Text)
{
config.DestinationPath = destinationTextBox.Text;
if (!config.DestinationPath.EndsWith("\\")) config.DestinationPath += "\\";
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
}
if (config.DestinationPath2 != destination2TextBox.Text)
{
config.DestinationPath2 = destination2TextBox.Text;
if (!config.DestinationPath2.EndsWith("\\")) config.DestinationPath2 += "\\";
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
}
for (YearFolders i = 0; i < YearFolders.Count; i++)
{
if (i.ToString().Equals(yearFoldersComboBox.Text) && (config.YearFolders != i))
{
config.YearFolders = i;
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
break;
}
}
for (MonthFolders i = 0; i < MonthFolders.Count; i++)
{
if (i.ToString().Equals(monthFoldersComboBox.Text) && (config.MonthFolders != i))
{
config.MonthFolders = i;
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
break;
}
}
for (DayFolders i = 0; i < DayFolders.Count; i++)
{
if (i.ToString().Equals(dayFoldersComboBox.Text) && (config.DayFolders != i))
{
config.DayFolders = i;
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
break;
}
}
if (config.FileNameFormat != fileNameFmtTextBox.Text)
{
config.FileNameFormat = fileNameFmtTextBox.Text;
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
}
string newPrinter = (printerComboBox.Text == Strings.default_printer) ? string.Empty : printerComboBox.Text;
if (config.PrinterName != newPrinter)
{
@ -545,7 +682,7 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
flags |= UpdateDifferent(ref config.ImgHgh, imageHeightTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
flags |= UpdateDifferent(ref config.ImgName, imageNameTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
flags |= UpdateDifferent(ref config.DocName, docNameTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
//flags |= UpdateDifferent(ref config.DocName, docNameTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
for (BarcodeType bt = BarcodeType.None; bt < BarcodeType.Count; bt++)
{
@ -567,9 +704,9 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
}
return flags;
}
}
private void headerButton_Click(object sender, EventArgs e)
private void headerButton_Click(object sender, EventArgs e)
{
HeaderFooterDlg dlg = new HeaderFooterDlg(true, string.IsNullOrEmpty(header) ? string.Empty : header.Replace("~", Environment.NewLine));
if (dlg.ShowDialog() == DialogResult.OK)
@ -724,5 +861,297 @@ namespace TBF.Rig.Output.Printers.OnePerMeter
printerComboBox.Text = dlg.PrinterSettings.PrinterName;
}
}
}
private void destinationButton_Click(object sender, EventArgs e)
{
using (var dlg = new FolderBrowserDialog())
{
dlg.Description = "Select destination folder";
dlg.ShowNewFolderButton = true;
// predfill existing folder if valid
if (System.IO.Directory.Exists(destinationTextBox.Text))
dlg.SelectedPath = destinationTextBox.Text;
if (dlg.ShowDialog() == DialogResult.OK)
destinationTextBox.Text = dlg.SelectedPath;
}
}
private void destination2Button_Click(object sender, EventArgs e)
{
using (var dlg = new FolderBrowserDialog())
{
dlg.Description = "Select destination folder";
dlg.ShowNewFolderButton = true;
// predfill existing folder if valid
if (System.IO.Directory.Exists(destination2TextBox.Text))
dlg.SelectedPath = destination2TextBox.Text;
if (dlg.ShowDialog() == DialogResult.OK)
destination2TextBox.Text = dlg.SelectedPath;
}
}
private void posibleParams1ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// Read the selected item text from the ComboBox
// Example: "{0} = start time" or ":ss = seconds"
string selected = posibleParams1ComboBox.Text;
// Find the position of '=' which separates the token from the description
int eqIndex = selected.IndexOf('=');
// Continue only if '=' exists in the string
if (eqIndex > 0)
{
// Extract the token part before '='
// Examples:
// "{0} = start time" -> "{0}"
// ":ss = seconds" -> ":ss"
string token = selected.Substring(0, eqIndex).Trim();
// Get the current caret position in the TextBox
int pos = fileNameFmtTextBox.SelectionStart;
// Insert the token at the caret position
fileNameFmtTextBox.Text =
fileNameFmtTextBox.Text.Insert(pos, token);
// Move caret to the end of the inserted token
fileNameFmtTextBox.SelectionStart = pos + token.Length;
}
}
private void previewButton_Click(object sender, EventArgs e)
{
var errors = new List<string>();
// Basic null / state checks
if (metaPrinter == null)
errors.Add("Printer object is not initialized.");
if (pf2 == null)
errors.Add("Preview data (pf2) are not available.");
if (pf2?.batch == null)
errors.Add("Batch data are not available.");
if (pf2?.batch?.WaterMeters == null || pf2.batch.WaterMeters.Count == 0)
errors.Add("There is no water meter in the selected batch.");
string documentName = documentNameTextBox.Text;
if (string.IsNullOrWhiteSpace(documentName))
errors.Add("Document name is not set.");
string destinationFolder = destinationTextBox.Text;
if (string.IsNullOrWhiteSpace(destinationFolder))
errors.Add("Destination folder is not set.");
// If there are any collected errors, show them in a single dialog
if (errors.Count > 0)
{
string message = "Preview cannot be started due to the following issues:\n\n" +
string.Join("\n", errors);
MessageBox.Show(
message,
"Preview error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
try
{
var wm = pf2.batch.WaterMeters[0];
metaPrinter.PrintResults(
pf2.batch,
wm,
documentName,
destinationFolder,
whoCall);
}
catch (Exception ex)
{
MessageBox.Show(
"Preview failed.\n\nError: " + ex.Message,
"Preview error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
/*private void fileNameFmtTextBox_TextChanged(object sender, EventArgs e)
{
if (whoCall == "preview")
{
generateDocumentName();
}
}*/
private void fileNameFmtTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (whoCall == "preview")
{
generateDocumentName();
}
// prevent "ding" sound when pressing Enter in TextBox
e.Handled = true;
e.SuppressKeyPress = true;
}
}
private void generateDocumentName()
{
var errors = new List<string>();
// Basic null checks
if (pf2 == null)
errors.Add("Preview data (pf2) are not available.");
if (pf2?.batch == null)
errors.Add("Batch data are not available.");
if (pf2?.batch?.WaterMeters == null || pf2.batch.WaterMeters.Count == 0)
errors.Add("There is no water meter in the selected batch.");
string format = fileNameFmtTextBox.Text;
if (string.IsNullOrWhiteSpace(format))
errors.Add("File name format is empty.");
// If we collected any errors, show them in a single dialog
if (errors.Count > 0)
{
string message = "Document name cannot be generated due to the following issues:\n\n" +
string.Join("\n", errors);
MessageBox.Show(
message,
"File name format error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
try
{
var wm = pf2.batch.WaterMeters[0];
documentNameTextBox.Text = string.Format(
format,
wm.StartTime(),
wm.EndTime(),
wm.BatchNr(),
wm.WMPosition,
wm.SerialNr,
wm.BenchId());
}
catch (FormatException ex)
{
MessageBox.Show(
"The file name format is not valid.\n\n" +
"Please check placeholders and format codes.\n\n" +
"Error: " + ex.Message,
"File name format error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(
"Failed to generate document name.\n\n" +
"Error: " + ex.Message,
"Document name error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void generateDocNameButton_Click(object sender, EventArgs e)
{
if (whoCall == "preview")
{
generateDocumentName();
}
}
private void saveComponentButton_Click(object sender, EventArgs e)
{
string message = string.Empty;
CfgUpdateFlags flags = VerifyCfg(ref message);
flags |= UpdateCfg();
if ((flags & CfgUpdateFlags.RestartRqrd) == CfgUpdateFlags.RestartRqrd)
{
MessageBox.Show(Strings.Program_restart_is_required_to_apply_some_settings,
Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
//ComponentCfgCtrl.Closing();
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
{
foreach (var cmpnt in cmpntEntities)
{
if (cmpnt.Name == config.Name)
{
string xml;
using (var sw = new StringWriter())
{
config.GetSerializer().Serialize(sw, config);
xml = sw.ToString();
}
cmpnt.Parameters = xml;
}
}
if (SaveDBChanges(session))
flags = CfgUpdateFlags.None; /// Changes saved
else
flags = CfgUpdateFlags.Error;
}
if ((flags & CfgUpdateFlags.Error) == CfgUpdateFlags.Error)
{
MessageBox.Show(Strings.Please_change_the_following_settings + message,
Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
///
/// Save DB changes, return true when DB changes saved OK
///
bool SaveDBChanges(ISession session)
{
using (ITransaction transaction = session.BeginTransaction())
{
try
{
foreach (var cmpnt in cmpntEntities)
{
if(cmpnt.Name == config.Name)
session.SaveOrUpdate(cmpnt);
}
transaction.Commit();
session.Flush();
return true;
}
catch (Exception exc)
{
transaction.Rollback();
log.ErrorFormat("Exception when saving components : {1}", exc.Message);
return false;
}
}
}
}
}

View File

@ -1456,7 +1456,9 @@
<Compile Include="Rig\Scales\MettlerToledo\Factory.cs" />
<Compile Include="Rig\Scales\MettlerToledo\GetSerNumOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\ReadStableMassOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\SerialPortDevice.cs" />
<Compile Include="Rig\Scales\MettlerToledo\SerialPortDevice.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Rig\Scales\MettlerToledo\SerialPortDeviceFake.cs" />
<Compile Include="Rig\Scales\MettlerToledo\SetUnitsOp.cs" />
<Compile Include="Rig\Scales\MettlerToledo\TaringOp.cs" />

View File

@ -1,39 +1,47 @@
///
using Common;
using NHibernate;
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Common;
using TBF.Resources;
using TBF.Rig;
using TBF.Rig.Generic;
using TBF.Resources;
using TBF.UI.Shared;
namespace TBF.UI.Bench.Components
{
public partial class ComponentParametersDlg : Form
{
public IComponentCfgCtrl ComponentCfgCtrl;
public partial class ComponentParametersDlg : Form
{
public IComponentCfgCtrl ComponentCfgCtrl;
const int ComponentCfgCtrlHeight = 350;
const int ComponentCfgCtrlMoreHeight = 250;
public Form SharedButtonsParentForm
{
get { return sharedButtons.ParentForm; }//...MF
}
public IComponentCfg Config
{
get
{
if (ComponentCfgCtrl == null) return null;
return ComponentCfgCtrl.Config;
}
}
public IComponentCfg Config
{
get
{
if (ComponentCfgCtrl == null) return null;
return ComponentCfgCtrl.Config;
}
}
public CfgUpdateFlags Flags;
public CfgUpdateFlags Flags;
public bool UnlockAfterStart;
/// <summary>
/// List of components (=component configuration instances)
/// </summary>
public IList<Config.Entities.Component> CmpntEntities;
/// <summary>
/// List of components (=component configuration instances)
/// </summary>
public IList<Config.Entities.Component> CmpntEntities;
public ISession Session;
int cmpntEntityId;
@ -48,7 +56,7 @@ namespace TBF.UI.Bench.Components
/// <param name="cmpntEntityId">Config.Entities.Component.Id or 0 when this is a new/copied/immported component</param>
public ComponentParametersDlg(Form parentForm, int cmpntEntityId = 0)
: this()
{
{
this.cmpntEntityId = cmpntEntityId;
/// SharedDlgButtons configuration
@ -62,20 +70,24 @@ namespace TBF.UI.Bench.Components
sharedButtons.MoreClicked += moreButton_Click;
Flags = CfgUpdateFlags.None;
}
}
private void ComponentCfgForm_Load(object sender, EventArgs e)
{
Text = Strings.Properties;
private void ComponentCfgForm_Load(object sender, EventArgs e)
{
Text = Strings.Properties;
if (ComponentCfgCtrl != null)
{
splitContainer.Panel1.Controls.Add((UserControl)ComponentCfgCtrl);
if (ComponentCfgCtrl != null)
{
var ctrl = (UserControl)ComponentCfgCtrl;
ctrl.Dock = DockStyle.Fill;
splitContainer.Panel1.Controls.Add(ctrl);
// autoresize dialog based on this control
ResizeToFitControl(ctrl);
if (ComponentCfgCtrl.ShowMore)
{
sharedButtons.OptionalButtons = SharedButtons.Buttons.More;
}
if (UnlockAfterStart)
{
@ -89,30 +101,30 @@ namespace TBF.UI.Bench.Components
/// Handler of the Unlock button click
/// </summary>
private void Unlock(object sender, EventArgs e)
{
ComponentCfgCtrl.Unlock();
}
{
ComponentCfgCtrl.Unlock();
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
if (ComponentCfgCtrl == null) return CfgUpdateFlags.None; /// Nothing to verify -> OK
public CfgUpdateFlags VerifyCfg(ref string message)
{
if (ComponentCfgCtrl == null) return CfgUpdateFlags.None; /// Nothing to verify -> OK
return ComponentCfgCtrl.VerifyCfg(ref message);
}
}
private void okButton_Click(object sender, EventArgs e)
{
string message = string.Empty;
CfgUpdateFlags flags = VerifyCfg(ref message);
if ((flags & CfgUpdateFlags.Error) == CfgUpdateFlags.Error)
{
MessageBox.Show(Strings.Please_change_the_following_settings + message,
Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
private void okButton_Click(object sender, EventArgs e)
{
string message = string.Empty;
CfgUpdateFlags flags = VerifyCfg(ref message);
if ((flags & CfgUpdateFlags.Error) == CfgUpdateFlags.Error)
{
MessageBox.Show(Strings.Please_change_the_following_settings + message,
Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (ComponentCfgCtrl != null)
{
flags = ComponentCfgCtrl.UpdateCfg();
if (ComponentCfgCtrl != null)
{
flags = ComponentCfgCtrl.UpdateCfg();
/// Prevent component name duplicity
if (CmpntEntities != null)
@ -127,41 +139,60 @@ namespace TBF.UI.Bench.Components
}
}
if ((flags & CfgUpdateFlags.RestartRqrd) == CfgUpdateFlags.RestartRqrd)
{
MessageBox.Show(Strings.Program_restart_is_required_to_apply_some_settings,
Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
ComponentCfgCtrl.Closing();
}
if ((flags & CfgUpdateFlags.RestartRqrd) == CfgUpdateFlags.RestartRqrd)
{
MessageBox.Show(Strings.Program_restart_is_required_to_apply_some_settings,
Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
ComponentCfgCtrl.Closing();
}
Flags = flags;
DialogResult = DialogResult.OK;
Close();
return;
}
Flags = flags;
DialogResult = DialogResult.OK;
Close();
return;
}
private void cancelButton_Click(object sender, EventArgs e)
{
if (ComponentCfgCtrl != null) ComponentCfgCtrl.Closing();
DialogResult = DialogResult.Cancel;
Close();
return;
}
private void cancelButton_Click(object sender, EventArgs e)
{
if (ComponentCfgCtrl != null) ComponentCfgCtrl.Closing();
DialogResult = DialogResult.Cancel;
Close();
return;
}
private void moreButton_Click(object sender, EventArgs e)
{
ComponentCfgCtrl.Unlock();
private void moreButton_Click(object sender, EventArgs e)
{
ComponentCfgCtrl.Unlock();
if (sharedButtons.MoreActive)
{
if (sharedButtons.MoreActive)
{
Height = Height + ComponentCfgCtrlMoreHeight;
}
else
{
}
else
{
Height = Height - ComponentCfgCtrlMoreHeight;
}
return;
}
}
}
return;
}
private void ResizeToFitControl(UserControl cfgCtrl)
{
if (cfgCtrl == null) return;
// Ask the control for its preferred size
Size desired = cfgCtrl.PreferredSize;
// Extra space for right panel + form borders
int extraWidth = splitContainer.Panel2.Width + 40;
int extraHeight = 80;
this.Width = desired.Width + extraWidth;
this.Height = desired.Height + extraHeight;
// Do not exceed screen working area
var screen = Screen.FromControl(this).WorkingArea;
if (this.Width > screen.Width) this.Width = screen.Width - 20;
if (this.Height > screen.Height) this.Height = screen.Height - 20;
}
}
}

View File

@ -221,16 +221,29 @@ namespace TBF.UI.ResultsMI
/// <summary>
/// Called from PreviousResultCtrl when 'Print' button pressed.
/// </summary>
public void OnPrint(object sender, PreviousResultIdEventArgs data)
public void OnPrint(object sender, PreviousResultIdEventArgs data) //...MF
{
if (PrintHandler == null) return;
if (PrintHandler == null)
return;
try
{
PrintHandler(sender, data);
}
catch (Exception e)
{
// Log to file / internal logger
log.Error("PrintHandler(...) failed", e);
// Show message box to user
MessageBox.Show(
"Printing failed.\n\n" +
"Error: " + e.Message +
"\n\nCheck printer settings or try again.",
"Printing error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
}
@ -245,7 +258,7 @@ namespace TBF.UI.ResultsMI
{
if (c is IResultsPrinter) printers.Add(c as IResultsPrinter);
}
var dlg = new PrintResultsSelectionDlg(printers);
var dlg = new PrintResultsSelectionDlg(printers, b);
if (dlg.ShowDialog() != DialogResult.OK) return;
TBF.Rig.IOperation printResultsOp = dlg.SelectedPrinter.ProcessResultsOp(b);

View File

@ -32,6 +32,7 @@
this.printerLabel = new System.Windows.Forms.Label();
this.okButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.editPrinterButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// printersComboBox
@ -73,11 +74,23 @@
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
//
// editPrinterButton
//
this.editPrinterButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.editPrinterButton.Location = new System.Drawing.Point(121, 68);
this.editPrinterButton.Name = "editPrinterButton";
this.editPrinterButton.Size = new System.Drawing.Size(92, 40);
this.editPrinterButton.TabIndex = 6;
this.editPrinterButton.Text = "Edit printer";
this.editPrinterButton.UseVisualStyleBackColor = true;
this.editPrinterButton.Click += new System.EventHandler(this.editPrinterButton_Click);
//
// PrintResultsSelectionDlg
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(546, 127);
this.Controls.Add(this.editPrinterButton);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.okButton);
this.Controls.Add(this.printerLabel);
@ -96,5 +109,6 @@
private System.Windows.Forms.Label printerLabel;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.Button editPrinterButton;
}
}

View File

@ -1,12 +1,18 @@
///
/// Copyright (c) 2023 Sensus Slovensko a.s.
///
using Common;
using NHibernate;
using Results.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using TBF.Resources;
using TBF.Rig.Generic;
using TBF.Rig.GenericDevices;
using TBF.UI.Bench.Components;
using Config.Entities;
namespace TBF.UI.ResultsMI
{
@ -14,10 +20,12 @@ namespace TBF.UI.ResultsMI
{
readonly IList<IResultsPrinter> printers;
public IResultsPrinter SelectedPrinter;
public Batch batch;
public PrintResultsSelectionDlg(IList<IResultsPrinter> printers)
public PrintResultsSelectionDlg(IList<IResultsPrinter> printers, Batch batch)//...MF
{
this.printers = printers;
this.batch = batch;
InitializeComponent();
@ -58,5 +66,19 @@ namespace TBF.UI.ResultsMI
DialogResult = DialogResult.Cancel;
Close();
}
private void editPrinterButton_Click(object sender, EventArgs e)//...MF
{
if (printers != null)
foreach (var p in printers)
if (p.Cfg.Name == printersComboBox.Text)
{
ComponentParametersDlg printerCfgForm = new ComponentParametersDlg(this, p.Cfg.Id);
printerCfgForm.ComponentCfgCtrl = p.Cfg.GetControl(null);
printerCfgForm.ComponentCfgCtrl.Config = p.Cfg;
DialogResult dr = printerCfgForm.ShowDialog();
if (dr != DialogResult.OK) return;
}
}
}
}