using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel.Design;
using System.ComponentModel;
using static WPFUI.PTAccess;
using System.Windows.Threading;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace WPFUI
{
///
/// Interaction logic for MainWindow.xaml
///
///
public enum SpecialFeatures
{
None,
Color,
Highlight
}
public class DoubleRangeRule : ValidationRule
{
public double Min { get; set; }
public double Max { get; set; }
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
double parameter = 0;
try
{
if (((string)value).Length > 0)
{
parameter = Double.Parse((String)value);
}
}
catch (Exception e)
{
MessageBox.Show("Illegal characters or " + e.Message, "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return new ValidationResult(false, "Illegal characters or " + e.Message);
}
if ((parameter < this.Min) || (parameter > this.Max))
{
MessageBox.Show("Invalid Dice Threshold. Enter a number between " + this.Min +" and "+ this.Max, "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return new ValidationResult(false,
"Please enter value in the range: "
+ this.Min + " - " + this.Max + ".");
}
return new ValidationResult(true, null);
}
}
public partial class MainWindow : Window, INotifyPropertyChanged
{
private double diceThreshold = 0.33;
public double DiceThreshold
{
get { return diceThreshold; }
set { diceThreshold = value; OnPropertyChanged("DiceThreshold"); }
}
public static char[] charsToTrim = { '*', ' ', '\'' };
public static string PatientName { get; set; } = string.Empty;
public static List trials { get; set; } = new List();
public static List structures { get; set; } = new List();
public static List ctName { get; set; } = new List();
public static List strucSetNames { get; set; } = new List();
// public static List strucNames { get; set; } = new List();
public static int CTindex { get; set; } = new int();
public static int StrSetIndex { get; set; } = new int();
const double DiceThresholdDefault = 0.33;
public List InitList(int count, T initValue)
{
return Enumerable.Repeat(initValue, count).ToList();
}
public class VelocityStructure
{
public int Num { get; set; } = new int();
public string Name { get; set; } = "";
}
public static List strucNames { get; set; } = new List();
public class VelocityDB
{
public string MyVelocityDB { get; set; } = System.String.Empty;
// public string IPadddress { get; set; } = string.Empty;
// public int Port { get; set; } = new int();
public string User { get; set; } = string.Empty;
public string Passwd { get; set; } = string.Empty;
}
public List velocityDB { get; set; } = new()
{
new VelocityDB { User = "codey", Passwd = "Rttqa123", MyVelocityDB = "RTTQA-2" },
new VelocityDB { User = "codey", Passwd = "Rttqa123", MyVelocityDB = "VMS_RESEARCH" },
new VelocityDB { User = "codey", Passwd = "Rttqa123", MyVelocityDB = "RTTQA-1" },
new VelocityDB { User = "codey", Passwd = "Rttqa123", MyVelocityDB = "RTTQA-3" }
};
public class EditableStructures : INotifyPropertyChanged
{
public string StrName { get; set; }
public bool IsAccepted { get; set; }
public int NamInd { get; set; }
private SpecialFeatures _specialFeatures;
public SpecialFeatures SpecialFeatures
{
get { return _specialFeatures; }
set
{
_specialFeatures = value;
OnPropertyChanged("SpecialFeatures");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
public ObservableCollection AutoNames { get; set; }
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
private void UpdateTrials()
{
TrialDB.ItemsSource = trials;
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
AutoNames = new ObservableCollection();
DBAccess db = new DBAccess();
trials = db.GetTrials(); // LOAD AND DISPLAY PROTOCOL TRIAL NAMEs
if (trials.Count <= 0)
{
MessageBox.Show("No trial foud in DataBase", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
UpdateTrials();
PTAccess pt = new PTAccess();
pt.InitializeVelocity();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void emptyProtocolListbox()
{
ProtocolStructures.ItemsSource = null;
ProtocolStructures.Items.Clear();
ProtocolStructures.Items.Refresh();
}
private void emptyCTnamesListbox()
{
PTAccess pt = new PTAccess();
CTnames.ItemsSource = null;
CTnames.Items.Clear();
CTnames.Items.Refresh();
StructSets.ItemsSource = null;
StructSets.Items.Clear();
StructSets.Items.Refresh();
pt.ResetVelocityContext();
}
private void emptyStructSetsListbox()
{
StructSets.ItemsSource = null;
StructSets.Items.Clear();
StructSets.Items.Refresh();
}
private void emptyVelStructuresListbox()
{
VelStructures.ItemsSource= null;
VelStructures.Items.Clear();
VelStructures.Items.Refresh();
}
private void emptyEditableStructsListBox()
{
AutoNames.Clear();
EditableStructs.ItemsSource = null;
EditableStructs.Items.Clear();
EditableStructs.Items.Refresh();
}
private void UpdateProtocol()
{
ProtocolStructures.ItemsSource = (System.Collections.IEnumerable)structures;
}
private void UpdateCT()
{
CTnames.ItemsSource = (System.Collections.IEnumerable)ctName;
CTnames.Items.Refresh();
}
private void UpdateStructSet()
{
StructSets.ItemsSource = (System.Collections.IEnumerable)strucSetNames;
}
public void UpdateVelStructures()
{
VelStructures.ItemsSource = (System.Collections.IEnumerable)strucNames;
VelStructures.Items.Refresh();
}
public void UpdateAutoStrucNames()
{
EditableStructs.ItemsSource = (System.Collections.IEnumerable)AutoNames;
}
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------- LOAD AND DISPLAY PROTOCOL TRIAL NAMEs ----------------------------------------------------------------------------*/
private void TrialDB_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DBAccess db = new DBAccess();
int TrialDBind = TrialDB.SelectedIndex;
string trialNam = TrialDB.SelectedItem.ToString();
if (String.IsNullOrEmpty(trialNam))
{
MessageBox.Show("No Trial has been selected", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
structures = db.GetStructures(trialNam);
UpdateProtocol();
emptyEditableStructsListBox();
}
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------- TRIAL-NAME-ERASED EVENT HANDLER -------------------------------------------------------------------------------------*/
private void Trial_TextChanged(object sender, TextChangedEventArgs e)
{
PTAccess pt = new PTAccess();
emptyProtocolListbox();
structures.Clear();
EditableStructs.ItemsSource = null;
EditableStructs.Items.Clear();
EditableStructs.Items.Refresh();
pt.RenamedStructNames.Clear();
}
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------- TRIAL-NAME-CHANGED EVENT HANDLER ----------------------------------------------------------------------------*/
/* private void Trial_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
DBAccess db = new DBAccess();
structures = db.GetStructures(Trial.Text);
UpdateProtocol();
} */
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------- LOAD PATIENT AND DISPLAY PATIENT CT VOLUMEs -----------------------------------------------------------------*/
private void PatientScan_Click(object sender, RoutedEventArgs e)
{
// if (CTnames.SelectedIndex == -1)
// return;
string content = Patient.Text; // CHECK IF PATIENT NAME HAS CHANGED
content = content.Trim(charsToTrim); // TRIM HEADING AND TRAILING SPACES
if(String.IsNullOrEmpty(content))
{
MessageBox.Show("Patient has to be loaded before loading any CT !.", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (content.Equals(PatientName))
return;
PatientName = content;
int Res = 0;
PTAccess pt = new PTAccess();
ctName = pt.GetCTVol(PatientName, ref Res); // GET PATIENT CT VOLUMES
if(Res == -1) // PATIENT NOT LOADED
{
Patient.Clear();
PatientName = System.String.Empty;
Patient.Text = " ";
}
if (ctName == null)
{
MessageBox.Show("Cannot find any CT for current patient Make another choice!.", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
}
UpdateCT();
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------- PATIENT-TEXT-CHANGE HANDLER --------------------------------------------------------------------------------------------*/
/*------------------------------- Wipe out the CTs list, the Structure-Sets list, the Velocity-Strutures list, the Editabe-Structures list ------------------------------------*/
/* */
private void Patient_TextChanged(object sender, TextChangedEventArgs e)
{
emptyCTnamesListbox();
emptyStructSetsListbox();
emptyVelStructuresListbox();
emptyEditableStructsListBox();
return;
}
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------- CT-NAME SELECTION EVENT HANDLER ----------------------------------------------------------------------------------------*/
/*---------------- Load and display the Structure-sets of the selected CT volume -----------------------------------------------------------------------------------------------*/
/* */
private void CTnames_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(CTnames.ItemsSource == null)
{
return;
}
string CTvalue = CTnames.SelectedItem.ToString(); // BREAK-POINT HERE TO CHECK NAME OF SELECTED CT
int Res = 0;
CTindex = CTnames.SelectedIndex;
emptyStructSetsListbox();
emptyVelStructuresListbox();
emptyEditableStructsListBox();
// DiceThreshold = DiceThresholdDefault;
// DiceTol.Text = DiceThresholdDefault.ToString();
PTAccess pt = new PTAccess();
pt.RenamedStructNames.Clear();
strucSetNames = pt.GetStructSet(CTindex, Res);
if (strucSetNames != null)
{
UpdateStructSet();
}
else
{
MessageBox.Show("Cannot find any structure-set for current CT.", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
UpdateCT();
// DiceThreshold = DiceThresholdDefault;
// DiceTol.Text = DiceThresholdDefault.ToString();
}
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------- STRUCTURE-SET-SELECTION EVENT HANDLER ----------------------------------------------------------------------------------*/
/* */
private void StructSets_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (StructSets.SelectedIndex == -1) // IF NO SELECTION UPDATE AGAIN STRUCTURE-SETs LIST
return;
string structSetValue = StructSets.SelectedItem.ToString(); // BREAK-POINT HERE TO CHECK NAME OF SELECTED STRUCTURE-SET
StrSetIndex = StructSets.SelectedIndex;
emptyVelStructuresListbox();
emptyEditableStructsListBox();
PTAccess pt = new PTAccess();
List VelNam = pt.GetStructures(StrSetIndex, PatientName);
if (VelNam == null)
{
MessageBox.Show("Cannot find any structure for current structure-set.", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
UpdateStructSet();
}
strucNames.Clear();
int j = 1;
foreach (string str in VelNam)
{
strucNames.Add(new VelocityStructure { Name = str, Num = j });
j++;
}
// DiceThreshold = DiceThresholdDefault;
// DiceTol.Text = DiceThresholdDefault.ToString();
UpdateVelStructures();
}
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------ CHANGING DICE THRESHOLD EVENT HANDLER-------------------------------------------------------------------------------*/
/* */
private void DiceTol_TextChanged(object sender, TextChangedEventArgs e)
{
if (0 <= DiceThreshold & DiceThreshold <= 1)
{
// MessageBox.Show("Invalid Dice Threshold. Enter a number between 0 and 1", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
// DiceThreshold = DiceThresholdDefault;
// DiceTol.Text = DiceThresholdDefault.ToString();
emptyEditableStructsListBox();
return;
}
}
/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------ DISPLAY AUTO-MATCHED STRUCTUREs EVENT HANDLER-------------------------------------------------------------------------------*/
/* */
private void AutoMatchedStruct_Click(object sender, RoutedEventArgs e)
{
emptyEditableStructsListBox();
if (DiceThreshold < 0 | DiceThreshold > 1)
{
MessageBox.Show("DiceThreshold invalid. Enter a number between 0 and 1", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
DiceThreshold = DiceThresholdDefault;
DiceTol.Text = DiceThresholdDefault.ToString();
return;
}
if (structures.Count <= 0) // CHECKS PROTOCOL STRUCTUREs HAVE BEEN LOADED
{
MessageBox.Show("Protocol structures must be loaded Before renaming can start.", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if(strucNames.Count <= 0)
{
MessageBox.Show("Patient structures must be loaded Before renaming can start.", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
PTAccess pt = new PTAccess();
int count = strucNames.Count;
List IsGuessed = InitList(count, false);
List EditedList = new List();
double DT = DiceThreshold;
EditedList = pt.StructuresAutomaticRename(structures, ref IsGuessed, DT);
int j = 0;
for (j=0; j < EditedList.Count; j++)
{
if (IsGuessed[j])
AutoNames.Add(new EditableStructures { StrName = EditedList[j], IsAccepted = false, NamInd = j+1, SpecialFeatures = SpecialFeatures.Color });
else
if(String.IsNullOrWhiteSpace(EditedList[j]))
AutoNames.Add(new EditableStructures { StrName = EditedList[j], IsAccepted = false, NamInd = j+1, SpecialFeatures = SpecialFeatures.None });
else
AutoNames.Add(new EditableStructures { StrName = EditedList[j], IsAccepted = true, NamInd = j + 1, SpecialFeatures = SpecialFeatures.None });
}
// string DbgList = "" ; // DEBUG PURPOSE
// DbgList = String.Join(" , ", AutoNames.Select(x => x.StrName)); // DEBUG PURPOSE
// MessageBox.Show($"AUTOMATICALLY RENAMED STRUCTURES: \n {DbgList}"); // DEBUG PURPOSE
//............................ Compare Number of Guessed Structure Names With Number Of Structure Names From Velocity DataBase
// ............................ Alert User If Less Than 50% Structures Could Not Be Guessed
int NumGuessed = 0;
int NumOriginal = 0;
var Guessed = AutoNames.Where(m => !string.IsNullOrWhiteSpace(m.StrName)).ToList();
NumGuessed = Guessed.Count;
NumOriginal = strucNames.Count;
MessageBox.Show($" {NumGuessed} structures automatically renamed out of {NumOriginal} patient structures\n", "Is this patient belonging to this trial? ", MessageBoxButton.OK, MessageBoxImage.Information);
UpdateAutoStrucNames();
}
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------- CLOSE THIS APPLICATION -----------------------------------------------------------------------*/
private void Cancel_Click(object sender, RoutedEventArgs e)
{
AppDomain.CurrentDomain.ProcessExit += (source, data) => { PTAccess.engine.logout(); }; // CLEAN UP VELOCITY ENVIRONMENT
MessageBox.Show("The application will be closed.", "Cancel Application ", MessageBoxButton.OK, MessageBoxImage.Information);
App.Current.Shutdown(); // TERMINATE APPLICATION
Application.Current.MainWindow.Close();
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------- COMMIT RENAMED STRUCTURES TO VELOCITY DATABASE ----------------------------------------*/
public void Accept_Click(object sender, RoutedEventArgs e)
{
if (AutoNames.Count <= 0)
{
MessageBox.Show($"No structure to save", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait; // SET MOUSE TO HOURGLASS
var selectedPairs = AutoNames.Where(m => m.IsAccepted && !string.IsNullOrWhiteSpace(m.StrName));
List SavedStruct = selectedPairs.Select(m => m.StrName).ToList(); // EXTRACTS SELECTED STRUCTURES
// string DbgList = "";
// DbgList = String.Join(" , ", SavedStruct.Select(x => x)); // DEBUG PURPOSE
// MessageBox.Show($"EDITED AND SELECTED STRUCTURES: \n {DbgList}"); // DEBUG PURPOSE
PTAccess pt = new PTAccess();
bool res = pt.StoreSavedStructuresToVelocityDB( AutoNames);
if(!res)
{
MessageBox.Show($"No structure set saved to Velocity DB ", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
{
MessageBox.Show($"Structure set Correctly Saved to Velocity DB with name {targetSetName} ", "Success ", MessageBoxButton.OK, MessageBoxImage.Information);
}
/*.......................................... Clean up all Velocity related ListBoxes ...........................................................................................................................*/
emptyCTnamesListbox();
emptyStructSetsListbox();
emptyVelStructuresListbox();
emptyEditableStructsListBox();
AutoNames.Clear();
PatientName = System.String.Empty;
Patient.Text = " ";
DiceThreshold = DiceThresholdDefault;
DiceTol.Text = DiceThresholdDefault.ToString();
Mouse.OverrideCursor = null; // SHOW DEFAULT MOUSE
}
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------- CHOICE OF VELOCITY DATABASE ---------------------------------------------------------------*/
private void VDB_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PTAccess pt = new PTAccess();
int VelDBind = VDB.SelectedIndex;
VelocityDataBase = ((VelocityDB)VDB.SelectedItem).MyVelocityDB.ToString();
if (String.IsNullOrEmpty(VelocityDataBase ))
{
MessageBox.Show("No Velocity database has been selected", "Warning ", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Password = velocityDB[VelDBind].Passwd;
UserName = velocityDB[VelDBind].User;
emptyCTnamesListbox();
emptyStructSetsListbox();
emptyVelStructuresListbox();
emptyEditableStructsListBox();
PatientName = System.String.Empty;
Patient.Text = " ";
}
}
}