402 lines
14 KiB
C#
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); }
|
|
|
|
*/
|
|
}
|