using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.MainForm.WPF; using System.Windows.Controls; using System.Windows; using HeuristicLab.BackgroundProcessing; using System.Diagnostics; using System.IO; using HeuristicLab.Persistence.Default.Xml; using HeuristicLab.Persistence.Core; using System.Collections.ObjectModel; using HeuristicLab.MainForm; using System.Data; using System.Globalization; using HeuristicLab.OKB.Client; namespace HeuristicLab.OKB.Cockpit.Admin { public partial class ProblemEditor : UserControl, IView, IOKBCockpitItem { public static DependencyProperty ProblemProperty = DependencyProperty.Register( "Problem", typeof(OKBAdmin.Problem), typeof(AlgorithmEditor)); public OKBAdmin.Problem Problem { get { return (OKBAdmin.Problem)GetValue(ProblemProperty); } set { SetValue(ProblemProperty, value); } } private Dictionary dataTypes; public ProblemEditor() { InitializeComponent(); Problem = null; InitializeSolutionRepresentations(); InitializeDataTypes(); InitializeProblemCharacteristics(); } protected void InitializeDataTypes() { dataTypes = new Dictionary(); var loader = new TableLoadWorker("DataType", false); loader.RunWorkerCompleted += (s, a) => { foreach (DataRow row in loader.Table.Rows) { try { dataTypes.Add((int)row["Id"], Type.GetType((string)row["clrName"])); } catch (Exception x) { MessageBox.Show( String.Format("Could not parse CLR name of database datatype '{0}':\n{1}", row["clrName"], x), Caption, MessageBoxButton.OK, MessageBoxImage.Error); } } }; loader.RunWorkerAsync(); } protected void InitializeProblemCharacteristics() { var loader = new TableLoadWorker("ProblemCharacteristic", false); loader.RunWorkerCompleted += (s, a) => { if (loader.Table != null) { loader.Table.Columns.Add(new DataColumn("Value", typeof(string))); loader.Table.Columns.Add(new DataColumn("IsSelected", typeof(bool))); loader.Table.Columns.Add(new DataColumn("DataType", typeof(Type))); foreach (DataRow row in loader.Table.Rows) { try { row["IsSelected"] = false; row["DataType"] = dataTypes[(int)row["DataTypeId"]]; } catch { } } ProblemCharacteristicsList.ItemsSource = loader.Table.DefaultView; } }; loader.RunWorkerAsync(); } protected void InitializeSolutionRepresentations() { var loader = new TableLoadWorker("SolutionRepresentation", false); loader.RunWorkerCompleted += (s, a) => { if (loader.Table != null) { SolutionRepresentationBox.ItemsSource = loader.Table.DefaultView; } }; loader.RunWorkerAsync(); } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == ProblemProperty) UpdateProblem(); } private void UpdateProblem() { if (Problem == null) { Clear(); return; } OnLoad(this, new RoutedEventArgs()); } private void Clear() { IdBox.Text = null; NameBox.Text = null; DescriptionBox.Text = null; } private bool isLoading = false; protected void OnLoad(object sender, RoutedEventArgs args) { if (isLoading) return; isLoading = true; var loader = new ObservableBackgroundWorker("downloading problem") { WorkerSupportsCancellation = true, WorkerReportsProgress = true, }; OKBAdmin.Problem problem = Problem; loader.DoWork += (s, a) => { OKBAdmin.AdminServiceClient client = ClientFactory.Create(); problem = client.GetCompleteProblem(problem.Id); client.Close(); loader.ReportProgress(10); byte[] data = new DataClientHelper(loader, a) { ReportProgress = p => loader.ReportProgress(10 + 80 * p / 100), }.Load(OKBData.EntityType.Problem, problem.Id); if (data != null && !loader.CancellationPending) { OperatorGraphEditor.LoadData(data, problem.Platform, OperatorGraphEditorHost.EditorType.Problem); loader.ReportProgress(100); } }; loader.RunWorkerCompleted += (s, a) => { try { if (problem == null) return; Problem = problem; IdBox.Text = Problem.Id.ToString(); NameBox.Text = Problem.Name; DescriptionBox.Text = Problem.Description; SolutionRepresentationBox.SelectedItem = SolutionRepresentationBox.Items.Cast() .SingleOrDefault(sr => (int)sr["Id"] == Problem.SolutionRepresentation.Id); LoadProblemCharacteristics(); } finally { isLoading = false; } }; loader.RunWorkerAsync(); } protected void LoadProblemCharacteristics() { var pcs = new Dictionary(); foreach (var pc in Problem.IntProblemCharacteristicValues) pcs.Add(pc.ProblemCharacteristicId, pc.Value); foreach (var pc in Problem.CharProblemCharacteristicValues) pcs.Add(pc.ProblemCharacteristicId, pc.Value); foreach (var pc in Problem.FloatProblemCharacteristicValues) pcs.Add(pc.ProblemCharacteristicId, pc.Value); foreach (DataRowView row in ProblemCharacteristicsList.Items) { int id = (int)row["Id"]; if (pcs.ContainsKey(id)) { row["IsSelected"] = true; row["Value"] = pcs[id].ToString(); } } } protected void OnSave(object sender, RoutedEventArgs args) { StoreProblemCharacteristics(); Problem.Name = NameBox.Text; Problem.Description = DescriptionBox.Text; OKBAdmin.Problem problem = Problem; OperatorGraphEditorHost editor = OperatorGraphEditor; var saver = new ObservableBackgroundWorker("uploading problem") { WorkerReportsProgress = true, WorkerSupportsCancellation = true, }; saver.DoWork += (s, a) => { OKBAdmin.AdminServiceClient client = ClientFactory.Create(); client.UpdateCompleteProblem(problem); client.Close(); saver.ReportProgress(10); byte[] data = editor.GetProblemData(); saver.ReportProgress(20); if (data != null) { new DataClientHelper(saver, a) { ReportProgress = i => saver.ReportProgress(20 + 80 * i / 100) }.Save(OKBData.EntityType.Problem, problem.Id, data); } else { saver.ReportProgress(100); } }; saver.RunWorkerAsync(); } private void StoreProblemCharacteristics() { Problem.IntProblemCharacteristicValues.Clear(); Problem.FloatProblemCharacteristicValues.Clear(); Problem.CharProblemCharacteristicValues.Clear(); foreach (DataRowView row in ProblemCharacteristicsList.Items) { string value = row["Value"] as string; if (string.IsNullOrEmpty(value) || !(bool)row["IsSelected"]) continue; try { Type dataType = (Type)row["DataType"]; if (dataType == typeof(int)) { Problem.IntProblemCharacteristicValues.Add(new OKBAdmin.IntProblemCharacteristicValue() { ProblemId = Problem.Id, ProblemCharacteristicId = (int)row["Id"], Value = int.Parse((string)row["Value"], CultureInfo.InvariantCulture.NumberFormat), }); } else if (dataType == typeof(double)) { Problem.FloatProblemCharacteristicValues.Add(new OKBAdmin.FloatProblemCharacteristicValue() { ProblemId = Problem.Id, ProblemCharacteristicId = (int)row["Id"], Value = double.Parse((string)row["Value"], CultureInfo.InvariantCulture.NumberFormat), }); } else if (dataType == typeof(string)) { Problem.CharProblemCharacteristicValues.Add(new OKBAdmin.CharProblemCharacteristicValue() { ProblemId = Problem.Id, ProblemCharacteristicId = (int)row["Id"], Value = (string)row["Value"], }); } } catch (Exception x) { MessageBox.Show( String.Format("Could not create problem characteristic {0} with value {1}:\n{2}", row["Name"], row["Value"], x), Caption, MessageBoxButton.OK, MessageBoxImage.Error); } } } private bool ContentHasParameter(OKBAdmin.Parameter p) { return Problem.Problem_Parameters.Any(ap => ap.ParameterId == p.Id); } protected void OnViewParameters(object sender, EventArgs args) { if (sender == ParametersButton && Problem != null) EntityEditorSupport.ShowSelector(ContentHasParameter, UpdateParameters); } private void UpdateParameters(IEnumerable parameters) { Problem.Problem_Parameters.Clear(); foreach (OKBAdmin.Parameter p in parameters) { Problem.Problem_Parameters.Add(new OKBAdmin.Problem_Parameter() { ProblemId = Problem.Id, ParameterId = p.Id, }); } } private void OnDownload(object sender, EventArgs args) { PersistenceHacker.Download(OKBData.EntityType.Problem, Problem.Id); } private void OnUpload(object sender, EventArgs args) { PersistenceHacker.Upload(OKBData.EntityType.Problem, Problem.Id); } #region IView Members public string Caption { get { return "Problem Editor"; } set { throw new NotSupportedException(); } } public event EventHandler CaptionChanged; public event EventHandler Changed; public virtual void Close() { MainFormManager.GetMainForm().CloseView(this); IsShown = false; } public void Hide() { MainFormManager.GetMainForm().HideView(this); IsShown = false; } public bool IsShown { get; protected set; } private bool readOnly = false; public bool ReadOnly { get { return readOnly; } set { if (value == readOnly) return; readOnly = value; OnReadOnlyChanged(); } } public event EventHandler ReadOnlyChanged; protected void OnReadOnlyChanged() { EventHandler handler = ReadOnlyChanged; if (handler != null) handler(this, EventArgs.Empty); } public void Show() { MainFormManager.GetMainForm().ShowView(this); IsShown = true; } #endregion } }