tbf/TBF/UI/Shared/SharedSearchForListBox.cs

312 lines
11 KiB
C#

using Common;
///
/// Copyright (c) 2013-2015 Senus Slovensko a.s.
///
using System;
using System.Windows.Forms;
using TBF.Resources;
namespace TBF.UI.Shared
{
public partial class SharedSearchForListBox : UserControl
{
private System.Windows.Forms.ListBox listBoxEx;
public System.Windows.Forms.ListBox ListBoxEx
{
get { return listBoxEx; }
set { listBoxEx = value; }
}
/// <summary>
/// Masks to specify the enabled state and the visibility of buttons.
/// Unlock button is hard coded in this control, cannot be set from the parent.
/// </summary>
public enum Buttons
{
None = 0,
Find = (1 << 0), /// optional
FindNext = (1 << 1), /// optional
FindBack = (1 << 2), /// optional
JumpToTop = (1 << 3), /// optional
JumpToBottom = (1 << 4), /// optional
}
readonly System.Windows.Forms.Button[] buttonCtrls;
/// <summary>
/// Optional buttons are Add, Remove, Up, Down, Edit and Copy.
/// OK and Cancel buttons are always visible (after unlock), but not always enabled.
/// </summary>
public Buttons OptionalButtons;
public enum LState
{
Locked, /// 'Unlock', 'Close' (=OK) are shown, all the othere are hidden
Unlocked, /// Unlock, Ok, Cancel, Add,Remove and all optional buttons are shown
}
LState lockState;
public LState LockState { get { return lockState; } }
bool buttonsRepositionsed;
public bool MoreActive;
public int MoreButtonTop;
/// <summary>
/// Used by controls to indicate which item is selected
/// and to appropriately update Remove, Up and Down Buttons.
/// </summary>
public enum SelectedItemPos
{
None,
First,
Last,
FirstAndLast,
Middle,
}
public Form ParentForm; /// Used as a current form reference when changing and restoring a user
public GID[] RequiredGroupMembership;
/// <summary>
/// Default constructor
/// </summary>
public SharedSearchForListBox()
{
InitializeComponent();
lockState = LState.Locked;
MoreActive = false;
RequiredGroupMembership = null;
buttonCtrls = new System.Windows.Forms.Button[]
{
findButton, findNextButton, findBackButton,
jumpToTopButton, jumpToBottomButton,
};
OptionalButtons = Buttons.None;
buttonsRepositionsed = false;
}
void ShowOrHideButtons(Buttons selectedButtons, bool value)
{
for (int i = 0; i < buttonCtrls.Length; i++)
{
if ((selectedButtons & (Buttons)(1 << i)) != 0) buttonCtrls[i].Visible = value;
}
}
public void EnableOrDisableButtons(Buttons selectedButtons, bool value)
{
for (int i = 0; i < buttonCtrls.Length; i++)
{
if ((selectedButtons & (Buttons)(1 << i)) != 0) buttonCtrls[i].Enabled = value;
}
}
/// <summary>
/// Initialize the buttons when the dialog is loaded
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SharedDlgSearchForListBox_Load(object sender, EventArgs e)
{
searchLabel.Text = "Search";
findButton.Text = "Find";
jumpToBottomButton.Text = "Jump down";
jumpToTopButton.Text = "Jump up";
ShowOrHideButtons((Buttons)0x1F, true);
}
// Stores the last search text
private string _lastSearchText = string.Empty;
// Stores the index of the last found item in the ListView
private int _lastFoundIndex = -1;
private void findButton_Click(object sender, EventArgs e)
{
string search = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(search))
return;
_lastSearchText = search;
_lastFoundIndex = -1;
int index = FindItemIndex(search, 0, +1);
if (index == -1)
{
MessageBox.Show("No results found.");
return;
}
_lastFoundIndex = index;
SelectItemAtIndex(index);
}
/// <summary>
/// Finds an item in the ListView starting from given index and direction.
/// </summary>
/// <param name="search">Search text (lowercase).</param>
/// <param name="startIndex">Index to start from.</param>
/// <param name="direction">+1 = forward, -1 = backward.</param>
/// <returns>Index of found item or -1 if not found.</returns>
private int FindItemIndex(string search, int startIndex, int direction)
{
// No items
if (listBoxEx.Items.Count == 0)
return -1;
// Clamp bounds
if (startIndex < 0)
startIndex = 0;
if (startIndex >= listBoxEx.Items.Count)
startIndex = listBoxEx.Items.Count - 1;
search = search.ToLower();
// Forward search
if (direction > 0)
{
for (int i = startIndex; i < listBoxEx.Items.Count; i++)
{
string text = listBoxEx.Items[i].ToString().ToLower();
if (text.Contains(search))
return i;
}
}
else // Backward search
{
for (int i = startIndex; i >= 0; i--)
{
string text = listBoxEx.Items[i].ToString().ToLower();
if (text.Contains(search))
return i;
}
}
return -1;
}
/// <summary>
/// Selects and scrolls to the item at given index.
/// </summary>
private void SelectItemAtIndex(int index)
{
if (index < 0 || index >= listBoxEx.Items.Count)
return;
listBoxEx.SelectedIndex = index; // selects item
listBoxEx.TopIndex = index; // scrolls to item
listBoxEx.Focus(); // ensures highlight is visible
}
private void findNextButton_Click(object sender, EventArgs e)
{
string search = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(search))
return;
if (search != _lastSearchText)
{
_lastSearchText = search;
_lastFoundIndex = -1;
}
int index = FindItemIndex(search, _lastFoundIndex + 1, +1);
if (index == -1)
{
MessageBox.Show("No more results.");
return;
}
_lastFoundIndex = index;
SelectItemAtIndex(index);
}
private void findBackButton_Click(object sender, EventArgs e)
{
string search = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(search))
return;
if (search != _lastSearchText)
{
_lastSearchText = search;
_lastFoundIndex = listBoxEx.Items.Count;
}
int index = FindItemIndex(search, _lastFoundIndex - 1, -1);
if (index == -1)
{
MessageBox.Show("No more results.");
return;
}
_lastFoundIndex = index;
SelectItemAtIndex(index);
}
private void jumpToBottomButton_Click(object sender, EventArgs e)
{
// Scroll to the bottom without selecting any item
if (listBoxEx.Items.Count == 0)
return;
listBoxEx.TopIndex = listBoxEx.Items.Count - 1; // last item index
}
private void jumpToTopButton_Click(object sender, EventArgs e)
{
// Scroll to the top without selecting any item
if (listBoxEx.Items.Count == 0)
return;
listBoxEx.TopIndex = 0; // first item index
}
private void searchTextBox_Enter(object sender, EventArgs e)
{
// When Search textbox has focus, Enter will trigger Find button
var form = this.FindForm();
if (form != null)
form.AcceptButton = findButton;
}
}
/*/// <summary>
/// Events invoked when buttons are clicked (and in case of Unlock kbutton also accepted)
/// </summary>
public event EventHandler Unlocked;
public event EventHandler GoClicked;
public event EventHandler FindClicked;
public event EventHandler FindNextClicked;
public event EventHandler FindBackClicked;
public event EventHandler JumpToTopClicked;
public event EventHandler JumpToBottomClicked;
///
/// All remaining handlers:
///
private void cancelBtn_Click(object s, EventArgs e) { if (CancelClicked != null) CancelClicked(s, e); }
private void addBtn_Click(object s, EventArgs e) { if (AddClicked != null) AddClicked(s, e); }
private void removeBtn_Click(object s, EventArgs e) { if (RemoveClicked != null) RemoveClicked(s, e); }
private void upBtn_Click(object s, EventArgs e) { if (UpClicked != null) UpClicked(s, e); }
private void downBtn_Click(object s, EventArgs e) { if (DownClicked != null) DownClicked(s, e); }
private void editBtn_Click(object s, EventArgs e) { if (EditClicked != null) EditClicked(s, e); }
private void copyBtn_Click(object s, EventArgs e) { if (CopyClicked != null) CopyClicked(s, e); }
private void exportButton_Click(object s, EventArgs e) { if (ExportClicked != null) ExportClicked(s, e); }
private void importButton_Click(object s, EventArgs e) { if (ImportClicked != null) ImportClicked(s, e); }
private void compareButton_Click(object s, EventArgs e) { if (CompareClicked != null) CompareClicked(s, e); }
private void newTabButton_Click(object s, EventArgs e) { if (NewTabClicked != null) NewTabClicked(s, e); }
private void renameTabButton_Click(object s, EventArgs e) { if (RenameTabClicked != null) RenameTabClicked(s, e); }
private void removeTabButton_Click(object s, EventArgs e) { if (RemoveTabClicked != null) RemoveTabClicked(s, e); }
private void customButton1_Click(object s, EventArgs e) { if (Custom1Clicked != null) Custom1Clicked(s, e); }
private void customButton2_Click(object s, EventArgs e) { if (Custom2Clicked != null) Custom2Clicked(s, e); }
private void customButton3_Click(object s, EventArgs e) { if (Custom3Clicked != null) Custom3Clicked(s, e); }
*/
}