Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11694 was 11657, checked in by jkarder, 10 years ago

#2262: applied some of the changes suggested by swagner in comment:17:ticket:2262

  • added highlighting of current line
  • added error markers and bookmarks
  • fixed <Ctrl> + <Backspace> bug
  • minor code changes
File size: 6.5 KB
RevLine 
[10332]1#region License Information
2/* HeuristicLab
[11171]3 * Copyright (C) 2002-2014 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;
24using System.Drawing;
[10506]25using System.Globalization;
[10332]26using System.Linq;
27using System.Windows.Forms;
28using HeuristicLab.Common.Resources;
29using HeuristicLab.Core.Views;
30using HeuristicLab.MainForm;
31
[10506]32namespace HeuristicLab.Scripting.Views {
[10332]33
[10401]34  [View("Script View")]
35  [Content(typeof(Script), true)]
36  public partial class ScriptView : NamedItemView {
[11657]37    #region Properties
[10401]38    public new Script Content {
39      get { return (Script)base.Content; }
[10731]40      set { base.Content = value; }
[10332]41    }
42
[11436]43    public override bool ReadOnly {
[11480]44      get { return codeEditor.ReadOnly || base.ReadOnly; }
45      set { base.ReadOnly = codeEditor.ReadOnly = value; }
[11436]46    }
47
48    public override bool Locked {
[11480]49      get { return codeEditor.ReadOnly || base.Locked; }
50      set { base.Locked = codeEditor.ReadOnly = value; }
[11436]51    }
[11657]52    #endregion
[11436]53
[11657]54    public ScriptView() {
55      InitializeComponent();
56      errorListView.SmallImageList.Images.AddRange(new Image[] { VSImageLibrary.Warning, VSImageLibrary.Error });
57    }
58
[10332]59    protected override void RegisterContentEvents() {
60      base.RegisterContentEvents();
[11657]61      Content.CodeChanged += Content_CodeChanged;
[10332]62    }
63
64    protected override void DeregisterContentEvents() {
[11657]65      Content.CodeChanged -= Content_CodeChanged;
[10332]66      base.DeregisterContentEvents();
67    }
68
[11657]69    #region Overrides
[10332]70    protected override void OnContentChanged() {
71      base.OnContentChanged();
72      if (Content == null) {
73        codeEditor.UserCode = string.Empty;
74      } else {
[11657]75        if (codeEditor.UserCode != Content.Code)
76          codeEditor.UserCode = Content.Code;
[10358]77        foreach (var asm in Content.GetAssemblies())
78          codeEditor.AddAssembly(asm);
[10332]79        if (Content.CompileErrors == null) {
80          compilationLabel.ForeColor = SystemColors.ControlDarkDark;
81          compilationLabel.Text = "Not compiled";
82        } else if (Content.CompileErrors.HasErrors) {
83          compilationLabel.ForeColor = Color.DarkRed;
84          compilationLabel.Text = "Compilation failed";
85        } else {
86          compilationLabel.ForeColor = Color.DarkGreen;
87          compilationLabel.Text = "Compilation successful";
88        }
89      }
90    }
91
92    protected override void SetEnabledStateOfControls() {
93      base.SetEnabledStateOfControls();
[10506]94      compileButton.Enabled = Content != null && !Locked && !ReadOnly;
[11436]95      codeEditor.Enabled = Content != null;
[10332]96    }
97
98    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
[10506]99      switch (keyData) {
100        case Keys.F6:
[10731]101          if (Content != null && !Locked)
102            Compile();
103          return true;
[10332]104      }
105      return base.ProcessCmdKey(ref msg, keyData);
106    }
[11657]107    #endregion
[10332]108
[10731]109    public virtual bool Compile() {
[10332]110      ReadOnly = true;
[10358]111      Locked = true;
[10332]112      errorListView.Items.Clear();
[10506]113      outputTextBox.Text = "Compiling ... ";
[10332]114      try {
115        Content.Compile();
116        outputTextBox.AppendText("Compilation succeeded.");
117        return true;
[11657]118      } catch (InvalidOperationException) {
[10865]119        if (Content.CompileErrors.HasErrors) {
120          outputTextBox.AppendText("Compilation failed.");
121          return false;
122        } else {
123          outputTextBox.AppendText("Compilation succeeded.");
124          return true;
125        }
[10332]126      } finally {
[10506]127        ShowCompilationResults();
[10642]128        if (Content.CompileErrors.Count > 0)
129          infoTabControl.SelectedTab = errorListTabPage;
[10332]130        ReadOnly = false;
[10358]131        Locked = false;
[11657]132        codeEditor.Focus();
[10506]133        OnContentChanged();
[10332]134      }
135    }
136
[11657]137    #region Helpers
[10731]138    protected virtual void ShowCompilationResults() {
[10332]139      if (Content.CompileErrors.Count == 0) return;
[11657]140
141      var messages = Content.CompileErrors.OfType<CompilerError>()
[10506]142                                      .OrderBy(x => x.IsWarning)
143                                      .ThenBy(x => x.Line)
144                                      .ThenBy(x => x.Column);
[11657]145
146      foreach (var m in messages) {
147        var item = new ListViewItem { Tag = m };
[10506]148        item.SubItems.AddRange(new[] {
[10332]149          m.IsWarning ? "Warning" : "Error",
150          m.ErrorNumber,
[10506]151          m.Line.ToString(CultureInfo.InvariantCulture),
152          m.Column.ToString(CultureInfo.InvariantCulture),
[10332]153          m.ErrorText
154        });
[10506]155        item.ImageIndex = m.IsWarning ? 0 : 1;
[10332]156        errorListView.Items.Add(item);
157      }
[11657]158
159      codeEditor.ShowCompileErrors(Content.CompileErrors, ".cs");
160
[10506]161      AdjustErrorListViewColumnSizes();
[10332]162    }
[10506]163
[10731]164    protected virtual void AdjustErrorListViewColumnSizes() {
[10506]165      foreach (ColumnHeader ch in errorListView.Columns)
[10865]166        // adjusts the column width to the width of the column header
[10506]167        ch.Width = -2;
168    }
[11657]169    #endregion
170
171    #region Event Handlers
172    private void Content_CodeChanged(object sender, EventArgs e) {
173      if (InvokeRequired)
174        Invoke(new EventHandler(Content_CodeChanged), sender, e);
175      else {
176        codeEditor.UserCode = Content.Code;
177      }
178    }
179
180    private void compileButton_Click(object sender, EventArgs e) {
181      Compile();
182    }
183
184    private void codeEditor_TextEditorTextChanged(object sender, EventArgs e) {
185      if (Content == null) return;
186      Content.Code = codeEditor.UserCode;
187    }
188
189    private void errorListView_MouseDoubleClick(object sender, MouseEventArgs e) {
190      if (e.Button == MouseButtons.Left) {
191        var item = errorListView.SelectedItems[0];
192        var message = (CompilerError)item.Tag;
193        codeEditor.ScrollToPosition(message.Line, message.Column);
194        codeEditor.Focus();
195      }
196    }
197    #endregion
[10332]198  }
199}
Note: See TracBrowser for help on using the repository browser.