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