diff --git a/VECTO3GUI/Helper/EventCommandExecuter.cs b/VECTO3GUI/Helper/EventCommandExecuter.cs new file mode 100644 index 0000000000000000000000000000000000000000..7457f06bff79d101835d2c8404d349131bd95599 --- /dev/null +++ b/VECTO3GUI/Helper/EventCommandExecuter.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Input; +using System.Windows.Interactivity; + +namespace VECTO3GUI.Helper +{ + public class EventCommandExecuter : TriggerAction<DependencyObject> + { + #region Constructors + + public EventCommandExecuter() + : this(CultureInfo.CurrentCulture) + { + } + + public EventCommandExecuter(CultureInfo culture) + { + Culture = culture; + } + + #endregion + + #region Properties + + #region Command + + public ICommand Command + { + get { return (ICommand)GetValue(CommandProperty); } + set { SetValue(CommandProperty, value); } + } + + public static readonly DependencyProperty CommandProperty = + DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(EventCommandExecuter), new PropertyMetadata(null)); + + #endregion + + #region EventArgsConverterParameter + + public object EventArgsConverterParameter + { + get { return (object)GetValue(EventArgsConverterParameterProperty); } + set { SetValue(EventArgsConverterParameterProperty, value); } + } + + public static readonly DependencyProperty EventArgsConverterParameterProperty = + DependencyProperty.Register(nameof(EventArgsConverterParameter), typeof(object), typeof(EventCommandExecuter), new PropertyMetadata(null)); + + #endregion + + public IValueConverter EventArgsConverter { get; set; } + + public CultureInfo Culture { get; set; } + + #endregion + + protected override void Invoke(object parameter) + { + var cmd = Command; + + if (cmd != null) + { + var param = parameter; + + if (EventArgsConverter != null) + { + param = EventArgsConverter.Convert(parameter, typeof(object), EventArgsConverterParameter, CultureInfo.InvariantCulture); + } + + if (cmd.CanExecute(param)) + { + cmd.Execute(param); + } + } + } + } +} diff --git a/VECTO3GUI/Helper/Extension.cs b/VECTO3GUI/Helper/Extension.cs index 5481aa798cb10ced9325780fb4822adbca67bad2..7e3ebb2e02b3cc2b08d52cf59416f4bead23693f 100644 --- a/VECTO3GUI/Helper/Extension.cs +++ b/VECTO3GUI/Helper/Extension.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml; +using System.Xml.Linq; namespace VECTO3GUI.Helper { @@ -29,5 +31,29 @@ namespace VECTO3GUI.Helper return currentObj; } + + public static XmlDocument ToXmlDocument(this XDocument xDocument) + { + var xmlDocument = new XmlDocument(); + using (var reader = xDocument.CreateReader()) + { + xmlDocument.Load(reader); + } + + var xDeclaration = xDocument.Declaration; + if (xDeclaration != null) + { + var xmlDeclaration = xmlDocument.CreateXmlDeclaration( + xDeclaration.Version, + xDeclaration.Encoding, + xDeclaration.Standalone); + + xmlDocument.InsertBefore(xmlDeclaration, xmlDocument.FirstChild); + } + + return xmlDocument; + } + + } } diff --git a/VECTO3GUI/Helper/FileDialogHelper.cs b/VECTO3GUI/Helper/FileDialogHelper.cs index b11560639249202a8a282507f209ad185b80636a..e8bfe59e80d6798c8db1502f09c8672edabbba55 100644 --- a/VECTO3GUI/Helper/FileDialogHelper.cs +++ b/VECTO3GUI/Helper/FileDialogHelper.cs @@ -16,10 +16,6 @@ namespace VECTO3GUI.Helper public const string XMLFilter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*"; public const string JobFilter = "Job Files (*.vectojob|*.vectojob|All Files (*.*)|*.*"; - - - - public static string[] ShowSelectFilesDialog(bool multiselect) { return ShowSelectFilesDialog(multiselect, XMLFilter); @@ -42,8 +38,7 @@ namespace VECTO3GUI.Helper return null; } - - + public static string ShowSelectDirectoryDialog(string initialDirectory = null) { using (var dialog = new CommonOpenFileDialog()) @@ -61,10 +56,21 @@ namespace VECTO3GUI.Helper return null; } + public static string SaveXmlFileToDialog(string initialDirectory = null) + { + return SaveToDialog(initialDirectory, XMLFilter); + } + public static string SaveJobFileToDialog(string initialDirectory = null) { - var saveFileDialog = new SaveFileDialog { - Filter = JobFilter + return SaveToDialog(initialDirectory, JobFilter); + } + + private static string SaveToDialog(string initialDirectory, string filter) + { + var saveFileDialog = new SaveFileDialog + { + Filter = filter }; if (initialDirectory != null) diff --git a/VECTO3GUI/Helper/MetroDialogHelper.cs b/VECTO3GUI/Helper/MetroDialogHelper.cs new file mode 100644 index 0000000000000000000000000000000000000000..efcbcbf19c75b34080da9ff20950954f1740d767 --- /dev/null +++ b/VECTO3GUI/Helper/MetroDialogHelper.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MahApps.Metro.Controls.Dialogs; + +namespace VECTO3GUI.Helper +{ + public static class MetroDialogHelper + { + public static MessageDialogResult GetModalDialogBox(object viewModel, string title, string message, + MetroDialogSettings settings) + { + return GetModalDialogBox(viewModel, title, message, MessageDialogStyle.AffirmativeAndNegative, settings); + } + + public static MessageDialogResult GetModalDialogBox(object viewModel, string title, string message, + MessageDialogStyle style = MessageDialogStyle.AffirmativeAndNegative, MetroDialogSettings settings = null) + { + var coordinator = DialogCoordinator.Instance; + return coordinator.ShowModalMessageExternal(viewModel, title, message, style, settings); + } + } +} diff --git a/VECTO3GUI/Helper/TextBoxInputRegExBehaviour.cs b/VECTO3GUI/Helper/TextBoxInputRegExBehaviour.cs new file mode 100644 index 0000000000000000000000000000000000000000..b8aeb35952676b0292c4f01fe1503688f4853b9f --- /dev/null +++ b/VECTO3GUI/Helper/TextBoxInputRegExBehaviour.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Interactivity; + +namespace VECTO3GUI.Helper +{ + /// Taken from https://stackoverflow.com/a/17715402 + /// <summary> + /// Regular expression for Textbox with properties: + /// <see cref="RegularExpression"/>, + /// <see cref="MaxLength"/>, + /// <see cref="EmptyValue"/>. + /// </summary> + public class TextBoxInputRegExBehaviour : Behavior<TextBox> + { + #region DependencyProperties + public static readonly DependencyProperty RegularExpressionProperty = + DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(".*")); + + public string RegularExpression + { + get { return (string)GetValue(RegularExpressionProperty); } + set { SetValue(RegularExpressionProperty, value); } + } + + public static readonly DependencyProperty MaxLengthProperty = + DependencyProperty.Register("MaxLength", typeof(int), typeof(TextBoxInputRegExBehaviour), + new FrameworkPropertyMetadata(int.MinValue)); + + public int MaxLength + { + get { return (int)GetValue(MaxLengthProperty); } + set { SetValue(MaxLengthProperty, value); } + } + + public static readonly DependencyProperty EmptyValueProperty = + DependencyProperty.Register("EmptyValue", typeof(string), typeof(TextBoxInputRegExBehaviour), null); + + public string EmptyValue + { + get { return (string)GetValue(EmptyValueProperty); } + set { SetValue(EmptyValueProperty, value); } + } + #endregion + + /// <summary> + /// Attach our behaviour. Add event handlers + /// </summary> + protected override void OnAttached() + { + base.OnAttached(); + + AssociatedObject.PreviewTextInput += PreviewTextInputHandler; + AssociatedObject.PreviewKeyDown += PreviewKeyDownHandler; + DataObject.AddPastingHandler(AssociatedObject, PastingHandler); + } + + /// <summary> + /// Deattach our behaviour. remove event handlers + /// </summary> + protected override void OnDetaching() + { + base.OnDetaching(); + + AssociatedObject.PreviewTextInput -= PreviewTextInputHandler; + AssociatedObject.PreviewKeyDown -= PreviewKeyDownHandler; + DataObject.RemovePastingHandler(AssociatedObject, PastingHandler); + } + + #region Event handlers [PRIVATE] -------------------------------------- + + void PreviewTextInputHandler(object sender, TextCompositionEventArgs e) + { + string text; + if (this.AssociatedObject.Text.Length < this.AssociatedObject.CaretIndex) + text = this.AssociatedObject.Text; + else + { + // Remaining text after removing selected text. + string remainingTextAfterRemoveSelection; + + text = TreatSelectedText(out remainingTextAfterRemoveSelection) + ? remainingTextAfterRemoveSelection.Insert(AssociatedObject.SelectionStart, e.Text) + : AssociatedObject.Text.Insert(this.AssociatedObject.CaretIndex, e.Text); + } + + e.Handled = !ValidateText(text); + } + + /// <summary> + /// PreviewKeyDown event handler + /// </summary> + void PreviewKeyDownHandler(object sender, KeyEventArgs e) + { + if (string.IsNullOrEmpty(this.EmptyValue)) + return; + + string text = null; + + // Handle the Backspace key + if (e.Key == Key.Back) + { + if (!this.TreatSelectedText(out text)) + { + if (AssociatedObject.SelectionStart > 0) + text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart - 1, 1); + } + } + // Handle the Delete key + else if (e.Key == Key.Delete) + { + // If text was selected, delete it + if (!this.TreatSelectedText(out text) && this.AssociatedObject.Text.Length > AssociatedObject.SelectionStart) + { + // Otherwise delete next symbol + text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, 1); + } + } + + if (text == string.Empty) + { + this.AssociatedObject.Text = this.EmptyValue; + if (e.Key == Key.Back) + AssociatedObject.SelectionStart++; + e.Handled = true; + } + } + + private void PastingHandler(object sender, DataObjectPastingEventArgs e) + { + if (e.DataObject.GetDataPresent(DataFormats.Text)) + { + string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text)); + + if (!ValidateText(text)) + e.CancelCommand(); + } + else + e.CancelCommand(); + } + #endregion Event handlers [PRIVATE] ----------------------------------- + + #region Auxiliary methods [PRIVATE] ----------------------------------- + + /// <summary> + /// Validate certain text by our regular expression and text length conditions + /// </summary> + /// <param name="text"> Text for validation </param> + /// <returns> True - valid, False - invalid </returns> + private bool ValidateText(string text) + { + return (new Regex(this.RegularExpression, RegexOptions.IgnoreCase)).IsMatch(text) && (MaxLength == int.MinValue || text.Length <= MaxLength); + } + + /// <summary> + /// Handle text selection + /// </summary> + /// <returns>true if the character was successfully removed; otherwise, false. </returns> + private bool TreatSelectedText(out string text) + { + text = null; + if (AssociatedObject.SelectionLength <= 0) + return false; + + var length = this.AssociatedObject.Text.Length; + if (AssociatedObject.SelectionStart >= length) + return true; + + if (AssociatedObject.SelectionStart + AssociatedObject.SelectionLength >= length) + AssociatedObject.SelectionLength = length - AssociatedObject.SelectionStart; + + text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, AssociatedObject.SelectionLength); + return true; + } + #endregion Auxiliary methods [PRIVATE] -------------------------------- + } +} + diff --git a/VECTO3GUI/Helper/XmlReaderHelper.cs b/VECTO3GUI/Helper/XmlHelper.cs similarity index 57% rename from VECTO3GUI/Helper/XmlReaderHelper.cs rename to VECTO3GUI/Helper/XmlHelper.cs index 960d6ffb0e8efaf395d33e245b5d3882586713c8..e719f90c0fcde39764885193129658cf7795ad02 100644 --- a/VECTO3GUI/Helper/XmlReaderHelper.cs +++ b/VECTO3GUI/Helper/XmlHelper.cs @@ -4,13 +4,16 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; +using System.Xml.Linq; using Castle.Core.Internal; using Microsoft.WindowsAPICodePack.Shell.PropertySystem; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCore.Utils; namespace VECTO3GUI.Helper { - public static class XmlReaderHelper + public static class XmlHelper { public static XmlDocument ReadXmlDocument(string filePath) { @@ -35,7 +38,20 @@ namespace VECTO3GUI.Helper return xmlDocument.SelectNodes($"//*[local-name()='{parentNode}']//*[local-name()='{nodeName}']"); } - + public static bool ValidateXDocument(XDocument xDocument) + { + var xmlDocument = xDocument.ToXmlDocument(); + if (xmlDocument == null) + return false; + + var documentType = XMLHelper.GetDocumentType(xmlDocument.DocumentElement.LocalName); + if (documentType == null) + { + throw new VectoException("unknown xml file! {0}", xmlDocument.DocumentElement.LocalName); + } + var validator = new XMLValidator(xmlDocument, null, XMLValidator.CallBackExceptionOnError); + return validator.ValidateXML(documentType.Value); ; + } } } diff --git a/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs b/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs index 01324dfaf3e70631bcaae6e589539aa857c8d305..678c6f0b9bbfa1122ea5e910f7cbf670a989d5bc 100644 --- a/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs +++ b/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs @@ -28,6 +28,7 @@ namespace VECTO3GUI.Model.TempDataObject public bool HeatPump { get; set; } public bool AdjustableAuxiliaryHeater { get; set; } public bool SeparateAirDistributionDucts { get; set; } + public ConsumerTechnology DoorDriveTechnology { get; set; } #endregion @@ -63,6 +64,7 @@ namespace VECTO3GUI.Model.TempDataObject viewModel.HeatPump = HeatPump; viewModel.AdjustableAuxiliaryHeater = AdjustableAuxiliaryHeater; viewModel.SeparateAirDistributionDucts = SeparateAirDistributionDucts; + viewModel.DoorDriveTechnology = viewModel.DoorDriveTechnology; } public void ClearValues(IAuxiliariesViewModel viewModel) @@ -81,6 +83,7 @@ namespace VECTO3GUI.Model.TempDataObject viewModel.HeatPump = default(bool); viewModel.AdjustableAuxiliaryHeater = default(bool); viewModel.SeparateAirDistributionDucts = default(bool); + viewModel.DoorDriveTechnology = ConsumerTechnology.Pneumatically; } private void SetValues(IAuxiliariesViewModel auxiliaries) @@ -99,6 +102,7 @@ namespace VECTO3GUI.Model.TempDataObject HeatPump = auxiliaries.HeatPump; AdjustableAuxiliaryHeater = auxiliaries.AdjustableAuxiliaryHeater; SeparateAirDistributionDucts = auxiliaries.SeparateAirDistributionDucts; + DoorDriveTechnology = auxiliaries.DoorDriveTechnology; } } diff --git a/VECTO3GUI/Util/XML/XMLCompletedBus.cs b/VECTO3GUI/Util/XML/XMLCompletedBus.cs index 923fcc830d5b61a1ba5a131402a81b19e8b7ba69..078b13ad18f4476b7fb768b5fc0e0f9d29a0d2ca 100644 --- a/VECTO3GUI/Util/XML/XMLCompletedBus.cs +++ b/VECTO3GUI/Util/XML/XMLCompletedBus.cs @@ -130,7 +130,7 @@ namespace VECTO3GUI.Util.XML new XAttribute("xmlns", _v20), new XElement(_v20 + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, airdrag.DigestValue.Reference), + new XAttribute(XMLNames.Component_ID_Attr, airdrag.DigestValue.Reference.Replace("#","")), new XAttribute(_xsi + "type", XMLDeclarationAirdragDataProviderV10.XSD_TYPE), // "AirDragDataDeclarationType" new XElement(_v20 + XMLNames.Component_Manufacturer, airdrag.Manufacturer), @@ -172,14 +172,16 @@ namespace VECTO3GUI.Util.XML new XElement(_v26 + XMLNames.Bus_Positionlights, auxBus?.PositionlightsLED), new XElement(_v26 + XMLNames.Bus_Brakelights, auxBus?.BrakelightsLED), new XElement(_v26 + XMLNames.Bus_Interiorlights, auxBus?.InteriorLightsLED))), + //----> ToDo remove if xsd gets changed <--- new XElement(_v26 + XMLNames.BusAux_PneumaticSystem, - new XElement(_v26 + XMLNames.BusAux_PneumaticSystem_DoorDriveTechnology)), + new XElement(_v26 + XMLNames.BusAux_PneumaticSystem_DoorDriveTechnology, auxBus?.DoorDriveTechnology.GetLabel().ToLower())), + //------------------------------------------ new XElement(_v26 + "HVAC", new XElement(_v26 + XMLNames.Bus_SystemConfiguration, auxBus?.SystemConfiguration.GetXmlFormat()), new XElement(_v26 + XMLNames.Bus_CompressorType, new XElement(_v26 + XMLNames.Bus_DriverAC, auxBus?.CompressorTypeDriver.GetLabel()), new XElement(_v26 + XMLNames.Bus_PassengerAC, auxBus?.CompressorTypePassenger.GetLabel())), - new XElement(_v26 + XMLNames.Bus_AuxiliaryHeaterPower, auxBus?.AuxHeaterPower.ToXMLFormat()), + new XElement(_v26 + XMLNames.Bus_AuxiliaryHeaterPower, Convert.ToInt32(auxBus?.AuxHeaterPower.Value())), new XElement(_v26 + XMLNames.Bus_DoubleGlasing, auxBus?.DoubleGlasing), new XElement(_v26 + XMLNames.Bus_HeatPump, auxBus?.HeatPump), new XElement(_v26 + XMLNames.Bus_AdjustableAuxiliaryHeater, auxBus?.AdjustableAuxiliaryHeater), diff --git a/VECTO3GUI/VECTO3GUI.csproj b/VECTO3GUI/VECTO3GUI.csproj index 15f1eec02dcb556145034482a3c12ca7e9f91142..0d9cbb0c7978339b89c6dfb9011e420b19c6b6af 100644 --- a/VECTO3GUI/VECTO3GUI.csproj +++ b/VECTO3GUI/VECTO3GUI.csproj @@ -164,15 +164,18 @@ <Compile Include="Helper\Converter\BoolVisibilityConverter.cs" /> <Compile Include="Helper\Converter\ComponentTitleConverter.cs" /> <Compile Include="Helper\Converter\EnumConverter.cs" /> + <Compile Include="Helper\EventCommandExecuter.cs" /> <Compile Include="Helper\Extension.cs" /> <Compile Include="Helper\FileDialogHelper.cs" /> + <Compile Include="Helper\MetroDialogHelper.cs" /> <Compile Include="Helper\ObservableCollectionEx.cs" /> <Compile Include="Helper\OutputWindowHelper.cs" /> <Compile Include="Helper\Converter\SaveButtonLabelConverter.cs" /> <Compile Include="Helper\SerializeHelper.cs" /> + <Compile Include="Helper\TextBoxInputRegExBehaviour.cs" /> <Compile Include="Helper\ViewModelBase.cs" /> <Compile Include="Helper\XmlComponentReaderHelper.cs" /> - <Compile Include="Helper\XmlReaderHelper.cs" /> + <Compile Include="Helper\XmlHelper.cs" /> <Compile Include="Model\InterfacesImpl.cs" /> <Compile Include="Model\JobListModel.cs" /> <Compile Include="Model\SettingsModel.cs" /> diff --git a/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs index db2d12879ac09cc44c5ee99fc6f3083723aa8103..76044356820eff24bb397fba78bcfd9eeb07d99c 100644 --- a/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs @@ -1,23 +1,34 @@ using System; +using System.ComponentModel; using System.Linq; using System.Windows; -using System.Windows.Controls; using System.Windows.Input; +using MahApps.Metro.Controls.Dialogs; using Ninject; +using VECTO3GUI.Helper; +using VECTO3GUI.Model; using VECTO3GUI.Util; using VECTO3GUI.ViewModel.Interfaces; +using Component = VECTO3GUI.Util.Component; namespace VECTO3GUI.ViewModel.Impl { public abstract class AbstractJobViewModel : AbstractViewModel { protected bool IsDeclarationMode; + protected bool WindowAlreadyClosed; + protected readonly SettingsModel SettingsModel; + private IComponentViewModel _currentComponent; private ICommand _saveJobCommand; private ICommand _closeJobCommand; private ICommand _saveToJobCommand; + protected string XmlFilePath { get; private set; } + + protected bool IsNewJob { get; set; } + public override bool DeclarationMode { get { return IsDeclarationMode; } @@ -31,39 +42,69 @@ namespace VECTO3GUI.ViewModel.Impl } } + public AbstractJobViewModel() + { + SettingsModel = new SettingsModel(); + } + public ICommand SaveJob { - get { return _saveJobCommand ?? (_saveJobCommand = new RelayCommand(DoSaveJob)); } + get { return _saveJobCommand ?? (_saveJobCommand = new RelayCommand<Window>(DoSaveJob, CanSaveJob)); } + } + protected virtual bool CanSaveJob(Window window) + { + return true; } + protected abstract void DoSaveJob(Window window); - protected abstract void DoSaveJob(); public ICommand CloseJob { - get { return _closeJobCommand ?? (_closeJobCommand = new RelayCommand<Window>(DoCloseJob));} + get { return _closeJobCommand ?? (_closeJobCommand = new RelayCommand<Window>(DoCloseJob, CanCloseJob));} + } + protected virtual bool CanCloseJob(Window obj) + { + return true; } - protected abstract void DoCloseJob(Window window); public ICommand SaveToJob { - get { return _saveToJobCommand ?? (_saveToJobCommand = new RelayCommand(DoSaveToJob)); } + get { return _saveToJobCommand ?? (_saveToJobCommand = new RelayCommand<Window>(DoSaveToJob, CanSaveToJob)); } + } + protected virtual bool CanSaveToJob(Window window) + { + return true; } + protected abstract void DoSaveToJob(Window window); - protected abstract void DoSaveToJob(); public ICommand EditComponent { get { return new RelayCommand<Component>(DoEditComponent); } } - protected virtual void DoEditComponent(Component component) { var nextView = GetComponentViewModel(component); CurrentComponent = nextView ?? Kernel.Get<INoneViewModel>(); } + public ICommand CloseWindowCommand + { + get { return new RelayCommand<CancelEventArgs>(DoCloseWindow);} + } + + private void DoCloseWindow(CancelEventArgs cancelEvent) + { + if (WindowAlreadyClosed) + return; + + if(!CloseWindowDialog()) + cancelEvent.Cancel = true; + } + + protected void CreateComponentModel(Component component) { var viewModelType = ViewModelFactory.ComponentViewModelMapping[component]; @@ -77,5 +118,30 @@ namespace VECTO3GUI.ViewModel.Impl RegisterSubmodel(component, viewModel); } } + + protected void SetXmlFilePath(string baseUri) + { + if (baseUri == null) + return; + + var uri = new Uri(baseUri); + XmlFilePath = uri.AbsolutePath; + } + + protected bool CloseWindowDialog() + { + var dialogSettings = new MetroDialogSettings() + { + AffirmativeButtonText = "Yes", + NegativeButtonText = "No", + AnimateShow = true, + AnimateHide = true + }; + + var res = MetroDialogHelper.GetModalDialogBox(this, + "", "Do you really want to close ?", dialogSettings); + + return res == MessageDialogResult.Affirmative; + } } } diff --git a/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs b/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs index f56514918a0f76315eca3ea1d14e9d56259de71c..70ae9f5f19bdfe9d8f88fc9166903539ffbdbb78 100644 --- a/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs @@ -263,8 +263,8 @@ namespace VECTO3GUI.ViewModel.Impl if (filePath.IsNullOrEmpty()) return; - var xmlDocument = XmlReaderHelper.ReadXmlDocument(filePath); - var nodes = XmlReaderHelper.GetComponentNodes(xmlDocument, + var xmlDocument = XmlHelper.ReadXmlDocument(filePath); + var nodes = XmlHelper.GetComponentNodes(xmlDocument, XMLNames.VectoInputDeclaration, VectoComponents.Airdrag.XMLElementName()); if(nodes.IsNullOrEmpty()) diff --git a/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs b/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs index e6b09c1825d18a81bef4d0eb291e0844d11a06b1..61fa55736a855f19eb2346021d7ecf9502a07355 100644 --- a/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs @@ -273,7 +273,9 @@ namespace VECTO3GUI.ViewModel.Impl } } - + public ConsumerTechnology DoorDriveTechnology { get; set; } + + public AllowedEntry<BusHVACSystemConfiguration>[] AllowedSystemConfigurations { get; private set; } public AllowedEntry<ACCompressorType>[] AllowedDriverACCompressorTypes { get; private set; } public AllowedEntry<ACCompressorType>[] AllowedPassengerACCompressorTypes { get; private set; } @@ -319,8 +321,8 @@ namespace VECTO3GUI.ViewModel.Impl AlternatorTechnologies.Add(busAux.ElectricSupply.Alternators[i].Technology); } - AlternatorTechnologies.Add("blu"); - AlternatorTechnologies.Add("bla"); + //AlternatorTechnologies.Add("blu"); + //AlternatorTechnologies.Add("bla"); } DayrunninglightsLED = busAux.ElectricConsumers.DayrunninglightsLED; @@ -336,6 +338,7 @@ namespace VECTO3GUI.ViewModel.Impl HeatPump = busAux.HVACAux.HeatPump; AdjustableAuxiliaryHeater = busAux.HVACAux.AdjustableAuxiliaryHeater; SeparateAirDistributionDucts = busAux.HVACAux.SeparateAirDistributionDucts; + DoorDriveTechnology = ConsumerTechnology.Pneumatically; _componentData = new AuxiliariesBusComponentData(this); ClearChangedProperties(); diff --git a/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs index 0e0246630aa09367626f172971fa32ae12b388c0..d414dcacfcf0548f5b2f56dd2e19855c1b766db4 100644 --- a/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs @@ -5,21 +5,25 @@ using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using MahApps.Metro.Controls.Dialogs; using Ninject; using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.OutputData.XML.DeclarationJobs; -using VECTO3GUI.Model.TempDataObject; +using VECTO3GUI.Helper; using VECTO3GUI.ViewModel.Interfaces; using VECTO3GUI.Util; using VECTO3GUI.Util.XML; + namespace VECTO3GUI.ViewModel.Impl { public class CompleteVehicleBusJobViewModel : AbstractJobViewModel, IJobEditViewModel { #region Members - + + private readonly XMLCompletedBus _xmlCompletedBus; + private readonly XMLCompletedBusWriter _xmlCompletedBusWriter; + private ICommand _saveComponentCommand; private ICommand _resetComponentCommand; @@ -35,45 +39,69 @@ namespace VECTO3GUI.ViewModel.Impl { Kernel = kernel; InputDataProvider = inputData; + IsNewJob = inputData == null; JobViewModel = this; CreateComponentModel(Component.CompleteBusVehicle); CreateComponentModel(Component.Airdrag); CreateComponentModel(Component.Auxiliaries); CurrentComponent = GetComponentViewModel(Component.CompleteBusVehicle); - } - - #region Commands + SetXmlFilePath(inputData?.JobInputData.Vehicle.XMLSource.BaseURI); - + _xmlCompletedBus = new XMLCompletedBus(); + _xmlCompletedBusWriter = new XMLCompletedBusWriter(); + } + #region Commands - - protected override void DoSaveJob() + protected override bool CanSaveJob(Window window) { - CompleteVehicleBusData = new Dictionary<Component, object> { - { Component.CompleteBusVehicle, _subModels[Component.CompleteBusVehicle].SaveComponentData()}, - { Component.Airdrag, _subModels[Component.Airdrag].SaveComponentData()}, - { Component.Auxiliaries, _subModels[Component.Auxiliaries].SaveComponentData()} + return !IsNewJob; + } + protected override void DoSaveJob(Window window) + { + var dialogSettings = new MetroDialogSettings() + { + AffirmativeButtonText = "Yes", + NegativeButtonText = "Cancel", + AnimateShow = true, + AnimateHide = true }; - - - //var completedXml = new XMLCompletedBus(); - //var xmlDoc = completedXml.GenerateCompletedBusDocument(CompleteVehicleBusData); - - //var writer = new XMLCompletedBusWriter(); - //writer.WriteCompletedBusXml(filePath, xmlDoc); + + var dialogResult = MetroDialogHelper.GetModalDialogBox(this, "Save", + "The existing file will be overwritten, do you want to continue?", + MessageDialogStyle.AffirmativeAndNegative, dialogSettings); + + if (dialogResult == MessageDialogResult.Affirmative) { + SetCurrentDataToSave(); + var xDoc = _xmlCompletedBus.GenerateCompletedBusDocument(CompleteVehicleBusData); + + if (XmlHelper.ValidateXDocument(xDoc)) { + _xmlCompletedBusWriter.WriteCompletedBusXml(XmlFilePath, xDoc); + CloseWindow(window); + } + } } protected override void DoCloseJob(Window window) { - window?.Close(); + if (CloseWindowDialog()) { + CloseWindow(window); + } } - protected override void DoSaveToJob() + protected override void DoSaveToJob(Window window) { - + var filePath = FileDialogHelper.SaveXmlFileToDialog(SettingsModel.XmlFilePathFolder); + + SetCurrentDataToSave(); + var xDocument = _xmlCompletedBus.GenerateCompletedBusDocument(CompleteVehicleBusData); + + if (XmlHelper.ValidateXDocument(xDocument)) { + _xmlCompletedBusWriter.WriteCompletedBusXml(filePath, xDocument); + CloseWindow(window); + } } public ICommand SaveComponent @@ -108,14 +136,10 @@ namespace VECTO3GUI.ViewModel.Impl get { return _resetComponentCommand ?? (_resetComponentCommand = new RelayCommand<Component>(DoResetComponent, CanResetComponent)); } } - - private bool CanResetComponent(Component component) { return ComponentsChanged(component); - } - - private void DoResetComponent(Component component) + }private void DoResetComponent(Component component) { switch (component) { @@ -133,7 +157,15 @@ namespace VECTO3GUI.ViewModel.Impl #endregion - + private void SetCurrentDataToSave() + { + CompleteVehicleBusData = new Dictionary<Component, object> { + { Component.CompleteBusVehicle, _subModels[Component.CompleteBusVehicle].SaveComponentData()}, + { Component.Airdrag, _subModels[Component.Airdrag].SaveComponentData()}, + { Component.Auxiliaries, _subModels[Component.Auxiliaries].SaveComponentData()} + }; + } + private bool ComponentsChanged(Component component) { switch (component) { @@ -148,6 +180,12 @@ namespace VECTO3GUI.ViewModel.Impl } } + private void CloseWindow(Window window) + { + WindowAlreadyClosed = true; + window?.Close(); + } + public string JobFile { get; } public IInputDataProvider InputDataProvider { get; set; } diff --git a/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs index d7243c341a4ae4fac8ebaf417733b094c38792fe..b55d31550846b85cf7fe3d2b8257959b246adfdc 100644 --- a/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs @@ -59,7 +59,7 @@ namespace VECTO3GUI.ViewModel.Impl } - protected override void DoSaveJob() + protected override void DoSaveJob(Window window) { var writer = new XMLDeclarationWriter("TEST"); var tmp = writer.GenerateVectoJob(ModelData); @@ -70,7 +70,7 @@ namespace VECTO3GUI.ViewModel.Impl throw new NotImplementedException(); } - protected override void DoSaveToJob() + protected override void DoSaveToJob(Window window) { throw new NotImplementedException(); } diff --git a/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs index 9791a60004e7707815d9aef2579f837687dae1d8..1fd5a9f413815247fc1ee3ae38442d66697a2e7a 100644 --- a/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs @@ -50,7 +50,7 @@ namespace VECTO3GUI.ViewModel.Impl #region Overrides of AbstractJobViewModel - protected override void DoSaveJob() + protected override void DoSaveJob(Window window) { throw new System.NotImplementedException(); } @@ -60,7 +60,7 @@ namespace VECTO3GUI.ViewModel.Impl throw new System.NotImplementedException(); } - protected override void DoSaveToJob() + protected override void DoSaveToJob(Window window) { throw new System.NotImplementedException(); } diff --git a/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs index f70e430fb85658852d0bc504413224d8ec91c5c6..0d17a35448f72749292eda9e01af03713192ef39 100644 --- a/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs @@ -25,7 +25,7 @@ namespace VECTO3GUI.ViewModel.Impl } - protected override void DoSaveJob() + protected override void DoSaveJob(Window window) { throw new NotImplementedException(); } @@ -35,7 +35,7 @@ namespace VECTO3GUI.ViewModel.Impl throw new NotImplementedException(); } - protected override void DoSaveToJob() + protected override void DoSaveToJob(Window window) { throw new NotImplementedException(); } diff --git a/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs b/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs index 1c93496d55442429ec9315eac469b8ae9f4f0b1d..2e849ec87e7c41c7912a3947ab4226e03626253e 100644 --- a/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs +++ b/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs @@ -34,5 +34,7 @@ namespace VECTO3GUI.ViewModel.Interfaces bool SeparateAirDistributionDucts { get; set; } #endregion + ConsumerTechnology DoorDriveTechnology { get; set; } + } } diff --git a/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml b/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml index 4ea7973e75f8d75873626a4b5afe4e835fffbb5f..259c5464310d942e3b737fda2798635d787c8b6c 100644 --- a/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml +++ b/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml @@ -8,6 +8,7 @@ xmlns:customControls="clr-namespace:VECTO3GUI.Views.CustomControls" xmlns:helper="clr-namespace:VECTO3GUI.Helper" xmlns:converter="clr-namespace:VECTO3GUI.Helper.Converter" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="500"> @@ -33,7 +34,9 @@ <customControls:VectoParameterControl Caption="Manufacturer" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding Manufacturer}" /> + Value="{Binding Manufacturer}" > + </customControls:VectoParameterControl> + <customControls:VectoParameterControl Caption="Manufacturer Address" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" Value="{Binding ManufacturerAddress}" /> diff --git a/VECTO3GUI/Views/CustomControls/VectoParameterControl.xaml b/VECTO3GUI/Views/CustomControls/VectoParameterControl.xaml index cc602f30f1093f24a6d8609500de7d056d8b9f73..d5d86f796583a7d3c47836d74a0840012196b3ee 100644 --- a/VECTO3GUI/Views/CustomControls/VectoParameterControl.xaml +++ b/VECTO3GUI/Views/CustomControls/VectoParameterControl.xaml @@ -4,6 +4,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:customControls="clr-namespace:VECTO3GUI.Views.CustomControls" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:helper="clr-namespace:VECTO3GUI.Helper" mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="300" d:DataContext="{d:DesignInstance {x:Type customControls:VectoParameterControl}}"> <Grid Margin="5"> @@ -18,7 +20,11 @@ <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Caption}" Margin="0,0,10,0"/> <TextBox Grid.Row="0" Grid.Column="1" Margin="20,0,0,0" Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" - TextAlignment="{Binding ValueAlign}"/> - <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Unit}" Margin="5,0,5,0"/> + TextAlignment="{Binding ValueAlign}"> + <!--<i:Interaction.Behaviors> + <helper:TextBoxInputRegExBehaviour RegularExpression="^\d+$" MaxLength="9" EmptyValue="0" /> + </i:Interaction.Behaviors>--> + </TextBox> + <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Unit}" Margin="5,0,5,0"/> </Grid> </UserControl> diff --git a/VECTO3GUI/Views/JoblistTabView.xaml b/VECTO3GUI/Views/JoblistTabView.xaml index 87664c951cfceb097cca296f0bf8f5fee8061890..f5391b0b561d4f8594d818f793509b59acab96da 100644 --- a/VECTO3GUI/Views/JoblistTabView.xaml +++ b/VECTO3GUI/Views/JoblistTabView.xaml @@ -7,12 +7,15 @@ xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:converter="clr-namespace:VECTO3GUI.Helper.Converter" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800"> + d:DesignHeight="450" d:DesignWidth="800" + xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro" + xmlns:interfaces="clr-namespace:VECTO3GUI.ViewModel.Interfaces" + Dialog:DialogParticipation.Register="{Binding}"> - <!--<d:JoblistTabView.DataContext> + <d:JoblistTabView.DataContext> <x:Type Type="interfaces:IJobEditViewModel"/> - </d:JoblistTabView.DataContext>--> + </d:JoblistTabView.DataContext> <Grid> @@ -26,10 +29,13 @@ <StackPanel Orientation="Vertical"> <Menu> <MenuItem Header="File"> - <MenuItem Header="Save" Command="{Binding SaveJob}"/> + <MenuItem Header="Save" + Command="{Binding SaveJob}" + CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> <MenuItem Header="Save to" Command="{Binding SaveToJob}"/> <Separator HorizontalAlignment="Stretch" Background="Gray"/> - <MenuItem Header="Exit" Command="{Binding CloseJob}" + <MenuItem Header="Exit" + Command="{Binding CloseJob}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> </MenuItem> </Menu> diff --git a/VECTO3GUI/Views/JoblistView.xaml b/VECTO3GUI/Views/JoblistView.xaml index 3bca126ed38c7cea3b11c3d00bee6f30e06fea45..8cc63c9467189b5db115e826fec105a9ddb97036 100644 --- a/VECTO3GUI/Views/JoblistView.xaml +++ b/VECTO3GUI/Views/JoblistView.xaml @@ -100,8 +100,7 @@ <DataGrid.ContextMenu> <ContextMenu> - <MenuItem Header="Add Job" Command="{Binding AddJob}" - CommandParameter="{Binding ElementName=JobList, Path=SelectedItem}"/> + <MenuItem Header="Add Job" Command="{Binding AddJob}"/> <Separator HorizontalAlignment="Stretch" Background="Gray"/> <MenuItem Header="Create Single Bus Job" Command="{Binding AddBusJob}" CommandParameter="{Binding Source={x:Static impl:JobType.SingleBusJob}}"/> diff --git a/VECTO3GUI/Views/OutputWindow.xaml b/VECTO3GUI/Views/OutputWindow.xaml index 8bad3430b2c056566be50497e7d057a093095a78..e81d0b388d0fca3afff9ae36a1c18ea005ed89b3 100644 --- a/VECTO3GUI/Views/OutputWindow.xaml +++ b/VECTO3GUI/Views/OutputWindow.xaml @@ -8,6 +8,8 @@ xmlns:impl="clr-namespace:VECTO3GUI.ViewModel.Impl" xmlns:interfaces="clr-namespace:VECTO3GUI.ViewModel.Interfaces" xmlns:converters="http://metro.mahapps.com/winfx/xaml/shared" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:helper="clr-namespace:VECTO3GUI.Helper" mc:Ignorable="d" Title="{Binding WindowTitle}" Height="450" Width="800" WindowStartupLocation="CenterScreen" TitleCharacterCasing="Normal" d:DataContext="{d:DesignInstance Type=impl:OutputWindowViewModel, IsDesignTimeCreatable=False}"> @@ -32,7 +34,7 @@ </Grid.RowDefinitions> <Grid Grid.Row="0"> - <ContentControl Content="{Binding ViewModel}" /> + <ContentControl Content="{Binding ViewModel}" /> </Grid> <Grid Grid.Row="1"> @@ -40,4 +42,10 @@ </Grid> </Grid> + <i:Interaction.Triggers> + <i:EventTrigger EventName="Closing"> + <helper:EventCommandExecuter Command="{Binding Path=ViewModel.CloseWindowCommand, Mode=OneTime}"/> + </i:EventTrigger> + </i:Interaction.Triggers> + </mah:MetroWindow>