Merge branch 'sgen-android'
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / BindingNavigator.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) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Olivier Dufour  olivier.duff@free.fr
24 //  Alan McGovern alan.mcgovern@gmail.com
25 //
26
27 using System;
28 using System.Collections.Generic;
29 using System.Text;
30 using System.ComponentModel;
31 using System.Runtime.InteropServices;
32
33 namespace System.Windows.Forms
34 {
35         [ComVisibleAttribute(true)]
36         [DefaultEvent ("RefreshItems")]
37         [DefaultProperty ("BindingSource")]
38         [ClassInterfaceAttribute(ClassInterfaceType.AutoDispatch)]
39         [Designer ("System.Windows.Forms.Design.BindingNavigatorDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
40         public class BindingNavigator : ToolStrip, ISupportInitialize
41         {
42                 #region Private Fields
43
44                 private ToolStripItem addNewItem = null;
45                 private BindingSource bindingSource = null;
46                 //private bool changingText = false;
47                 private ToolStripItem countItem = null;
48                 private string countItemFormat = Locale.GetText("of {0}");
49                 private ToolStripItem deleteItem = null;
50                 private bool initFlag = false;
51                 private ToolStripItem moveFirstItem = null;
52                 private ToolStripItem moveLastItem = null;
53                 private ToolStripItem moveNextItem = null;
54                 private ToolStripItem movePreviousItem = null;
55                 private ToolStripItem positionItem = null;
56
57                 #endregion Private Fields
58
59
60                 #region Public Properties
61
62                 [TypeConverter(typeof(ReferenceConverter))]
63                 public ToolStripItem AddNewItem
64                 {
65                         get { return addNewItem; }
66                         set
67                         {
68                                 ReplaceItem(ref addNewItem, value, new EventHandler(OnAddNew));
69                                 OnRefreshItems();
70                         }
71                 }
72
73                 [DefaultValue (null)]
74                 [TypeConverter(typeof(ReferenceConverter))]
75                 public BindingSource BindingSource
76                 {
77                         get { return bindingSource; }
78                         set
79                         {
80                                 AttachNewSource(value);
81                                 OnRefreshItems();
82                         }
83                 }
84
85                 [TypeConverter(typeof(ReferenceConverter))]
86                 public ToolStripItem CountItem
87                 {
88                         get { return countItem; }
89                         set
90                         {
91                                 countItem = value;
92                                 OnRefreshItems();
93                         }
94                 }
95
96                 public string CountItemFormat
97                 {
98                         get { return countItemFormat; }
99                         set
100                         {
101                                 countItemFormat = value;
102                                 OnRefreshItems();
103                         }
104                 }
105
106                 [TypeConverter(typeof(ReferenceConverter))]
107                 public ToolStripItem DeleteItem
108                 {
109                         get { return deleteItem; }
110                         set
111                         {
112                                 ReplaceItem(ref deleteItem, value, new EventHandler(OnDelete));
113                                 this.OnRefreshItems();
114                         }
115                 }
116
117                 [TypeConverter(typeof(ReferenceConverter))]
118                 public ToolStripItem MoveFirstItem
119                 {
120                         get { return moveFirstItem; }
121                         set
122                         {
123                                 ReplaceItem(ref moveFirstItem, value, new EventHandler(OnMoveFirst));
124                                 OnRefreshItems();
125                         }
126                 }
127
128                 private void ReplaceItem(ref ToolStripItem existingItem, ToolStripItem newItem, EventHandler clickHandler)
129                 {
130                         if (existingItem != null)
131                                 existingItem.Click -= clickHandler;
132                         if (newItem != null)
133                                 newItem.Click += clickHandler;
134
135                         existingItem = newItem;
136                 }
137
138
139                 [TypeConverter(typeof(ReferenceConverter))]
140                 public ToolStripItem MoveLastItem
141                 {
142                         get { return moveLastItem; }
143                         set
144                         {
145                                 ReplaceItem(ref moveLastItem, value, new EventHandler(OnMoveLast));
146                                 OnRefreshItems();
147                         }
148                 }
149
150                 [TypeConverter(typeof(ReferenceConverter))]
151                 public ToolStripItem MoveNextItem
152                 {
153                         get { return moveNextItem; }
154                         set
155                         {
156                                 ReplaceItem(ref moveNextItem, value, new EventHandler(OnMoveNext));
157                                 OnRefreshItems();
158                         }
159                 }
160
161                 [TypeConverter(typeof(ReferenceConverter))]
162                 public ToolStripItem MovePreviousItem
163                 {
164                         get { return movePreviousItem; }
165                         set
166                         {
167                                 ReplaceItem(ref movePreviousItem, value, new EventHandler(OnMovePrevious));
168                                 OnRefreshItems();
169                         }
170                 }
171
172                 [TypeConverter(typeof(ReferenceConverter))]
173                 public ToolStripItem PositionItem
174                 {
175                         get { return positionItem; }
176                         set
177                         {
178                                 positionItem = value;
179                                 OnRefreshItems();
180                         }
181                 }
182
183                 #endregion
184
185
186                 #region Constructors
187
188                 [EditorBrowsable (EditorBrowsableState.Never)]
189                 public BindingNavigator ()
190                         : this(false)
191                 {
192                 }
193
194                 public BindingNavigator(BindingSource bindingSource)
195                         :base()
196                 {
197                         AttachNewSource(bindingSource);
198                         this.AddStandardItems();
199                 }
200
201
202                 public BindingNavigator(bool addStandardItems)
203                         : base()
204                 {
205                         bindingSource = null;
206                         if (addStandardItems)
207                                 this.AddStandardItems();
208                 }
209
210                 [EditorBrowsable (EditorBrowsableState.Never)]
211                 public BindingNavigator(IContainer container)
212                         :base()
213                 {
214                         bindingSource = null;
215                         container.Add(this);
216                 }
217
218                 #endregion Constructors
219
220
221                 #region Public Events
222
223                 public event EventHandler RefreshItems;
224
225                 #endregion
226
227
228                 #region Public And Protected Methods
229
230                 public virtual void AddStandardItems()
231                 {
232                         BeginInit();
233
234                         MoveFirstItem = new ToolStripButton();
235                         moveFirstItem.Image = ResourceImageLoader.Get("nav_first.png");
236                         moveFirstItem.ToolTipText = Locale.GetText("Move first");
237                         Items.Add(moveFirstItem);
238
239                         MovePreviousItem = new ToolStripButton();
240                         movePreviousItem.Image = ResourceImageLoader.Get("nav_previous.png");
241                         movePreviousItem.ToolTipText = Locale.GetText("Move previous");
242                         Items.Add(movePreviousItem);
243
244                         Items.Add(new ToolStripSeparator());
245
246                         PositionItem = new ToolStripTextBox();
247                         positionItem.Width = 50;
248                         positionItem.Text = (bindingSource == null ? 0 : 1).ToString();
249                         positionItem.Width = 50;
250                         positionItem.ToolTipText = Locale.GetText("Current position");
251                         Items.Add(positionItem);
252
253                         CountItem = new ToolStripLabel();
254                         countItem.ToolTipText = Locale.GetText("Total number of items");
255                         countItem.Text = Locale.GetText(countItemFormat, bindingSource == null ? 0 : bindingSource.Count);
256                         Items.Add(countItem);
257
258                         Items.Add(new ToolStripSeparator());
259
260                         MoveNextItem = new ToolStripButton();
261                         moveNextItem.Image = ResourceImageLoader.Get("nav_next.png");
262                         moveNextItem.ToolTipText = Locale.GetText("Move next");
263                         Items.Add(moveNextItem);
264
265                         MoveLastItem = new ToolStripButton();
266                         moveLastItem.Image = ResourceImageLoader.Get("nav_end.png");
267                         moveLastItem.ToolTipText = Locale.GetText("Move last");
268                         Items.Add(moveLastItem);
269
270                         Items.Add(new ToolStripSeparator());
271
272                         AddNewItem = new ToolStripButton();
273                         addNewItem.Image = ResourceImageLoader.Get("nav_plus.png");
274                         addNewItem.ToolTipText = Locale.GetText("Add new");
275                         Items.Add(addNewItem);
276
277                         DeleteItem = new ToolStripButton();
278                         deleteItem.Image = ResourceImageLoader.Get("nav_delete.png");
279                         deleteItem.ToolTipText = Locale.GetText("Delete");
280                         Items.Add(deleteItem);
281
282                         EndInit();
283                 }
284
285                 public void BeginInit()
286                 {
287                         initFlag = true;
288                 }
289
290                 protected override void Dispose(bool disposing)
291                 {
292                         base.Dispose(disposing);
293                 }
294
295                 public void EndInit()
296                 {
297                         initFlag = false;
298                         OnRefreshItems();
299                 }
300
301                 protected virtual void OnRefreshItems()
302                 {
303                         if (initFlag)
304                                 return;
305
306                         if (this.RefreshItems != null)
307                                 this.RefreshItems(this, EventArgs.Empty);
308
309                         this.RefreshItemsCore();
310                 }
311
312                 [EditorBrowsable (EditorBrowsableState.Advanced)]
313                 protected virtual void RefreshItemsCore ()
314                 {
315                         try
316                         {
317                                 bool is_source_available = bindingSource != null;
318                                 initFlag = true;
319                                 //changingText = true;
320
321                                 if (addNewItem != null)
322                                         addNewItem.Enabled = is_source_available && bindingSource.AllowNew;
323
324                                 if (moveFirstItem != null)
325                                         moveFirstItem.Enabled = is_source_available && bindingSource.Position > 0;
326
327                                 if (moveLastItem != null)
328                                         moveLastItem.Enabled = is_source_available && bindingSource.Position < (bindingSource.Count - 1);
329
330                                 if (moveNextItem != null)
331                                         moveNextItem.Enabled = is_source_available && bindingSource.Position < (bindingSource.Count - 1);
332
333                                 if (movePreviousItem != null)
334                                         movePreviousItem.Enabled = is_source_available && bindingSource.Position > 0;
335
336                                 if (deleteItem != null)
337                                         deleteItem.Enabled = is_source_available && (bindingSource.Count != 0 && bindingSource.AllowRemove);
338
339                                 if (countItem != null) {
340                                         countItem.Text = string.Format(countItemFormat, is_source_available ? bindingSource.Count : 0);
341                                         countItem.Enabled = is_source_available && bindingSource.Count > 0;
342                                 }
343
344                                 if (positionItem != null) {
345                                         positionItem.Text = string.Format("{0}", is_source_available? bindingSource.Position + 1 : 0);
346                                         positionItem.Enabled = is_source_available && bindingSource.Count > 0;
347                                 }
348                         }
349                         finally
350                         {
351                                 //changingText = false;
352                                 initFlag = false;
353                         }
354                 }
355
356                 [MonoTODO ("Not implemented, will throw NotImplementedException")]
357                 public bool Validate ()
358                 {
359                         throw new NotImplementedException();
360                 }
361
362                 #endregion
363
364
365                 #region Private Methode
366
367                 private void AttachNewSource(BindingSource source)
368                 {
369                         if (bindingSource != null)
370                         {
371                                 bindingSource.ListChanged -= new ListChangedEventHandler(OnListChanged);
372                                 bindingSource.PositionChanged -= new EventHandler(OnPositionChanged);
373                                 bindingSource.AddingNew -= new AddingNewEventHandler(OnAddingNew);
374                         }
375
376                         bindingSource = source;
377
378                         if (bindingSource != null)
379                         {
380                                 bindingSource.ListChanged += new ListChangedEventHandler(OnListChanged);
381                                 bindingSource.PositionChanged += new EventHandler(OnPositionChanged);
382                                 bindingSource.AddingNew += new AddingNewEventHandler(OnAddingNew);
383                         }
384                 }
385
386                 private void OnAddNew(object sender, EventArgs e)
387                 {
388                         if (bindingSource != null)
389                                 bindingSource.AddNew();
390
391                         OnRefreshItems();
392                 }
393
394                 private void OnAddingNew(object sender, AddingNewEventArgs e)
395                 {
396                         OnRefreshItems();
397                 }
398
399                 private void OnDelete(object sender, EventArgs e)
400                 {
401                         if (bindingSource != null)
402                                 bindingSource.RemoveCurrent();
403
404                         OnRefreshItems();
405                 }
406
407                 private void OnListChanged(object sender, ListChangedEventArgs e)
408                 {
409                         OnRefreshItems();
410                 }
411
412                 private void OnMoveFirst(object sender, EventArgs e)
413                 {
414                         if (bindingSource != null)
415                                 bindingSource.MoveFirst();
416
417                         OnRefreshItems();
418                 }
419
420                 private void OnMoveLast(object sender, EventArgs e)
421                 {
422                         if (bindingSource != null)
423                                 bindingSource.MoveLast();
424
425                         OnRefreshItems();
426                 }
427
428                 private void OnMoveNext(object sender, EventArgs e)
429                 {
430                         if (bindingSource != null)
431                                 bindingSource.MoveNext();
432
433                         OnRefreshItems();
434                 }
435
436                 private void OnMovePrevious(object sender, EventArgs e)
437                 {
438                         if (bindingSource != null)
439                                 bindingSource.MovePrevious();
440
441                         OnRefreshItems();
442                 }
443
444                 private void OnPositionChanged(object sender, EventArgs e)
445                 {
446                         OnRefreshItems();
447                 }
448
449                 /*private void OnPositionTextChanged(object sender, EventArgs e)
450                 {
451                         if (changingText)
452                                 return;
453
454                         try
455                         {
456                                 changingText = true;
457
458                                 int position;
459                                 ToolStripTextBox txt = sender as ToolStripTextBox;
460
461                                 if (txt == null)
462                                         return;
463
464                                 if (!int.TryParse(txt.Text, out position))
465                                 {
466                                         txt.Text = (bindingSource == null ? 0 : bindingSource.Position).ToString();
467                                 }
468                                 else
469                                 {
470                                         if (position < 0)
471                                                 position = 1;
472
473                                         if (position > bindingSource.Count)
474                                                 position = bindingSource.Count;
475
476                                         bindingSource.Position = position;
477                                 }
478                         }
479                         finally
480                         {
481                                 changingText = false;
482                                 OnRefreshItems();
483                         }
484                 }*/
485
486                 #endregion
487         }
488 }