* X11Keyboard.cs: Detect and use the num lock mask.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / MenuItem.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004 Novell, Inc.
21 //
22 // Authors:
23 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System.ComponentModel;
30 using System.Collections;
31
32 namespace System.Windows.Forms
33 {
34         public class MenuItem : Menu
35         {
36                 internal Menu parent_menu = null;
37                 internal bool separator;
38                 internal bool break_;
39                 internal bool bar_break;
40                 private Shortcut shortcut;
41                 private string text;
42                 private bool checked_;
43                 private bool radiocheck;
44                 private bool enabled;
45                 private char mnemonic;
46                 private bool showshortcut;
47                 private int index;
48                 private bool mdilist;
49                 private bool defaut_item;
50                 private bool visible;
51                 private bool ownerdraw;
52                 private int menuid;
53                 private int mergeorder;
54                 private MenuMerge mergetype;
55
56                 public MenuItem (): base (null)
57                 {       
58                         CommonConstructor (string.Empty);
59                         shortcut = Shortcut.None;
60                 }
61
62                 public MenuItem (string text) : base (null)
63                 {
64                         CommonConstructor (text);
65                         shortcut = Shortcut.None;
66                 }
67
68                 public MenuItem (string text, EventHandler onClick) : base (null)
69                 {
70                         CommonConstructor (text);
71                         shortcut = Shortcut.None;
72                         Click += onClick;
73                 }
74
75                 public MenuItem (string text, MenuItem[] items) : base (items)
76                 {
77                         CommonConstructor (text);
78                         shortcut = Shortcut.None;
79                 }
80
81                 public MenuItem (string text, EventHandler onClick, Shortcut shortcut) : base (null)
82                 {
83                         CommonConstructor (text);
84                         Click += onClick;
85                         this.shortcut = shortcut;
86                 }
87
88                 public MenuItem (MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string text,
89                         EventHandler onClick, EventHandler onPopup,  EventHandler onSelect,  MenuItem[] items)
90                         : base (items)
91                 {
92                         CommonConstructor (text);
93                         shortcut = shortcut;
94                         mergeorder = mergeOrder;
95                         mergetype = mergeType;
96
97                         Click += onClick;
98                         Popup += onPopup;
99                         Select += onSelect;
100                 }
101
102                 private void CommonConstructor (string text)
103                 {
104                         separator = false;
105                         break_ = false;
106                         bar_break = false;
107                         checked_ = false;
108                         radiocheck = false;
109                         enabled = true;
110                         showshortcut = true;
111                         visible = true;
112                         ownerdraw = false;
113                         index = -1;
114                         mnemonic = '\0';
115                         menuid = -1;
116                         mergeorder = 0;
117                         mergetype = MenuMerge.Add;
118                         Text = text;    // Text can change separator status
119                 }
120
121                 #region Events
122                 public event EventHandler Click;
123                 public event DrawItemEventHandler DrawItem;
124                 public event MeasureItemEventHandler MeasureItem;
125                 public event EventHandler Popup;
126                 public event EventHandler Select;
127                 #endregion // Events
128
129                 #region Public Properties
130
131                 public bool BarBreak {
132                         get { return break_; }
133                         set { break_ = value; }
134                 }
135
136                 public bool Break {
137                         get { return bar_break; }
138                         set { bar_break = value; }
139                 }
140
141                 public bool Checked {
142                         get { return checked_; }
143                         set { checked_ = value; }
144                 }
145
146                 public bool DefaultItem {
147                         get { return defaut_item; }
148                         set { defaut_item = value; }
149                 }
150
151                 public bool Enabled {
152                         get { return enabled; }
153                         set { enabled = value; }
154                 }
155
156                 public int Index {
157                         get { return index; }
158                         set { index = value; }
159                 }
160
161                 public override bool IsParent {
162                         get { return IsPopup; }
163                 }
164
165                 public bool MdiList {
166                         get { return mdilist; }
167                         set { mdilist = value; }
168                 }
169
170                 protected int MenuID {
171                         get { return menuid; }
172                 }
173
174                 public int MergeOrder {
175                         get { return mergeorder; }
176                         set { mergeorder = value; }
177                 }
178
179                 public MenuMerge MergeType {
180                         get { return mergetype; }
181                         set {
182                                 if (!Enum.IsDefined (typeof (MenuMerge), value))
183                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for MenuMerge", value));
184
185                                 mergetype = value;
186                         }
187                 }
188
189                 public char Mnemonic {
190                         get { return mnemonic; }
191                 }
192
193                 public bool OwnerDraw {
194                         get { return ownerdraw; }
195                         set { ownerdraw = value; }
196                 }
197
198                 public Menu Parent {
199                         get { return parent_menu;}
200                 }
201
202                 public bool RadioCheck {
203                         get { return radiocheck; }
204                         set { radiocheck = value; }
205                 }
206
207                 public Shortcut Shortcut {
208                         get { return shortcut;}
209                         set {
210                                 if (!Enum.IsDefined (typeof (Shortcut), value))
211                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Shortcut", value));
212
213                                 shortcut = value;
214                         }
215                 }
216
217                 public bool ShowShortcut {
218                         get { return showshortcut;}
219                         set { showshortcut = value; }
220                 }
221
222                 public string Text {
223                         get { return text; }
224                         set {
225                                 text = value;
226
227                                 if (text == "-")
228                                         separator = true;
229                                 else
230                                         separator = false;
231
232                                 ProcessMnemonic ();
233                         }
234                 }
235
236                 public bool Visible {
237                         get { return visible;}
238                         set { visible = value; }
239                 }
240
241                 #endregion Public Properties
242
243                 #region Private Properties
244
245                 internal bool IsPopup {
246                         get {
247                                 if (menu_items.Count > 0)
248                                         return true;
249                                 else
250                                         return false;
251                         }
252                 }
253
254                 internal bool Separator {
255                         get { return separator; }
256                         set { separator = value; }
257                 }
258
259                 #endregion Private Properties
260
261                 #region Public Methods
262
263                 public virtual MenuItem CloneMenu ()
264                 {
265                         MenuItem item = new MenuItem ();
266                         item.CloneMenu (item);
267                         return item;
268                 }
269
270                 protected void CloneMenu (MenuItem menuitem)
271                 {
272                         base.CloneMenu (menuitem); // Copy subitems
273
274                         // Properties
275                         BarBreak = menuitem.BarBreak;\r
276                         Break = menuitem.Break;\r
277                         Checked = menuitem.Checked;\r
278                         DefaultItem = menuitem.DefaultItem;\r
279                         Enabled = menuitem.Enabled;                     \r
280                         MergeOrder = menuitem.MergeOrder;\r
281                         MergeType = menuitem.MergeType;\r
282                         OwnerDraw = menuitem.OwnerDraw;\r
283                         //Parent = menuitem.Parent;\r
284                         RadioCheck = menuitem.RadioCheck;\r
285                         Shortcut = menuitem.Shortcut;\r
286                         ShowShortcut = menuitem.ShowShortcut;\r
287                         Text = menuitem.Text;\r
288                         Visible = menuitem.Visible;
289
290                         // Events
291                         Click = menuitem.Click;
292                         DrawItem = menuitem.DrawItem;
293                         MeasureItem = menuitem.MeasureItem;
294                         Popup = menuitem.Popup;
295                         Select = menuitem.Select;
296                 }
297
298                 protected override void Dispose (bool disposing)
299                 {
300                         base.Dispose (disposing);                       
301                 }
302
303                 public virtual void MergeMenu ()
304                 {
305                         base.MergeMenu (this);
306                 }
307
308                 public void MergeMenu (MenuItem menuitem)
309                 {
310                         base.MergeMenu (menuitem);
311                 }
312
313                 protected virtual void OnClick (EventArgs e)
314                 {
315                         if (Click != null)
316                                 Click (this, e);
317                 }
318
319                 protected virtual void OnDrawItem (DrawItemEventArgs e)
320                 {
321                         if (DrawItem != null)
322                                 DrawItem (this, e);
323                 }
324
325
326                 protected virtual void OnInitMenuPopup (EventArgs e)
327                 {
328                         OnPopup (e);
329                 }
330
331                 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
332                 {
333                         if (MeasureItem != null)
334                                 MeasureItem (this, e);
335                 }
336
337                 protected virtual void OnPopup (EventArgs e)
338                 {
339                         if (Popup != null)
340                                 Popup (this, e);
341                 }
342
343                 protected virtual void OnSelect (EventArgs e)
344                 {
345                         if (Select != null)
346                                 Select (this, e);
347                 }
348
349                 public void PerformClick ()
350                 {
351                         OnClick (EventArgs.Empty);
352                 }
353
354                 public virtual void PerformSelect ()
355                 {
356                         OnSelect (EventArgs.Empty);
357                 }
358
359                 public override string ToString ()
360                 {
361                         return "item:" + text;
362                 }
363
364                 #endregion Public Methods
365
366                 #region Private Methods
367
368                 internal void Create ()
369                 {
370                         IntPtr hSubMenu = IntPtr.Zero;
371
372                         menuid = index = MenuAPI.InsertMenuItem (Parent.Handle, -1, true, this, ref hSubMenu);
373                         IsDirty = false;
374
375                         if (IsPopup) {
376                                 menu_handle = hSubMenu;
377                                 CreateItems ();
378                         }
379                 }
380
381                 private void ProcessMnemonic ()
382                 {
383                         if (text.Length < 2) {
384                                 mnemonic = '\0';
385                                 return;
386                         }
387
388                         bool bPrevAmp = false;
389                         for (int i = 0; i < text.Length -1 ; i++) {
390                                 if (text[i] == '&') {
391                                         if (bPrevAmp == false &&  (text[i+1] != '&')) {
392                                                 mnemonic = Char.ToUpper (text[i+1]);
393                                                 return;
394                                         }
395
396                                         bPrevAmp = true;
397                                 }
398                                 else
399                                         bPrevAmp = false;
400                         }
401
402                         mnemonic = '\0';
403                 }
404
405                 private string GetShortCutTextCtrl () { return "Ctrl"; }
406                 private string GetShortCutTextAlt () { return "Alt"; }
407                 private string GetShortCutTextShift () { return "Shift"; }              
408
409                 internal string GetShortCutText ()
410                 {
411                         /* Ctrl+A - Ctrl+Z */
412                         if (Shortcut >= Shortcut.CtrlA && Shortcut <= Shortcut.CtrlZ)
413                                 return GetShortCutTextCtrl () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlA));
414
415                         /* Alt+0 - Alt+9 */
416                         if (Shortcut >= Shortcut.Alt0 && Shortcut <= Shortcut.Alt9)
417                                 return GetShortCutTextAlt () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Alt0));
418
419                         /* Alt+F1 - Alt+F2 */
420                         if (Shortcut >= Shortcut.AltF1 && Shortcut <= Shortcut.AltF9)
421                                 return GetShortCutTextAlt () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.AltF1));
422
423                         /* Ctrl+0 - Ctrl+9 */
424                         if (Shortcut >= Shortcut.Ctrl0 && Shortcut <= Shortcut.Ctrl9)
425                                 return GetShortCutTextCtrl () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Ctrl0));
426                                                         
427                         /* Ctrl+F0 - Ctrl+F9 */
428                         if (Shortcut >= Shortcut.CtrlF1 && Shortcut <= Shortcut.CtrlF9)
429                                 return GetShortCutTextCtrl () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlF1));
430                                 
431                         /* Ctrl+Shift+0 - Ctrl+Shift+9 */
432                         if (Shortcut >= Shortcut.CtrlShift0 && Shortcut <= Shortcut.CtrlShift9)
433                                 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.CtrlShift0));
434                                 
435                         /* Ctrl+Shift+A - Ctrl+Shift+Z */
436                         if (Shortcut >= Shortcut.CtrlShiftA && Shortcut <= Shortcut.CtrlShiftZ)
437                                 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlShiftA));
438
439                         /* Ctrl+Shift+F1 - Ctrl+Shift+F9 */
440                         if (Shortcut >= Shortcut.CtrlShiftF1 && Shortcut <= Shortcut.CtrlShiftF9)
441                                 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlShiftF1));
442                                 
443                         /* F1 - F9 */
444                         if (Shortcut >= Shortcut.F1 && Shortcut <= Shortcut.F9)
445                                 return "F" + (char)((int) '1' + (int)(Shortcut - Shortcut.F1));
446                                 
447                         /* Shift+F1 - Shift+F9 */
448                         if (Shortcut >= Shortcut.ShiftF1 && Shortcut <= Shortcut.ShiftF9)
449                                 return GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.ShiftF1));
450                         
451                         /* Special cases */
452                         switch (Shortcut) {
453                                 case Shortcut.AltBksp:
454                                         return "AltBksp";
455                                 case Shortcut.AltF10:
456                                         return GetShortCutTextAlt () + "+F10";
457                                 case Shortcut.AltF11:
458                                         return GetShortCutTextAlt () + "+F11";
459                                 case Shortcut.AltF12:
460                                         return GetShortCutTextAlt () + "+F12";
461                                 case Shortcut.CtrlDel:          
462                                         return GetShortCutTextCtrl () + "+Del";
463                                 case Shortcut.CtrlF10:
464                                         return GetShortCutTextCtrl () + "+F10";
465                                 case Shortcut.CtrlF11:
466                                         return GetShortCutTextCtrl () + "+F11";
467                                 case Shortcut.CtrlF12:
468                                         return GetShortCutTextCtrl () + "+F12";
469                                 case Shortcut.CtrlIns:
470                                         return GetShortCutTextCtrl () + "+Ins";
471                                 case Shortcut.CtrlShiftF10:
472                                         return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F10";
473                                 case Shortcut.CtrlShiftF11:
474                                         return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F11";
475                                 case Shortcut.CtrlShiftF12:
476                                         return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F12";
477                                 case Shortcut.Del:
478                                         return "Del";
479                                 case Shortcut.F10:
480                                         return "F10";   
481                                 case Shortcut.F11:
482                                         return "F11";   
483                                 case Shortcut.F12:
484                                         return "F12";   
485                                 case Shortcut.Ins:
486                                         return "Ins";   
487                                 case Shortcut.None:
488                                         return "None";  
489                                 case Shortcut.ShiftDel:
490                                         return GetShortCutTextShift () + "+Del";
491                                 case Shortcut.ShiftF10:
492                                         return GetShortCutTextShift () + "+F10";
493                                 case Shortcut.ShiftF11:
494                                         return GetShortCutTextShift () + "+F11";
495                                 case Shortcut.ShiftF12:
496                                         return GetShortCutTextShift () + "+F12";                                
497                                 case Shortcut.ShiftIns:
498                                         return GetShortCutTextShift () + "+Ins";
499                                 default:
500                                         break;
501                                 }
502                                 
503                         return "";
504                 }
505
506                 #endregion Private Methods
507
508         }
509 }
510
511