Fix bug #395
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridViewLinkCell.cs
1 // Permission is hereby granted, free of charge, to any person obtaining\r
2 // a copy of this software and associated documentation files (the\r
3 // "Software"), to deal in the Software without restriction, including\r
4 // without limitation the rights to use, copy, modify, merge, publish,\r
5 // distribute, sublicense, and/or sell copies of the Software, and to\r
6 // permit persons to whom the Software is furnished to do so, subject to\r
7 // the following conditions:\r
8 // \r
9 // The above copyright notice and this permission notice shall be\r
10 // included in all copies or substantial portions of the Software.\r
11 // \r
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
19 //\r
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)\r
21 //\r
22 // Authors:\r
23 //      olivier Dufour  olivier.duff@free.fr\r
24 //\r
25 //\r
26 \r
27 using System;\r
28 using System.Collections.Generic;\r
29 using System.Text;\r
30 using System.Drawing;\r
31 using System.Security.Permissions;\r
32 using System.ComponentModel;\r
33 \r
34 namespace System.Windows.Forms\r
35 {\r
36         public class DataGridViewLinkCell : DataGridViewCell\r
37         {\r
38 \r
39                 public DataGridViewLinkCell ()\r
40                 {\r
41                         activeLinkColor = Color.Red;\r
42                         linkColor = Color.FromArgb (0, 0, 255);\r
43                         trackVisitedState = true;\r
44                         visited_link_color = Color.FromArgb (128, 0, 128);\r
45                 }\r
46 \r
47                 #region Public Methods\r
48 \r
49                 public override object Clone ()\r
50                 {\r
51                         DataGridViewLinkCell clone = (DataGridViewLinkCell)base.Clone ();\r
52                         \r
53                         clone.activeLinkColor = this.activeLinkColor;\r
54                         clone.linkColor = this.linkColor;\r
55                         clone.linkVisited = this.linkVisited;\r
56                         clone.linkBehavior = this.linkBehavior;\r
57                         clone.visited_link_color = this.visited_link_color;\r
58                         clone.trackVisitedState = this.trackVisitedState;\r
59                         \r
60                         return clone;\r
61                 }\r
62 \r
63                 public override string ToString ()\r
64                 {\r
65                         return string.Format ("DataGridViewLinkCell {{ ColumnIndex={0}, RowIndex={1} }}", ColumnIndex, RowIndex);\r
66                 }\r
67 \r
68                 #endregion\r
69 \r
70                 #region Protected Methods\r
71 \r
72                 protected override AccessibleObject CreateAccessibilityInstance ()\r
73                 {\r
74                         return new DataGridViewLinkCellAccessibleObject (this);\r
75                 }\r
76                 \r
77                 protected override Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)\r
78                 {\r
79                         if (DataGridView == null)\r
80                                 return Rectangle.Empty;\r
81 \r
82                         object o = FormattedValue;\r
83                         Size s = Size.Empty;\r
84 \r
85                         if (o != null) {\r
86                                 s = DataGridViewCell.MeasureTextSize (graphics, o.ToString (), cellStyle.Font, TextFormatFlags.Default);\r
87                                 s.Height += 3;\r
88                         } else {\r
89                                 return new Rectangle (1, 10, 0, 0);\r
90                         }\r
91 \r
92                         return new Rectangle (1, (OwningRow.Height - s.Height) / 2 - 1, s.Width, s.Height);\r
93                 }\r
94                 \r
95                 protected override Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)\r
96                 {\r
97                         if (DataGridView == null || string.IsNullOrEmpty (ErrorText))\r
98                                 return Rectangle.Empty;\r
99 \r
100                         Size error_icon = new Size (12, 11);\r
101                         return new Rectangle (new Point (Size.Width - error_icon.Width - 5, (Size.Height - error_icon.Height) / 2), error_icon);\r
102                 }\r
103                 \r
104                 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)\r
105                 {\r
106                         object o = FormattedValue;\r
107 \r
108                         if (o != null) {\r
109                                 Size s = DataGridViewCell.MeasureTextSize (graphics, o.ToString (), cellStyle.Font, TextFormatFlags.Default);\r
110                                 s.Height = Math.Max (s.Height, 20);\r
111                                 s.Width += 4;\r
112                                 return s;\r
113                         } else\r
114                                 return new Size (21, 20);\r
115                 }\r
116                 \r
117                 protected override object GetValue (int rowIndex)\r
118                 {\r
119                         if (useColumnTextForLinkValue)\r
120                                 return (OwningColumn as DataGridViewLinkColumn).Text;\r
121                                 \r
122                         return base.GetValue (rowIndex);\r
123                 }\r
124 \r
125                 protected override bool KeyUpUnsharesRow (KeyEventArgs e, int rowIndex)\r
126                 {\r
127                         if (e.KeyCode != Keys.Space\r
128                                 && trackVisitedState == true\r
129                                 && linkVisited == false\r
130                                 && !e.Shift \r
131                                 && !e.Control\r
132                                 && !e.Alt)\r
133                                 return true;\r
134 \r
135                         return false;\r
136                 }\r
137                 \r
138                 protected override bool MouseDownUnsharesRow (DataGridViewCellMouseEventArgs e)\r
139                 {\r
140                         return true;\r
141                 }\r
142                 \r
143                 protected override bool MouseLeaveUnsharesRow (int rowIndex)\r
144                 {\r
145                         return (linkState != LinkState.Normal);\r
146                 }\r
147 \r
148                 protected override bool MouseMoveUnsharesRow (DataGridViewCellMouseEventArgs e)\r
149                 {\r
150                         if (linkState == LinkState.Hover)\r
151                                 return true;\r
152 \r
153                         return false;\r
154                 }\r
155 \r
156                 protected override bool MouseUpUnsharesRow (DataGridViewCellMouseEventArgs e)\r
157                 {\r
158                         return (linkState == LinkState.Hover);\r
159                 }\r
160                 \r
161                 protected override void OnKeyUp (KeyEventArgs e, int rowIndex)\r
162                 {\r
163                         if ((e.KeyData & Keys.Space) == Keys.Space) {\r
164                                 linkState = LinkState.Normal;\r
165                                 DataGridView.InvalidateCell (this);\r
166                         }\r
167                 }\r
168 \r
169                 protected override void OnMouseDown (DataGridViewCellMouseEventArgs e)\r
170                 {\r
171                         base.OnMouseDown (e);\r
172                         \r
173                         linkState = LinkState.Active;\r
174                         DataGridView.InvalidateCell (this);\r
175                 }\r
176                 \r
177                 protected override void OnMouseLeave (int rowIndex)\r
178                 {\r
179                         base.OnMouseLeave (rowIndex);\r
180                         \r
181                         linkState = LinkState.Normal;\r
182                         DataGridView.InvalidateCell (this);\r
183                         DataGridView.Cursor = parent_cursor;\r
184                 }\r
185                 \r
186                 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e)\r
187                 {\r
188                         base.OnMouseMove (e);\r
189                         \r
190                         if (linkState != LinkState.Hover) {\r
191                                 linkState = LinkState.Hover;\r
192                                 DataGridView.InvalidateCell (this);\r
193                                 parent_cursor = DataGridView.Cursor;\r
194                                 DataGridView.Cursor = Cursors.Hand;\r
195                         }\r
196                 }\r
197                 \r
198                 protected override void OnMouseUp (DataGridViewCellMouseEventArgs e)\r
199                 {\r
200                         base.OnMouseUp (e);\r
201                         \r
202                         linkState = LinkState.Hover;\r
203                         LinkVisited = true;\r
204                         DataGridView.InvalidateCell (this);\r
205                 }\r
206 \r
207                 protected override void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)\r
208                 {\r
209                         base.Paint (graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);\r
210                 }\r
211                 \r
212                 internal override void PaintPartContent (Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, object formattedValue)\r
213                 {\r
214                         Font font = cellStyle.Font;\r
215 \r
216                         switch (LinkBehavior) {\r
217                                 case LinkBehavior.AlwaysUnderline:\r
218                                 case LinkBehavior.SystemDefault:\r
219                                         font = new Font (font, FontStyle.Underline);\r
220                                         break;\r
221                                 case LinkBehavior.HoverUnderline:\r
222                                         if (linkState == LinkState.Hover)\r
223                                                 font = new Font (font, FontStyle.Underline);\r
224                                         break;\r
225                         }\r
226 \r
227                         Color color;\r
228                         \r
229                         if (linkState == LinkState.Active)\r
230                                 color = ActiveLinkColor;\r
231                         else if (linkVisited)\r
232                                 color = VisitedLinkColor;\r
233                         else\r
234                                 color = LinkColor;\r
235 \r
236                         TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.TextBoxControl;\r
237 \r
238                         cellBounds.Height -= 2;\r
239                         cellBounds.Width -= 2;\r
240 \r
241                         if (formattedValue != null)\r
242                                 TextRenderer.DrawText (graphics, formattedValue.ToString (), font, cellBounds, color, flags);\r
243                 }\r
244                 #endregion\r
245 \r
246                 #region Private fields\r
247 \r
248                 private Color activeLinkColor;\r
249                 private LinkBehavior linkBehavior;\r
250                 private Color linkColor;\r
251                 private bool linkVisited;\r
252                 private Cursor parent_cursor;\r
253                 private bool trackVisitedState;\r
254                 private bool useColumnTextForLinkValue;\r
255                 private Color visited_link_color;\r
256                 private LinkState linkState;\r
257 \r
258                 #endregion\r
259 \r
260                 #region Public properties\r
261 \r
262                 public Color ActiveLinkColor {\r
263                         get { return activeLinkColor; }\r
264                         set { activeLinkColor = value; }\r
265                 }\r
266 \r
267                 [DefaultValue (LinkBehavior.SystemDefault)]\r
268                 public LinkBehavior LinkBehavior {\r
269                         get { return linkBehavior; }\r
270                         set { linkBehavior = value; }\r
271                 }\r
272                 public Color LinkColor {\r
273                         get { return linkColor; }\r
274                         set { linkColor = value; }\r
275                 }\r
276                 public bool LinkVisited {\r
277                         get { return linkVisited; }\r
278                         set { linkVisited = value; }\r
279                 }\r
280                 [DefaultValue (true)]\r
281                 public bool TrackVisitedState {\r
282                         get { return trackVisitedState; }\r
283                         set { trackVisitedState = value; }\r
284                 }\r
285                 [DefaultValue (false)]\r
286                 public bool UseColumnTextForLinkValue {\r
287                         get { return useColumnTextForLinkValue; }\r
288                         set { useColumnTextForLinkValue = value; }\r
289                 }\r
290 \r
291                 public Color VisitedLinkColor {\r
292                         get { return visited_link_color; }\r
293                         set { visited_link_color = value; }\r
294                 }\r
295 \r
296                 public override Type ValueType {\r
297                         get { return base.ValueType == null ? typeof (object) : base.ValueType; }\r
298                 }\r
299 \r
300                 public override Type EditType {\r
301                         get { return null; }\r
302                 }\r
303                 public override Type FormattedValueType {\r
304                         get { return typeof(string); }\r
305                 }\r
306 \r
307                 #endregion\r
308 \r
309                 protected class DataGridViewLinkCellAccessibleObject : DataGridViewCell.DataGridViewCellAccessibleObject\r
310                 {\r
311                         public DataGridViewLinkCellAccessibleObject (DataGridViewCell owner) : base(owner) \r
312                         {\r
313                                 //DO NOTHING\r
314                         }\r
315 \r
316                         [MonoTODO ("Stub, does nothing")]\r
317                         [SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]\r
318                         public override void DoDefaultAction ()\r
319                         {\r
320                                 //DataGridViewLinkCell cell = base.Owner as DataGridViewLinkCell;\r
321                                 //if (cell.DataGridView != null && cell.RowIndex == -1)\r
322                                 //        throw new InvalidOperationException ();\r
323                         }\r
324 \r
325                         public override int GetChildCount ()\r
326                         {\r
327                                 return -1;\r
328                         }\r
329 \r
330                         public override string DefaultAction { get { return "Click"; } }\r
331                 }\r
332                 \r
333         }\r
334 }\r