2007-01-10 Jonathan Pobst <jpobst@novell.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListViewItem.cs
index 07d2e3291f431935eb1caab67520c32514721337..f16cd3bb813e0f584c85ff3a43a4a22887bc6e26 100644 (file)
 // Author:
 //      Ravindra (rkumar@novell.com)
 //      Mike Kestner <mkestner@novell.com>
+//      Daniel Nauck (dna(at)mono-project(dot)de)
 
 
 
-// NOT COMPLETE
-
-
 using System.Collections;
 using System.ComponentModel;
 using System.Drawing;
@@ -51,9 +49,10 @@ namespace System.Windows.Forms
                private object tag;
                private bool use_item_style = true;
 #if NET_2_0
+               private ListViewGroup group = null;
                private string name = String.Empty;
+               private string image_key = String.Empty;
 #endif
-
                Rectangle bounds;
                Rectangle checkbox_rect;        // calculated by CalcListViewItem method
                Rectangle icon_rect;
@@ -72,7 +71,7 @@ namespace System.Windows.Forms
                public ListViewItem ()
                {
                        this.sub_items = new ListViewSubItemCollection (this);
-                       this.sub_items.Add ("");                        
+                       this.sub_items.Add ("");
                }
 
                public ListViewItem (string text) : this (text, -1)
@@ -114,6 +113,100 @@ namespace System.Windows.Forms
                        BackColor = backColor;
                        this.font = font;
                }
+
+#if NET_2_0
+               public ListViewItem(string[] items, string imageKey) : this(items)
+               {
+                       this.ImageKey = imageKey;
+               }
+
+               public ListViewItem(string text, string imageKey) : this(text)
+               {
+                       this.ImageKey = imageKey;
+               }
+
+               public ListViewItem(ListViewSubItem[] subItems, string imageKey) : this()
+               {
+                       this.sub_items.AddRange(subItems);
+                       this.ImageKey = imageKey;
+               }
+
+               public ListViewItem(string[] items, string imageKey, Color foreColor,
+                                       Color backColor, Font font) : this()
+               {
+                       this.sub_items = new ListViewSubItemCollection(this);
+                       this.sub_items.AddRange(items);
+                       ForeColor = foreColor;
+                       BackColor = backColor;
+                       this.font = font;
+                       this.ImageKey = imageKey;
+               }
+
+               public ListViewItem(ListViewGroup group) : this()
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string text, ListViewGroup group) : this(text)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string[] items, ListViewGroup group) : this(items)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(ListViewSubItem[] subItems, int imageIndex, ListViewGroup group)
+                       : this(subItems, imageIndex)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(ListViewSubItem[] subItems, string imageKey, ListViewGroup group)
+                       : this(subItems, imageKey)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string text, int imageIndex, ListViewGroup group)
+                       : this(text, imageIndex)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string text, string imageKey, ListViewGroup group)
+                       : this(text, imageKey)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string[] items, int imageIndex, ListViewGroup group)
+                       : this(items, imageIndex)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string[] items, string imageKey, ListViewGroup group)
+                       : this(items, imageKey)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string[] items, int imageIndex, Color foreColor, Color backColor,
+                               Font font, ListViewGroup group)
+                       : this(items, imageIndex, foreColor, backColor, font)
+               {
+                       this.group = group;
+               }
+
+               public ListViewItem(string[] items, string imageKey, Color foreColor, Color backColor,
+                               Font font, ListViewGroup group)
+                       : this(items, imageKey, foreColor, backColor, font)
+               {
+                       this.group = group;
+               }
+#endif
                #endregion      // Public Constructors
 
                #region Public Instance Properties
@@ -217,7 +310,12 @@ namespace System.Windows.Forms
                [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
                         typeof (System.Drawing.Design.UITypeEditor))]
                [Localizable (true)]
+#if NET_2_0
+               [RefreshProperties (RefreshProperties.Repaint)]
+               // [TypeConverter (typeof (NoneExcludedImageIndexConverter))]
+#else
                [TypeConverter (typeof (ImageIndexConverter))]
+#endif
                public int ImageIndex {
                        get { return image_index; }
                        set {
@@ -225,6 +323,9 @@ namespace System.Windows.Forms
                                        throw new ArgumentException ("Invalid ImageIndex. It must be greater than or equal to -1.");
                                
                                image_index = value;
+#if NET_2_0
+                               image_key = String.Empty;
+#endif
 
                                if (owner != null)
                                        Layout ();
@@ -232,6 +333,29 @@ namespace System.Windows.Forms
                        }
                }
 
+#if NET_2_0
+               [DefaultValue ("")]
+               [LocalizableAttribute (true)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
+                        typeof (System.Drawing.Design.UITypeEditor))]
+               [RefreshProperties (RefreshProperties.Repaint)]
+               // XXX [TypeConverter (typeof (ImageKeyConverter))
+               public string ImageKey {
+                       get {
+                               return image_key;
+                       }
+                       set {
+                               image_key = value == null ? String.Empty : value;
+                               image_index = -1;
+
+                               if (owner != null)
+                                       Layout ();
+                               Invalidate ();
+                       }
+               }
+#endif
+
                [Browsable (false)]
                public ImageList ImageList {
                        get {
@@ -262,6 +386,7 @@ namespace System.Windows.Forms
 #if NET_2_0
                [Browsable (false)]
                [Localizable (true)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public string Name {
                        get {
                                return name;
@@ -299,7 +424,13 @@ namespace System.Windows.Forms
                [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design,
                         typeof (System.Drawing.Design.UITypeEditor))]
                [Localizable (true)]
+#if NET_2_0
+               [RefreshProperties (RefreshProperties.Repaint)]
+               // XXX [RelatedImageListAttribute ("ListView.StateImageList")]
+               // XXX [TypeConverter (typeof (NoneExcludedImageIndexConverter))]
+#else
                [TypeConverter (typeof (ImageIndexConverter))]
+#endif
                public int StateImageIndex {
                        get { return state_image_index; }
                        set {
@@ -311,6 +442,10 @@ namespace System.Windows.Forms
                }
 
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+#if NET_2_0
+               [Editor ("System.Windows.Forms.Design.ListViewSubItemCollectionEditor, " + Consts.AssemblySystem_Design,
+                        typeof (System.Drawing.Design.UITypeEditor))]
+#endif
                public ListViewSubItemCollection SubItems {
                        get { return sub_items; }
                }
@@ -331,7 +466,7 @@ namespace System.Windows.Forms
                                if (this.sub_items.Count > 0)
                                        return this.sub_items [0].Text;
                                else
-                                       return "";
+                                       return string.Empty;
                        }
                        set { 
                                if (sub_items [0].Text == value)
@@ -350,6 +485,35 @@ namespace System.Windows.Forms
                        get { return use_item_style; }
                        set { use_item_style = value; }
                }
+
+#if NET_2_0
+               [LocalizableAttribute(true)]
+               [DefaultValue (null)]
+               public ListViewGroup Group {
+                       get { return this.group; }
+                       set
+                       {
+                               if (this.group != value)
+                               {
+                                       if (value != null)
+                                       {
+                                               value.Items.Add(this);
+
+                                               if (this.group != null)
+                                                       this.group.Items.Remove(this);
+
+                                               this.group = value;
+                                       }
+                                       else
+                                       {
+                                               if(this.group != null)
+                                               this.group.Items.Remove(this);
+                                       }
+                               }
+                       }
+               }
+#endif
+
                #endregion      // Public Instance Properties
 
                #region Public Instance Methods
@@ -421,7 +585,7 @@ namespace System.Windows.Forms
                                rect = bounds;
                                rect.X -= owner.h_marker;
                                rect.Y -= owner.v_marker;
-                               return rect;                            
+                               return rect;
 
                        default:
                                throw new ArgumentException ("Invalid value for portion.");
@@ -621,6 +785,63 @@ namespace System.Windows.Forms
                                total = Rectangle.Union (item_rect, checkbox_rect);
                                bounds.Size = total.Size;
                                break;
+#if NET_2_0
+                       case View.Tile:
+                               label_rect = icon_rect = Rectangle.Empty;
+
+                               if (owner.LargeImageList != null) {
+                                       icon_rect.Width = owner.LargeImageList.ImageSize.Width;
+                                       icon_rect.Height = owner.LargeImageList.ImageSize.Height;
+                               }
+
+                               int separation = 2;
+                               SizeF tsize = owner.DeviceContext.MeasureString (Text, Font);
+
+                               // Set initial values for subitem's layout
+                               int total_height = (int)Math.Ceiling (tsize.Height);
+                               int max_subitem_width = (int)Math.Ceiling (tsize.Width);
+                               SubItems [0].bounds.Height = total_height;
+                       
+                               int count = Math.Min (owner.Columns.Count, SubItems.Count);
+                               for (int i = 1; i < count; i++) { // Ignore first column and first subitem
+                                       ListViewSubItem sub_item = SubItems [i];
+                                       if (sub_item.Text == null || sub_item.Text.Length == 0)
+                                               continue;
+
+                                       tsize = owner.DeviceContext.MeasureString (sub_item.Text, sub_item.Font);
+                               
+                                       int width = (int)Math.Ceiling (tsize.Width);
+                               
+                                       if (width > max_subitem_width)
+                                               max_subitem_width = width;
+                               
+                                       int height = (int)Math.Ceiling (tsize.Height);
+                                       total_height += height + separation;
+                               
+                                       sub_item.bounds.Height = height;
+                       
+                               }
+
+                               label_rect.X = icon_rect.Right + 4;
+                               label_rect.Y = owner.TileSize.Height / 2 - total_height / 2;
+                               label_rect.Width = max_subitem_width;
+                               label_rect.Height = total_height;
+                       
+                               // Second pass for assigning bounds. This time take first subitem into account.
+                               int current_y = label_rect.Y;
+                               for (int j = 0; j < count; j++) {
+                                       ListViewSubItem sub_item = SubItems [j];
+                                       if (sub_item.Text == null || sub_item.Text.Length == 0)
+                                               continue;
+
+                                       sub_item.SetBounds (label_rect.X, current_y, max_subitem_width, sub_item.bounds.Height);
+                                       current_y += sub_item.Bounds.Height + separation;
+                               }
+                               
+                               item_rect = Rectangle.Union (icon_rect, label_rect);
+                               bounds.Size = item_rect.Size;
+                               break;
+#endif
                        }
                        
                }
@@ -639,7 +860,12 @@ namespace System.Windows.Forms
                        private Font font;
                        private Color fore_color;
                        internal ListViewItem owner;
-                       private string text;
+                       private string text = string.Empty;
+#if NET_2_0
+                       private string name = String.Empty;
+                       private object tag;
+                       internal Rectangle bounds;
+#endif
                        
                        #region Public Constructors
                        public ListViewSubItem ()
@@ -656,7 +882,7 @@ namespace System.Windows.Forms
                                                Color backColor, Font font)
                        {
                                this.owner = owner;
-                               this.text = text;
+                               Text = text;
                                this.fore_color = foreColor;
                                this.back_color = backColor;
                                this.font = font;
@@ -672,6 +898,20 @@ namespace System.Windows.Forms
                                    }
                        }
 
+#if NET_2_0
+                       public Rectangle Bounds {
+                               get {
+                                       Rectangle retval = bounds;
+                                       if (owner != null) {
+                                               retval.X += owner.Bounds.X;
+                                               retval.Y += owner.Bounds.Y;
+                                       }
+
+                                       return retval;
+                               }
+                       }
+#endif
+
                        [Localizable (true)]
                        public Font Font {
                                get {
@@ -697,11 +937,43 @@ namespace System.Windows.Forms
                                    }
                        }
 
+#if NET_2_0
+                       [Localizable (true)]
+                       public string Name {
+                               get {
+                                       return name;
+                               }
+                               set {
+                                       name = value == null ? String.Empty : value;
+                               }
+                       }
+
+                       [TypeConverter (typeof (StringConverter))]
+                       [BindableAttribute (true)]
+                       [DefaultValue (null)]
+                       [Localizable (false)]
+                       public object Tag {
+                               get {
+                                       return tag;
+                               }
+                               set {
+                                       tag = value;
+                               }
+                       }
+#endif
+
                        [Localizable (true)]
                        public string Text {
                                get { return text; }
                                set { 
-                                       text = value; 
+                                       if(text == value)
+                                               return;
+
+                                       if(value == null)
+                                               text = string.Empty;
+                                       else
+                                               text = value; 
+
                                        Invalidate ();
                                    }
                        }
@@ -731,6 +1003,13 @@ namespace System.Windows.Forms
 
                                owner.owner.Invalidate ();
                        }
+
+#if NET_2_0
+                       internal void SetBounds (int x, int y, int width, int height)
+                       {
+                               bounds = new Rectangle (x, y, width, height);
+                       }
+#endif
                        #endregion // Private Methods
                }
 
@@ -765,6 +1044,18 @@ namespace System.Windows.Forms
                                }
                        }
 
+#if NET_2_0
+                       public virtual ListViewSubItem this [string key] {
+                               get {
+                                       int idx = IndexOfKey (key);
+                                       if (idx == -1)
+                                               return null;
+
+                                       return (ListViewSubItem) list [idx];
+                               }
+                       }
+#endif
+
                        bool ICollection.IsSynchronized {
                                get { return list.IsSynchronized; }
                        }
@@ -813,24 +1104,39 @@ namespace System.Windows.Forms
 
                        public void AddRange (ListViewSubItem [] items)
                        {
-                               list.Clear ();
-                               foreach (ListViewSubItem item in items)
+                               if (items == null)
+                                       throw new ArgumentNullException ("items");
+
+                               foreach (ListViewSubItem item in items) {
+                                       if (item == null)
+                                               continue;
                                        this.Add (item);
+                               }
                        }
 
                        public void AddRange (string [] items)
                        {
-                               list.Clear ();
-                               foreach (string item in items)
+                               if (items == null)
+                                       throw new ArgumentNullException ("items");
+
+                               foreach (string item in items) {
+                                       if (item == null)
+                                               continue;
                                        this.Add (item);
+                               }
                        }
 
                        public void AddRange (string [] items, Color foreColor,
                                              Color backColor, Font font)
                        {
-                               list.Clear ();
-                               foreach (string item in items)
+                               if (items == null)
+                                       throw new ArgumentNullException ("items");
+
+                               foreach (string item in items) {
+                                       if (item == null)
+                                               continue;
                                        this.Add (item, foreColor, backColor, font);
+                               }
                        }
 
                        public void Clear ()
@@ -843,6 +1149,13 @@ namespace System.Windows.Forms
                                return list.Contains (item);
                        }
 
+#if NET_2_0
+                       public virtual bool ContainsKey (string key)
+                       {
+                               return IndexOfKey (key) != -1;
+                       }
+#endif
+
                        public IEnumerator GetEnumerator ()
                        {
                                return list.GetEnumerator ();
@@ -905,6 +1218,22 @@ namespace System.Windows.Forms
                                return list.IndexOf (subItem);
                        }
 
+#if NET_2_0
+                       public virtual int IndexOfKey (string key)
+                       {
+                               if (key == null || key.Length == 0)
+                                       return -1;
+
+                               for (int i = 0; i < list.Count; i++) {
+                                       ListViewSubItem l = (ListViewSubItem) list [i];
+                                       if (String.Compare (l.Name, key, true) == 0)
+                                               return i;
+                               }
+
+                               return -1;
+                       }
+#endif
+
                        public void Insert (int index, ListViewSubItem item)
                        {
                                item.owner = this.owner;
@@ -916,6 +1245,15 @@ namespace System.Windows.Forms
                                list.Remove (item);
                        }
 
+#if NET_2_0
+                       public virtual void RemoveByKey (string key)
+                       {
+                               int idx = IndexOfKey (key);
+                               if (idx != -1)
+                                       RemoveAt (idx);
+                       }
+#endif
+
                        public void RemoveAt (int index)
                        {
                                list.RemoveAt (index);