Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Scripting.Views/3.3/ScriptView.cs @ 18030

Last change on this file since 18030 was 17384, checked in by jkarder, 5 years ago

#3045: added dialog that displays warning/error information

File size: 9.1 KB
RevLine 
[10332]1#region License Information
2/* HeuristicLab
[17180]3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[10332]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.CodeDom.Compiler;
[11807]24using System.Collections.Generic;
[10332]25using System.Drawing;
[10506]26using System.Globalization;
[10332]27using System.Linq;
[11807]28using System.Reflection;
[10332]29using System.Windows.Forms;
[11807]30using HeuristicLab.Common;
[10332]31using HeuristicLab.Common.Resources;
32using HeuristicLab.Core.Views;
33using HeuristicLab.MainForm;
34
[10506]35namespace HeuristicLab.Scripting.Views {
[10332]36
[10401]37  [View("Script View")]
38  [Content(typeof(Script), true)]
39  public partial class ScriptView : NamedItemView {
[11819]40    private const string NotCompiledMessage = "Not compiled";
41    private const string CompilationSucceededMessage = "Compilation succeeded";
42    private const string CompilationFailedMessage = "Compilation failed";
[11807]43    private const string AssembliesLoadingMessage = "Loading Assemblies";
44    private const string AssembliesUnloadingMessage = "Unloading Assemblies";
45    private const int SilentAssemblyLoadingOperationLimit = 10;
46
[11657]47    #region Properties
[10401]48    public new Script Content {
49      get { return (Script)base.Content; }
[10731]50      set { base.Content = value; }
[10332]51    }
52
[11436]53    public override bool ReadOnly {
[11480]54      get { return codeEditor.ReadOnly || base.ReadOnly; }
55      set { base.ReadOnly = codeEditor.ReadOnly = value; }
[11436]56    }
57
58    public override bool Locked {
[11480]59      get { return codeEditor.ReadOnly || base.Locked; }
60      set { base.Locked = codeEditor.ReadOnly = value; }
[11436]61    }
[11657]62    #endregion
[11436]63
[11657]64    public ScriptView() {
65      InitializeComponent();
66      errorListView.SmallImageList.Images.AddRange(new Image[] { VSImageLibrary.Warning, VSImageLibrary.Error });
67    }
68
[10332]69    protected override void RegisterContentEvents() {
70      base.RegisterContentEvents();
[11657]71      Content.CodeChanged += Content_CodeChanged;
[10332]72    }
73
74    protected override void DeregisterContentEvents() {
[11657]75      Content.CodeChanged -= Content_CodeChanged;
[10332]76      base.DeregisterContentEvents();
77    }
78
[11657]79    #region Overrides
[10332]80    protected override void OnContentChanged() {
81      base.OnContentChanged();
82      if (Content == null) {
83        codeEditor.UserCode = string.Empty;
[16528]84        codeEditor.ClearEditHistory();
[10332]85      } else {
[11807]86        codeEditor.UserCode = Content.Code;
[16528]87        codeEditor.ClearEditHistory();
[11807]88        codeEditor.AddAssembliesAsync(Content.GetAssemblies());
[10332]89        if (Content.CompileErrors == null) {
[11836]90          UpdateInfoTextLabel(NotCompiledMessage, SystemColors.ControlText);
[10332]91        }
92      }
93    }
94
95    protected override void SetEnabledStateOfControls() {
96      base.SetEnabledStateOfControls();
[10506]97      compileButton.Enabled = Content != null && !Locked && !ReadOnly;
[11436]98      codeEditor.Enabled = Content != null;
[10332]99    }
100
101    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
[10506]102      switch (keyData) {
103        case Keys.F6:
[10731]104          if (Content != null && !Locked)
105            Compile();
106          return true;
[10332]107      }
108      return base.ProcessCmdKey(ref msg, keyData);
109    }
[11657]110    #endregion
[10332]111
[10731]112    public virtual bool Compile() {
[10332]113      ReadOnly = true;
[10358]114      Locked = true;
[10332]115      errorListView.Items.Clear();
[10506]116      outputTextBox.Text = "Compiling ... ";
[10332]117      try {
118        Content.Compile();
[11819]119        outputTextBox.AppendText(CompilationSucceededMessage);
[11836]120        UpdateInfoTextLabel(CompilationSucceededMessage, Color.DarkGreen);
[10332]121        return true;
[11882]122      } catch (CompilationException) {
[10865]123        if (Content.CompileErrors.HasErrors) {
[11819]124          outputTextBox.AppendText(CompilationFailedMessage);
[11836]125          UpdateInfoTextLabel(CompilationFailedMessage, Color.DarkRed);
[10865]126          return false;
127        } else {
[11819]128          outputTextBox.AppendText(CompilationSucceededMessage);
[11836]129          UpdateInfoTextLabel(CompilationSucceededMessage, Color.DarkGreen);
[10865]130          return true;
131        }
[10332]132      } finally {
[10506]133        ShowCompilationResults();
[10642]134        if (Content.CompileErrors.Count > 0)
135          infoTabControl.SelectedTab = errorListTabPage;
[10332]136        ReadOnly = false;
[10358]137        Locked = false;
[11657]138        codeEditor.Focus();
[10332]139      }
140    }
141
[11657]142    #region Helpers
[10731]143    protected virtual void ShowCompilationResults() {
[11657]144      var messages = Content.CompileErrors.OfType<CompilerError>()
[10506]145                                      .OrderBy(x => x.IsWarning)
146                                      .ThenBy(x => x.Line)
147                                      .ThenBy(x => x.Column);
[11657]148
149      foreach (var m in messages) {
150        var item = new ListViewItem { Tag = m };
[10506]151        item.SubItems.AddRange(new[] {
[10332]152          m.IsWarning ? "Warning" : "Error",
153          m.ErrorNumber,
[10506]154          m.Line.ToString(CultureInfo.InvariantCulture),
155          m.Column.ToString(CultureInfo.InvariantCulture),
[10332]156          m.ErrorText
157        });
[10506]158        item.ImageIndex = m.IsWarning ? 0 : 1;
[10332]159        errorListView.Items.Add(item);
160      }
[11657]161
[11807]162      codeEditor.ShowCompileErrors(Content.CompileErrors);
[11657]163
[10506]164      AdjustErrorListViewColumnSizes();
[10332]165    }
[10506]166
[11836]167    protected virtual void UpdateInfoTextLabel(string message, Color color) {
168      infoTextLabel.Text = message;
169      infoTextLabel.ForeColor = color;
170    }
171
[10731]172    protected virtual void AdjustErrorListViewColumnSizes() {
[10506]173      foreach (ColumnHeader ch in errorListView.Columns)
[10865]174        // adjusts the column width to the width of the column header
[10506]175        ch.Width = -2;
176    }
[11807]177
178    #region ProgressView
179    private bool progressViewCreated;
180
181    private void AddProgressView(string progressMessage) {
[16430]182      Progress.Show(this, progressMessage, ProgressMode.Indeterminate);
[11807]183      progressViewCreated = true;
184    }
185
186    private void RemoveProgressView() {
187      if (!progressViewCreated) return;
[16430]188      Progress.Hide(this);
[11807]189      progressViewCreated = false;
190    }
[11657]191    #endregion
[11807]192    #endregion
[11657]193
194    #region Event Handlers
[11942]195    protected virtual void Content_CodeChanged(object sender, EventArgs e) {
[11807]196      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_CodeChanged, sender, e);
[11657]197      else {
198        codeEditor.UserCode = Content.Code;
199      }
200    }
201
202    private void compileButton_Click(object sender, EventArgs e) {
203      Compile();
204    }
205
206    private void codeEditor_TextEditorTextChanged(object sender, EventArgs e) {
207      if (Content == null) return;
208      Content.Code = codeEditor.UserCode;
209    }
210
[17384]211    private void errorListView_MouseClick(object sender, MouseEventArgs e) {
212      if (e.Button != MouseButtons.Left) return;
213
214      var item = errorListView.SelectedItems[0];
215      var message = (CompilerError)item.Tag;
216
217      codeEditor.ScrollToPosition(message.Line, message.Column);
218      codeEditor.Focus();
219    }
220
[11657]221    private void errorListView_MouseDoubleClick(object sender, MouseEventArgs e) {
[17384]222      if (e.Button != MouseButtons.Left) return;
223
224      var item = errorListView.SelectedItems[0];
225      var message = (CompilerError)item.Tag;
226
227      using (var dialog = new CompilerErrorDialog(message)) {
228        dialog.ShowDialog(this);
229      };
[11657]230    }
231    #endregion
[11807]232
233    private void codeEditor_AssembliesLoading(object sender, EventArgs<IEnumerable<Assembly>> e) {
234      if (InvokeRequired) Invoke((Action<object, EventArgs<IEnumerable<Assembly>>>)codeEditor_AssembliesLoading, sender, e);
235      else {
236        int nrOfAssemblies = e.Value.Count();
237        if (nrOfAssemblies > SilentAssemblyLoadingOperationLimit)
238          AddProgressView(AssembliesLoadingMessage);
239      }
240    }
241
242    private void codeEditor_AssembliesLoaded(object sender, EventArgs<IEnumerable<Assembly>> e) {
243      if (InvokeRequired) Invoke((Action<object, EventArgs<IEnumerable<Assembly>>>)codeEditor_AssembliesLoaded, sender, e);
244      else {
245        RemoveProgressView();
246      }
247    }
248
249    private void codeEditor_AssembliesUnloading(object sender, EventArgs<IEnumerable<Assembly>> e) {
250      if (InvokeRequired) Invoke((Action<object, EventArgs<IEnumerable<Assembly>>>)codeEditor_AssembliesUnloading, sender, e);
251      else {
252        int nrOfAssemblies = e.Value.Count();
253        if (nrOfAssemblies > SilentAssemblyLoadingOperationLimit)
254          AddProgressView(AssembliesUnloadingMessage);
255      }
256    }
257
258    private void codeEditor_AssembliesUnloaded(object sender, EventArgs<IEnumerable<Assembly>> e) {
259      if (InvokeRequired) Invoke((Action<object, EventArgs<IEnumerable<Assembly>>>)codeEditor_AssembliesUnloaded, sender, e);
260      else {
261        RemoveProgressView();
262      }
263    }
[10332]264  }
265}
Note: See TracBrowser for help on using the repository browser.