PageRenderTime 48ms CodeModel.GetById 19ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NUnit/UiException/Controls/CodeBox.cs

#
C# | 227 lines | 155 code | 46 blank | 26 comment | 8 complexity | d972a505ed61b6f2fbd1dda0f3cdc99f MD5 | raw file
  1// ****************************************************************
  2// This is free software licensed under the NUnit license. You may
  3// obtain a copy of the license at http://nunit.org
  4// ****************************************************************
  5
  6using System;
  7using System.Collections.Generic;
  8using System.ComponentModel;
  9using System.Drawing;
 10using System.Text;
 11using System.Windows.Forms;
 12using NUnit.UiException.CodeFormatters;
 13using System.Diagnostics;
 14
 15/// This control could have been replaced by a standard RichTextBox control, but
 16/// it turned out that RichTextBox:
 17///     - was hard to configure
 18///     - was hard to set the viewport
 19///     - doesn't use double buffer optimization
 20///     - scrolls text one line at a time without be configurable.
 21/// 
 22/// CodeBox has been written to address these specific issues in order to display
 23/// C# source code where exceptions occured.
 24
 25namespace NUnit.UiException.Controls
 26{
 27    /// <summary>
 28    /// A control that implements ICodeView.
 29    /// </summary>
 30    public class CodeBox : UserControl, ICodeView
 31    {
 32        protected CodeRenderingContext _workingContext;
 33        protected FormattedCode _formattedCode;
 34
 35        private IFormatterCatalog _formatter;
 36        private ICodeRenderer _renderer;
 37        private string _language;
 38
 39        private bool _showCurrentLine;
 40        private int _currentLine;
 41        
 42        public CodeBox() :
 43            this(new GeneralCodeFormatter(), new DefaultCodeRenderer()) { }
 44
 45        #region ICodeView Members
 46
 47        public override string Text
 48        {
 49            get { return (_formattedCode.Text); }
 50            set
 51            {
 52                if (value == null)
 53                    value = "";
 54
 55                SizeF docSize;
 56
 57                _formattedCode = _formatter.Format(value, _language);
 58                docSize = _renderer.GetDocumentSize(
 59                    _formattedCode, _workingContext.Graphics, _workingContext.Font);
 60                AutoScrollMinSize = new Size((int)docSize.Width, (int)docSize.Height);
 61
 62                Invalidate();
 63
 64                return;
 65            }
 66        }
 67
 68        public string Language
 69        {
 70            get { return (_language); }
 71            set
 72            {
 73                if (value == null)
 74                    value = "";
 75                if (_language == value)
 76                    return;
 77
 78                _language = value;
 79                Text = Text;
 80            }
 81        }
 82
 83        public int CurrentLine
 84        {
 85            get { return (_currentLine); }
 86            set
 87            {
 88                float y = _renderer.LineIndexToYCoordinate(value,
 89                    _workingContext.Graphics, _workingContext.Font);
 90
 91                y -= Height / 2;
 92
 93                _currentLine = value;
 94                AutoScrollPosition = new Point(0, (int)y);
 95
 96                Invalidate();
 97            }
 98        }
 99
100        public IFormatterCatalog Formatter
101        {
102            get { return (_formatter); }
103        }
104
105        #endregion
106
107        /// <summary>
108        /// Gets or sets a value telling whether or not displaying a special
109        /// feature for the current line at drawing time.
110        /// </summary>        
111        public bool ShowCurrentLine
112        {
113            get { return (_showCurrentLine); }
114            set { _showCurrentLine = value; }
115        }
116
117        /// <summary>
118        /// If ShowCurrentLine is set, this set the current line's background color.
119        /// </summary>
120        public Color CurrentLineBackColor
121        {
122            get { return (_workingContext.CurrentLineBackColor); }
123            set { 
124                _workingContext.CurrentLineBackColor = value;
125                Invalidate();
126            }
127        }
128
129        /// <summary>
130        /// If ShowCurrentLine is set, this set current line's foreground color.
131        /// </summary>
132        public Color CurrentLineForeColor
133        {
134            get { return (_workingContext.CurrentLineForeColor); }
135            set { 
136                _workingContext.CurrentLineForeColor = value;
137                Invalidate();
138            }
139        }
140       
141        protected CodeBox(IFormatterCatalog formatter, ICodeRenderer renderer)
142        {
143            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
144            SetStyle(ControlStyles.UserPaint, true);
145            DoubleBuffered = true;
146
147            _formatter = formatter;
148            _formattedCode = FormattedCode.Empty;
149
150            _renderer = renderer;
151
152            _currentLine = -1;
153            _showCurrentLine = false;
154
155            _language = "";
156
157            this.Font = new Font(FontFamily.GenericMonospace, 8);
158            this.BackColor = Color.White;
159
160            createGraphics();
161            AutoScroll = true;
162
163            return;
164        }
165
166        protected override void OnMouseHover(EventArgs e)
167        {
168            base.OnMouseHover(e);
169            Focus();
170        }
171
172        protected override void OnPaint(PaintEventArgs e)
173        {
174            Graphics backup;
175
176            base.OnPaint(e);
177
178            backup = _workingContext.Graphics;
179            _workingContext.Graphics = e.Graphics;
180            _workingContext.CurrentLine = (_showCurrentLine ? _currentLine : -1);
181
182            _renderer.DrawToGraphics(_formattedCode, _workingContext,
183                new Rectangle(-AutoScrollPosition.X, -AutoScrollPosition.Y, Width, Height));
184
185            _workingContext.Graphics = backup;
186
187            return;
188        }
189
190        protected override void OnFontChanged(EventArgs e)
191        {
192            base.OnFontChanged(e);
193
194            if (_workingContext != null)
195            {
196                _workingContext.Font = Font;
197                Text = Text;
198            }
199
200            return;
201        }
202
203        private void createGraphics()
204        {
205            Graphics gCurrent = CreateGraphics();
206            Image img = new Bitmap(10, 10, gCurrent);
207            Graphics gImg = Graphics.FromImage(img);
208
209            gCurrent.Dispose();
210
211            _workingContext = new CodeRenderingContext();
212            _workingContext.Graphics = gImg;
213            _workingContext.Font = Font;
214
215            _workingContext.CurrentLine = -1;
216            _workingContext.BackgroundColor = Color.White;
217            _workingContext.CurrentLineBackColor = Color.Red;
218            _workingContext.CurrentLineForeColor = Color.White;
219            _workingContext.CodeColor = Color.Black;
220            _workingContext.CommentColor = Color.Green;
221            _workingContext.KeywordColor = Color.Blue;
222            _workingContext.StringColor = Color.Red;
223
224            return;
225        }
226    }    
227}