using FastReport.Controls; using FastReport.Utils; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; using System; using System.Threading.Tasks; using System.Threading; #if !MONO using FastReport.DevComponents.DotNetBar; #endif namespace FastReport.Design.ToolWindows { /// /// Represents the "Validator" window. /// public class ValidatorWindow : ToolWindowBase { #region Fields private DataGridView gridView; private Splitter splitter; private TextBox tbUpdating; private CancellationTokenSource updateErrCancelToken; System.Windows.Forms.Timer timer; private bool skipSelectChanged; #endregion #region Private Methods private Image GetImage(ValidationError.ErrorLevel level) { switch (level) { case ValidationError.ErrorLevel.Warning: return Res.GetImage(211, 96); default: return Res.GetImage(80, 96); } } private void Timer_Tick(object sender, EventArgs e) { if (tbUpdating.Text.Contains("...")) tbUpdating.Text = tbUpdating.Text.Replace("...", ""); else tbUpdating.Text += "."; } #if !MONO private void ParentControl_VisibleChanged(object sender, EventArgs e) { if (ParentControl.Visible) UpdateErrors(!PageDesigners.Page.ReportWorkspace.EnableBacklightIntersectingObjects); } #else private void ValidatorWindow_VisibleChanged(object sender, EventArgs e) { if (this.Visible) UpdateErrors(!PageDesigners.Page.ReportWorkspace.EnableBacklightIntersectingObjects); } #endif private void GridView_SelectionChanged(object sender, EventArgs e) { if (skipSelectChanged || gridView.SelectedRows.Count == 0) return; ValidationError validationError = (ValidationError)gridView.SelectedRows[0].Tag; if (validationError.Object.Page != Designer.ActiveReportTab.ActivePage) Designer.ActiveReportTab.ActivePage = validationError.Object.Page; Designer.SelectedObjects.Clear(); Designer.SelectedObjects.Add(validationError.Object); Designer.SelectionChanged(this); } private void UpdateUI(List errors, CancellationTokenSource token) { if (errors == null) return; skipSelectChanged = true; gridView.Rows.Clear(); if (!token.IsCancellationRequested) { timer.Enabled = false; tbUpdating.Hide(); gridView.Show(); } foreach (ValidationError error in errors) { gridView.Rows.Add(GetImage(error.Level), error.Name, error.Message); gridView.Rows[gridView.RowCount - 1].Tag = error; } skipSelectChanged = false; } #endregion #region Public Methods /// /// Initializes a new instance of the class with default settings. /// /// The report designer. public ValidatorWindow(Designer designer) : base(designer) { #if !MONO ParentControl.VisibleChanged += ParentControl_VisibleChanged; #else this.VisibleChanged += ValidatorWindow_VisibleChanged; #endif updateErrCancelToken = new CancellationTokenSource(); Name = "ValidatorWindow"; skipSelectChanged = false; timer = new System.Windows.Forms.Timer(); timer.Interval = 1500; timer.Tick += Timer_Tick; tbUpdating = new TextBox(); tbUpdating.Dock = DockStyle.Top; tbUpdating.TextAlign = HorizontalAlignment.Center; tbUpdating.Visible = false; tbUpdating.Text = "Updating"; tbUpdating.ReadOnly = true; tbUpdating.BackColor = Color.White; gridView = new DataGridView(); gridView.Dock = DockStyle.Fill; gridView.ColumnHeadersHeight = 25; gridView.BackgroundColor = Color.White; gridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; gridView.AllowUserToAddRows = false; gridView.AllowUserToDeleteRows = false; gridView.RowHeadersVisible = false; gridView.SelectionChanged += GridView_SelectionChanged; gridView.CellClick += GridView_SelectionChanged; gridView.Columns.Add(new DataGridViewColumn(new DataGridViewImageCell())); gridView.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; gridView.Columns[0].MinimumWidth = 24; gridView.Columns[0].ReadOnly = true; gridView.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; gridView.Columns.Add(new DataGridViewColumn(new DataGridViewTextBoxCell())); gridView.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; gridView.Columns[1].ReadOnly = true; gridView.Columns.Add(new DataGridViewColumn(new DataGridViewTextBoxCell())); gridView.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; gridView.Columns[2].ReadOnly = true; #if !MONO splitter = new Splitter(); splitter.Dock = DockStyle.Bottom; splitter.Visible = true; ParentControl.Controls.AddRange(new Control[] { gridView, splitter, tbUpdating }); #else splitter = new Splitter(); splitter.Dock = DockStyle.Bottom; splitter.Visible = true; Controls.AddRange(new Control[] { gridView, splitter, tbUpdating }); #endif timer.Enabled = true; tbUpdating.Show(); gridView.Hide(); UpdateDpiDependencies(); Localize(); } /// /// Updating list of report objects errors in other thread. /// /// public void UpdateErrors(bool checkIntersectObj) { tbUpdating.Show(); timer.Enabled = true; updateErrCancelToken.Cancel(); updateErrCancelToken = new CancellationTokenSource(); Action action = (object token) => { CancellationTokenSource tokenSource = token as CancellationTokenSource; List errors = Validator.ValidateReport(Designer.ActiveReport, checkIntersectObj, tokenSource.Token); if(!tokenSource.IsCancellationRequested) gridView.Invoke((Action)(() => UpdateUI(errors, tokenSource))); }; Task.Factory.StartNew(action, updateErrCancelToken, updateErrCancelToken.Token); } /// /// Stoping thread with UpdateErrors task. /// public void CancelUpdateErrors() { updateErrCancelToken.Cancel(); } /// /// Hiding table with errors and showing loading progress. /// public void ShowLoadingProgress() { tbUpdating.Show(); gridView.Hide(); timer.Enabled = true; } /// public override void UpdateContent() { base.UpdateContent(); #if !MONO if (ParentControl.Visible) #else if (Visible) #endif UpdateErrors(!PageDesigners.Page.ReportWorkspace.EnableBacklightIntersectingObjects); } /// public override void UpdateUIStyle() { base.UpdateUIStyle(); #if !MONO splitter.BackColor = UIStyleUtils.GetControlColor(Designer.UIStyle); #else splitter.BackColor = UIStyleUtils.GetColorTable(Designer.UIStyle).ControlBackColor; #endif } /// public override void Localize() { base.Localize(); MyRes res = new MyRes("Designer,ToolWindow,Validator"); Text = res.Get(""); gridView.Columns[1].HeaderText = res.Get("Name"); gridView.Columns[2].HeaderText = res.Get("Message"); tbUpdating.Text = res.Get("Updating"); UpdateErrors(!Design.PageDesigners.Page.ReportWorkspace.EnableBacklightIntersectingObjects); } /// public override void UpdateDpiDependencies() { base.UpdateDpiDependencies(); Image = Designer.GetImage(70); } /// public override void SaveState() { XmlItem xi = Config.Root.FindItem("Designer").FindItem(Name); xi.SetProp("GridViewColumn1Width", gridView.Columns[1].Width.ToString()); xi.SetProp("GridViewColumn2Width", gridView.Columns[2].Width.ToString()); xi.SetProp("GridViewHeadersHeight", gridView.ColumnHeadersHeight.ToString()); } /// public override void RestoreState() { XmlItem xi = Config.Root.FindItem("Designer").FindItem(Name); string s = xi.GetProp("GridViewColumn1Width"); if (s != "") gridView.Columns[1].Width = int.Parse(s); s = xi.GetProp("GridViewColumn2Width"); if (s != "") gridView.Columns[2].Width = int.Parse(s); s = xi.GetProp("GridViewHeadersHeight"); if (s != "") gridView.ColumnHeadersHeight = int.Parse(s); } #endregion } }