using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Data;
using CMS.ExtendedControls;
using CMS.FormControls;
using CMS.GlobalHelper;
using CMS.SettingsProvider;
using CMS.UIControls;
using CMS.URLRewritingEngine;
public partial class CMSAdminControls_UI_Trees_UniTree : CMSUserControl, IPostBackEventHandler
{
#region "Variables"
private bool mEnableRootAction = true;
private bool mCollapseAll = false;
private bool mExpandAll = false;
private bool mUsePostBack = true;
private string mSelectedItem = null;
private string mExpandPath = string.Empty;
private string mSelectPath = string.Empty;
private string mNodeTemplate = "##ICON####NODENAME##";
private string mSelectedNodeTemplate = "##ICON####NODENAME##";
private string mDefaultItemTemplate = "##ICON####NODENAME##";
private string mSelectedDefaultItemTemplate = "##ICON####NODENAME##";
private UniTreeProvider mProviderObject = null;
private TreeNode mCustomRootNode = null;
private TreeNode mRootNode = null;
private bool mLocalize = false;
private bool mDisplayPopulatingindicator = true;
private string selectedPath = string.Empty;
private string mCollapseTooltip = null;
private string mExpandTooltip = null;
private string mLineImagesFolder = string.Empty;
private string mDefaultImagePath = string.Empty;
private int mExpandLevel = 0;
private ArrayList defaultItems = new ArrayList();
#endregion
#region "Public properties"
///
/// Gets or sets the value which indicates whether pupulating indicator should be displayed or not.
///
public bool DisplayPopulatingIndicator
{
get
{
return mDisplayPopulatingindicator;
}
set
{
mDisplayPopulatingindicator = value;
}
}
///
/// Indicates if the root element action should be None or Select.
///
public bool EnableRootAction
{
get
{
return mEnableRootAction;
}
set
{
mEnableRootAction = value;
}
}
///
/// Indicates if all nodes should be expanded.
///
public bool ExpandAll
{
get
{
return mExpandAll;
}
set
{
mExpandAll = value;
}
}
///
/// Indicates if all nodes should be collapsed.
///
public bool CollapseAll
{
get
{
return mCollapseAll;
}
set
{
mCollapseAll = value;
}
}
///
/// Gets or sets the ToolTip for the image that is displayed for the expandable node indicator.
///
public string ExpandTooltip
{
get
{
return mExpandTooltip;
}
set
{
mExpandTooltip = value;
treeElem.ExpandImageToolTip = value;
}
}
///
/// Gets or sets the ToolTip for the image that is displayed for the collapsible node indicator.
///
public string CollapseTooltip
{
get
{
return mCollapseTooltip;
}
set
{
treeElem.CollapseImageToolTip = value;
mCollapseTooltip = value;
}
}
///
/// Gets or sets the path to a folder that contains the line images that are used to connect child nodes to parent nodes.
///
public string LineImagesFolder
{
get
{
if (string.IsNullOrEmpty(mLineImagesFolder))
{
if ((IsLiveSite && CultureHelper.IsPreferredCultureRTL()) || (!IsLiveSite && CultureHelper.IsUICultureRTL()))
{
mLineImagesFolder = "~" + URLHelper.CurrentRelativePath + "?cmsimg=/rt"; // GetImageUrl("RTL/Design/Controls/Tree", IsLiveSite, true);
}
else
{
mLineImagesFolder = "~" + URLHelper.CurrentRelativePath + "?cmsimg=/t"; // GetImageUrl("Design/Controls/Tree", IsLiveSite, true);
}
}
return mLineImagesFolder;
}
set
{
mLineImagesFolder = value;
treeElem.LineImagesFolder = value;
}
}
///
/// Indicates number of expanded levels.
///
public int ExpandLevel
{
get
{
return mExpandLevel;
}
set
{
mExpandLevel = value;
}
}
///
/// Indicates if ##NODENAME## should be localized.
///
public bool Localize
{
get
{
return mLocalize;
}
set
{
mLocalize = value;
}
}
///
/// Gets ors sets the value which determines whether the tree will generate postbacks on node click.
///
public bool UsePostBack
{
get
{
return mUsePostBack;
}
set
{
mUsePostBack = value;
}
}
///
/// Gets or sets selected item.
///
public string SelectedItem
{
get
{
if (mSelectedItem == null)
{
mSelectedItem = hdnSelectedItem.Value;
}
return mSelectedItem;
}
set
{
hdnSelectedItem.Value = value;
mSelectedItem = value;
}
}
///
/// Gets the client ID of hidden field with selected item value.
///
public string SelectedItemFieldId
{
get
{
return hdnSelectedItem.ClientID;
}
}
///
/// Gets or sets expand path.
///
public string ExpandPath
{
get
{
return mExpandPath;
}
set
{
mExpandPath = value;
}
}
///
/// Gets or sets select path.
///
public string SelectPath
{
get
{
return mSelectPath;
}
set
{
mSelectPath = value;
}
}
///
/// Gets or sets node template. You can use following macros:
/// ##NODEID## (ID of item),##PARENTNODEID## (ID of parent), ##NODEJAVA## (encoded item name for using in javascript),
/// ##NODECHILDNODESCOUNT## (count of children of node), ##NODENAME## (name of item), ##ICON## (image), ##OBJECTTYPE## (object type).
///
public string NodeTemplate
{
get
{
return mNodeTemplate;
}
set
{
mNodeTemplate = value;
}
}
///
/// Gets or sets node template. You can use following macros:
/// ##NODEID## (ID of item), ##PARENTNODEID## (ID of parent), ##NODEJAVA## (encoded item name for using in javascript),
/// ##NODECHILDNODESCOUNT## (count of children of node), ##NODENAME## (name of item), ##ICON## (image), ##OBJECTTYPE## (object type).
///
public string SelectedNodeTemplate
{
get
{
return mSelectedNodeTemplate;
}
set
{
mSelectedNodeTemplate = value;
}
}
///
/// Gets or sets node template. You can use following macros:
/// ##NODEJAVA## (encoded item name for using in javascript),
/// ##NODENAME## (name of item), ##ICON## (image)
///
public string DefaultItemTemplate
{
get
{
return mDefaultItemTemplate;
}
set
{
mDefaultItemTemplate = value;
}
}
///
/// Gets or sets node template. You can use following macros:
/// ##NODEJAVA## (encoded item name for using in javascript),
/// ##NODENAME## (name of item), ##ICON## (image)
///
public string SelectedDefaultItemTemplate
{
get
{
return mSelectedDefaultItemTemplate;
}
set
{
mSelectedDefaultItemTemplate = value;
}
}
///
/// Gets or sets TreeProvider object.
///
public UniTreeProvider ProviderObject
{
get
{
return mProviderObject;
}
set
{
mProviderObject = value;
}
}
///
/// Gets or sets default image path.
///
public string DefaultImagePath
{
get
{
return mDefaultImagePath;
}
set
{
mDefaultImagePath = value;
}
}
///
/// Gets custom root node.
///
public TreeNode CustomRootNode
{
get
{
return mCustomRootNode;
}
}
///
/// Gets root node from provider object.
///
public TreeNode RootNode
{
get
{
if (mRootNode == null)
{
return CustomRootNode;
}
return mRootNode;
}
}
#endregion
#region "Custom events"
///
/// Image delegate.
///
public delegate string GetImageEventHandler(UniTreeNode node);
///
/// Gets image Url.
///
public event GetImageEventHandler OnGetImage;
///
/// On selected item event handler.
///
public delegate void ItemSelectedEventHandler(string selectedValue);
///
/// On selected item event handler.
///
public event ItemSelectedEventHandler OnItemSelected;
///
/// Node created delegate.
///
public delegate TreeNode NodeCreatedEventHandler(DataRow itemData, TreeNode defaultNode);
///
/// Node created event handler.
///
public event NodeCreatedEventHandler OnNodeCreated;
#endregion
#region "Events"
///
/// Page load event.
///
/// Sender
/// Arguments
protected void Page_Load(object sender, EventArgs e)
{
mCollapseTooltip = GetString("general.collapse");
mExpandTooltip = GetString("general.expand");
treeElem.ExpandImageToolTip = ExpandTooltip;
treeElem.CollapseImageToolTip = CollapseTooltip;
treeElem.LineImagesFolder = LineImagesFolder;
btnItemSelected.Style.Add("display", "none");
}
///
/// Tree populate.
///
/// Sender
/// Arguments
protected void treeElem_TreeNodePopulate(object sender, TreeNodeEventArgs e)
{
OnNodePopulate(e.Node);
}
///
/// Page PreRender.
///
/// Arguments
protected override void OnPreRender(EventArgs e)
{
int index = 0;
foreach (object item in defaultItems)
{
string[] defaultItem = (string[])item;
if (defaultItem != null)
{
// Generate link HTML tag
string link = null;
string selectedItem = ValidationHelper.GetString(SelectedItem, "").ToLowerCSafe();
if (selectedItem == defaultItem[2].ToLowerCSafe())
{
link = ReplaceMacros(SelectedDefaultItemTemplate, 0, 0, defaultItem[0], defaultItem[1], 0, "", "");
}
else
{
link = ReplaceMacros(DefaultItemTemplate, 0, 0, defaultItem[0], defaultItem[1], 0, "", "");
}
// Add complete HTML code to page
if (UsePostBack)
{
link = "" + link + "";
}
TreeNode tn = new TreeNode();
tn.Text = link;
tn.NavigateUrl = URLRewriter.CurrentURL + "#";
treeElem.Nodes.AddAt(index, tn);
index++;
}
}
if (DisplayPopulatingIndicator && !Page.IsCallback)
{
// Register tree progress icon
ScriptHelper.RegisterTreeProgress(Page);
}
base.OnPreRender(e);
}
#endregion
#region "Methods"
///
/// Adds default item to control (link over the tree).
///
/// Item name
/// Value
/// Image path
public void AddDefaultItem(string itemName, string value, string imagePath)
{
string imgTag = "";
// Generate image HTML tag
if (!string.IsNullOrEmpty(imagePath))
{
imgTag = "
";
}
// Insert default item to arraylist
string[] defaultItem = new string[3];
defaultItem[0] = HTMLHelper.HTMLEncode(ResHelper.LocalizeString(itemName));
defaultItem[1] = imgTag;
defaultItem[2] = value;
defaultItems.Add(defaultItem);
}
///
/// Adds root node (allows customization of the root item).
///
/// Root text
/// Root value
/// Image path
public void SetRoot(string rootText, string value, string imagePath)
{
mCustomRootNode = new TreeNode(rootText, value, imagePath);
}
///
/// Adds root node (allows customization of the root item).
///
/// Root text
/// Root value
/// Image path
/// Navigate URL
/// Target
public void SetRoot(string rootText, string value, string imagePath, string navigateUrl, string target)
{
mCustomRootNode = new TreeNode(rootText, value, imagePath, navigateUrl, target);
}
///
/// Reloads data.
///
public void ReloadData()
{
if (!StopProcessing && (ProviderObject != null))
{
treeElem.Nodes.Clear();
treeElem.EnableViewState = false;
// Add custom root node
if (mCustomRootNode != null)
{
if (!EnableRootAction)
{
mCustomRootNode.SelectAction = TreeNodeSelectAction.None;
}
treeElem.Nodes.Add(mCustomRootNode);
RaiseOnPopulateRootNode();
}
else
{
// Add root node from provider
if (ProviderObject.RootNode != null)
{
mRootNode = CreateNode((UniTreeNode)ProviderObject.RootNode);
treeElem.Nodes.Add(mRootNode);
}
}
}
}
///
/// Creates node.
///
/// Node to create
protected TreeNode CreateNode(UniTreeNode uniNode)
{
DataRow dr = (DataRow)uniNode.ItemData;
if (dr != null)
{
TreeNode node = new TreeNode();
// Get data
int childNodesCount = 0;
if (!string.IsNullOrEmpty(ProviderObject.ChildCountColumn))
{
childNodesCount = ValidationHelper.GetInteger(dr[ProviderObject.ChildCountColumn], 0);
}
// Node ID
int nodeID = 0;
if (!string.IsNullOrEmpty(ProviderObject.IDColumn))
{
nodeID = ValidationHelper.GetInteger(dr[ProviderObject.IDColumn], 0);
}
// Node value
string nodeValue = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.ValueColumn))
{
nodeValue = nodeID.ToString();
}
string objectType = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.ObjectTypeColumn))
{
objectType = ValidationHelper.GetString(dr[ProviderObject.ObjectTypeColumn], "");
// Add object type to value
nodeValue += "_" + objectType;
}
// Display name
string displayName = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.DisplayNameColumn))
{
displayName = HTMLHelper.HTMLEncode(ResHelper.LocalizeString(ValidationHelper.GetString(dr[ProviderObject.DisplayNameColumn], "")));
}
// Path
string nodePath = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.PathColumn))
{
nodePath = HTMLHelper.HTMLEncode(ValidationHelper.GetString(dr[ProviderObject.PathColumn], "")).ToLowerCSafe();
}
// Parent ID
int parentID = 0;
if (!string.IsNullOrEmpty(ProviderObject.ParentIDColumn))
{
parentID = ValidationHelper.GetInteger(dr[ProviderObject.ParentIDColumn], 0);
}
// Parameter
string parameter = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.ParameterColumn))
{
parameter = HTMLHelper.HTMLEncode(ValidationHelper.GetString(dr[ProviderObject.ParameterColumn], "")).ToLowerCSafe();
}
int nodeLevel = 0;
if (!String.IsNullOrEmpty(ProviderObject.LevelColumn))
{
nodeLevel = ValidationHelper.GetInteger(dr[ProviderObject.LevelColumn], 0);
}
node.NavigateUrl = URLRewriter.CurrentURL + "#";
// Set value
node.Value = nodeValue;
// Get image html tag
string imgPath = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.ImageColumn))
{
imgPath = ResolveUrl(ValidationHelper.GetString(dr[ProviderObject.ImageColumn], ""));
}
if (string.IsNullOrEmpty(imgPath))
{
imgPath = ResolveUrl(DefaultImagePath);
}
if (OnGetImage != null)
{
imgPath = ResolveUrl(OnGetImage(uniNode));
}
string imgTag = string.Empty;
if (!string.IsNullOrEmpty(imgPath))
{
imgTag = "
";
}
// Set text
string text = null;
string selectedItem = ValidationHelper.GetString(SelectedItem, "");
string selectPathLowered = SelectPath.ToLowerCSafe();
if (nodeValue.EqualsCSafe(selectedItem, true) || ((selectPathLowered == nodePath) && string.IsNullOrEmpty(selectedItem)))
{
text = ReplaceMacros(SelectedNodeTemplate, nodeID, childNodesCount, displayName, imgTag, parentID, objectType, parameter);
}
else
{
text = ReplaceMacros(NodeTemplate, nodeID, childNodesCount, displayName, imgTag, parentID, objectType, parameter);
}
if (UsePostBack)
{
text = "" + text + "";
}
node.Text = text;
// Set populate node automatically
if (childNodesCount != 0)
{
node.PopulateOnDemand = true;
}
// Expand tree
if (ExpandAll)
{
node.Expanded = true;
}
else if (CollapseAll)
{
node.Expanded = false;
}
else
{
// Handle expand path
if (!nodePath.EndsWith("/"))
{
nodePath += "/";
}
string expandPathLowered = ExpandPath.ToLowerCSafe();
// SelectPath property
if (selectPathLowered.StartsWithCSafe(nodePath) && (selectPathLowered != nodePath))
{
node.Expanded = true;
}
// ExpandPath property
else if ((expandPathLowered.StartsWithCSafe(nodePath)))
{
node.Expanded = true;
}
// Path expanded by user
else if (selectedPath.StartsWithCSafe(nodePath) && (selectedPath != nodePath))
{
node.Expanded = true;
}
else
{
node.Expanded = false;
}
}
// Expand level
if ((ExpandLevel != 0) && !CollapseAll)
{
node.Expanded = nodeLevel <= ExpandLevel;
}
return node;
}
return null;
}
///
/// Replaces all macros in template by values.
///
/// Template with macros
/// Item ID
/// Child count
/// Node name
/// Parent item ID
/// Icon
/// Object type
/// Additional parameter
public string ReplaceMacros(string template, int itemID, int childCount, string nodeName, string icon, int parentNodeID, string objectType, string parameter)
{
template = template.Replace("##NODEID##", itemID.ToString());
template = template.Replace("##NODEJAVA##", ScriptHelper.GetString(nodeName));
template = template.Replace("##NODECHILDNODESCOUNT##", childCount.ToString());
if (Localize)
{
template = template.Replace("##NODENAME##", ResHelper.LocalizeString(nodeName));
}
else
{
template = template.Replace("##NODENAME##", nodeName);
}
template = template.Replace("##ICON##", icon);
template = template.Replace("##PARENTNODEID##", parentNodeID.ToString());
template = template.Replace("##OBJECTTYPE##", objectType);
template = template.Replace("##PARAMETER##", parameter);
return template;
}
///
/// Returns javascript code raising postback and OnItemSelected event.
///
/// Postback parameter
public string GetOnSelectedItemBackEventReference()
{
return ControlsHelper.GetPostBackEventReference(btnItemSelected, null, false);
}
///
/// Handles simulated hidden button click and raises OnItemSelected event with value from hidden field.
///
protected void btnItemSelected_Click(object sender, EventArgs e)
{
RaiseOnItemSelected(hdnSelectedItem.Value);
}
///
/// Raises on selected item event.
///
/// Selected value
public void RaiseOnItemSelected(string selectedValue)
{
SelectedItem = selectedValue;
if (OnItemSelected != null)
{
OnItemSelected(selectedValue);
}
}
///
/// Populates root node.
///
public void RaiseOnPopulateRootNode()
{
TreeNode node = treeElem.Nodes[0];
if (node != null)
{
if (!string.IsNullOrEmpty(ExpandPath))
{
node.Expanded = true;
OnNodePopulate(node);
}
}
}
///
/// Handle node is populated.
///
private void OnNodePopulate(TreeNode node)
{
if ((ProviderObject != null) && (node != null))
{
string[] splitted = node.Value.Split('_');
int nodeID = ValidationHelper.GetInteger(splitted[0], 0);
// Get node object type
string nodeObjectType = string.Empty;
if (splitted.Length == 2)
{
nodeObjectType = splitted[1];
}
// Get child nodes
SiteMapNodeCollection childNodes = ProviderObject.GetChildNodes(node.Value, node.Depth + 1);
// Add to treeview
foreach (UniTreeNode childNode in childNodes)
{
// Get ID
int childNodeId = (int)(((DataRow)childNode.ItemData)[ProviderObject.IDColumn]);
// Get object type
string childNodeType = string.Empty;
if (!string.IsNullOrEmpty(ProviderObject.ObjectTypeColumn))
{
childNodeType = ValidationHelper.GetString((((DataRow)childNode.ItemData)[ProviderObject.ObjectTypeColumn]), "");
}
// Don't insert one object more than once
if ((childNodeId != nodeID) || (nodeObjectType != childNodeType))
{
TreeNode createdNode = CreateNode(childNode);
if (OnNodeCreated != null)
{
createdNode = OnNodeCreated((DataRow)childNode.ItemData, createdNode);
}
if (createdNode != null)
{
node.ChildNodes.Add(createdNode);
}
}
}
}
}
#endregion
#region "IPostBackEventHandler Members"
///
/// Raises event postback event.
///
public void RaisePostBackEvent(string eventArgument)
{
// Get argument
string arg = HttpUtility.HtmlDecode(eventArgument);
// Get value
string[] selectedItem = arg.Split(';');
string value = selectedItem[0];
// Get path
if (selectedItem.Length >= 2)
{
selectedPath = selectedItem[1].ToLowerCSafe();
}
// Raise event
RaiseOnItemSelected(value);
}
#endregion
}