tbf/TBF/UI/Shared/SharedSearchForListView.cs

402 lines
14 KiB
C#

using Common;
///
/// Copyright (c) 2013-2015 Senus Slovensko a.s.
///
using System;
using System.Windows.Forms;
using TBF.Resources;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace TBF.UI.Shared
{
public partial class SharedSearchForListView : UserControl
{
private Common.Forms.ListViewEx listViewEx;
public Common.Forms.ListViewEx ListViewEx
{
get { return listViewEx; }
set { listViewEx = 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,
Go = (1 << 0), /// optional
Find = (1 << 1), /// optional
FindNext = (1 << 2), /// optional
FindBack = (1 << 3), /// optional
JumpToTop = (1 << 4), /// optional
JumpToBottom = (1 << 5), /// 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 OwnerForm; /// Used as a current form reference when changing and restoring a user
public GID[] RequiredGroupMembership;
/// <summary>
/// Default constructor
/// </summary>
public SharedSearchForListView()
{
InitializeComponent();
lockState = LState.Locked;
MoreActive = false;
RequiredGroupMembership = null;
buttonCtrls = new System.Windows.Forms.Button[]
{
findButton, findNextButton, findBackButton,
goButton,
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 SharedDlgSearchForListView_Load(object sender, EventArgs e)
{
//Label.Text = "nr.";//Strings.UnlockBtnText;
searchLabel.Text = "Search";
findButton.Text = "Find";
goButton.Text = "Go";
jumpToBottomButton.Text = "Jump to bottom";
jumpToTopButton.Text = "Jump to top";
ShowOrHideButtons((Buttons)0x1F, true);
}
private void goButton_Click(object sender, EventArgs e)
{
if (int.TryParse(nrTextBox.Text, out int index))
{
// ListView indexing: first = 0
index--;
if (index >= 0 && index < listViewEx.Items.Count)
{
//listViewEx.SelectedItems.Clear();
/*listViewEx.FullRowSelect = true;
listViewEx.HideSelection = false;
listViewEx.OwnerDraw = false;*/
var item = listViewEx.Items[index];
listViewEx.HideSelection = false;
item.Selected = true;
listViewEx.Select();
item.Focused = true;
item.EnsureVisible(); // automatic scroll
}
}
else
{
MessageBox.Show("Invalid character.");
}
}
// 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)
{
// Get search text
string search = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(search))
return;
string searchLower = search.ToLower();
// Store search state
_lastSearchText = search;
_lastFoundIndex = -1;
// Find first occurrence from the top
int index = FindItemIndex(searchLower, 0, +1);
if (index == -1)
{
MessageBox.Show("No results found.");
return;
}
// Remember last found index
_lastFoundIndex = index;
// Select item
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 -> nothing to search
if (listViewEx.Items.Count == 0)
return -1;
// Clamp start index to valid range
if (startIndex < 0)
startIndex = 0;
if (startIndex >= listViewEx.Items.Count)
startIndex = listViewEx.Items.Count - 1;
// Forward search
if (direction > 0)
{
for (int i = startIndex; i < listViewEx.Items.Count; i++)
{
var item = listViewEx.Items[i];
// Check all subitems (columns)
foreach (ListViewItem.ListViewSubItem sub in item.SubItems)
{
if (sub.Text.ToLower().Contains(search))
return i;
}
}
}
// Backward search
else if (direction < 0)
{
for (int i = startIndex; i >= 0; i--)
{
var item = listViewEx.Items[i];
// Check all subitems (columns)
foreach (ListViewItem.ListViewSubItem sub in item.SubItems)
{
if (sub.Text.ToLower().Contains(search))
return i;
}
}
}
// Nothing found
return -1;
}
/// <summary>
/// Selects and scrolls to the item at given index.
/// </summary>
private void SelectItemAtIndex(int index)
{
if (index < 0 || index >= listViewEx.Items.Count)
return;
// Clear previous selection
listViewEx.SelectedItems.Clear();
// Select and focus item
var item = listViewEx.Items[index];
listViewEx.HideSelection = false;
item.Selected = true;
listViewEx.Select();
item.Focused = true;
item.EnsureVisible();
}
private void findNextButton_Click(object sender, EventArgs e)
{
// Get current search text
string search = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(search))
return;
string searchLower = search.ToLower();
// If search text changed, start from scratch
if (search != _lastSearchText)
{
_lastSearchText = search;
_lastFoundIndex = -1;
}
// Start searching from the next item after the last found one
int startIndex = _lastFoundIndex + 1;
int index = FindItemIndex(searchLower, startIndex, +1);
if (index == -1)
{
MessageBox.Show("No more results.");
return;
}
_lastFoundIndex = index;
SelectItemAtIndex(index);
}
private void findBackButton_Click(object sender, EventArgs e)
{
// Get current search text
string search = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(search))
return;
string searchLower = search.ToLower();
// If search text changed, start from scratch
if (search != _lastSearchText)
{
_lastSearchText = search;
_lastFoundIndex = listViewEx.Items.Count; // start from bottom
}
// Start searching from the previous item before the last found one
int startIndex = _lastFoundIndex - 1;
int index = FindItemIndex(searchLower, startIndex, -1);
if (index == -1)
{
MessageBox.Show("No more results.");
return;
}
_lastFoundIndex = index;
SelectItemAtIndex(index);
}
private void jumpToTopButton_Click(object sender, EventArgs e)
{
// Check if there are any items in the ListView
if (listViewEx.Items.Count == 0)
return;
// Get the first item (index 0)
ListViewItem firstItem = listViewEx.Items[0];
// Clear previous selection
//listViewEx.SelectedItems.Clear();
// Select the first item
firstItem.Selected = true;
firstItem.Focused = true; // give keyboard focus to the item
firstItem.EnsureVisible(); // scroll so the item is visible (top)
}
private void jumpToBottomButton_Click(object sender, EventArgs e)
{
if (listViewEx.Items.Count == 0) return;
var last = listViewEx.Items[listViewEx.Items.Count - 1];
//listViewEx.SelectedItems.Clear();
last.Selected = true;
last.Focused = true;
last.EnsureVisible();
}
private void procedureNrTextBox_Enter(object sender, EventArgs e)
{
// When ProcedureNr textbox has focus, Enter will trigger Go button
var form = this.FindForm();
if (form != null)
form.AcceptButton = goButton;
}
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); }
*/
}