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