2023-01-24 15:29:31 +01:00
/ * Copyright ( c ) Cloud Software Group , Inc .
2013-06-24 13:41:48 +02:00
*
* Redistribution and use in source and binary forms ,
* with or without modification , are permitted provided
* that the following conditions are met :
*
* * Redistributions of source code must retain the above
* copyright notice , this list of conditions and the
* following disclaimer .
* * Redistributions in binary form must reproduce the above
* copyright notice , this list of conditions and the
* following disclaimer in the documentation and / or other
* materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES ,
* INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING ,
* BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ,
* WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
* /
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Drawing ;
using System.Windows.Forms ;
using XenAdmin.Controls.DataGridViewEx ;
using XenAdmin.Core ;
using System.Linq ;
using XenAdmin.Commands ;
namespace XenAdmin.Controls
{
public partial class PDSection : UserControl
{
#region Private fields
/// <summary>
/// Used to persist selection over a repaint, we set this when we clear the datagridview
/// </summary>
private string previousSelectionKey ;
private bool inLayout ;
/// <summary>
/// Whether the mouse is over the chevron
/// </summary>
private bool chevronHot ;
#endregion
#region Delegates and Events
/// <summary>
/// Event for when the datagridview received focus
/// </summary>
2020-03-13 16:22:45 +01:00
public event Action < PDSection > ContentReceivedFocus ;
2013-06-24 13:41:48 +02:00
/// <summary>
/// Event for when the datagridview receives focus
/// </summary>
2020-03-13 16:22:45 +01:00
public event Action < PDSection > ContentChangedSelection ;
2013-06-24 13:41:48 +02:00
public event Action < PDSection > ExpandedChanged ;
#endregion
public PDSection ( )
{
InitializeComponent ( ) ;
SetDefaultValues ( ) ;
Contract ( ) ;
MinimumSize = new Size ( 0 , Height ) ;
dataGridViewEx1 . LostFocus + = dataGridViewEx1_LostFocus ;
dataGridViewEx1 . GotFocus + = dataGridViewEx1_GotFocus ;
if ( ! Application . RenderWithVisualStyles )
{
panel1 . BackColor = SystemColors . Control ;
this . BackColor = SystemColors . ControlDark ;
}
}
#region Accessors
[Browsable(false)]
public bool DisableFocusEvent { private get ; set ; }
[DefaultValue("Title")]
[Browsable(true)]
[Localizable(true)]
public string SectionTitle
{
get { return label1 . Text ; }
set { label1 . Text = value ; }
}
[Browsable(false)]
public bool IsEmpty ( )
{
return dataGridViewEx1 . Rows . Count = = 0 ;
}
[DefaultValue(true)]
[Browsable(false)]
public bool IsExpanded { get ; private set ; }
[Browsable(false)]
public bool HasNoSelection ( )
{
return dataGridViewEx1 . SelectedRows . Count < = 0 ;
}
[Browsable(false)]
public Rectangle SelectedRowBounds
{
get
{
if ( HasNoSelection ( ) )
return new Rectangle ( 0 , 0 , 0 , 0 ) ;
int x = dataGridViewEx1 . Location . X ;
int y = dataGridViewEx1 . RowDepth ( dataGridViewEx1 . SelectedRows [ 0 ] . Index ) + dataGridViewEx1 . Location . Y ;
int w = dataGridViewEx1 . Width ;
int h = dataGridViewEx1 . SelectedRows [ 0 ] . Height ;
return new Rectangle ( x , y , w , h ) ;
}
}
[Browsable(false)]
public bool ShowCellToolTips
{
get { return dataGridViewEx1 . ShowCellToolTips ; }
set { dataGridViewEx1 . ShowCellToolTips = value ; }
}
#endregion
protected override void OnGotFocus ( EventArgs e )
{
base . OnGotFocus ( e ) ;
// For keyboard access
if ( DisableFocusEvent )
return ;
if ( ! IsExpanded )
Expand ( ) ;
}
#region Control Event Handlers
private void dataGridViewEx1_CellContentClick ( object sender , DataGridViewCellEventArgs e )
{
if ( e . ColumnIndex > = 0 & & e . RowIndex > = 0 )
2021-08-31 12:31:16 +02:00
RunCellCommandOrAction ( dataGridViewEx1 . Rows [ e . RowIndex ] . Cells [ e . ColumnIndex ] ) ;
2013-06-24 13:41:48 +02:00
}
private void dataGridViewEx1_KeyPress ( object sender , KeyPressEventArgs e )
{
if ( e . KeyChar = = ( char ) Keys . Enter )
2021-08-31 12:31:16 +02:00
RunCellCommandOrAction ( dataGridViewEx1 . CurrentCell ) ;
2013-06-24 13:41:48 +02:00
}
private void dataGridViewEx1_LostFocus ( object sender , EventArgs e )
{
dataGridViewEx1 . HideSelection = true ;
}
private void dataGridViewEx1_GotFocus ( object sender , EventArgs e )
{
dataGridViewEx1 . HideSelection = false ;
2020-03-13 16:22:45 +01:00
ContentReceivedFocus ? . Invoke ( this ) ;
2013-06-24 13:41:48 +02:00
}
private void dataGridViewEx1_SelectionChanged ( object sender , EventArgs e )
{
if ( inLayout )
return ;
2020-03-13 16:22:45 +01:00
ContentChangedSelection ? . Invoke ( this ) ;
2013-06-24 13:41:48 +02:00
}
private void dataGridViewEx1_MouseClick ( object sender , MouseEventArgs e )
{
if ( e . Button ! = MouseButtons . Right )
return ;
DataGridView . HitTestInfo i = dataGridViewEx1 . HitTest ( e . X , e . Y ) ;
if ( i . RowIndex < 0 | | i . RowIndex > dataGridViewEx1 . RowCount )
return ;
if ( i . ColumnIndex < 0 | | i . ColumnIndex > dataGridViewEx1 . ColumnCount )
return ;
dataGridViewEx1 . Focus ( ) ;
var row = dataGridViewEx1 . Rows [ i . RowIndex ] ;
row . Selected = true ;
contextMenuStrip1 . Items . Clear ( ) ;
contextMenuStrip1 . Items . Add ( copyToolStripMenuItem ) ;
2021-06-16 00:58:30 +02:00
if ( row . Tag is ToolStripMenuItem [ ] menuItems & & menuItems . Length > 0 )
2013-06-24 13:41:48 +02:00
{
contextMenuStrip1 . Items . Add ( new ToolStripSeparator ( ) ) ;
2021-06-16 00:58:30 +02:00
contextMenuStrip1 . Items . AddRange ( menuItems . Cast < ToolStripItem > ( ) . ToArray ( ) ) ;
2013-06-24 13:41:48 +02:00
}
contextMenuStrip1 . Show ( dataGridViewEx1 , dataGridViewEx1 . PointToClient ( MousePosition ) ) ;
}
private void CopyMenuItem_Click ( object sender , EventArgs e )
{
Clipboard . SetDataObject ( dataGridViewEx1 . SelectedRows [ 0 ] . Cells [ 1 ] . Value ) ;
}
private void panel1_MouseDoubleClick ( object sender , MouseEventArgs e )
{
if ( IsExpanded )
Contract ( ) ;
else
{
Expand ( ) ;
dataGridViewEx1 . Focus ( ) ;
}
}
private void chevron_Click ( object sender , EventArgs e )
{
if ( IsExpanded )
Contract ( ) ;
else
{
Expand ( ) ;
dataGridViewEx1 . Focus ( ) ;
}
}
private void chevron_MouseEnter ( object sender , EventArgs e )
{
chevronHot = true ;
RefreshChevron ( ) ;
}
private void chevron_MouseLeave ( object sender , EventArgs e )
{
chevronHot = false ;
RefreshChevron ( ) ;
}
#endregion
#region Private Methods
private void SetDefaultValues ( )
{
SectionTitle = Messages . PDSECTION_TITLE ;
IsExpanded = true ;
}
2021-08-31 12:31:16 +02:00
private void RunCellCommandOrAction ( DataGridViewCell cell )
2013-06-24 13:41:48 +02:00
{
if ( cell = = null )
return ;
var command = cell . Tag as Command ;
if ( command ! = null )
2021-08-31 12:31:16 +02:00
command . Run ( ) ;
2013-06-24 13:41:48 +02:00
var action = cell . Tag as Action ;
if ( action ! = null )
action . Invoke ( ) ;
}
private void RefreshHeight ( )
{
if ( IsExpanded )
{
int newHeight = dataGridViewEx1 . Rows . GetRowsHeight ( DataGridViewElementStates . Visible ) ;
int valueColWidth = dataGridViewEx1 . Width - dataGridViewEx1 . Columns [ KeyColumn . Index ] . Width ;
int preferredValueColWidth =
dataGridViewEx1 . Columns [ ValueColumn . Index ] . GetPreferredWidth (
DataGridViewAutoSizeColumnMode . AllCells , true ) ;
int horizontalScrollBarHeight = preferredValueColWidth - 1 > = valueColWidth
? dataGridViewEx1 . HorizontalScrollBarHeight
: 0 ;
// 3px added so we have a border (one at top of control, one between title and grid, one at bottom)
Height = panel1 . Height + newHeight + horizontalScrollBarHeight + 3 ;
// this correction is needed because the anchor property of the grid drags it to fill the space we want to be a border
// when we go from contracted (2 borders) to expanded (3 borders)
}
else
{
Height = panel1 . Height + 2 ;
}
}
private void RefreshChevron ( )
{
if ( IsExpanded )
{
2020-06-18 02:20:29 +02:00
chevron . Image = chevronHot ? Images . StaticImages . PDChevronUpOver : Images . StaticImages . PDChevronUp ;
2013-06-24 13:41:48 +02:00
}
else
{
2020-06-18 02:20:29 +02:00
chevron . Image = chevronHot ? Images . StaticImages . PDChevronDownOver : Images . StaticImages . PDChevronDown ;
2013-06-24 13:41:48 +02:00
}
}
private void AddRow ( DataGridViewRow r )
{
dataGridViewEx1 . Rows . Add ( r ) ;
if ( inLayout )
return ;
RefreshHeight ( ) ;
}
private void ToggleExpandedState ( bool expand )
{
if ( IsExpanded = = expand )
return ;
IsExpanded = expand ;
dataGridViewEx1 . Visible = expand ;
RefreshHeight ( ) ;
RefreshChevron ( ) ;
if ( ExpandedChanged ! = null )
ExpandedChanged ( this ) ;
}
#endregion
public void Contract ( )
{
ToggleExpandedState ( false ) ;
}
public void Expand ( )
{
ValueColumn . MinimumWidth = 5 ;
2018-06-21 15:41:19 +02:00
HelpersGUI . ResizeGridViewColumnToAllCells ( ValueColumn ) ;
2013-06-24 13:41:48 +02:00
ToggleExpandedState ( true ) ;
}
2014-10-29 15:51:42 +01:00
private DataGridViewExRow CreateRow ( string Key , string Value )
2013-06-24 13:41:48 +02:00
{
if ( ! String . IsNullOrEmpty ( Key ) )
Key + = Messages . GENERAL_PAGE_KVP_SEPARATOR ;
DataGridViewExRow r = new DataGridViewExRow ( ) ;
r . CreateCells ( dataGridViewEx1 ) ;
r . Cells [ 0 ] . Value = Key ;
r . Cells [ 1 ] . Value = Value ;
2014-10-29 15:51:42 +01:00
return r ;
}
2013-06-24 13:41:48 +02:00
2013-12-22 18:33:13 +01:00
2021-06-16 00:58:30 +02:00
public void AddEntry ( string Key , string Value , params ToolStripMenuItem [ ] contextMenuItems )
2013-06-24 13:41:48 +02:00
{
2014-10-29 15:51:42 +01:00
var r = CreateRow ( Key , Value ) ;
2013-06-24 13:41:48 +02:00
r . Tag = contextMenuItems ;
AddRow ( r ) ;
}
2021-06-16 00:58:30 +02:00
public void AddEntry ( string Key , string Value , string toolTipText , params ToolStripMenuItem [ ] contextMenuItems )
2013-06-24 13:41:48 +02:00
{
AddEntry ( Key , Value , contextMenuItems ) ;
if ( toolTipText ! = Key )
dataGridViewEx1 . Rows [ dataGridViewEx1 . RowCount - 1 ] . Cells [ 0 ] . ToolTipText = toolTipText ;
}
public void AddEntry ( string Key , string Value , Color fontColor )
{
2014-10-29 15:51:42 +01:00
var r = CreateRow ( Key , Value ) ;
2013-06-24 13:41:48 +02:00
r . Cells [ 1 ] . Style . ForeColor = fontColor ;
AddRow ( r ) ;
dataGridViewEx1 . DefaultCellStyle = new DataGridViewCellStyle ( ) ;
}
2021-06-16 00:58:30 +02:00
public void AddEntry ( string Key , string Value , Color fontColor , params ToolStripMenuItem [ ] contextMenuItems )
2013-06-24 13:41:48 +02:00
{
2014-10-29 15:51:42 +01:00
var r = CreateRow ( Key , Value ) ;
2013-06-24 13:41:48 +02:00
r . Cells [ 1 ] . Style . ForeColor = fontColor ;
r . Tag = contextMenuItems ;
AddRow ( r ) ;
dataGridViewEx1 . DefaultCellStyle = new DataGridViewCellStyle ( ) ;
}
2021-06-16 00:58:30 +02:00
public void AddEntry ( string Key , FolderListItem Value , params ToolStripMenuItem [ ] contextMenuItems )
2013-06-24 13:41:48 +02:00
{
// Special case for folders: CA-33311
if ( ! String . IsNullOrEmpty ( Key ) )
Key + = Messages . GENERAL_PAGE_KVP_SEPARATOR ;
DataGridViewExRow r = new DataGridViewExRow ( ) ;
r . Cells . Add ( new DataGridViewTextBoxCell ( ) ) ;
r . Cells [ 0 ] . Value = Key ;
r . Cells . Add ( new FolderCell ( Value ) ) ;
r . Tag = contextMenuItems ;
AddRow ( r ) ;
}
2021-06-16 00:58:30 +02:00
public void AddEntry ( string Key , string Value , bool visible , params ToolStripMenuItem [ ] contextMenuItems )
{
var r = CreateRow ( Key , Value ) ;
r . Tag = contextMenuItems ;
r . Visible = visible ;
AddRow ( r ) ;
}
internal void AddEntryLink ( string Key , string Value , Command command , params ToolStripMenuItem [ ] contextMenuItems )
2013-06-24 13:41:48 +02:00
{
if ( ! String . IsNullOrEmpty ( Key ) )
Key + = Messages . GENERAL_PAGE_KVP_SEPARATOR ;
DataGridViewExRow r = new DataGridViewExRow ( ) ;
r . CreateCells ( dataGridViewEx1 ) ;
r . Cells [ 0 ] . Value = Key ;
r . Cells [ 1 ] = new DataGridViewLinkCell ( ) ;
r . Cells [ 1 ] . Value = Value ;
r . Cells [ 1 ] . Tag = command ;
r . Tag = contextMenuItems ;
AddRow ( r ) ;
}
2021-06-16 00:58:30 +02:00
internal void AddEntryLink ( string Key , string Value , Action action , params ToolStripMenuItem [ ] contextMenuItems )
2013-06-24 13:41:48 +02:00
{
if ( ! String . IsNullOrEmpty ( Key ) )
Key + = Messages . GENERAL_PAGE_KVP_SEPARATOR ;
DataGridViewExRow r = new DataGridViewExRow ( ) ;
r . CreateCells ( dataGridViewEx1 ) ;
r . Cells [ 0 ] . Value = Key ;
r . Cells [ 1 ] = new DataGridViewLinkCell ( ) ;
r . Cells [ 1 ] . Value = Value ;
r . Cells [ 1 ] . Tag = action ;
r . Tag = contextMenuItems ;
AddRow ( r ) ;
}
2014-10-29 15:51:42 +01:00
public void UpdateEntryValueWithKey ( string Key , string newValue , bool visible )
2013-06-24 13:41:48 +02:00
{
List < DataGridViewExRow > matchingRows = ( from DataGridViewExRow row in dataGridViewEx1 . Rows
where row . Cells [ 0 ] . Value . ToString ( ) . Contains ( Key )
select row ) . ToList ( ) ;
2014-10-29 15:51:42 +01:00
2013-06-24 13:41:48 +02:00
if ( matchingRows . Count ! = 1 | | matchingRows [ 0 ] . Cells . Count < 2 )
return ;
matchingRows [ 0 ] . Cells [ 1 ] . Value = newValue ;
2014-10-29 15:51:42 +01:00
if ( matchingRows [ 0 ] . Visible ! = visible )
{
matchingRows [ 0 ] . Visible = visible ;
RefreshHeight ( ) ;
}
2013-06-24 13:41:48 +02:00
}
internal void fixFirstColumnWidth ( int width )
{
dataGridViewEx1 . Columns [ 0 ] . Width = width ;
}
/// <summary>
/// Clears the rows in the data grid view. If performing a repaint, you can attempt to restore the previous selection with a call to RestoreSelection()
/// </summary>
public void ClearData ( )
{
if ( dataGridViewEx1 . SelectedRows . Count > 0 )
previousSelectionKey = dataGridViewEx1 . SelectedRows [ 0 ] . Cells [ 0 ] . Value . ToString ( ) ;
dataGridViewEx1 . Rows . Clear ( ) ;
}
/// <summary>
/// Restores selection to the row stored from the last ClearData() call
/// </summary>
public void RestoreSelection ( )
{
if ( string . IsNullOrEmpty ( previousSelectionKey ) )
return ;
foreach ( DataGridViewRow r in dataGridViewEx1 . Rows )
{
if ( r . Cells [ 0 ] . Value . ToString ( ) = = previousSelectionKey )
{
r . Cells [ 0 ] . Selected = true ;
return ;
}
}
}
public void PauseLayout ( )
{
inLayout = true ;
}
public void StartLayout ( )
{
inLayout = false ;
RefreshHeight ( ) ;
}
}
}