copying the latest Sys.Web.Services from trunk.
[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-2005 Novell, Inc.
21 //
22 // Authors:
23 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System.Collections;
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
32 using System.Drawing;
33 using System.Drawing.Text;
34
35 namespace System.Windows.Forms
36 {
37         [DefaultProperty("Text")]
38         [DefaultEvent("Click")]
39         [DesignTimeVisible(false)]
40         [ToolboxItem(false)]
41         public class MenuItem : Menu
42         {               
43                 internal bool separator;
44                 internal bool break_;
45                 internal bool bar_break;
46                 private Shortcut shortcut;
47                 private string text;
48                 private bool checked_;
49                 private bool radiocheck;
50                 private bool enabled;
51                 private char mnemonic;
52                 private bool showshortcut;
53                 private int index;
54                 private bool mdilist;
55                 private bool defaut_item;
56                 private bool visible;
57                 private bool ownerdraw;
58                 private int menuid;
59                 private int mergeorder;
60                 private int xtab;
61                 private int menuheight;
62                 private bool menubar;
63                 private DrawItemState status;
64                 private MenuMerge mergetype;
65                 
66                 public MenuItem (): base (null)
67                 {       
68                         CommonConstructor (string.Empty);
69                         shortcut = Shortcut.None;
70                 }
71
72                 public MenuItem (string text) : base (null)
73                 {
74                         CommonConstructor (text);
75                         shortcut = Shortcut.None;
76                 }
77
78                 public MenuItem (string text, EventHandler onClick) : base (null)
79                 {
80                         CommonConstructor (text);
81                         shortcut = Shortcut.None;
82                         Click += onClick;
83                 }
84
85                 public MenuItem (string text, MenuItem[] items) : base (items)
86                 {
87                         CommonConstructor (text);
88                         shortcut = Shortcut.None;
89                 }
90
91                 public MenuItem (string text, EventHandler onClick, Shortcut shortcut) : base (null)
92                 {
93                         CommonConstructor (text);
94                         Click += onClick;
95                         this.shortcut = shortcut;
96                 }
97
98                 public MenuItem (MenuMerge mergeType, int mergeOrder, Shortcut shortcut, string text,
99                         EventHandler onClick, EventHandler onPopup,  EventHandler onSelect,  MenuItem[] items)
100                         : base (items)
101                 {
102                         CommonConstructor (text);
103                         this.shortcut = shortcut;
104                         mergeorder = mergeOrder;
105                         mergetype = mergeType;
106
107                         Click += onClick;
108                         Popup += onPopup;
109                         Select += onSelect;
110                 }
111
112                 private void CommonConstructor (string text)
113                 {
114                         separator = false;
115                         break_ = false;
116                         bar_break = false;
117                         checked_ = false;
118                         radiocheck = false;
119                         enabled = true;
120                         showshortcut = true;
121                         visible = true;
122                         ownerdraw = false;
123                         status = DrawItemState.None;
124                         menubar = false;
125                         menuheight = 0;
126                         xtab = 0;
127                         index = -1;
128                         mnemonic = '\0';
129                         menuid = -1;
130                         mergeorder = 0;
131                         mergetype = MenuMerge.Add;
132                         Text = text;    // Text can change separator status
133                 }
134
135                 #region Events
136                 public event EventHandler Click;
137                 public event DrawItemEventHandler DrawItem;
138                 public event MeasureItemEventHandler MeasureItem;
139                 public event EventHandler Popup;
140                 public event EventHandler Select;
141                 #endregion // Events
142
143                 #region Public Properties
144
145                 [Browsable(false)]
146                 [DefaultValue(false)]
147                 public bool BarBreak {
148                         get { return break_; }
149                         set { break_ = value; }
150                 }
151
152                 [Browsable(false)]
153                 [DefaultValue(false)]
154                 public bool Break {
155                         get { return bar_break; }
156                         set { bar_break = value; }
157                 }
158
159                 [DefaultValue(false)]
160                 public bool Checked {
161                         get { return checked_; }
162                         set { checked_ = value; }
163                 }
164
165                 [DefaultValue(false)]
166                 public bool DefaultItem {
167                         get { return defaut_item; }
168                         set { defaut_item = value; }
169                 }
170
171                 [DefaultValue(true)]
172                 [Localizable(true)]
173                 public bool Enabled {
174                         get { return enabled; }
175                         set { enabled = value; }
176                 }
177
178                 [Browsable(false)]
179                 public int Index {
180                         get { return index; }
181                         set { index = value; }
182                 }
183
184                 [Browsable(false)]
185                 public override bool IsParent {
186                         get { return IsPopup; }
187                 }
188
189                 [DefaultValue(false)]
190                 public bool MdiList {
191                         get { return mdilist; }
192                         set { mdilist = value; }
193                 }
194
195                 protected int MenuID {
196                         get { return menuid; }
197                 }
198
199                 [DefaultValue(0)]
200                 public int MergeOrder {
201                         get { return mergeorder; }
202                         set { mergeorder = value; }
203                 }
204
205                 [DefaultValue(MenuMerge.Add)]
206                 public MenuMerge MergeType {
207                         get { return mergetype; }
208                         set {
209                                 if (!Enum.IsDefined (typeof (MenuMerge), value))
210                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for MenuMerge", value));
211
212                                 mergetype = value;
213                         }
214                 }
215
216                 [Browsable(false)]
217                 public char Mnemonic {
218                         get { return mnemonic; }
219                 }
220
221                 [DefaultValue(false)]
222                 public bool OwnerDraw {
223                         get { return ownerdraw; }
224                         set { ownerdraw = value; }
225                 }
226
227                 [Browsable(false)]
228                 public Menu Parent {
229                         get { return parent_menu;}
230                 }
231
232                 [DefaultValue(false)]
233                 public bool RadioCheck {
234                         get { return radiocheck; }
235                         set { radiocheck = value; }
236                 }
237
238                 [DefaultValue(Shortcut.None)]
239                 [Localizable(true)]
240                 public Shortcut Shortcut {
241                         get { return shortcut;}
242                         set {
243                                 if (!Enum.IsDefined (typeof (Shortcut), value))
244                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Shortcut", value));
245
246                                 shortcut = value;
247                         }
248                 }
249
250                 [DefaultValue(true)]
251                 [Localizable(true)]
252                 public bool ShowShortcut {
253                         get { return showshortcut;}
254                         set { showshortcut = value; }
255                 }
256
257                 [Localizable(true)]
258                 public string Text {
259                         get { return text; }
260                         set {
261                                 text = value;
262
263                                 if (text == "-")
264                                         separator = true;
265                                 else
266                                         separator = false;
267
268                                 ProcessMnemonic ();
269                         }
270                 }
271
272                 [DefaultValue(true)]
273                 [Localizable(true)]
274                 public bool Visible {
275                         get { return visible;}
276                         set { visible = value; }
277                 }
278
279                 #endregion Public Properties
280
281                 #region Private Properties
282
283                 internal bool IsPopup {
284                         get {
285                                 if (menu_items.Count > 0)
286                                         return true;
287                                 else
288                                         return false;
289                         }
290                 }
291                 
292                 internal bool MeasureEventDefined {
293                         get { 
294                                 if (ownerdraw == true && MeasureItem != null) {
295                                         return true;
296                                 } else {
297                                         return false;
298                                 }
299                         }
300                 }
301                 
302                 internal bool MenuBar {
303                         get { return menubar; }
304                         set { menubar = value; }
305                 }
306                 
307                 internal int MenuHeight {
308                         get { return menuheight; }
309                         set { menuheight = value; }
310                 }       
311
312                 internal bool Separator {
313                         get { return separator; }
314                         set { separator = value; }
315                 }
316                 
317                 internal DrawItemState Status {
318                         get { return status; }
319                         set { status = value; }
320                 }
321                 
322                 internal int XTab {
323                         get { return xtab; }
324                         set { xtab = value; }
325                 }
326
327                 #endregion Private Properties
328
329                 #region Public Methods
330
331                 public virtual MenuItem CloneMenu ()
332                 {
333                         MenuItem item = new MenuItem ();
334                         item.CloneMenu (this);
335                         return item;
336                 }
337
338                 protected void CloneMenu (MenuItem menuitem)
339                 {
340                         base.CloneMenu (menuitem); // Copy subitems
341
342                         // Properties
343                         BarBreak = menuitem.BarBreak;
344                         Break = menuitem.Break;
345                         Checked = menuitem.Checked;
346                         DefaultItem = menuitem.DefaultItem;
347                         Enabled = menuitem.Enabled;                     
348                         MergeOrder = menuitem.MergeOrder;
349                         MergeType = menuitem.MergeType;
350                         OwnerDraw = menuitem.OwnerDraw;
351                         //Parent = menuitem.Parent;
352                         RadioCheck = menuitem.RadioCheck;
353                         Shortcut = menuitem.Shortcut;
354                         ShowShortcut = menuitem.ShowShortcut;
355                         Text = menuitem.Text;
356                         Visible = menuitem.Visible;
357
358                         // Events
359                         Click = menuitem.Click;
360                         DrawItem = menuitem.DrawItem;
361                         MeasureItem = menuitem.MeasureItem;
362                         Popup = menuitem.Popup;
363                         Select = menuitem.Select;
364                 }
365
366                 protected override void Dispose (bool disposing)
367                 {
368                         base.Dispose (disposing);                       
369                 }
370
371                 // This really clones the item
372                 public virtual MenuItem MergeMenu ()
373                 {
374                         MenuItem item = new MenuItem ();
375                         item.CloneMenu (this);
376                         return item;
377                 }
378
379                 public void MergeMenu (MenuItem menuitem)
380                 {
381                         base.MergeMenu (menuitem);
382                 }
383
384                 protected virtual void OnClick (EventArgs e)
385                 {
386                         if (Click != null)
387                                 Click (this, e);
388                 }
389
390                 protected virtual void OnDrawItem (DrawItemEventArgs e)
391                 {
392                         if (DrawItem != null) {
393                                 DrawItem (this, e);
394                                 return;
395                         }
396                         
397                         ThemeEngine.Current.DrawMenuItem (this, e);     
398                 }
399
400
401                 protected virtual void OnInitMenuPopup (EventArgs e)
402                 {
403                         OnPopup (e);
404                 }
405
406                 protected virtual void OnMeasureItem (MeasureItemEventArgs e)
407                 {
408                         if (MeasureItem != null)
409                                 MeasureItem (this, e);
410                 }
411
412                 protected virtual void OnPopup (EventArgs e)
413                 {
414                         if (Popup != null)
415                                 Popup (this, e);
416                 }
417
418                 protected virtual void OnSelect (EventArgs e)
419                 {
420                         if (Select != null)
421                                 Select (this, e);
422                 }
423
424                 public void PerformClick ()
425                 {
426                         OnClick (EventArgs.Empty);
427                 }
428
429                 public virtual void PerformSelect ()
430                 {
431                         OnSelect (EventArgs.Empty);
432                 }
433
434                 public override string ToString ()
435                 {
436                         return base.ToString () + ", Items.Count: " + MenuItems.Count + ", Text: " + text;
437                 }
438
439                 #endregion Public Methods
440
441                 #region Private Methods
442
443                 internal void Create ()
444                 {
445                         IntPtr hSubMenu = IntPtr.Zero;
446
447                         menuid = index = MenuAPI.InsertMenuItem (Parent.Handle, -1, true, this, ref hSubMenu);
448                         IsDirty = false;
449
450                         if (IsPopup) {
451                                 menu_handle = hSubMenu;
452                                 CreateItems ();
453                         }
454                 }
455                 
456                 internal void PerformDrawItem (DrawItemEventArgs e)
457                 {
458                         OnDrawItem (e);
459                 }
460                 
461                 internal void PerformMeasureItem (MeasureItemEventArgs e)
462                 {
463                         OnMeasureItem (e);
464                 }
465
466                 private void ProcessMnemonic ()
467                 {
468                         if (text.Length < 2) {
469                                 mnemonic = '\0';
470                                 return;
471                         }
472
473                         bool bPrevAmp = false;
474                         for (int i = 0; i < text.Length -1 ; i++) {
475                                 if (text[i] == '&') {
476                                         if (bPrevAmp == false &&  (text[i+1] != '&')) {
477                                                 mnemonic = Char.ToUpper (text[i+1]);
478                                                 return;
479                                         }
480
481                                         bPrevAmp = true;
482                                 }
483                                 else
484                                         bPrevAmp = false;
485                         }
486
487                         mnemonic = '\0';
488                 }
489
490                 private string GetShortCutTextCtrl () { return "Ctrl"; }
491                 private string GetShortCutTextAlt () { return "Alt"; }
492                 private string GetShortCutTextShift () { return "Shift"; }              
493
494                 internal string GetShortCutText ()
495                 {
496                         /* Ctrl+A - Ctrl+Z */
497                         if (Shortcut >= Shortcut.CtrlA && Shortcut <= Shortcut.CtrlZ)
498                                 return GetShortCutTextCtrl () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlA));
499
500                         /* Alt+0 - Alt+9 */
501                         if (Shortcut >= Shortcut.Alt0 && Shortcut <= Shortcut.Alt9)
502                                 return GetShortCutTextAlt () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Alt0));
503
504                         /* Alt+F1 - Alt+F2 */
505                         if (Shortcut >= Shortcut.AltF1 && Shortcut <= Shortcut.AltF9)
506                                 return GetShortCutTextAlt () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.AltF1));
507
508                         /* Ctrl+0 - Ctrl+9 */
509                         if (Shortcut >= Shortcut.Ctrl0 && Shortcut <= Shortcut.Ctrl9)
510                                 return GetShortCutTextCtrl () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.Ctrl0));
511                                                         
512                         /* Ctrl+F0 - Ctrl+F9 */
513                         if (Shortcut >= Shortcut.CtrlF1 && Shortcut <= Shortcut.CtrlF9)
514                                 return GetShortCutTextCtrl () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlF1));
515                                 
516                         /* Ctrl+Shift+0 - Ctrl+Shift+9 */
517                         if (Shortcut >= Shortcut.CtrlShift0 && Shortcut <= Shortcut.CtrlShift9)
518                                 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) '0' + (int)(Shortcut - Shortcut.CtrlShift0));
519                                 
520                         /* Ctrl+Shift+A - Ctrl+Shift+Z */
521                         if (Shortcut >= Shortcut.CtrlShiftA && Shortcut <= Shortcut.CtrlShiftZ)
522                                 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+" + (char)((int) 'A' + (int)(Shortcut - Shortcut.CtrlShiftA));
523
524                         /* Ctrl+Shift+F1 - Ctrl+Shift+F9 */
525                         if (Shortcut >= Shortcut.CtrlShiftF1 && Shortcut <= Shortcut.CtrlShiftF9)
526                                 return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.CtrlShiftF1));
527                                 
528                         /* F1 - F9 */
529                         if (Shortcut >= Shortcut.F1 && Shortcut <= Shortcut.F9)
530                                 return "F" + (char)((int) '1' + (int)(Shortcut - Shortcut.F1));
531                                 
532                         /* Shift+F1 - Shift+F9 */
533                         if (Shortcut >= Shortcut.ShiftF1 && Shortcut <= Shortcut.ShiftF9)
534                                 return GetShortCutTextShift () + "+F" + (char)((int) '1' + (int)(Shortcut - Shortcut.ShiftF1));
535                         
536                         /* Special cases */
537                         switch (Shortcut) {
538                                 case Shortcut.AltBksp:
539                                         return "AltBksp";
540                                 case Shortcut.AltF10:
541                                         return GetShortCutTextAlt () + "+F10";
542                                 case Shortcut.AltF11:
543                                         return GetShortCutTextAlt () + "+F11";
544                                 case Shortcut.AltF12:
545                                         return GetShortCutTextAlt () + "+F12";
546                                 case Shortcut.CtrlDel:          
547                                         return GetShortCutTextCtrl () + "+Del";
548                                 case Shortcut.CtrlF10:
549                                         return GetShortCutTextCtrl () + "+F10";
550                                 case Shortcut.CtrlF11:
551                                         return GetShortCutTextCtrl () + "+F11";
552                                 case Shortcut.CtrlF12:
553                                         return GetShortCutTextCtrl () + "+F12";
554                                 case Shortcut.CtrlIns:
555                                         return GetShortCutTextCtrl () + "+Ins";
556                                 case Shortcut.CtrlShiftF10:
557                                         return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F10";
558                                 case Shortcut.CtrlShiftF11:
559                                         return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F11";
560                                 case Shortcut.CtrlShiftF12:
561                                         return GetShortCutTextCtrl () + "+" + GetShortCutTextShift () + "+F12";
562                                 case Shortcut.Del:
563                                         return "Del";
564                                 case Shortcut.F10:
565                                         return "F10";   
566                                 case Shortcut.F11:
567                                         return "F11";   
568                                 case Shortcut.F12:
569                                         return "F12";   
570                                 case Shortcut.Ins:
571                                         return "Ins";   
572                                 case Shortcut.None:
573                                         return "None";  
574                                 case Shortcut.ShiftDel:
575                                         return GetShortCutTextShift () + "+Del";
576                                 case Shortcut.ShiftF10:
577                                         return GetShortCutTextShift () + "+F10";
578                                 case Shortcut.ShiftF11:
579                                         return GetShortCutTextShift () + "+F11";
580                                 case Shortcut.ShiftF12:
581                                         return GetShortCutTextShift () + "+F12";                                
582                                 case Shortcut.ShiftIns:
583                                         return GetShortCutTextShift () + "+Ins";
584                                 default:
585                                         break;
586                                 }
587                                 
588                         return "";
589                 }
590
591                 #endregion Private Methods
592
593         }
594 }
595
596