#region Using Directives using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; #endregion Using Directives namespace ScintillaNET { /// /// Used to invoke AutoComplete and UserList windows. Also manages AutoComplete /// settings. /// /// /// Autocomplete is typically used in IDEs to automatically complete some kind /// of identifier or keyword based on a partial name. /// [TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))] public class AutoComplete : TopLevelHelper { #region Fields private List _list = new List(); private string _stopCharacters = string.Empty; private bool _automaticLengthEntered = true; private string _fillUpCharacters = string.Empty; #endregion Fields #region Methods /// /// Accepts the current AutoComplete window entry /// /// /// If the AutoComplete window is open Accept() will close it. This also causes the /// event to fire /// public void Accept() { NativeScintilla.AutoCComplete(); } /// /// Cancels the autocomplete window /// /// /// If the AutoComplete window is displayed calling Cancel() will close the window. /// public void Cancel() { NativeScintilla.AutoCCancel(); } /// /// Deletes all registered images. /// public void ClearRegisteredImages() { NativeScintilla.ClearRegisteredImages(); } private int GetLengthEntered() { if (!_automaticLengthEntered) return 0; int pos = NativeScintilla.GetCurrentPos(); return pos - NativeScintilla.WordStartPosition(pos, true); } private string GetListString(IEnumerable list) { StringBuilder listString = new StringBuilder(); foreach (string s in list) { listString.Append(s).Append(ListSeparator); } if (listString.Length > 1) listString.Remove(listString.Length - 1, 1); return listString.ToString().Trim(); } /// /// Registers an image with index to be displayed in the AutoComplete window. /// /// Index of the image to register to /// Image to display in Bitmap format private void RegisterImage(int type, Bitmap image) { NativeScintilla.RegisterImage(type, XpmConverter.ConvertToXPM(image)); } /// /// Registers an image with index to be displayed in the AutoComplete window. /// /// Index of the image to register to /// Image to display in the XPM image format /// Color to mask the image as transparent private void RegisterImage(int type, Bitmap image, Color transparentColor) { NativeScintilla.RegisterImage(type, XpmConverter.ConvertToXPM(image, Utilities.ColorToHtml(transparentColor))); } /// /// Registers an image with index to be displayed in the AutoComplete window. /// /// Index of the image to register to /// Image in the XPM image format public void RegisterImage(int type, string xpmImage) { NativeScintilla.RegisterImage(type, xpmImage); } /// /// Registers a list of images to be displayed in the AutoComplete window. /// /// List of images in the Bitmap image format /// Indecis are assigned sequentially starting at 0 public void RegisterImages(IList images) { for (int i = 0; i < images.Count; i++) RegisterImage(i, images[i]); } /// /// Registers a list of images to be displayed in the AutoComplete window. /// /// List of images in the Bitmap image format /// Color to mask the image as transparent /// Indecis are assigned sequentially starting at 0 public void RegisterImages(IList images, Color transparentColor) { for (int i = 0; i < images.Count; i++) RegisterImage(i, images[i], transparentColor); } /// /// Registers a list of images to be displayed in the AutoComplete window. /// /// List of images in the XPM image format /// Indecis are assigned sequentially starting at 0 public void RegisterImages(IList xpmImages) { for (int i = 0; i < xpmImages.Count; i++) NativeScintilla.RegisterImage(i, xpmImages[i]); } /// /// Registers a list of images to be displayed in the AutoComplete window. /// /// List of images contained in an ImageList /// Indecis are assigned sequentially starting at 0 public void RegisterImages(ImageList images) { RegisterImages(XpmConverter.ConvertToXPM(images)); } /// /// Registers a list of images to be displayed in the AutoComplete window. /// /// List of images contained in an ImageList /// Color to mask the image as transparent /// Indecis are assigned sequentially starting at 0 public void RegisterImages(ImageList images, Color transparentColor) { RegisterImages(XpmConverter.ConvertToXPM(images, Utilities.ColorToHtml(transparentColor))); } private void ResetAutoHide() { AutoHide = true; } private void ResetAutomaticLengthEntered() { AutomaticLengthEntered = true; } private void ResetCancelAtStart() { CancelAtStart = true; } private void ResetDropRestOfWord() { DropRestOfWord = false; } private void ResetFillUpCharacters() { _fillUpCharacters = string.Empty; } private void ResetImageSeparator() { ImageSeparator = '?'; } private void ResetIsCaseSensitive() { IsCaseSensitive = true; } private void ResetListSeparator() { ListSeparator = ' '; } private void ResetMaxHeight() { MaxHeight = 5; } private void ResetMaxWidth() { MaxWidth = 0; } private void ResetSingleLineAccept() { SingleLineAccept = false; } private void ResetStopCharacters() { _stopCharacters = string.Empty; } internal bool ShouldSerialize() { return ShouldSerializeAutoHide() || ShouldSerializeCancelAtStart() || ShouldSerializeDropRestOfWord() || ShouldSerializeFillUpCharacters() || ShouldSerializeImageSeparator() || ShouldSerializeIsCaseSensitive() || ShouldSerializeListSeparator() || ShouldSerializeMaxHeight() || ShouldSerializeMaxWidth() || ShouldSerializeSingleLineAccept() || ShouldSerializeStopCharacters(); } private bool ShouldSerializeAutoHide() { return !AutoHide; } private bool ShouldSerializeAutomaticLengthEntered() { return !AutomaticLengthEntered; } private bool ShouldSerializeCancelAtStart() { return !CancelAtStart; } private bool ShouldSerializeDropRestOfWord() { return DropRestOfWord; } private bool ShouldSerializeFillUpCharacters() { return _fillUpCharacters != string.Empty; } private bool ShouldSerializeImageSeparator() { return ImageSeparator != '?'; } private bool ShouldSerializeIsCaseSensitive() { return !IsCaseSensitive; } private bool ShouldSerializeListSeparator() { return ListSeparator != ' '; } private bool ShouldSerializeMaxHeight() { return MaxHeight != 5; } private bool ShouldSerializeMaxWidth() { return MaxWidth != 0; } private bool ShouldSerializeSingleLineAccept() { return SingleLineAccept; } private bool ShouldSerializeStopCharacters() { return _stopCharacters != string.Empty; } /// /// Shows the autocomplete window. /// /// /// This overload assumes that the property has been /// set. The lengthEntered is automatically detected by the editor. /// public void Show() { Show(-1, GetListString(_list), false); } /// /// Shows the autocomplete window /// /// /// Sets the property. /// In this overload the lengthEntered is automatically detected by the editor. /// public void Show(IEnumerable list) { _list = new List(list); Show(-1); } /// /// Shows the autocomplete window /// /// Number of characters of the current word already entered in the editor /// /// This overload assumes that the property has been set. /// public void Show(int lengthEntered) { Show(lengthEntered, GetListString(_list), false); } /// /// Shows the autocomplete window /// /// Number of characters of the current word already entered in the editor /// Sets the property. public void Show(int lengthEntered, IEnumerable list) { _list = new List(list); Show(-1); } /// /// Shows the autocomplete window. /// /// Number of characters of the current word already entered in the editor /// Sets the property. public void Show(int lengthEntered, string list) { if (list == string.Empty) _list = new List(); else _list = new List(list.Split(ListSeparator)); Show(lengthEntered, list, true); } internal void Show(int lengthEntered, string list, bool dontSplit) { // We may have the auto-detect of lengthEntered. In which case // look for the last word character as the _start int le = lengthEntered; if (le < 0) le = GetLengthEntered(); NativeScintilla.AutoCShow(le, list); // Now it may have been that the auto-detect lengthEntered // caused to AutoCShow call to fail becuase no words matched // the letters we autodetected. In this case just show the // list with a 0 lengthEntered to make sure it will show if (!IsActive && lengthEntered < 0) NativeScintilla.AutoCShow(0, list); } /// /// Shows the autocomplete window. /// /// Sets the property. /// /// In this overload the lengthEntered is automatically detected by the editor. /// public void Show(string list) { Show(-1, list); } /// /// Shows a UserList window /// /// Index of the userlist to show. Can be any integer /// List of words to show. /// /// UserLists are not as powerful as autocomplete but can be assigned to a user defined index. /// public void ShowUserList(int listType, IEnumerable list) { Show(listType, GetListString(list), true); } /// /// Shows a UserList window /// /// Index of the userlist to show. Can be any integer /// List of words to show separated by " " /// /// UserLists are not as powerful as autocomplete but can be assigned to a user defined index. /// public void ShowUserList(int listType, string list) { NativeScintilla.UserListShow(listType, list); } #endregion Methods #region Properties /// /// By default, the list is cancelled if there are no viable matches (the user has typed characters that no longer match a list entry). /// If you want to keep displaying the original list, set AutoHide to false. /// public bool AutoHide { get { return NativeScintilla.AutoCGetAutoHide(); } set { NativeScintilla.AutoCSetAutoHide(value); } } /// /// Gets or Sets the last automatically calculated LengthEntered used whith . /// public bool AutomaticLengthEntered { get { return _automaticLengthEntered; } set { _automaticLengthEntered = value; } } /// /// The default behavior is for the list to be cancelled if the caret moves before the location it was at when the list was displayed. /// By setting this property to false, the list is not cancelled until the caret moves before the first character of the word being completed. /// public bool CancelAtStart { get { return NativeScintilla.AutoCGetCancelAtStart(); } set { NativeScintilla.AutoCSetCancelAtStart(value); } } /// /// When an item is selected, any word characters following the caret are first erased if dropRestOfWord is set to true. /// /// Defaults to false public bool DropRestOfWord { get { return NativeScintilla.AutoCGetDropRestOfWord(); } set { NativeScintilla.AutoCSetDropRestOfWord(value); } } /// /// List of characters (no separated) that causes the AutoComplete window to accept the current /// selection. /// public string FillUpCharacters { get { return _fillUpCharacters; } set { _fillUpCharacters = value; NativeScintilla.AutoCSetFillUps(value); } } /// /// Autocompletion list items may display an image as well as text. Each image is first registered with an integer type. /// Then this integer is included in the text of the list separated by a '?' from the text. For example, "fclose?2 fopen" /// displays image 2 before the string "fclose" and no image before "fopen". /// public char ImageSeparator { get { return NativeScintilla.AutoCGetTypeSeparator(); } set { NativeScintilla.AutoCSetTypeSeparator(value); } } /// /// Returns wether or not the AutoComplete window is currently displayed /// [Browsable(false)] public bool IsActive { get { return NativeScintilla.AutoCActive(); } } /// /// Gets or Sets if the comparison of words to the AutoComplete are case sensitive. /// /// Defaults to true public bool IsCaseSensitive { get { return !NativeScintilla.AutoCGetIgnoreCase(); } set { NativeScintilla.AutoCSetIgnoreCase(!value); } } /// /// Gets the document posision when the AutoComplete window was last invoked /// [Browsable(false)] public int LastStartPosition { get { return NativeScintilla.AutoCPosStart(); } } /// /// List if words to display in the AutoComplete window when invoked. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public List List { get { return _list; } set { if (value == null) value = new List(); _list = value; } } /// /// Character used to split to convert to a List. /// [TypeConverter(typeof(ScintillaNET.WhitespaceStringConverter))] public char ListSeparator { get { return NativeScintilla.AutoCGetSeparator(); } set { NativeScintilla.AutoCSetSeparator(value); } } /// /// List of words to display in the AutoComplete window. /// /// /// The list of words separated by which /// is " " by default. /// public string ListString { get { return GetListString(_list); } set { _list = new List(value.Split(ListSeparator)); } } /// /// Get or set the maximum number of rows that will be visible in an autocompletion list. If there are more rows in the list, then a vertical scrollbar is shown /// /// Defaults to 5 public int MaxHeight { get { return NativeScintilla.AutoCGetMaxHeight(); } set { NativeScintilla.AutoCSetMaxHeight(value); } } /// /// Get or set the maximum width of an autocompletion list expressed as the number of characters in the longest item that will be totally visible. /// /// /// If zero (the default) then the list's width is calculated to fit the item with the most characters. Any items that cannot be fully displayed /// within the available width are indicated by the presence of ellipsis. /// public int MaxWidth { get { return NativeScintilla.AutoCGetMaxWidth(); } set { NativeScintilla.AutoCSetMaxWidth(value); } } /// /// Gets or Sets the index of the currently selected item in the AutoComplete /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int SelectedIndex { get { return NativeScintilla.AutoCGetCurrent(); } set { SelectedText = _list[value]; } } /// /// Gets or Sets the Text of the currently selected AutoComplete item. /// /// /// When setting this property it does not change the text of the currently /// selected item. Instead it searches the list for the given value and selects /// that item if it matches. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string SelectedText { get { return _list[NativeScintilla.AutoCGetCurrent()]; } set { NativeScintilla.AutoCSelect(value); } } /// /// If you set this value to true and a list has only one item, it is automatically added and no list is displayed. /// The default is to display the list even if there is only a single item. /// public bool SingleLineAccept { get { return NativeScintilla.AutoCGetChooseSingle(); } set { NativeScintilla.AutoCSetChooseSingle(value); } } /// /// List of characters (no separator) that causes the AutoComplete window to cancel. /// public string StopCharacters { get { return _stopCharacters; } set { _stopCharacters = value; NativeScintilla.AutoCStops(value); } } #endregion Properties #region Constructors internal AutoComplete(Scintilla scintilla) : base(scintilla) { } #endregion Constructors } }