From 985385527af4cc486668f21d346b1a2e07bc4fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Tue, 27 Mar 2018 00:41:51 +0100 Subject: [PATCH] Builder improvements. --- source/Cosmos.Build.Builder/Models/Section.cs | 40 +++ .../ViewModels/MainWindowViewModel.cs | 7 + .../Views/MainWindow.xaml | 40 ++- .../Views/MainWindow.xaml.cs | 336 +++++++++--------- 4 files changed, 248 insertions(+), 175 deletions(-) create mode 100644 source/Cosmos.Build.Builder/Models/Section.cs diff --git a/source/Cosmos.Build.Builder/Models/Section.cs b/source/Cosmos.Build.Builder/Models/Section.cs new file mode 100644 index 000000000..e784be846 --- /dev/null +++ b/source/Cosmos.Build.Builder/Models/Section.cs @@ -0,0 +1,40 @@ +using System.ComponentModel; +using System.Text; + +namespace Cosmos.Build.Builder.Models +{ + internal class Section : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public string Name { get; } + public string Log => _logBuilder.ToString(); + public bool HasLoggedErrors { get; private set; } + + private StringBuilder _logBuilder; + + public Section(string name) + { + Name = name; + _logBuilder = new StringBuilder(); + } + + public void LogMessage(string message) + { + _logBuilder.AppendLine(message); + OnPropertyChanged(nameof(Log)); + } + + public void SetError() + { + if (!HasLoggedErrors) + { + HasLoggedErrors = true; + OnPropertyChanged(nameof(HasLoggedErrors)); + } + } + + private void OnPropertyChanged(string propertyName) => + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } +} diff --git a/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs b/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs index 602ffaffb..07d1d3a8e 100644 --- a/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs +++ b/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.ObjectModel; +using System.Linq; using System.Text; using System.Windows; using System.Windows.Input; using Cosmos.Build.Builder.Collections; +using Cosmos.Build.Builder.Models; namespace Cosmos.Build.Builder.ViewModels { @@ -14,6 +17,9 @@ namespace Cosmos.Build.Builder.ViewModels public ICommand CopyCommand { get; } public ObservableFixedSizeStack TailItems { get; } + public ObservableCollection
Sections { get; } + + public Section CurrentSection => Sections.LastOrDefault(); public StringBuilder LogBuilder { get; set; } @@ -22,6 +28,7 @@ namespace Cosmos.Build.Builder.ViewModels CopyCommand = new Command(this); TailItems = new ObservableFixedSizeStack(TailItemCount); + Sections = new ObservableCollection
(); } private class Command : ICommand diff --git a/source/Cosmos.Build.Builder/Views/MainWindow.xaml b/source/Cosmos.Build.Builder/Views/MainWindow.xaml index 3af890baf..81a31af49 100644 --- a/source/Cosmos.Build.Builder/Views/MainWindow.xaml +++ b/source/Cosmos.Build.Builder/Views/MainWindow.xaml @@ -12,6 +12,9 @@ Title="Cosmos Kit Builder" WindowStartupLocation="CenterScreen" DataContext="{StaticResource MainWindowViewModel}"> + + + @@ -28,13 +31,13 @@ FontSize="18" Foreground="Blue" FontWeight="ExtraBold" - Text="Current Task Log Tail" /> + Text="{Binding CurrentSection.Name, StringFormat='Current Task Log Tail - {0}', FallbackValue='Current Task Log Tail'}" /> @@ -51,8 +54,37 @@ - - + + + + + + + + + + + + + + + + + diff --git a/source/Cosmos.Build.Builder/Views/MainWindow.xaml.cs b/source/Cosmos.Build.Builder/Views/MainWindow.xaml.cs index abbd8ce5b..0e728fc98 100644 --- a/source/Cosmos.Build.Builder/Views/MainWindow.xaml.cs +++ b/source/Cosmos.Build.Builder/Views/MainWindow.xaml.cs @@ -3,183 +3,177 @@ using System.IO; using System.Linq; using System.Text; using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; using System.Windows.Threading; + +using Cosmos.Build.Builder.Models; using Cosmos.Build.Installer; -namespace Cosmos.Build.Builder.Views { - public partial class MainWindow : Window { - private static readonly string[] NewLineStringArray = new string[] { Environment.NewLine }; +namespace Cosmos.Build.Builder.Views +{ + public partial class MainWindow : Window + { + private static readonly string[] NewLineStringArray = new string[] { Environment.NewLine }; - string mCosmosDir; - string mSetupPath; - // Needs updating with each new release. - int mReleaseNo = 106027; - string mTailCaption; + string mCosmosDir; + string mSetupPath; + // Needs updating with each new release. + int mReleaseNo = 106027; - - public MainWindow() { - InitializeComponent(); - mTailCaption = tblkTail.Text + " - "; - } - - bool mPreventAutoClose = false; - TextBlock mSection; - TextBlock mContent; - StringBuilder mClipboard = new StringBuilder(); - DispatcherTimer mCloseTimer; - - - public bool Build() { - Log.LogLine += new Log.LogLineHandler(Log_LogLine); - Log.LogSection += new Log.LogSectionHandler(Log_LogSection); - Log.LogError += new Log.LogErrorHandler(Log_LogError); - - if (App.IsUserKit) { - mReleaseNo = Int32.Parse(DateTime.Now.ToString("yyyyMMdd")); - } - if (mPreventAutoClose) { - return true; - } - - var xTask = new CosmosTask(mCosmosDir, mReleaseNo); - - var xThread = new System.Threading.Thread(delegate () { - xTask.Run(); - ThreadDone(); - }); - xThread.Start(); - - return true; - } - - void ThreadDone() { - Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () { - if (App.StayOpen == false) { - mCloseTimer = new DispatcherTimer(); - mCloseTimer.Interval = TimeSpan.FromSeconds(5); - mCloseTimer.Tick += delegate { - mCloseTimer.Stop(); - if (mPreventAutoClose) { - if (WindowState == WindowState.Minimized) { - WindowState = WindowState.Normal; - } - } else { - Close(); - } - }; - mCloseTimer.Start(); - } - }); - } - - void ClearTail() { - if (DataContext is ViewModels.MainWindowViewModel viewModel) - { - viewModel.TailItems.Clear(); - } - } - - void Log_LogError() { - Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () { - ClearTail(); - - mSection.Foreground = Brushes.Red; - mContent.Visibility = Visibility.Visible; - mPreventAutoClose = true; - }); - } - - void Log_LogLine(string aLine) { - Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () { - WriteTail(aLine); - - mClipboard.AppendLine(aLine); - - mContent.Inlines.Add(aLine); - mContent.Inlines.Add(new LineBreak()); - }); - } - - void Log_LogSection(string aLine) { - Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () { - Title = aLine; - - ClearTail(); - tblkTail.Text = mTailCaption + aLine; - - mClipboard.AppendLine(); - mClipboard.AppendLine(new string('=', aLine.Length)); - mClipboard.AppendLine(aLine); - mClipboard.AppendLine(new string('=', aLine.Length)); - mClipboard.AppendLine(); - - mSection = new TextBlock(); - mSection.Text = aLine; - mSection.Background = Brushes.LightGray; - mSection.Foreground = Brushes.Green; - mSection.FontSize = 18; - mSection.FontWeight = FontWeights.Bold; - mSection.MouseUp += new MouseButtonEventHandler(mSection_MouseUp); - spnlLog.Children.Add(mSection); - - mContent = new TextBlock(); - mContent.Visibility = Visibility.Collapsed; - spnlLog.Children.Add(mContent); - mSection.Tag = mContent; - }); - } - - void mSection_MouseUp(object sender, MouseButtonEventArgs e) { - var xSection = (TextBlock)sender; - var xContent = (TextBlock)xSection.Tag; - xContent.Visibility = xContent.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; - mPreventAutoClose = true; - } - - void WriteTail(string aText) { - if (DataContext is ViewModels.MainWindowViewModel viewModel) - { - foreach (var line in aText.Split(NewLineStringArray, StringSplitOptions.None)) + public MainWindow() { - viewModel.TailItems.Push(line); + InitializeComponent(); + } + + bool mPreventAutoClose = false; + StringBuilder mClipboard = new StringBuilder(); + DispatcherTimer mCloseTimer; + + public bool Build() + { + Log.LogLine += new Log.LogLineHandler(Log_LogLine); + Log.LogSection += new Log.LogSectionHandler(Log_LogSection); + Log.LogError += new Log.LogErrorHandler(Log_LogError); + + if (App.IsUserKit) + { + mReleaseNo = Int32.Parse(DateTime.Now.ToString("yyyyMMdd")); + } + if (mPreventAutoClose) + { + return true; + } + + var xTask = new CosmosTask(mCosmosDir, mReleaseNo); + + var xThread = new System.Threading.Thread(delegate () + { + xTask.Run(); + ThreadDone(); + }); + xThread.Start(); + + return true; + } + + void ThreadDone() + { + Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () + { + if (App.StayOpen == false) + { + mCloseTimer = new DispatcherTimer(); + mCloseTimer.Interval = TimeSpan.FromSeconds(5); + mCloseTimer.Tick += delegate + { + mCloseTimer.Stop(); + if (mPreventAutoClose) + { + if (WindowState == WindowState.Minimized) + { + WindowState = WindowState.Normal; + } + } + else + { + Close(); + } + }; + mCloseTimer.Start(); + } + }); + } + + void ClearTail() => DoOnViewModel(vm => vm.TailItems.Clear()); + + void Log_LogError() + { + Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () + { + ClearTail(); + + DoOnViewModel(vm => vm.CurrentSection?.SetError()); + + mPreventAutoClose = true; + }); + } + + void Log_LogLine(string aLine) + { + Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () + { + WriteTail(aLine); + + DoOnViewModel(vm => vm.CurrentSection?.LogMessage(aLine)); + + mClipboard.AppendLine(aLine); + }); + } + + void Log_LogSection(string name) + { + Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate () + { + DoOnViewModel(vm => vm.Sections.Add(new Section(name))); + + ClearTail(); + + mClipboard.AppendLine(); + mClipboard.AppendLine(new string('=', name.Length)); + mClipboard.AppendLine(name); + mClipboard.AppendLine(new string('=', name.Length)); + mClipboard.AppendLine(); + }); + } + + void WriteTail(string aText) => DoOnViewModel( + vm => + { + foreach (var line in aText.Split(NewLineStringArray, StringSplitOptions.None)) + { + vm.TailItems.Push(line); + } + }); + + protected bool mLoaded = false; + void Window_Loaded(object sender, RoutedEventArgs e) + { + if (!App.mArgs.Any()) + { + MessageBox.Show("Builder not meant to be called directly. Use install.bat instead.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); + Close(); + return; + } + + mLoaded = true; + + DoOnViewModel(vm => vm.LogBuilder = mClipboard); + + string xAppPath = AppContext.BaseDirectory; + mCosmosDir = Path.GetFullPath(xAppPath + @"..\..\..\..\..\"); + mSetupPath = Path.Combine(mCosmosDir, @"Setup\Output\" + CosmosTask.GetSetupName(mReleaseNo) + ".exe"); + if (!Build()) + { + Close(); + } + } + + private void Window_SizeChanged(object sender, SizeChangedEventArgs e) + { + // User had non minimized window, or maximized it, or otherwise manually intervened. + // Even if starting minimized, this event gets called with Normal before load. + // This is why we have mLoaded. + if (mLoaded && WindowState != WindowState.Minimized) + { + mPreventAutoClose = true; + } + } + + private void DoOnViewModel(Action action) + { + if (DataContext is ViewModels.MainWindowViewModel viewModel) + { + action(viewModel); + } } - } } - - protected bool mLoaded = false; - void Window_Loaded(object sender, RoutedEventArgs e) { - if (!App.mArgs.Any()) { - MessageBox.Show("Builder not meant to be called directly. Use install.bat instead.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); - Close(); - return; - } - - mLoaded = true; - - if (DataContext is ViewModels.MainWindowViewModel viewModel) - { - viewModel.LogBuilder = mClipboard; - } - - string xAppPath = AppContext.BaseDirectory; - mCosmosDir = Path.GetFullPath(xAppPath + @"..\..\..\..\..\"); - mSetupPath = Path.Combine(mCosmosDir, @"Setup\Output\" + CosmosTask.GetSetupName(mReleaseNo) + ".exe"); - if (!Build()) { - Close(); - } - } - - private void Window_SizeChanged(object sender, SizeChangedEventArgs e) { - // User had non minimized window, or maximized it, or otherwise manually intervened. - // Even if starting minimized, this event gets called with Normal before load. - // This is why we have mLoaded. - if (mLoaded && WindowState != WindowState.Minimized) { - mPreventAutoClose = true; - } - } - } }