Copied remotely
[mono.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / Menu.cs
1 //
2 // System.Windows.Forms.Menu.cs
3 //
4 // Author:
5 //   stubbed out by Paul Osman (paul.osman@sympatico.ca)
6 //      Dennis Hayes (dennish@raytek.com)
7 //      Alexandre Pigolkine (pigolkine@gmx.de)
8 //
9 // (C) 2002 Ximian, Inc
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Reflection;
35 using System.Globalization;
36 //using System.Windows.Forms.AccessibleObject.IAccessible;
37 using System.Drawing;
38 using System.Collections;
39 using System.Runtime.Remoting;
40
41 namespace System.Windows.Forms  {
42
43
44         /// <summary>
45         /// </summary>
46         using System.ComponentModel;
47         public abstract class Menu : Component  {
48
49                 // Static Constant Fields
50                 public const int FindHandle = 0;
51                 public const int FindShortcut = 1;
52
53
54                 //
55                 // -- Public Methods
56                 //
57
58                 [MonoTODO]
59                 public MenuItem FindMenuItem(int type, IntPtr value) {
60                         throw new NotImplementedException();
61                 }
62
63                 [MonoTODO]
64                 public ContextMenu GetContextMenu() {
65                         throw new NotImplementedException();
66                 }
67
68                 [MonoTODO]
69                 public MainMenu GetMainMenu() {
70                         if ( parent_ == null )
71                                 return this as MainMenu;
72
73                         Menu parent = parent_;
74
75                         while ( parent != null ) {
76                                 if ( parent.parent_ != null )
77                                         parent = parent.parent_;
78                                 else
79                                         break;
80                         }
81
82                         return parent as MainMenu;
83                 }
84
85                 [MonoTODO]
86                 public virtual void MergeMenu(Menu menuSrc) {
87                         // FIXME:
88                 }
89                 
90                 [MonoTODO]
91                 public override string ToString() {
92                         //do our own ToString here.
93                         // this is overrridden
94                         return base.ToString();
95                 }
96
97                 //
98                 // -- Protected Methods
99                 //
100
101
102                 [MonoTODO]
103                 protected void CloneMenu(Menu menuSrc) {
104                         // FIXME:
105                 }
106
107                 [MonoTODO]
108                 protected override void Dispose(bool disposing) {
109                         // FIXME:
110                         base.Dispose(disposing);
111                 }
112
113                 [MonoTODO]
114                 protected int FindMergePosition(int mergeOrder) {
115                         throw new NotImplementedException();
116                 }
117
118                 protected Menu( MenuItem[] items) {
119                         MenuItems.AddRange ( items);
120                 }
121
122                 //
123                 // -- Public Properties
124                 //
125
126                 private bool menuStructureModified_ = true;
127
128                 internal bool MenuStructureModified {
129                         set {
130                                 menuStructureModified_ = value;
131                         }
132                 }
133
134                 
135                 internal void BuildMenuStructure () {
136                         if( menuStructureModified_) {
137                                 Win32.SetMenuDefaultItem(menuHandle_, -1, 0);
138                                 while( Win32.RemoveMenu( menuHandle_, 0, (uint)MF_.MF_BYPOSITION) != 0);
139                                 foreach(MenuItem mi in MenuItems) {
140                                         //System.Console.WriteLine("MenuItem {0} Parent {1}", mi.Text, mi.IsParent);
141                                         if( mi.IsParent){
142                                                 Win32.AppendMenuA( menuHandle_, (int)MF_.MF_ENABLED | (int)MF_.MF_STRING | (int)MF_.MF_POPUP,
143                                                                                                                         mi.Handle, mi.Text);
144                                         }
145                                         else {
146                                                 Win32.AppendMenuA( menuHandle_, mi.MenuItemFlags,
147                                                                    (IntPtr) mi.GetID(), mi.Text);
148                                                 if(mi.DefaultItem) {
149                                                         Win32.SetMenuDefaultItem(menuHandle_, mi.GetID(), 0);
150                                                 }
151                                         }
152                                 }
153                                 menuStructureModified_ = false;
154                         }
155                 }
156                 
157                 internal Menu parent_ = null;
158         
159                 internal IntPtr menuHandle_ = IntPtr.Zero;
160                 internal bool   isPopupMenu = false;
161                 
162                 [MonoTODO]
163                 protected virtual IntPtr CreateMenuHandle() {
164                         //changed from internal void to protected intptr for signture reasons.
165                         //Also had to add return menuitem_ at same time.
166                         if( menuHandle_ == IntPtr.Zero) {
167                                 if ( !isPopupMenu )
168                                         menuHandle_ = Win32.CreateMenu();
169                                 else
170                                         menuHandle_ = Win32.CreatePopupMenu ( );
171                                 //System.Console.WriteLine("Create menu {0}", menuHandle_);
172                                 BuildMenuStructure();
173                                 allMenus_[menuHandle_] = this;
174                         }
175                         return menuHandle_;
176                 }
177                 
178                 public IntPtr Handle {
179                         get {
180                                 CreateMenuHandle();
181                                 return menuHandle_;
182                         }
183                 }
184
185                 public virtual bool IsParent {
186
187                         get {
188                                 return MenuItems.Count != 0;
189                         }
190                 }
191
192                 public MenuItem MdiListItem {
193                         get {
194                                 MenuItem mdiListItem = null;
195                                 foreach( MenuItem mi in MenuItems) {
196                                         if ( mi.MdiList )
197                                                 return mi;
198
199                                         mdiListItem = mi.MdiListItem;
200                                         if ( mdiListItem != null ) break;
201                                 }
202                                 return mdiListItem;
203                         }
204                 }
205
206                 private Menu.MenuItemCollection  menuCollection_ = null;
207
208                 public Menu.MenuItemCollection MenuItems {
209                         get {
210                                 if( menuCollection_ == null) {
211                                         menuCollection_ = new Menu.MenuItemCollection( this);
212                                 }
213                                 return menuCollection_;
214                         }
215                 }
216
217
218                 // Library interface
219
220                 // Recursively searches for specified item in menu.
221                 // Goes immediately into child, when mets one.
222                 internal MenuItem GetMenuItemByID (uint id) {
223                         foreach( MenuItem mi in MenuItems) {
224                                 if( mi.IsParent) {
225                                         MenuItem submi = mi.GetMenuItemByID(id);
226                                         if( submi != null) return submi;
227                                 }
228                                 else {
229                                         if( mi.GetID() == id){
230                                                 return mi;
231                                         }
232                                 }
233                         }
234                         return null;
235                 }
236                 
237                 private static Hashtable allMenus_ = new Hashtable();
238                 
239                 internal static Menu GetMenuByHandle (IntPtr hMenu) {
240                         Menu result = null;
241                         try {
242                                 result = allMenus_[hMenu] as Menu;
243                         }
244                         catch(ArgumentNullException) {
245                         }
246                         catch(NotSupportedException) {
247                         }
248                         return result;
249                 }
250                 
251                 internal void OnNewMenuItemAdd (MenuItem mi){
252                         menuStructureModified_ = true;
253                         mi.SetParent( this);
254                 }
255                 
256                 internal void OnRemoveMenuItem (MenuItem mi)
257                 {
258                         if(menuHandle_ != IntPtr.Zero) {
259                                 menuStructureModified_ = true;
260                         }
261                         mi.SetParent( null);
262                 }
263                 
264                 internal void OnLastSubItemRemoved ()
265                 {
266                         if( menuHandle_ != IntPtr.Zero) {
267                                 //System.Console.WriteLine("Delete menu {0}", menuHandle_);
268                                 Win32.DestroyMenu(menuHandle_);
269                                 allMenus_.Remove(menuHandle_);
270                                 menuHandle_ = IntPtr.Zero;
271                                 
272                                 if( parent_ != null) {
273                                         parent_.MenuStructureModified = true;
274                                 }
275                         }
276                 }
277                 
278                 internal void OnWmInitMenu ()
279                 {
280                 }
281                 
282                 internal void OnWmInitMenuPopup ()
283                 {
284                         BuildMenuStructure();
285                 }
286
287                 //
288                 // System.Windows.Forms.Menu.MenuItemCollection.cs
289                 //
290                 // Author:
291                 //   stubbed out by Paul Osman (paul.osman@sympatico.ca)
292                 //
293                 // (C) 2002 Ximian, Inc
294                 //
295                 /// <summary>
296                 /// </summary>
297
298                 public class MenuItemCollection : IList, ICollection, IEnumerable {
299                         private ArrayList               items_ = new ArrayList();
300                         private Menu                    parentMenu_ = null;
301                         //
302                         // -- Constructor
303                         //
304
305                         public MenuItemCollection (Menu m) {
306                                 parentMenu_ = m;
307                         }
308
309                         internal void MoveItemToIndex( int index, MenuItem mi) {
310                                 if( index >= items_.Count){
311                                         // FIXME: Set exception parameters
312                                         throw new ArgumentException();
313                                 }
314                                 else if( items_.Count != 1){
315                                         items_.Remove (mi);
316                                         items_.Insert (index, mi);
317                                         mi.SetIndex(index);
318                                 }
319                         }
320
321                         //
322                         // -- Public Methods
323                         //
324
325                         public virtual int Add (MenuItem mi) {
326                                 int result = -1;
327                                 if( mi != null && parentMenu_ != null){
328                                         parentMenu_.OnNewMenuItemAdd(mi);
329                                         items_.Add(mi);
330                                         result = items_.Count - 1;
331                                         mi.SetIndex(result);
332                                 }
333                                 return result;
334                         }
335                         
336                         private MenuItem AddMenuItemCommon (MenuItem mi) {
337                                 return ( -1 != Add (mi)) ? mi : null;
338                         }
339
340                         public virtual MenuItem Add ( string s) {
341                                 return AddMenuItemCommon( new MenuItem (s));
342                         }
343
344                         public virtual int Add ( int i, MenuItem mi) {
345                                 if( i > items_.Count){
346                                         // FIXME: Set exception details
347                                         throw new System.ArgumentException();
348                                 }
349                                 int result = -1;
350                                 if( mi != null && parentMenu_ != null){
351                                         parentMenu_.OnNewMenuItemAdd(mi);
352                                         items_.Insert(i, mi);
353                                         result = i;
354                                         mi.SetIndex(result);
355                                 }
356                                 return result;
357                         }
358
359                         public virtual MenuItem Add (string s, EventHandler e) {
360                                 return AddMenuItemCommon(new MenuItem ( s, e));
361                         }
362
363                         public virtual MenuItem Add (string s, MenuItem[] items) {
364                                 return AddMenuItemCommon(new MenuItem ( s, items));
365                         }
366
367                         public virtual void AddRange(MenuItem[] items) {
368                                 if( items != null) {
369                                         foreach( MenuItem mi in items) {
370                                                 Add(mi);
371                                         }
372                                 }
373                         }
374
375                         private void DoClear() {
376                                 if( parentMenu_ != null) {
377                                         foreach( MenuItem mi in items_) {
378                                                 parentMenu_.OnRemoveMenuItem( mi);
379                                         }
380                                 }
381                                 items_.Clear();
382                                 if( parentMenu_ != null) {
383                                         parentMenu_.OnLastSubItemRemoved();
384                                 }                               
385                         }
386
387                         public virtual void Clear() {
388                                 DoClear();
389                         }
390
391                         public bool Contains(MenuItem m) {
392                                 return items_.Contains(m);
393                         }
394
395                         public void CopyTo(Array a, int i) {
396                                 int targetIdx = i;
397                                 foreach( MenuItem mi in items_) {
398                                         MenuItem newMi = mi.CloneMenu();
399                                         a.SetValue(newMi,targetIdx++);
400                                 }
401                         }
402
403                         public override bool Equals(object o) {
404                                 return base.Equals(o);
405                         }
406
407                         [MonoTODO]
408                         public override int GetHashCode() {
409                                 //FIXME add our proprities
410                                 return base.GetHashCode();
411                         }
412
413                         public IEnumerator GetEnumerator() {
414                                 return items_.GetEnumerator();
415                         }
416
417                         public int IndexOf(MenuItem m) {
418                                 return items_.IndexOf(m);
419                         }
420
421                         public virtual void Remove(MenuItem m) {
422                                 if( m != null && parentMenu_ != null){
423                                         if( Contains(m)){
424                                                 parentMenu_.OnRemoveMenuItem(m);
425                                                 items_.Remove(m);
426                                                 if( items_.Count == 0){
427                                                         parentMenu_.OnLastSubItemRemoved();
428                                                 }                               
429                                         }
430                                 }
431                         }
432
433                         public virtual void RemoveAt(int i) {
434                                 Remove(items_[i] as MenuItem);
435                         }
436
437                         public override string ToString() {
438                                 throw new NotImplementedException ();
439                         }
440
441                         //
442                         // -- Protected Methods
443                         //
444
445                         ~MenuItemCollection() {
446                                 Clear();
447                         }
448
449                         //inherited
450                         //protected object MemberwiseClone() {
451                         //      throw new NotImplementedException ();
452                         //}
453
454                         //
455                         // -- Public Properties
456                         //
457
458                         public int Count {
459
460                                 get {
461                                         return items_.Count;                                    
462                                 }
463                         }
464
465                         //              public virtual MenuItem this(int i)
466                         //              {
467                         //                      get
468                         //                      {
469                         //                              throw new NotImplementedException ();
470                         //                      }
471                         //              }
472                         /// <summary>
473                         /// IList Interface implmentation.
474                         /// </summary>
475                         bool IList.IsReadOnly {
476                                 get {
477                                         // We allow addition, removeal, and editing of items after creation of the list.
478                                         return false;
479                                 }
480                         }
481
482                         bool IList.IsFixedSize {
483                                 get {
484                                         // We allow addition and removeal of items after creation of the list.
485                                         return false;
486                                 }
487                         }
488
489                         public MenuItem this[int index] {
490                                 get {
491                                         return items_[index] as MenuItem;
492                                 }
493                         }
494
495                         //[MonoTODO]
496                         object IList.this[int index] {
497                                 get {
498                                         return items_[index];
499                                 }
500                                 set {
501                                         // FIXME: Set exception members
502                                         throw new System.NotSupportedException();
503                                 }
504                         }
505                 
506                         [MonoTODO]
507                         void IList.Clear() {
508                                 DoClear();
509                         }
510
511                         private MenuItem Object2MenuItem( object value) {
512                                 MenuItem result = value as MenuItem;
513                                 if( result == null) {
514                                         // FIXME: Set exception parameters
515                                         throw new System.ArgumentException();
516                                 }
517                                 return result;
518                         }
519
520                         [MonoTODO]
521                         int IList.Add( object value) {
522                                 return Add( Object2MenuItem(value));
523                         }
524
525                         [MonoTODO]
526                         bool IList.Contains( object value) {
527                                 return Contains(Object2MenuItem(value));
528                         }
529
530                         [MonoTODO]
531                         int IList.IndexOf( object value) {
532                                 return IndexOf(Object2MenuItem(value));
533                         }
534
535                         [MonoTODO]
536                         void IList.Insert(int index, object value) {
537                                 Add( index, Object2MenuItem(value));
538                         }
539
540                         [MonoTODO]
541                         void IList.Remove( object value) {
542                                 Remove( Object2MenuItem(value));
543                         }
544
545                         [MonoTODO]
546                         void IList.RemoveAt( int index){
547                                 RemoveAt(index);
548                         }
549                         // End of IList interface
550
551                         /// <summary>
552                         /// ICollection Interface implmentation.
553                         /// </summary>
554                         int ICollection.Count {
555                                 get {
556                                         return Count;
557                                 }
558                         }
559                         bool ICollection.IsSynchronized {
560                                 get {
561                                         throw new NotImplementedException ();
562                                 }
563                         }
564                         object ICollection.SyncRoot {
565                                 get {
566                                         throw new NotImplementedException ();
567                                 }
568                         }
569                         void ICollection.CopyTo(Array array, int index){
570                                 CopyTo(array, index);
571                         }
572                         // End Of ICollection
573                 }
574         }
575 }
576
577
578