New test.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / PropertyGrid.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 //      Jonathan Chambers (jonathan.chambers@ansys.com)
24 //
25
26 // NOT COMPLETE
27
28 using System;
29 using System.Drawing;
30 using System.Drawing.Design;
31 using System.ComponentModel;
32 using System.Collections;
33 using System.ComponentModel.Design;
34 using System.Reflection;
35 using System.Windows.Forms.Design;
36 using System.Windows.Forms.PropertyGridInternal;
37
38 namespace System.Windows.Forms {
39         [Designer("System.Windows.Forms.Design.PropertyGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
40         public class PropertyGrid : System.Windows.Forms.ContainerControl, ComponentModel.Com2Interop.IComPropertyBrowser {
41                 #region Private Members
42                 
43                 
44                 private const int GRID_ITEM_HEIGHT = 16;
45                 private const int GRID_LEFT_COLUMN_WIDTH = 16;
46                 private const int DIVIDER_PADDING = 2;
47
48                 private AttributeCollection browsable_attributes = null;
49                 private bool can_show_commands = false;
50                 private Color commands_back_color;
51                 private Color commands_fore_color;
52                 private bool commands_visible;
53                 private bool commands_visible_if_available;
54                 private Point context_menu_default_location;
55                 private bool large_buttons;
56                 private Color line_color;
57                 private PropertySort property_sort;
58                 private PropertyTabCollection property_tabs;
59                 private GridItem selected_grid_item;
60                 internal GridItem root_grid_item;
61                 private object[] selected_objects;
62                 private PropertyTab selected_tab;
63
64                 private ImageList toolbar_imagelist;
65                 private ToolBarButton categorized_toolbarbutton;
66                 private ToolBarButton alphabetic_toolbarbutton;
67                 private ToolBarButton separator_toolbarbutton;
68                 private ToolBarButton propertypages_toolbarbutton;
69
70                 internal ToolBar toolbar;
71                 internal PropertyGridView property_grid_view;
72                 internal Splitter splitter;
73                 internal Panel help_panel;
74                 internal Label help_title_label;
75                 internal Label help_description_label;
76                 private ContextMenu context_menu;
77                 private MenuItem reset_menuitem;
78                 private MenuItem description_menuitem;
79                 private object current_property_value;
80
81                 #endregion      // Private Members
82                 
83                 #region Contructors
84                 public PropertyGrid() {
85                         selected_objects = new object[0];
86                         property_tabs = new PropertyTabCollection();
87
88                         line_color = SystemColors.ScrollBar;
89                         line_color = SystemColors.ScrollBar;
90                         browsable_attributes = new AttributeCollection(new Attribute[] {});
91                         commands_visible_if_available = false;
92                         property_sort = PropertySort.Categorized;
93
94                         property_grid_view = new PropertyGridView(this);
95
96                         splitter = new Splitter();
97                         splitter.Dock = DockStyle.Bottom;
98
99                         help_panel = new Panel();
100                         help_panel.Dock = DockStyle.Bottom;
101                         //help_panel.DockPadding.All = 3;
102                         help_panel.Height = 50;
103                         help_panel.BackColor = SystemColors.Control;
104
105
106                         help_title_label = new Label();
107                         help_title_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
108                         help_title_label.Name = "help_title_label";
109                         help_title_label.Font = new Font(this.Font,FontStyle.Bold);
110                         help_title_label.Location = new Point(2,2);
111                         help_title_label.Height = 17;
112                         help_title_label.Width = help_panel.Width - 4;
113
114                         
115                         help_description_label = new Label();
116                         help_description_label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
117                         help_description_label.Name = "help_description_label";
118                         help_description_label.Font = this.Font;
119                         help_description_label.Location = new Point(2,help_title_label.Top+help_title_label.Height);
120                         help_description_label.Width = help_panel.Width - 4;
121                         help_description_label.Height = help_panel.Height - help_description_label.Top - 2;
122
123                         help_panel.Controls.Add(help_description_label);
124                         help_panel.Controls.Add(help_title_label);
125                         help_panel.Paint+=new PaintEventHandler(help_panel_Paint);
126
127                         toolbar = new PropertyToolBar();
128                         toolbar.Dock = DockStyle.Top;
129                         categorized_toolbarbutton = new ToolBarButton();
130                         alphabetic_toolbarbutton = new ToolBarButton();
131                         separator_toolbarbutton = new ToolBarButton();
132                         propertypages_toolbarbutton = new ToolBarButton();
133                         context_menu = new ContextMenu();
134
135                         toolbar_imagelist = new ImageList();
136                         toolbar_imagelist.ColorDepth = ColorDepth.Depth32Bit;
137                         toolbar_imagelist.ImageSize = new System.Drawing.Size(16, 16);
138                         toolbar_imagelist.TransparentColor = System.Drawing.Color.Transparent;
139                         toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_category") );
140                         toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_sort_alphabetical") );
141                         toolbar_imagelist.Images.Add( (Image)Locale.GetResource( "propertygrid_tab_properties") );
142
143                         toolbar.Appearance = ToolBarAppearance.Flat;
144                         toolbar.AutoSize = false;
145                         toolbar.Buttons.AddRange(new ToolBarButton[] {categorized_toolbarbutton,
146                                                                       alphabetic_toolbarbutton,
147                                                                       separator_toolbarbutton,
148                                                                       propertypages_toolbarbutton});
149                         
150                         toolbar.ButtonSize = new System.Drawing.Size(20, 20);
151                         toolbar.ImageList = toolbar_imagelist;
152                         toolbar.Location = new System.Drawing.Point(0, 0);
153                         toolbar.ShowToolTips = true;
154                         toolbar.Size = new System.Drawing.Size(256, 27);
155                         toolbar.TabIndex = 0;
156                         toolbar.ButtonClick += new ToolBarButtonClickEventHandler(toolbar_ButtonClick);
157
158                         categorized_toolbarbutton.ImageIndex = 0;
159                         categorized_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
160                         categorized_toolbarbutton.ToolTipText = Locale.GetText ("Categorized");
161
162                         alphabetic_toolbarbutton.ImageIndex = 1;
163                         alphabetic_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
164                         alphabetic_toolbarbutton.ToolTipText = Locale.GetText ("Alphabetic");
165
166                         separator_toolbarbutton.Style = ToolBarButtonStyle.Separator;
167
168                         propertypages_toolbarbutton.Enabled = false;
169                         propertypages_toolbarbutton.ImageIndex = 2;
170                         propertypages_toolbarbutton.Style = ToolBarButtonStyle.ToggleButton;
171                         propertypages_toolbarbutton.ToolTipText = "Property Pages";
172
173                         
174                         reset_menuitem = context_menu.MenuItems.Add("Reset");
175                         reset_menuitem.Click +=new EventHandler(OnResetPropertyClick);
176                         context_menu.MenuItems.Add("-");
177                         description_menuitem = context_menu.MenuItems.Add("Description");
178                         description_menuitem.Click += new EventHandler(OnDescriptionClick);
179                         description_menuitem.Checked = this.HelpVisible;
180                         this.ContextMenu = context_menu;
181                         toolbar.ContextMenu = context_menu;
182                         
183                         BorderHelperControl helper = new BorderHelperControl ();
184                         helper.Dock = DockStyle.Fill;
185                         helper.Controls.Add (property_grid_view);
186                         
187                         this.Controls.Add(helper);
188                         this.Controls.Add(toolbar);
189                         this.Controls.Add(splitter);
190                         this.Controls.Add(help_panel);
191                         this.Name = "PropertyGrid";
192                         this.Size = new System.Drawing.Size(256, 400);
193
194                         UpdateToolBarButtons();
195                 }
196                 #endregion      // Constructors
197
198                 #region Public Instance Properties
199
200                 [BrowsableAttribute(false)]
201                 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
202                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
203                 public AttributeCollection BrowsableAttributes {
204                         get {
205                                 return browsable_attributes;
206                         }
207
208                         set {
209                                 if (browsable_attributes == value) {
210                                         return;
211                                 }
212
213                                 browsable_attributes = value;
214                         }
215                 }
216                 
217                 [Browsable(false)]
218                 [EditorBrowsable(EditorBrowsableState.Never)]
219                 public override bool AutoScroll {
220                         get {
221                                 return base.AutoScroll;
222                         }
223                         set {
224                                 base.AutoScroll = value;
225                         }
226                 }
227
228                 public override Color BackColor {
229                         get {
230                                 return base.BackColor;
231                         }
232
233                         set {
234                                 base.BackColor = value;
235                                 toolbar.BackColor = value;
236                                 Refresh ();
237                         }
238                 }
239                 
240                 [Browsable(false)]
241                 [EditorBrowsable(EditorBrowsableState.Never)]
242                 public override Image BackgroundImage {
243                         get {
244                                 return base.BackgroundImage;
245                         }               
246                         set {
247                                 base.BackgroundImage = value;
248                         }
249                 }
250
251
252                 [BrowsableAttribute(false)]
253                 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
254                 public virtual bool CanShowCommands {
255                         get {
256                                 return can_show_commands;
257                         }
258                 }
259
260                 public Color CommandsBackColor {
261                         get {
262                                 return commands_back_color;
263                         }
264
265                         set {
266                                 if (commands_back_color == value) {
267                                         return;
268                                 }
269                                 commands_back_color = value;
270                         }
271                 }
272
273                 public Color CommandsForeColor {
274                         get {
275                                 return commands_fore_color;
276                         }
277
278                         set {
279                                 if (commands_fore_color == value) {
280                                         return;
281                                 }
282                                 commands_fore_color = value;
283                         }
284                 }
285
286                 [BrowsableAttribute(false)]
287                 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
288                 public virtual bool CommandsVisible {
289                         get {
290                                 return commands_visible;
291                         }
292                 }
293
294                 [DefaultValue(false)]
295                 public virtual bool CommandsVisibleIfAvailable {
296                         get {
297                                 return commands_visible_if_available;
298                         }
299
300                         set {
301                                 if (commands_visible_if_available == value) {
302                                         return;
303                                 }
304                                 commands_visible_if_available = value;
305                         }
306                 }
307
308                 [BrowsableAttribute(false)]
309                 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
310                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
311                 public Point ContextMenuDefaultLocation {
312                         get {
313                                 return context_menu_default_location;
314                         }
315                 }
316                 
317                 [Browsable(false)]
318                 [EditorBrowsable(EditorBrowsableState.Never)]
319                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
320                 public new Control.ControlCollection Controls {
321                         get {
322                                 return base.Controls;
323                         }
324                 }
325                 
326                 [Browsable(false)]
327                 [EditorBrowsable(EditorBrowsableState.Never)]
328                 public override Color ForeColor {
329                         get {
330                                 return base.ForeColor;
331                         }
332                         set {
333                                 base.ForeColor = value;
334                         }
335                 }
336
337                 public Color HelpBackColor {
338                         get {
339                                 return help_panel.BackColor;
340                         }
341                         set {
342                                 if (help_panel.BackColor == value) {
343                                         return;
344                                 }
345
346                                 help_panel.BackColor = value;
347                         }
348                 }
349
350                 public Color HelpForeColor {
351                         get {
352                                 return help_panel.ForeColor;
353                         }
354
355                         set {
356                                 if (help_panel.ForeColor == value) {
357                                         return;
358                                 }
359
360                                 help_panel.ForeColor = value;
361                         }
362                 }
363
364                 [DefaultValue(true)]
365                 [Localizable(true)]
366                 public virtual bool HelpVisible {
367                         get {
368                                 return help_panel.Visible;
369                         }
370
371                         set {
372                                 if (help_panel.Visible == value) {
373                                         return;
374                                 }
375
376                                 help_panel.Visible = value;
377                         }
378                 }
379
380                 public bool LargeButtons {
381                         get {
382                                 return large_buttons;
383                         }
384
385                         set {
386                                 if (large_buttons == value) {
387                                         return;
388                                 }
389
390                                 large_buttons = value;
391                         }
392                 }
393
394                 public Color LineColor {
395                         get {
396                                 return line_color;
397                         }
398
399                         set {
400                                 if (line_color == value) {
401                                         return;
402                                 }
403
404                                 line_color = value;
405                         }
406                 }
407
408                 [DefaultValue(PropertySort.CategorizedAlphabetical)]
409                 public PropertySort PropertySort {
410                         get {
411                                 return property_sort;
412                         }
413
414                         set {
415                                 if (!Enum.IsDefined (typeof (PropertySort), value)) {
416                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for PropertySort", value));
417                                 }
418
419                                 if (property_sort == value) {
420                                         return;
421                                 }
422
423                                 property_sort = value;
424
425                                 UpdateToolBarButtons();
426                                 ReflectObjects();
427                                 property_grid_view.Refresh();
428                                 
429                                 if (PropertySortChanged != null) {
430                                         PropertySortChanged(this, EventArgs.Empty);
431                                 }
432                         }
433                 }
434
435                 [BrowsableAttribute(false)]
436                 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
437                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
438                 public PropertyTabCollection PropertyTabs {
439                         get {
440                                 return property_tabs;
441                         }
442                 }
443
444                 [BrowsableAttribute(false)]
445                 [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
446                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
447                 public GridItem SelectedGridItem {
448                         get {
449                                 return selected_grid_item;
450                         }
451
452                         set {
453                                 if (selected_grid_item == value) {
454                                         return;
455                                 }
456
457                                 GridItem oldItem = selected_grid_item;
458                                 selected_grid_item = value;
459                                 this.help_title_label.Text = selected_grid_item.Label;
460                                 if (selected_grid_item.PropertyDescriptor != null)
461                                         this.help_description_label.Text = selected_grid_item.PropertyDescriptor.Description;
462                                         
463                                 current_property_value = value.Value;
464                                 if (oldItem != null && oldItem.PropertyDescriptor != null) {
465                                         for (int i = 0; i < ((GridEntry)oldItem).SelectedObjects.Length; i ++) {
466                                                 object target = GetTarget (oldItem, i);
467                                                 oldItem.PropertyDescriptor.RemoveValueChanged(target, new EventHandler(HandlePropertyValueChanged));
468                                         }
469                                 }
470                                 if (selected_grid_item.PropertyDescriptor != null) {
471                                         for (int i = 0; i < ((GridEntry)selected_grid_item).SelectedObjects.Length; i ++) {
472                                                 object target = GetTarget (selected_grid_item, i);
473                                                 selected_grid_item.PropertyDescriptor.AddValueChanged(target, new EventHandler(HandlePropertyValueChanged));
474                                         }
475                                 }
476                                 OnSelectedGridItemChanged(new SelectedGridItemChangedEventArgs (oldItem, selected_grid_item));
477                         }
478                 }
479
480                 private void HandlePropertyValueChanged(object sender, EventArgs e) {
481                         OnPropertyValueChanged(new PropertyValueChangedEventArgs( selected_grid_item, current_property_value));
482                 }
483
484                 [DefaultValue(null)]
485                 [TypeConverter("System.Windows.Forms.PropertyGrid+SelectedObjectConverter, " + Consts.AssemblySystem_Windows_Forms)]
486                 public object SelectedObject {
487                         get {
488                                 if (selected_objects.Length > 0)
489                                         return selected_objects[0];
490                                 return null;
491                         }
492
493                         set {
494                                 if (value == null)
495                                         SelectedObjects = new object[0];
496                                 else
497                                         SelectedObjects = new object[] {value};
498
499                         }
500                 }
501
502                 [BrowsableAttribute(false)]
503                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
504                 public object[] SelectedObjects {
505                         get {
506                                 return selected_objects;
507                         }
508
509                         set {
510                                 if (value != null) {
511                                         for (int i = 0; i < value.Length; i++) {
512                                                 if (value [i] == null)
513                                                         throw new ArgumentException (String.Format ("Item {0} in the objs array is null.", i));
514                                         }
515                                         selected_objects = value;
516                                 } else {
517                                         selected_objects = new object [0];
518                                 }
519
520                                 if (selected_objects.Length > 0) {
521                                         PropertyTabAttribute[] propTabs = (PropertyTabAttribute[])this.SelectedObject.GetType().GetCustomAttributes(typeof(PropertyTabAttribute),true);
522                                         if (propTabs.Length > 0) {
523                                                 foreach (Type tabType in propTabs[0].TabClasses) {
524                                                         this.PropertyTabs.AddTabType(tabType);
525                                                 }
526                                         }
527                                 }
528
529                                 RefreshTabs(PropertyTabScope.Component);
530                                 ReflectObjects();
531                                 if (root_grid_item != null) {
532                                         /* find the first non category grid item and select it */
533                                         SelectedGridItem = FindFirstItem (root_grid_item);
534                                 }
535                                 property_grid_view.Refresh();
536                                 OnSelectedObjectsChanged (EventArgs.Empty);
537                         }
538                 }
539
540                 [BrowsableAttribute(false)]
541                 [EditorBrowsable(EditorBrowsableState.Advanced)]
542                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
543                 public PropertyTab SelectedTab {
544                         get {
545                                 return selected_tab;
546                         }
547                 }
548
549                 public override ISite Site {
550                         get {
551                                 return base.Site;
552                         }
553
554                         set {
555                                 base.Site = value;
556                         }
557                 }
558
559
560                 [DefaultValue(true)]
561                 public virtual bool ToolbarVisible {
562                         get {
563                                 return toolbar.Visible;
564                         }
565
566                         set {
567                                 if (toolbar.Visible == value) {
568                                         return;
569                                 }
570
571                                 toolbar.Visible = value;
572                         }
573                 }
574
575                 public Color ViewBackColor {
576                         get {
577                                 return property_grid_view.BackColor;
578                         }
579
580                         set {
581                                 if (property_grid_view.BackColor == value) {
582                                         return;
583                                 }
584
585                                 property_grid_view.BackColor = value;
586                         }
587                 }
588
589                 public Color ViewForeColor {
590                         get {
591                                 return property_grid_view.ForeColor;
592                         }
593
594                         set {
595                                 if (property_grid_view.ForeColor == value) {
596                                         return;
597                                 }
598
599                                 property_grid_view.ForeColor = value;
600                         }
601                 }
602
603                 #endregion      // Public Instance Properties
604
605                 #region Protected Instance Properties
606
607                 protected override Size DefaultSize {
608                         get {
609                                 return base.DefaultSize;
610                         }
611                 }
612
613
614                 [Browsable(false)]
615                 [EditorBrowsable(EditorBrowsableState.Advanced)]
616                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
617                 protected virtual Type DefaultTabType {
618                         get {
619                                 return typeof(PropertiesTab);
620                         }
621                 }
622                 
623                 protected bool DrawFlatToolbar {
624                         get {
625                                 return (toolbar.Appearance == ToolBarAppearance.Flat);
626                         }                       
627                         set {
628                                 if (value) 
629                                         toolbar.Appearance = ToolBarAppearance.Flat;
630                                 else
631                                         toolbar.Appearance = ToolBarAppearance.Normal;
632                         }
633                 }
634
635                 protected override bool ShowFocusCues {
636                         get {
637                                 return base.ShowFocusCues;
638                         }
639                 }
640
641                 #endregion      // Protected Instance Properties
642
643                 #region Public Instance Methods
644                 
645                 protected override void Dispose(bool val) {
646                         base.Dispose(val);
647                 }
648
649                 [MonoTODO ("should this be recursive?  or just the toplevel items?")]
650                 public void CollapseAllGridItems () {
651                         if (root_grid_item != null) {
652                                 foreach (GridItem item in root_grid_item.GridItems) {
653                                         item.Expanded = false;
654                                 }
655                         }
656                 }
657
658                 [MonoTODO ("should this be recursive?  or just the toplevel items?")]
659                 public void ExpandAllGridItems () {
660                         if (root_grid_item != null) {
661                                 foreach (GridItem item in root_grid_item.GridItems) {
662                                         item.Expanded = true;
663                                 }
664                         }
665                 }
666
667                 public override void Refresh () {
668                         base.Refresh ();
669                 }
670
671                 public void RefreshTabs (PropertyTabScope tabScope) {
672                         
673                         /*button = new ToolBarButton("C");
674                         button.ImageIndex = 0;
675                         this.toolbar.Buttons.Add(button);
676                         button = new ToolBarButton();
677                         button.ImageIndex = 0;
678                         button.Style = ToolBarButtonStyle.Separator;
679                         this.toolbar.Buttons.Add(button);
680                         foreach (PropertyTab tab in this.PropertyTabs)
681                         {
682
683                                 int index = toolbar.ImageList.Images.Count;
684                                 this.toolbar.ImageList.Images.Add(tab.Bitmap);
685                                 button = new ToolBarButton();
686                                 button.ImageIndex = index;
687                                 this.toolbar.Buttons.Add(button);
688                         }*/
689                         
690                 }
691
692                 public void ResetSelectedProperty() {
693                         if (selected_grid_item == null || selected_grid_item.PropertyDescriptor == null)
694                                 return;
695                         
696                         selected_grid_item.PropertyDescriptor.ResetValue(SelectedObject);
697                 }
698                 #endregion      // Public Instance Methods
699
700                 #region Protected Instance Methods
701
702                 protected virtual PropertyTab CreatePropertyTab(Type tabType) {
703                         return (PropertyTab)Activator.CreateInstance(tabType);
704                 }
705                 
706                 [MonoTODO]
707                 protected void OnComComponentNameChanged(ComponentRenameEventArgs e) {
708                         throw new NotImplementedException();
709                 }
710
711                 protected override void OnFontChanged(EventArgs e) {
712                         base.OnFontChanged (e);
713                 }
714
715                 protected override void OnGotFocus(EventArgs e) {
716                         base.OnGotFocus(e);
717                 }
718
719                 protected override void OnHandleCreated (EventArgs e) {
720                         base.OnHandleCreated (e);
721                 }
722
723                 protected override void OnHandleDestroyed (EventArgs e) {
724                         base.OnHandleDestroyed (e);
725                 }
726
727                 protected override void OnMouseDown (MouseEventArgs e) {
728                         base.OnMouseDown (e);
729                 }
730
731                 protected override void OnMouseMove (MouseEventArgs e) {
732                         base.OnMouseMove (e);
733                 }
734
735                 protected override void OnMouseUp (MouseEventArgs e) {
736                         base.OnMouseUp (e);
737                 }
738                 
739                 [MonoTODO]
740                 protected void OnNotifyPropertyValueUIItemsChanged(object sender, EventArgs e) {
741                 }
742
743                 protected override void OnPaint (PaintEventArgs pevent) {
744                         pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
745                         base.OnPaint (pevent);
746                 }
747
748                 [MonoTODO]
749                 protected virtual void OnPropertyTabChanged (PropertyTabChangedEventArgs e) {
750                         throw new NotImplementedException();
751                 }
752
753                 protected virtual void OnPropertyValueChanged (PropertyValueChangedEventArgs e) {
754                         if (PropertyValueChanged != null) {
755                                 PropertyValueChanged(this, e);
756                                 current_property_value = selected_grid_item.Value;
757                         }
758                 }
759
760                 protected override void OnResize (EventArgs e) {
761                         base.OnResize (e);
762                 }
763
764                 protected virtual void OnSelectedGridItemChanged (SelectedGridItemChangedEventArgs e) {
765                         if (SelectedGridItemChanged != null) {
766                                 SelectedGridItemChanged(this, e);
767                         }
768                 }
769
770                 protected virtual void OnSelectedObjectsChanged (EventArgs e) {
771                         if (SelectedObjectsChanged != null) {
772                                 SelectedObjectsChanged(this, e);
773                         }
774                 }
775
776                 protected override void OnSystemColorsChanged (EventArgs e) {
777                         base.OnSystemColorsChanged (e);
778                 }
779
780                 protected override void OnVisibleChanged (EventArgs e) {
781                         base.OnVisibleChanged (e);
782                 }
783
784                 protected override bool ProcessDialogKey (Keys keyData) {
785                         return base.ProcessDialogKey (keyData);
786                 }
787
788                 protected override void ScaleCore (float dx, float dy) {
789                         base.ScaleCore (dx, dy);
790                 }
791                 
792                 [MonoTODO]
793                 protected void ShowEventsButton(bool value) {
794                         throw new NotImplementedException();
795                 }
796
797                 protected override void WndProc (ref Message m) {
798                         base.WndProc (ref m);
799                 }
800                 #endregion
801
802                 #region Events
803                 public event EventHandler PropertySortChanged;
804                 public event PropertyTabChangedEventHandler PropertyTabChanged;
805                 public event PropertyValueChangedEventHandler PropertyValueChanged;
806                 public event SelectedGridItemChangedEventHandler SelectedGridItemChanged;
807                 public event EventHandler SelectedObjectsChanged;
808                 
809                 [Browsable(false)]
810                 [EditorBrowsable(EditorBrowsableState.Never)]
811                 public new event EventHandler BackgroundImageChanged {
812                         add { base.BackgroundImageChanged += value; }
813                         remove { base.BackgroundImageChanged -= value; }
814                 }
815
816                 [Browsable(false)]
817                 [EditorBrowsable(EditorBrowsableState.Never)]
818                 public new event EventHandler ForeColorChanged {
819                         add { base.ForeColorChanged += value; }
820                         remove { base.ForeColorChanged -= value; }
821                 }
822                 #endregion
823
824                 #region Com2Interop.IComPropertyBrowser Interface
825                 [MonoTODO]
826                 bool ComponentModel.Com2Interop.IComPropertyBrowser.InPropertySet {
827                         get  {
828                                 throw new NotImplementedException();
829                         }
830                 }
831
832                 [MonoTODO]
833                 void ComponentModel.Com2Interop.IComPropertyBrowser.DropDownDone() {
834                         throw new NotImplementedException();
835                 }
836
837                 [MonoTODO]
838                 bool ComponentModel.Com2Interop.IComPropertyBrowser.EnsurePendingChangesCommitted() {
839                         throw new NotImplementedException();
840                 }
841
842                 [MonoTODO]
843                 void ComponentModel.Com2Interop.IComPropertyBrowser.HandleF4() {
844                         throw new NotImplementedException();
845                 }
846
847                 [MonoTODO]
848                 void ComponentModel.Com2Interop.IComPropertyBrowser.LoadState(Microsoft.Win32.RegistryKey key) {
849                         throw new NotImplementedException();
850                 }
851
852                 [MonoTODO]
853                 void ComponentModel.Com2Interop.IComPropertyBrowser.SaveState(Microsoft.Win32.RegistryKey key) {
854                         throw new NotImplementedException();
855                 }
856
857                 [MonoTODO]
858                 private event ComponentRenameEventHandler com_component_name_changed;
859                 event ComponentRenameEventHandler ComponentModel.Com2Interop.IComPropertyBrowser.ComComponentNameChanged {
860                         add { com_component_name_changed += value; }
861                         remove { com_component_name_changed -= value; }
862                 }
863                 #endregion      // Com2Interop.IComPropertyBrowser Interface
864
865                 #region PropertyTabCollection Class
866                 public class PropertyTabCollection : ICollection, IEnumerable {
867                         System.Collections.ArrayList list;
868                         #region Private Constructors
869                         internal PropertyTabCollection() {
870                                 list = new ArrayList();
871                         }
872
873                         #endregion      // Private Constructors
874
875                         public PropertyTab this[int index] {
876                                 get {
877                                         return (PropertyTab)list[index];
878                                 }
879                         }
880                 
881                         #region ICollection Members
882                         bool ICollection.IsSynchronized {
883                                 get {
884                                         return list.IsSynchronized;
885                                 }
886                         }
887
888                         void ICollection.CopyTo(Array array, int index) {
889                                 list.CopyTo(array, index);
890                         }
891
892                         object ICollection.SyncRoot {
893                                 get {
894                                         return list.SyncRoot;
895                                 }
896                         }
897
898                         #endregion
899
900                         #region IEnumerable Members
901                         public IEnumerator GetEnumerator() {
902                                 return list.GetEnumerator();
903                         }
904
905                         #endregion
906                 
907                         #region ICollection Members
908                         public int Count {
909                                 get {
910                                         return list.Count;
911                                 }
912                         }
913
914                         #endregion
915                         
916                         #region Public Instance Methods
917                         public void AddTabType(System.Type propertyTabType) {
918                                 list.Add(Activator.CreateInstance(propertyTabType));
919                         }
920                         [MonoTODO]
921                         public void AddTabType(System.Type propertyTabType,
922                                 System.ComponentModel.PropertyTabScope tabScope) {
923                                 AddTabType(propertyTabType);
924                         }
925                         [MonoTODO]
926                         public void Clear(System.ComponentModel.PropertyTabScope tabScope) {
927                                 throw new NotImplementedException();
928                         }
929                         [MonoTODO]
930                         public void RemoveTabType(System.Type propertyTabType) {
931                                 throw new NotImplementedException();
932                         }
933                         #endregion
934                 }
935                 #endregion      // PropertyTabCollection Class
936
937                 #region Private Helper Methods
938
939                 public GridItem FindFirstItem (GridItem root)
940                 {
941                         if (root.GridItemType == GridItemType.Property)
942                                 return root;
943
944                         foreach (GridItem item in root.GridItems) {
945                                 GridItem subitem = FindFirstItem (item);
946                                 if (subitem != null)
947                                         return subitem;
948                         }
949
950                         return null;
951                 }
952
953
954                 private void toolbar_ButtonClick (object sender, ToolBarButtonClickEventArgs e) {
955                         if (e.Button == alphabetic_toolbarbutton) {
956                                 this.PropertySort = PropertySort.Alphabetical;
957                         }
958                         else if (e.Button == categorized_toolbarbutton) {
959                                 this.PropertySort = PropertySort.Categorized;
960                         }
961                 }
962
963                 internal void UpdateToolBarButtons () {
964                         if (PropertySort == PropertySort.Alphabetical) {
965                                 categorized_toolbarbutton.Pushed = false;
966                                 alphabetic_toolbarbutton.Pushed = true;
967                         }
968                         else if (PropertySort == PropertySort.Categorized) {
969                                 categorized_toolbarbutton.Pushed = true;
970                                 alphabetic_toolbarbutton.Pushed = false;
971                         }
972                         else {
973                                 categorized_toolbarbutton.Pushed = false;
974                                 alphabetic_toolbarbutton.Pushed = false;
975                         }
976                 }
977
978                 private void OnResetPropertyClick (object sender, EventArgs e) {
979                         ResetSelectedProperty();
980                 }
981
982                 private void OnDescriptionClick (object sender, EventArgs e) {
983                         this.HelpVisible = !this.HelpVisible;
984                         description_menuitem.Checked = this.HelpVisible;
985
986                 }
987
988                 private void ReflectObjects () {
989                         if (selected_objects.Length > 0) {
990                                 root_grid_item = new RootGridEntry (property_grid_view,
991                                                                     selected_objects.Length > 1 ? selected_objects : selected_objects[0]);
992                                                                            
993                                 PopulateMergedGridItems (selected_objects, root_grid_item.GridItems, true, root_grid_item);
994                         }
995                 }
996
997                 private void PopulateMergedGridItems (object[] objs, GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item)
998                 {
999                         ArrayList intersection = null;
1000
1001                         for (int i = 0; i < objs.Length; i ++) {
1002                                 if (objs [i] == null)
1003                                         continue;
1004
1005                                 ArrayList new_intersection = new ArrayList ();
1006                                 Type type = objs[i].GetType();
1007
1008                                 /* i tried using filter attributes, but there's no way to do it for EditorBrowsableAttributes,
1009                                    since that type lacks an override for IsDefaultAttribute, and for some reason the
1010                                    BrowsableAttribute.Yes filter wasn't working */
1011                                 PropertyDescriptorCollection properties = null;
1012
1013                                 if (typeof (ICustomTypeDescriptor).IsAssignableFrom (type)) {
1014                                         properties = ((ICustomTypeDescriptor)objs[i]).GetProperties ();
1015                                 }
1016                                 if (properties == null) {
1017                                         TypeConverter cvt = TypeDescriptor.GetConverter (objs[i]);
1018                                         properties = cvt.GetProperties (objs[i]);
1019                                 }
1020                                 if (properties == null) {
1021                                         properties = TypeDescriptor.GetProperties (objs[i]);
1022                                 }
1023
1024                                 foreach (PropertyDescriptor p in (i == 0 ? (ICollection)properties : (ICollection)intersection)) {
1025                                         PropertyDescriptor property = (i == 0 ? p : properties [p.Name]);
1026                                         if (property == null) {
1027                                                 /* since the property doesn't exist in at least one of the other types, 
1028                                                    exclude it */
1029                                         }
1030                                         else if (!property.IsBrowsable
1031                                             || (objs.Length > 1 && property.Attributes.Contains (MergablePropertyAttribute.No))
1032                                             || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Never))
1033                                             || property.Attributes.Contains (new EditorBrowsableAttribute (EditorBrowsableState.Advanced))) {
1034                                                 /* if the property isn't supposed to be displayed in the merged view,
1035                                                    excluded it */
1036                                         }
1037                                         else {
1038                                                 Type p_type = p.ComponentType;
1039                                                 Type property_type = property.ComponentType;
1040
1041                                                 if (p_type.IsAssignableFrom (type))
1042                                                         new_intersection.Add (p);
1043                                                 else if (property_type.IsAssignableFrom (p_type))
1044                                                         new_intersection.Add (property);
1045                                         }
1046                                 }
1047
1048                                 intersection = new_intersection;
1049                         }
1050
1051                         if (intersection != null && intersection.Count > 0)
1052                                 PopulateGridItemsFromProperties (objs, intersection, grid_item_coll, recurse, parent_grid_item);
1053                 }
1054
1055                 private void PopulateGridItemsFromProperties (object[] objs, ArrayList properties,
1056                                                               GridItemCollection grid_item_coll, bool recurse, GridItem parent_grid_item) {
1057                         foreach (PropertyDescriptor property in properties) {
1058
1059                                 GridEntry grid_entry = new GridEntry (property_grid_view, objs, property);
1060                                 grid_entry.SetParent (parent_grid_item);
1061                                 if (property_sort == PropertySort.Alphabetical || /* XXX */property_sort == PropertySort.NoSort || !recurse) {
1062                                         if (grid_item_coll[property.Name] == null) {
1063                                                 grid_item_coll.Add(property.Name,grid_entry);
1064                                                 grid_entry.SetParent ((GridEntry)parent_grid_item);
1065                                         }
1066                                 }
1067                                 else if (property_sort == PropertySort.Categorized || property_sort == PropertySort.CategorizedAlphabetical) {
1068
1069                                         string category = property.Category;
1070                                         CategoryGridEntry cat_item = grid_item_coll[category] as CategoryGridEntry;
1071                                         if (cat_item == null) {
1072                                                 cat_item = new CategoryGridEntry (property_grid_view, category);
1073                                                 cat_item.SetParent (parent_grid_item);
1074                                                 grid_item_coll.Add (category, cat_item);
1075                                         }
1076                                         if (cat_item.GridItems[property.Name] == null) {
1077                                                 cat_item.GridItems.Add(property.Name,grid_entry);
1078                                                 grid_entry.SetParent (cat_item);
1079                                         }
1080                                 }
1081
1082                                 if (recurse && property.Converter != null && property.Converter.GetPropertiesSupported()) {
1083                                         object[] subobjs = new object[objs.Length];
1084                                         for (int i = 0; i < objs.Length; i ++)
1085                                                 subobjs[i] = property.GetValue (objs[i]);
1086                                         PopulateMergedGridItems (subobjs, grid_entry.GridItems, false, grid_entry);
1087                                 }
1088                                 grid_entry.Expanded = false;
1089                         }
1090                 }
1091
1092                 private void help_panel_Paint(object sender, PaintEventArgs e) {
1093                         e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(help_panel.BackColor), help_panel.ClientRectangle );
1094                         e.Graphics.DrawRectangle(SystemPens.ControlDark, 0,0,help_panel.Width-1,help_panel.Height-1 );
1095                 }
1096
1097                 internal object GetTarget (GridItem item, int selected_index)
1098                 {
1099                         object target = ((GridEntry)item).SelectedObjects[selected_index];
1100
1101                         while (item.Parent != null && item.Parent.GridItemType != GridItemType.Property)
1102                                 item = item.Parent;
1103
1104                         if (item.Parent != null && item.Parent.PropertyDescriptor != null)
1105                                 target = item.Parent.PropertyDescriptor.GetValue (((GridEntry)item.Parent).SelectedObjects[selected_index]);
1106
1107                         return target;
1108                 }
1109                 #endregion      // Private Helper Methods
1110
1111
1112 #if NET_2_0
1113
1114                 public bool UseCompatibleTextRendering {
1115                         get {
1116                                 return use_compatible_text_rendering;
1117                         }
1118
1119                         set {
1120                                 use_compatible_text_rendering = value;
1121                         }
1122                 }
1123 #endif
1124                 
1125                 // as we can not change the color for BorderStyle.FixedSingle and we need the correct
1126                 // ClientRectangle so that the ScrollBar doesn't draw over the border we need this class
1127                 internal class BorderHelperControl : Control {
1128
1129                         public BorderHelperControl ()
1130                         {
1131                                 BackColor = ThemeEngine.Current.ColorWindow;
1132                         }
1133
1134                         protected override void OnPaint (PaintEventArgs e)
1135                         {
1136                                 e.Graphics.DrawRectangle (SystemPens.ControlDark, 0 , 0 , Width - 1, Height - 1);
1137                                 base.OnPaint (e);
1138                         }
1139                         
1140                         protected override void OnSizeChanged (EventArgs e)
1141                         {
1142                                 if (Controls.Count == 1) {
1143                                         Control control = Controls [0];
1144                                         
1145                                         if (control.Location.X != 1 || control.Location.Y != 1)
1146                                                 control.Location = new Point (1, 1);
1147                                         
1148                                         control.Width = ClientRectangle.Width - 2;
1149                                         control.Height = ClientRectangle.Height - 2;
1150                                 }
1151                                 base.OnSizeChanged (e);
1152                         }
1153                 }
1154                 
1155                 // needed! this little helper makes it possible to draw a different toolbar border
1156                 // and toolbar backcolor in ThemeWin32Classic
1157                 internal class PropertyToolBar : ToolBar {}
1158
1159
1160                 [MonoTODO ("not sure what this class does, but it's listed as a type converter for a property in this class, and this causes problems if it's not present")]
1161                 internal class SelectedObjectConverter : TypeConverter
1162                 {
1163                 }
1164         }
1165 }