using System;
using System.Collections.Generic;
using System.Text;
using Mullivan.Serialization;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace Mullivan.SharePoint.WebParts
{
[Guid("89f69852-4044-4979-8ccd-35f177b7b0b2")]
[XmlRoot(Namespace = "PagesNavigationWebPart")]
public class PagesNavigationWebPart : Microsoft.SharePoint.WebPartPages.WebPart
{
private Dictionary<string, NavLink> _mainLinks;
private string _errorMessage;
public PagesNavigationWebPart()
: base()
{
this.DisplayField = "Title";
}
public string DisplayField
{
get;
set;
}
public string ContentSourceField
{
get;
set;
}
protected override void OnLoad(EventArgs e)
{
_errorMessage = null;
try
{
_mainLinks = this.GetNavLinks();
}
catch (Exception ex)
{
_errorMessage = ex.ToString() + Environment.NewLine + Environment.NewLine;
_errorMessage += "Link Configuration" + Environment.NewLine;
}
base.OnLoad(e);
}
protected override void OnPreRender(EventArgs e)
{
ClientScriptManager csm = this.Page.ClientScript;
Type lnType = this.GetType();
//Register our Javascript file
if (!csm.IsClientScriptIncludeRegistered(@"Mullivan.SharePoint.WebParts.JS.LibraryNavigation.js"))
{
string url = csm.GetWebResourceUrl(lnType, @"Mullivan.SharePoint.WebParts.JS.LibraryNavigation.js");
csm.RegisterClientScriptInclude(lnType, "Mullivan.SharePoint.WebParts.JS.LibraryNavigation.js", ResolveClientUrl(url));
}
RegisterStyleSheet(ResolveUrl(csm.GetWebResourceUrl(lnType, @"Mullivan.SharePoint.WebParts.CSS.LibraryNavigation.css")));
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (!string.IsNullOrEmpty(_errorMessage))
{
writer.Write(HttpUtility.HtmlEncode(_errorMessage).Replace("\n", "<br/>"));
return;
}
ClientScriptManager csm = this.Page.ClientScript;
Type lnType = this.GetType();
StringBuilder sbSubMenus = new StringBuilder();
string libNavLeftUrl = ResolveUrl(csm.GetWebResourceUrl(lnType, "Mullivan.SharePoint.WebParts.Images.LibNav_Left.jpg"));
string libNavMidUrl = ResolveUrl(csm.GetWebResourceUrl(lnType, "Mullivan.SharePoint.WebParts.Images.LibNav_Mid.jpg"));
string libNavRightUrl = ResolveUrl(csm.GetWebResourceUrl(lnType, "Mullivan.SharePoint.WebParts.Images.LibNav_Right.jpg"));
string libNavOverUrl = ResolveUrl(csm.GetWebResourceUrl(lnType, "Mullivan.SharePoint.WebParts.Images.LibNav_Over.jpg"));
string libNavSubItemMidUrl = ResolveUrl(csm.GetWebResourceUrl(lnType, "Mullivan.SharePoint.WebParts.Images.LibNav_SubItem_Mid.jpg"));
string libNavSubItemOverUrl = ResolveUrl(csm.GetWebResourceUrl(lnType, "Mullivan.SharePoint.WebParts.Images.LibNav_SubItem_Over.jpg"));
RegisterPreloadImage("preload_libNavOver", libNavOverUrl);
RegisterPreloadImage("preload_libNavSubItemOver", libNavSubItemOverUrl);
writer.WriteLine("<div class=\"lnwp_Container\">");
writer.WriteLine("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
//create td with middle background image
writer.WriteLine(string.Format("<tr style=\"background-image:url('{0}')\">", libNavMidUrl));
writer.WriteLine("<td>");
writer.WriteLine(string.Format("<div class=\"lnwp_LeftImage\" style=\"background-image:url('{0}')\" />", libNavLeftUrl));
writer.WriteLine("</td>");
foreach (string key in _mainLinks.Keys)
{
NavLink navLink = _mainLinks[key];
string containerName = "LPNW_Container_" + Guid.NewGuid().ToString().Replace("-", "");
string menuName = "LPNW_Menu_" + Guid.NewGuid().ToString().Replace("-", "");
//Generate Title Text
writer.WriteLine(
string.Format(
"<td style=\"cursor:pointer\" onmouseover=\"LPNW_SwapImage(this, '{0}');LPNW_MenuShowMenu(this, '{2}', '{3}',0,-8,'{4}');\" onmouseout=\"LPNW_SwapImage(this, '{1}');LPNW_MenuStartTimeout(10);\">"
, libNavOverUrl
, libNavMidUrl
, containerName
, menuName
, navLink.Title
, navLink.Url));
AppendCenteredText(writer, " " + navLink.Title + " ");
writer.WriteLine("</td>");//Generate Title Text
writer.WriteLine("<td>");
AppendCenteredText(writer, "<span class=\"lnwp_Spacer\">|</span>");
writer.WriteLine("</td>");
sbSubMenus.AppendLine(string.Format("<div style=\"position:absolute;z-index:2;width:200px;display:none\" id=\"{0}\">", containerName));
sbSubMenus.AppendLine(string.Format("<table id=\"{0}\" class=\"lnwp_MenuTable\" onmouseout=\"LPNW_MenuStartTimeout(10);\" onmouseover=\"LPNW_MenuResetTimeout();\" cellpadding=\"0\" cellspacing=\"0\">"
, menuName));
if (string.IsNullOrEmpty(navLink.ErrorMessage))
{
foreach (NavLink subItem in navLink.SubLinks)
{
sbSubMenus.AppendLine(string.Format("<tr style=\"background-image:url('{0}')\" onmouseover=\"LPNW_SwapImage(this, '{1}');LPNW_MenuOverMenuItem('{2}');\" onmouseout=\"LPNW_SwapImage(this,'{0}');\" >"
, libNavSubItemMidUrl
, libNavSubItemOverUrl
, menuName));
sbSubMenus.AppendLine(string.Format("<td nowrap=\"nowrap\" style=\"padding-left:4px;text-align:left;vertical-align:middle;height:20px;cursor:pointer;\" onclick=\"LPNW_NavigateTo('{0}');\">", subItem.Url));
sbSubMenus.AppendLine(string.Format("<a href=\"{0}\">", subItem.Url));
sbSubMenus.AppendLine(subItem.Title);
sbSubMenus.AppendLine("</a>");
sbSubMenus.AppendLine("</td>");
sbSubMenus.AppendLine("</tr>");
}
}
else
{
sbSubMenus.AppendLine(string.Format("<tr style=\"background-color:white\" >"));
sbSubMenus.AppendLine(string.Format("<td style=\"color:red;padding-left:4px;text-align:left;vertical-align:top;\">"));
sbSubMenus.AppendLine(HttpUtility.HtmlEncode(navLink.ErrorMessage).Replace("\n", "<br/>"));
sbSubMenus.AppendLine("</td>");
sbSubMenus.AppendLine("</tr>");
}
sbSubMenus.AppendLine("</table>");
sbSubMenus.AppendLine("</div>");
}
//Generate Title Text
writer.WriteLine("<td width=\"99%\" class=\"lnwp_td_Title\">");
AppendCenteredText(writer, this.Title);
writer.WriteLine("</td>");
//create td with right background image
writer.WriteLine("<td>");
writer.WriteLine(string.Format("<div class=\"lnwp_RightImage\" style=\"background-image:url('{0}')\" />", libNavRightUrl));
writer.WriteLine("</td>");
writer.WriteLine("</tr>");
writer.WriteLine("</table>");
writer.Write(sbSubMenus.ToString());
writer.WriteLine("</div>");
base.Render(writer);
}
private void RegisterPreloadImage(string name, string libNavOverUrl)
{
ClientScriptManager csm = this.Page.ClientScript;
Type lnType = this.GetType();
string strPreLoad = @"
<script type=""text/javascript"">
var image = new Image();
image.src = '{0}';
</script>
";
strPreLoad = string.Format(strPreLoad, libNavOverUrl);
csm.RegisterStartupScript(lnType, name, strPreLoad);
}
private void AppendCenteredText(HtmlTextWriter writer, string html)
{
writer.WriteLine("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
writer.WriteLine("<tr>");
writer.WriteLine("<td nowrap=\"nowrap\" style=\"height:32px;vertical-align:middle;\">");
writer.WriteLine(html);
writer.WriteLine("</td>");
writer.WriteLine("</tr>");
writer.WriteLine("</table>");
}
private Dictionary<string, NavLink> GetNavLinks()
{
Dictionary<string, NavLink> navLinks = new Dictionary<string, NavLink>();
SPWeb web = SPContext.Current.Web;
string listName = "Pages";
SPList list = web.Lists[listName];
if (list == null)
throw new Exception(string.Format("List {0} could not be found.", listName));
//Set Defaults
if (string.IsNullOrEmpty(this.DisplayField))
this.DisplayField = "Title";
SPField spField = null;
if (!string.IsNullOrEmpty(this.ContentSourceField))
spField = list.Fields.GetFieldByInternalName(this.ContentSourceField);
else
{
foreach (SPField f in list.Fields)
{
if (f.Title.ToLower().Contains("content source"))
{
spField = f;
break;
}
}
}
if (spField == null)
throw new Exception("Content Source field could not be found.");
SPQuery query = new SPQuery();
query.ViewAttributes = "Scope=\"Recursive\"";
query.ViewFields = string.Format(
"<FieldRef Name=\"EncodedAbsUrl\" /><FieldRef Name=\"{0}\" /><FieldRef Name=\"{1}\" />"
, spField.InternalName, this.DisplayField);
query.Query = string.Format(@"<Where><IsNotNull><FieldRef Name='{0}' /></IsNotNull></Where>
<OrderBy><FieldRef Name='{0}' /><FieldRef Name='{1}' /></OrderBy>"
,spField.InternalName, this.DisplayField);
SPField displayField = list.Fields.GetField(this.DisplayField);
if (displayField == null)
displayField = list.Fields.GetFieldByInternalName(this.DisplayField);
SPListItemCollection items = list.GetItems(query);
foreach (SPListItem item in items)
{
NavLink subLink = new NavLink();
if (displayField != null)
{
object objDisplay = item[displayField.Id];
if (objDisplay != null)
subLink.Title = objDisplay.ToString();
else
subLink.Title = "[not set]";
}
else
subLink.Title = "Column not found";
subLink.Url = item["EncodedAbsUrl"].ToString();
string tabName = item[spField.InternalName].ToString();
if (navLinks.ContainsKey(tabName))
navLinks[tabName].SubLinks.Add(subLink);
else
{
NavLink tab = new NavLink();
tab.Title = tabName;
tab.SubLinks.Add(subLink);
navLinks.Add(tabName, tab);
}
}
return navLinks;
}
private void RegisterStyleSheet(string cssUrl)
{
HtmlHead header = FindControl<HtmlHead>(this.Page.Master.Controls);
if (header != null)
{
Literal literal = new Literal();
literal.Text = string.Format("<link href=\"{0}\" type=\"text/css\" rel=\"stylesheet\"/>", cssUrl);
header.Controls.Add(literal);
}
}
private T FindControl<T>(ControlCollection controlCollection)
where T : Control
{
foreach (Control c in controlCollection)
{
if (c.GetType() == typeof(T))
return (T)c;
else
{
T child = FindControl<T>(c.Controls);
if (child != null)
return child;
}
}
return null;
}
}
}