using CodeStatistics.Handling; using CodeStatistics.Input; using System; using System.ComponentModel; using System.Windows.Forms; using CodeStatistics.Output; using System.Diagnostics; using System.Globalization; using CodeStatistics.Data; using CodeStatistics.Input.Methods; using System.IO; using CodeStatisticsCore.Forms; using CodeStatisticsCore.Handling; namespace CodeStatistics.Forms{ sealed partial class ProjectLoadForm : Form{ private readonly IInputMethod inputMethod; private FileSearch search; private Project project; private Variables variables; private string outputFile; [Localizable(true)] private string lastOutputGenError; private ProjectLoadForm(){ InitializeComponent(); Text = Lang.Get["TitleProject"]; btnCancel.Text = Lang.Get["LoadProjectCancel"]; btnClose.Text = Lang.Get["LoadProjectClose"]; btnOpenOutput.Text = Lang.Get["LoadProjectOpenOutput"]; btnDebugProject.Text = Lang.Get["LoadProjectDebug"]; btnBreakPoint.Text = Lang.Get["LoadProjectBreakpoint"]; if (Program.Config.NoGui)Opacity = 0; } public ProjectLoadForm(IInputMethod inputMethod) : this(){ this.inputMethod = inputMethod; } private void OnLoad(object sender, EventArgs e){ inputMethod.BeginProcess(new UpdateCallbacks(this)); } private void OnReady(FileSearch fileSearch){ this.search = fileSearch; BeginProjectLoad(); } private void BeginProjectLoad(){ labelLoadInfo.Text = Lang.Get["LoadProjectSearchIO"]; labelLoadData.Text = ""; search.Refresh += count => this.InvokeOnUIThread(() => { labelLoadData.Text = count.ToString(CultureInfo.InvariantCulture); }); search.Finish += data => this.InvokeOnUIThread(() => { labelLoadInfo.Text = Lang.Get["LoadProjectProcess"]; labelLoadData.Text = ""; UpdateProgress(ProgressBarStyle.Continuous,0); project = new Project(data); project.Progress += (percentage, processedEntries, totalEntries) => this.InvokeOnUIThread(() => { UpdateProgress(ProgressBarStyle.Continuous,percentage); labelLoadData.Text = Lang.Get["LoadProjectProcessingFiles",processedEntries,totalEntries]; }); project.Finish += vars => this.InvokeOnUIThread(() => { variables = Program.Config.IsDebuggingTemplate ? new Variables.Dummy() : vars; labelLoadInfo.Text = Lang.Get["LoadProjectProcessingDone"]; btnCancel.Visible = false; flowLayoutButtonsReady.Visible = true; #if DEBUG flowLayoutButtonsDebug.Visible = true; #else flowLayoutButtonsDebug.Visible = Program.Config.IsDebuggingProject; #endif while(!GenerateOutputFile()){ DialogResult res = MessageBox.Show(lastOutputGenError,Lang.Get["LoadProjectError"],MessageBoxButtons.RetryCancel,MessageBoxIcon.Warning); if (res == DialogResult.Cancel){ DialogResult = DialogResult.Abort; Close(); break; } } if (Program.Config.AutoOpenBrowser){ btnOpenOutput_Click(null,new EventArgs()); } if (Program.Config.CloseOnFinish){ DialogResult = DialogResult.Abort; Close(); } if (Program.Config.IsDebuggingTemplate){ string templateFile = Program.Config.GetCustomTemplateFilePath(); if (templateFile == null)return; // WTF FileSystemWatcher watcher = new FileSystemWatcher{ Path = Path.GetDirectoryName(templateFile), Filter = Path.GetFileName(templateFile), NotifyFilter = NotifyFilters.LastWrite }; watcher.Changed += (sender, args) => { labelLoadData.Text = Lang.Get["LoadProjectDummyTemplateRebuild"]; labelLoadData.Text = GenerateOutputFile() ? Lang.Get["LoadProjectDummyTemplateWait"] : Lang.Get["LoadProjectDummyTemplateFailed"]; }; watcher.EnableRaisingEvents = true; labelLoadData.Text = Lang.Get["LoadProjectDummyTemplateWait"]; } }); project.Failure += ex => this.InvokeOnUIThread(() => { MessageBox.Show(Lang.Get["LoadProjectErrorProcessing",ex.ToString()],Lang.Get["LoadProjectError"],MessageBoxButtons.OK,MessageBoxIcon.Error); Close(); }); project.ProcessAsync(); }); search.Failure += ex => this.InvokeOnUIThread(() => { MessageBox.Show(Lang.Get["LoadProjectErrorFileSearch",ex.ToString()],Lang.Get["LoadProjectError"],MessageBoxButtons.OK,MessageBoxIcon.Error); Close(); }); search.StartAsync(); } private bool GenerateOutputFile(){ string template = Program.Config.GetTemplateContents(); if (template == null){ lastOutputGenError = Lang.Get["LoadProjectErrorNoTemplate"]; return false; } outputFile = Program.Config.GetOutputFilePath(); GenerateHtml generator = new GenerateHtml(template.Split('\n','\r'),variables); switch(generator.ToFile(outputFile)){ case GenerateHtml.Result.Succeeded: return true; case GenerateHtml.Result.TemplateError: lastOutputGenError = Lang.Get["LoadProjectErrorInvalidTemplate",generator.LastError]; return false; case GenerateHtml.Result.IoError: lastOutputGenError = Lang.Get["LoadProjectErrorIO",generator.LastError]; return false; default: lastOutputGenError = Lang.Get["LoadProjectErrorUnknown"]; return false; } } private void UpdateProgress(ProgressBarStyle style, int percentage){ if (progressBarLoad.Style == ProgressBarStyle.Marquee && style == ProgressBarStyle.Marquee){ return; // fix progress bar freaking out when re-setting marquee } progressBarLoad.Style = style; int percValue = percentage*10; // instant progress bar update hack if (percValue == progressBarLoad.Maximum){ progressBarLoad.Value = percValue; progressBarLoad.Value = percValue-1; progressBarLoad.Value = percValue; } else{ progressBarLoad.Value = percValue+1; progressBarLoad.Value = percValue; } } private void btnCancel_Click(object sender, EventArgs e){ if (variables == null){ if (project != null)project.Cancel(() => this.InvokeOnUIThread(OnCancel)); else if (search != null)search.CancelProcess(() => this.InvokeOnUIThread(OnCancel)); else if (inputMethod != null)inputMethod.CancelProcess(() => this.InvokeOnUIThread(OnCancel)); else return; } btnCancel.Enabled = false; } private void OnCancel(){ DialogResult = DialogResult.Cancel; Close(); } private void btnClose_Click(object sender, EventArgs e){ DialogResult = DialogResult.OK; Close(); } private void btnOpenOutput_Click(object sender, EventArgs e){ if (outputFile == null)return; Process.Start(outputFile); } private void btnDebugProject_Click(object sender, EventArgs e){ if (project == null || variables == null)return; new ProjectDebugForm(project).ShowDialog(); } private void btnBreakPoint_Click(object sender, EventArgs e){ if (project == null || variables == null)return; Debugger.Break(); } public class UpdateCallbacks{ private readonly ProjectLoadForm form; public UpdateCallbacks(ProjectLoadForm form){ this.form = form; } public void UpdateInfoLabel([Localizable(true)] string text){ form.InvokeOnUIThread(() => form.labelLoadInfo.Text = text); } public void UpdateDataLabel([Localizable(true)] string text){ form.InvokeOnUIThread(() => form.labelLoadData.Text = text); } public void UpdateProgress(int progress){ form.InvokeOnUIThread(() => { if (progress == -1)form.UpdateProgress(ProgressBarStyle.Marquee,100); else form.UpdateProgress(ProgressBarStyle.Continuous,progress); }); } public void OnReady(FileSearch fileSearch){ form.InvokeOnUIThread(() => form.OnReady(fileSearch)); } } } }