PageRenderTime 167ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/IZWebFileManager/FolderTree.cs

http://izwebfilemanager.googlecode.com/
C# | 979 lines | 780 code | 158 blank | 41 comment | 165 complexity | df908acd3774ed93c8e01f77c446d0a4 MD5 | raw file
  1. // Copyright (C) 2006 Igor Zelmanovich <izwebfilemanager@gmail.com>
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. using System;
  17. using System.Collections.Generic;
  18. using System.ComponentModel;
  19. using System.Text;
  20. using System.Web;
  21. using System.Web.UI;
  22. using System.Web.UI.WebControls;
  23. using System.Globalization;
  24. using IZ.WebFileManager.Components;
  25. using System.IO;
  26. using System.Drawing;
  27. using System.Collections.ObjectModel;
  28. using System.Collections.Specialized;
  29. using System.Collections;
  30. namespace IZ.WebFileManager
  31. {
  32. [SupportsEventValidation]
  33. [DefaultProperty ("Text")]
  34. [ToolboxData ("<{0}:FolderTree runat=\"server\"></{0}:FolderTree>")]
  35. public sealed class FolderTree : FileManagerControlBase, ICallbackEventHandler
  36. {
  37. #region Constructors
  38. public FolderTree ()
  39. : base () {
  40. InitTreeView ();
  41. }
  42. public FolderTree (FileManagerController controller)
  43. : base (controller) {
  44. InitTreeView ();
  45. }
  46. public FolderTree (FileManagerController controller, FileView fileFiew)
  47. : this (controller) {
  48. _fileView = fileFiew;
  49. }
  50. #endregion
  51. #region Fields
  52. FileView _fileView;
  53. bool stylesPrepared;
  54. Style hoverNodeStyle;
  55. TreeNodeStyle nodeStyle;
  56. TreeNodeStyle selectedNodeStyle;
  57. Collection<FolderNode> _nodes;
  58. Style controlLinkStyle;
  59. Style nodeLinkStyle;
  60. Style selectedNodeLinkStyle;
  61. Style hoverNodeLinkStyle;
  62. int _registeredStylesCounter = -1;
  63. Dictionary<Style, string> _registeredStyleClassNames;
  64. #endregion
  65. #region Events
  66. public EventHandler SelectedFolderChanged;
  67. #endregion
  68. #region Properties
  69. // TODO
  70. string SelectedPath {
  71. get { return null; }
  72. }
  73. [DefaultValue ("")]
  74. [Description ("The url of the image to show when a node can be collapsed.")]
  75. [UrlProperty]
  76. [Category ("Appearance")]
  77. string CollapseImageUrl {
  78. get {
  79. return (string) (ViewState ["CollapseImageUrl"] ?? String.Empty);
  80. }
  81. set {
  82. ViewState ["CollapseImageUrl"] = value;
  83. }
  84. }
  85. [DefaultValue ("")]
  86. [UrlProperty]
  87. [Description ("The url of the image to show when a node can be expanded.")]
  88. [Category ("Appearance")]
  89. string ExpandImageUrl {
  90. get {
  91. return (string) (ViewState ["ExpandImageUrl"] ?? String.Empty);
  92. }
  93. set {
  94. ViewState ["ExpandImageUrl"] = value;
  95. }
  96. }
  97. [PersistenceMode (PersistenceMode.InnerProperty)]
  98. [NotifyParentProperty (true)]
  99. [DefaultValue (null)]
  100. [Category ("Styles")]
  101. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  102. Style HoverNodeStyle {
  103. get {
  104. if (hoverNodeStyle == null) {
  105. hoverNodeStyle = new Style ();
  106. if (IsTrackingViewState)
  107. ((IStateManager) hoverNodeStyle).TrackViewState ();
  108. }
  109. return hoverNodeStyle;
  110. }
  111. }
  112. [DefaultValue (20)]
  113. int NodeIndent {
  114. get {
  115. return (int) (ViewState ["NodeIndent"] ?? 20);
  116. }
  117. set {
  118. ViewState ["NodeIndent"] = value;
  119. }
  120. }
  121. Collection<FolderNode> Nodes {
  122. get {
  123. if (_nodes == null) {
  124. _nodes = new Collection<FolderNode> ();
  125. }
  126. return _nodes;
  127. }
  128. }
  129. [PersistenceMode (PersistenceMode.InnerProperty)]
  130. [NotifyParentProperty (true)]
  131. [DefaultValue (null)]
  132. [Category ("Styles")]
  133. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  134. TreeNodeStyle NodeStyle {
  135. get {
  136. if (nodeStyle == null) {
  137. nodeStyle = new TreeNodeStyle ();
  138. if (IsTrackingViewState)
  139. ((IStateManager) nodeStyle).TrackViewState ();
  140. }
  141. return nodeStyle;
  142. }
  143. }
  144. [UrlProperty]
  145. [DefaultValue ("")]
  146. [Description ("The url of the image to show for leaf nodes.")]
  147. [Category ("Appearance")]
  148. string NoExpandImageUrl {
  149. get {
  150. return (string) (ViewState ["NoExpandImageUrl"] ?? String.Empty);
  151. }
  152. set {
  153. ViewState ["NoExpandImageUrl"] = value;
  154. }
  155. }
  156. char PathSeparator {
  157. get {
  158. return '/';
  159. }
  160. }
  161. string ClientScriptReference {
  162. get {
  163. if (_fileView != null)
  164. return FileManagerController.ClientScriptObjectNamePrefix + _fileView.ClientID + "_FolderTree";
  165. return FileManagerController.ClientScriptObjectNamePrefix + ClientID;
  166. }
  167. }
  168. [PersistenceMode (PersistenceMode.InnerProperty)]
  169. [NotifyParentProperty (true)]
  170. [DefaultValue (null)]
  171. [Category ("Styles")]
  172. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  173. TreeNodeStyle SelectedNodeStyle {
  174. get {
  175. if (selectedNodeStyle == null) {
  176. selectedNodeStyle = new TreeNodeStyle ();
  177. if (IsTrackingViewState)
  178. ((IStateManager) selectedNodeStyle).TrackViewState ();
  179. }
  180. return selectedNodeStyle;
  181. }
  182. }
  183. Style ControlLinkStyle {
  184. get {
  185. if (controlLinkStyle == null) {
  186. controlLinkStyle = new Style ();
  187. controlLinkStyle.Font.Underline = false;
  188. //controlLinkStyle.AlwaysRenderTextDecoration = true;
  189. }
  190. return controlLinkStyle;
  191. }
  192. }
  193. Style NodeLinkStyle {
  194. get {
  195. if (nodeLinkStyle == null) {
  196. nodeLinkStyle = new Style ();
  197. }
  198. return nodeLinkStyle;
  199. }
  200. }
  201. Style SelectedNodeLinkStyle {
  202. get {
  203. if (selectedNodeLinkStyle == null) {
  204. selectedNodeLinkStyle = new Style ();
  205. }
  206. return selectedNodeLinkStyle;
  207. }
  208. }
  209. Style HoverNodeLinkStyle {
  210. get {
  211. if (hoverNodeLinkStyle == null) {
  212. hoverNodeLinkStyle = new Style ();
  213. }
  214. return hoverNodeLinkStyle;
  215. }
  216. }
  217. [DefaultValue (false)]
  218. bool ShowLines {
  219. get {
  220. return (bool) (ViewState ["ShowLines"] ?? false);
  221. }
  222. set {
  223. ViewState ["ShowLines"] = value;
  224. }
  225. }
  226. protected override HtmlTextWriterTag TagKey {
  227. get { return HtmlTextWriterTag.Div; }
  228. }
  229. #endregion
  230. #region Methods
  231. protected override void AddAttributesToRender (HtmlTextWriter writer) {
  232. base.AddAttributesToRender (writer);
  233. writer.AddStyleAttribute (HtmlTextWriterStyle.Position, "relative");
  234. writer.AddStyleAttribute (HtmlTextWriterStyle.ZIndex, "20");
  235. writer.AddStyleAttribute (HtmlTextWriterStyle.Overflow, "auto");
  236. }
  237. void InitTreeView () {
  238. NodeStyle.HorizontalPadding = 4;
  239. NodeStyle.Height = 20;
  240. NodeStyle.ForeColor = Color.Black;
  241. NodeStyle.Font.Names = new string [] { "Tahoma", "Verdana", "Geneva", "Arial", "Helvetica", "sans-serif" };
  242. NodeStyle.Font.Size = FontUnit.Parse ("11px", null);
  243. HoverNodeStyle.Font.Underline = true;
  244. SelectedNodeStyle.Font.Underline = false;
  245. SelectedNodeStyle.ForeColor = Color.White;
  246. SelectedNodeStyle.BackColor = Color.FromArgb (0x316AC5);
  247. }
  248. void OnSelectedFolderChanged (object sender, EventArgs e) {
  249. if (SelectedFolderChanged != null)
  250. SelectedFolderChanged (this, EventArgs.Empty);
  251. }
  252. void OnFolderPopulate (FolderNode node) {
  253. Controller.EnsureDefaults ();
  254. DirectoryInfo directoryInfo = Controller.ResolveFileManagerItemInfo (node.ValuePath).Directory;
  255. if (!directoryInfo.Exists)
  256. return;
  257. DirectoryProvider provider = new DirectoryProvider (directoryInfo, SortMode.Name, SortDirection.Ascending);
  258. foreach (DirectoryInfo dir in provider.GetFileSystemInfos (DirectoryProvider.FileSystemInfosFilter.Directories)) {
  259. FileViewItem item = new FileViewItem (dir, this);
  260. if (!ShowHiddenFilesAndFolders && item.Hidden)
  261. continue;
  262. FolderNode treeNode = new FolderNode (this);
  263. node.ChildNodes.Add (treeNode);
  264. treeNode.Text = dir.Name;
  265. treeNode.Hidden = item.Hidden;
  266. treeNode.ImageUrl = Controller.GetFolderSmallImage (dir);
  267. if (_fileView != null)
  268. treeNode.NavigateUrl = "javascript:WFM_" + _fileView.ClientID + ".Navigate(\"" + treeNode.ValuePath + "\");";
  269. }
  270. }
  271. void BuildTree () {
  272. for (int i = 0; i < RootDirectories.Count; i++) {
  273. RootDirectory rootDir = RootDirectories [i];
  274. FolderNode treeNode = new FolderNode (this);
  275. Nodes.Add (treeNode);
  276. treeNode.ImageUrl = Controller.GetRootFolderSmallImage (rootDir);
  277. SetText (rootDir, treeNode, i);
  278. treeNode.Value = PathSeparator + rootDir.TextInternal;
  279. if (_fileView != null)
  280. treeNode.NavigateUrl = "javascript:WFM_" + _fileView.ClientID + ".Navigate(\"" + treeNode.ValuePath + "\");";
  281. }
  282. for (int i = 0; i < RootDirectories.Count; i++)
  283. ExpandRecursive (Nodes [i], RootDirectories [i].ExpandDepth);
  284. }
  285. void SetText (RootDirectory rootDir, FolderNode treeNode, int index) {
  286. if (rootDir.ShowRootIndex)
  287. treeNode.Text = String.Format (CultureInfo.InvariantCulture, "{0} ([{1}])", rootDir.TextInternal, index);
  288. else
  289. treeNode.Text = rootDir.TextInternal;
  290. }
  291. void ExpandRecursive (FolderNode treeNode, int dept) {
  292. if (dept == 0)
  293. return;
  294. treeNode.Expand ();
  295. foreach (FolderNode child in treeNode.ChildNodes)
  296. ExpandRecursive (child, dept - 1);
  297. }
  298. #endregion
  299. protected override void TrackViewState () {
  300. base.TrackViewState ();
  301. if (hoverNodeStyle != null) {
  302. ((IStateManager) hoverNodeStyle).TrackViewState ();
  303. }
  304. if (nodeStyle != null) {
  305. ((IStateManager) nodeStyle).TrackViewState ();
  306. }
  307. if (selectedNodeStyle != null) {
  308. ((IStateManager) selectedNodeStyle).TrackViewState ();
  309. }
  310. }
  311. protected override object SaveViewState () {
  312. object [] states = new object [4];
  313. states [0] = base.SaveViewState ();
  314. states [1] = (hoverNodeStyle == null ? null : ((IStateManager) hoverNodeStyle).SaveViewState ());
  315. states [2] = (nodeStyle == null ? null : ((IStateManager) nodeStyle).SaveViewState ());
  316. states [3] = (selectedNodeStyle == null ? null : ((IStateManager) selectedNodeStyle).SaveViewState ());
  317. for (int i = states.Length - 1; i >= 0; i--) {
  318. if (states [i] != null)
  319. return states;
  320. }
  321. return null;
  322. }
  323. protected override void LoadViewState (object savedState) {
  324. if (savedState == null)
  325. return;
  326. object [] states = (object []) savedState;
  327. base.LoadViewState (states [0]);
  328. if (states [1] != null)
  329. ((IStateManager) HoverNodeStyle).LoadViewState (states [1]);
  330. if (states [2] != null)
  331. ((IStateManager) NodeStyle).LoadViewState (states [2]);
  332. if (states [3] != null)
  333. ((IStateManager) SelectedNodeStyle).LoadViewState (states [3]);
  334. }
  335. string callbackResult;
  336. void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs) {
  337. int index = eventArgs.IndexOf ('|');
  338. FolderNode node = new FolderNode (this);
  339. node.ValuePath = eventArgs.Substring (index + 1);
  340. node.Expand ();
  341. int num = node.ChildNodes.Count;
  342. if (num == 0) {
  343. callbackResult = "*";
  344. return;
  345. }
  346. ArrayList levelLines = new ArrayList ();
  347. for (int i = 0; i < index; i++)
  348. levelLines.Add (eventArgs [i] == '1' ? this : null);
  349. StringBuilder sb = new StringBuilder ();
  350. HtmlTextWriter writer = new HtmlTextWriter (new StringWriter (sb));
  351. EnsureStylesPrepared ();
  352. for (int n = 0; n < num; n++)
  353. RenderNode (writer, node.ChildNodes [n], index, levelLines, true, n < num - 1);
  354. callbackResult = sb.ToString ();
  355. }
  356. string ICallbackEventHandler.GetCallbackResult () {
  357. return callbackResult;
  358. }
  359. protected override ControlCollection CreateControlCollection () {
  360. return new EmptyControlCollection (this);
  361. }
  362. protected override void OnPreRender (EventArgs e) {
  363. base.OnPreRender (e);
  364. if (Page.Header == null)
  365. throw new InvalidOperationException ("Using FolderTree requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
  366. Page.ClientScript.RegisterClientScriptResource (typeof (FolderTree), "IZ.WebFileManager.resources.FolderTree.js");
  367. string callbackScript = string.Format ("FolderTree.prototype.PopulateNode = function(argument, clientCallback, context, clientErrorCallback) {{ {0}; }};\n", Page.ClientScript.GetCallbackEventReference ("this._uniqueId", "argument", "clientCallback", "context", "clientErrorCallback", true));
  368. Page.ClientScript.RegisterClientScriptBlock (typeof (FolderTree), "FolderTree.prototype.PopulateNode", callbackScript, true);
  369. string folderTree = ClientScriptReference;
  370. StringBuilder script = new StringBuilder ();
  371. script.AppendLine ("var " + folderTree + "= new FolderTree ('" + Controller.ClientID + "','" + ClientID + "','" + UniqueID + "','" + GetNodeImageUrl ("Expand") + "','" + GetNodeImageUrl ("Collapse") + "','" + GetNodeImageUrl ("NoExpand") + "');");
  372. EnsureStylesPrepared ();
  373. if (selectedNodeStyle != null) {
  374. script.AppendFormat ("{0}._selectedClass = '{1}';\n", folderTree, _registeredStyleClassNames [SelectedNodeStyle]);
  375. script.AppendFormat ("{0}._selectedLinkClass = '{1}';\n", folderTree, _registeredStyleClassNames [SelectedNodeLinkStyle]);
  376. }
  377. if (hoverNodeStyle != null) {
  378. script.AppendFormat ("{0}._hoverClass = '{1}';\n", folderTree, _registeredStyleClassNames [HoverNodeStyle]);
  379. script.AppendFormat ("{0}._hoverLinkClass = '{1}';\n", folderTree, _registeredStyleClassNames [HoverNodeLinkStyle]);
  380. }
  381. if (_fileView != null)
  382. script.AppendLine (folderTree + ".Navigate (['" + String.Join ("','", Controller.GetPathHashCodes (_fileView.CurrentDirectory.FileManagerPath)) + "'],0);");
  383. Page.ClientScript.RegisterStartupScript (typeof (FolderTree), this.ClientID, script.ToString (), true);
  384. BuildTree ();
  385. }
  386. void EnsureStylesPrepared () {
  387. if (stylesPrepared)
  388. return;
  389. stylesPrepared = true;
  390. PrepareStyles ();
  391. }
  392. private void PrepareStyles () {
  393. _registeredStyleClassNames = new Dictionary<Style, string> ();
  394. ControlLinkStyle.Font.CopyFrom (ControlStyle.Font);
  395. ControlLinkStyle.ForeColor = ControlStyle.ForeColor;
  396. RegisterStyle (ControlLinkStyle);
  397. if (nodeStyle != null)
  398. RegisterStyle (NodeStyle, NodeLinkStyle);
  399. if (selectedNodeStyle != null)
  400. RegisterStyle (SelectedNodeStyle, SelectedNodeLinkStyle);
  401. if (hoverNodeStyle != null)
  402. RegisterStyle (HoverNodeStyle, HoverNodeLinkStyle);
  403. }
  404. void RegisterStyle (Style baseStyle, Style linkStyle) {
  405. linkStyle.Font.CopyFrom (baseStyle.Font);
  406. linkStyle.ForeColor = baseStyle.ForeColor;
  407. linkStyle.BorderStyle = BorderStyle.None;
  408. baseStyle.Font.ClearDefaults ();
  409. RegisterStyle (linkStyle);
  410. RegisterStyle (baseStyle);
  411. }
  412. string IncrementStyleClassName () {
  413. _registeredStylesCounter++;
  414. return ClientID + "_" + _registeredStylesCounter;
  415. }
  416. void RegisterStyle (Style baseStyle) {
  417. string className = IncrementStyleClassName ();
  418. Page.Header.StyleSheet.CreateStyleRule (baseStyle, this, "." + className);
  419. _registeredStyleClassNames [baseStyle] = className;
  420. }
  421. string GetBindingKey (string dataMember, int depth) {
  422. return dataMember + " " + depth;
  423. }
  424. protected override void RenderContents (HtmlTextWriter writer) {
  425. int num = Nodes.Count;
  426. for (int n = 0; n < num; n++)
  427. RenderNode (writer, Nodes [n], 0, new ArrayList (), n > 0, n < num - 1);
  428. }
  429. void RenderNode (HtmlTextWriter writer, FolderNode node, int level, ArrayList levelLines, bool hasPrevious, bool hasNext) {
  430. string nodeImage;
  431. bool hasChildNodes = node.Expanded ? node.ChildNodes.Count > 0 : true;
  432. if (hasNext)
  433. levelLines.Add (this);
  434. else
  435. levelLines.Add (null);
  436. writer.AddAttribute ("cellpadding", "0", false);
  437. writer.AddAttribute ("cellspacing", "0", false);
  438. writer.AddStyleAttribute ("border-width", "0");
  439. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  440. Unit nodeSpacing = GetNodeSpacing (node);
  441. if (nodeSpacing != Unit.Empty && (node.Depth > 0 || node.Index > 0))
  442. RenderMenuItemSpacing (writer, nodeSpacing);
  443. writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  444. // Vertical lines from previous levels
  445. nodeImage = GetNodeImageUrl ("I");
  446. for (int n = 0; n < level; n++) {
  447. writer.RenderBeginTag (HtmlTextWriterTag.Td);
  448. writer.AddStyleAttribute ("width", NodeIndent + "px");
  449. //writer.AddStyleAttribute ("height", "1px");
  450. writer.RenderBeginTag (HtmlTextWriterTag.Div);
  451. if (ShowLines && levelLines [n] != null) {
  452. writer.AddAttribute ("src", nodeImage);
  453. writer.AddAttribute (HtmlTextWriterAttribute.Alt, "", false);
  454. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  455. writer.RenderEndTag ();
  456. }
  457. writer.RenderEndTag ();
  458. writer.RenderEndTag (); // TD
  459. }
  460. // Node image + line
  461. string shape = String.Empty;
  462. if (ShowLines) {
  463. if (hasPrevious && hasNext)
  464. shape = "T";
  465. else if (hasPrevious && !hasNext)
  466. shape = "L";
  467. else if (!hasPrevious && hasNext)
  468. shape = "R";
  469. else
  470. shape = "Dash";
  471. }
  472. if (hasChildNodes) {
  473. if (node.Expanded)
  474. shape += "Collapse";
  475. else
  476. shape += "Expand";
  477. }
  478. else if (!ShowLines)
  479. shape = "NoExpand";
  480. if (!String.IsNullOrEmpty (shape)) {
  481. nodeImage = GetNodeImageUrl (shape);
  482. writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
  483. writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent (node));
  484. writer.RenderBeginTag (HtmlTextWriterTag.A); // Anchor
  485. writer.AddAttribute ("alt", String.Empty);
  486. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "img"));
  487. writer.AddAttribute ("src", nodeImage);
  488. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
  489. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  490. writer.RenderEndTag ();
  491. writer.RenderEndTag (); // Anchor
  492. writer.RenderEndTag (); // TD
  493. }
  494. writer.RenderBeginTag (HtmlTextWriterTag.Td);
  495. writer.AddAttribute ("onmouseout", ClientScriptReference + ".UnhoverNode(this)", false);
  496. writer.AddAttribute ("onmouseover", ClientScriptReference + ".HoverNode(this, event)", false);
  497. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, null));
  498. writer.RenderBeginTag (HtmlTextWriterTag.Div);
  499. writer.AddAttribute ("cellpadding", "0", false);
  500. writer.AddAttribute ("cellspacing", "0", false);
  501. writer.AddStyleAttribute ("border-width", "0");
  502. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  503. writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  504. // Node icon
  505. string imageUrl = node.ImageUrl.Length > 0 ? ResolveClientUrl (node.ImageUrl) : null;
  506. if (!String.IsNullOrEmpty (imageUrl)) {
  507. if (node.Hidden)
  508. Controller.HiddenItemStyle.AddAttributesToRender (writer);
  509. writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
  510. BeginNodeTag (writer, node);
  511. writer.AddAttribute ("src", imageUrl);
  512. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
  513. writer.AddAttribute ("alt", String.Empty);
  514. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  515. writer.RenderEndTag (); // IMG
  516. writer.RenderEndTag (); // node tag
  517. writer.RenderEndTag (); // TD
  518. }
  519. writer.AddStyleAttribute ("white-space", "nowrap");
  520. AddNodeStyle (writer, node, level);
  521. writer.AddAttribute ("nodepath", GetNodePath (node, levelLines));
  522. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "node"));
  523. writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
  524. AddNodeLinkStyle (writer, node, level);
  525. BeginNodeTag (writer, node);
  526. writer.Write (node.Text);
  527. writer.RenderEndTag (); // node tag
  528. writer.RenderEndTag (); // TD
  529. writer.RenderEndTag (); // TR
  530. writer.RenderEndTag (); // TABLE
  531. writer.RenderEndTag (); // DIV
  532. writer.RenderEndTag (); // TD
  533. writer.RenderEndTag (); // TR
  534. if (nodeSpacing != Unit.Empty)
  535. RenderMenuItemSpacing (writer, nodeSpacing);
  536. writer.RenderEndTag (); // TABLE
  537. // Children
  538. if (!node.Expanded || node.ChildNodes.Count == 0)
  539. writer.AddStyleAttribute ("display", "none");
  540. else
  541. writer.AddStyleAttribute ("display", "block");
  542. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "span"));
  543. writer.RenderBeginTag (HtmlTextWriterTag.Span);
  544. if (node.Expanded) {
  545. //AddChildrenPadding (writer, node);
  546. int num = node.ChildNodes.Count;
  547. if (num == 0)
  548. writer.Write ("*");
  549. else
  550. for (int n = 0; n < num; n++)
  551. RenderNode (writer, node.ChildNodes [n], level + 1, levelLines, true, n < num - 1);
  552. //if (hasNext)
  553. // AddChildrenPadding (writer, node);
  554. }
  555. writer.RenderEndTag (); // SPAN
  556. levelLines.RemoveAt (level);
  557. }
  558. //private void AddChildrenPadding (HtmlTextWriter writer, FolderNode node) {
  559. // int level = node.Depth;
  560. // Unit cnp = Unit.Empty;
  561. // if (cnp.IsEmpty && nodeStyle != null)
  562. // cnp = nodeStyle.ChildNodesPadding;
  563. // double value;
  564. // if (cnp.IsEmpty || (value = cnp.Value) == 0 || cnp.Type != UnitType.Pixel)
  565. // return;
  566. // writer.RenderBeginTag (HtmlTextWriterTag.Table);
  567. // writer.AddAttribute ("height", ((int) value).ToString (), false);
  568. // writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  569. // writer.RenderBeginTag (HtmlTextWriterTag.Td);
  570. // writer.RenderEndTag (); // td
  571. // writer.RenderEndTag (); // tr
  572. // writer.RenderEndTag (); // table
  573. //}
  574. private void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing) {
  575. writer.AddStyleAttribute ("height", itemSpacing.ToString ());
  576. writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  577. writer.RenderBeginTag (HtmlTextWriterTag.Td);
  578. writer.RenderEndTag ();
  579. writer.RenderEndTag ();
  580. }
  581. private Unit GetNodeSpacing (FolderNode node) {
  582. if (node.Selected && selectedNodeStyle != null && selectedNodeStyle.NodeSpacing != Unit.Empty)
  583. return selectedNodeStyle.NodeSpacing;
  584. if (nodeStyle != null)
  585. return nodeStyle.NodeSpacing;
  586. else
  587. return Unit.Empty;
  588. }
  589. void AddNodeStyle (HtmlTextWriter writer, FolderNode node, int level) {
  590. StringBuilder sb = new StringBuilder ();
  591. if (nodeStyle != null) {
  592. sb.Append (" ");
  593. sb.Append (nodeStyle.CssClass);
  594. sb.Append (" ");
  595. sb.Append (_registeredStyleClassNames [nodeStyle]);
  596. }
  597. if (node.ValuePath == SelectedPath && selectedNodeStyle != null) {
  598. sb.Append (" ");
  599. sb.Append (selectedNodeStyle.CssClass);
  600. sb.Append (" ");
  601. sb.Append (_registeredStyleClassNames [selectedNodeStyle]);
  602. }
  603. writer.AddAttribute (HtmlTextWriterAttribute.Class, sb.ToString ());
  604. }
  605. void AddNodeLinkStyle (HtmlTextWriter writer, FolderNode node, int level) {
  606. StringBuilder sb = new StringBuilder ();
  607. sb.Append (" ");
  608. sb.Append (_registeredStyleClassNames [ControlLinkStyle]);
  609. if (nodeStyle != null) {
  610. sb.Append (" ");
  611. sb.Append (nodeLinkStyle.CssClass);
  612. sb.Append (" ");
  613. sb.Append (_registeredStyleClassNames [nodeLinkStyle]);
  614. }
  615. if (node.ValuePath == SelectedPath && selectedNodeStyle != null) {
  616. sb.Append (" ");
  617. sb.Append (selectedNodeLinkStyle.CssClass);
  618. sb.Append (" ");
  619. sb.Append (_registeredStyleClassNames [selectedNodeLinkStyle]);
  620. }
  621. writer.AddAttribute (HtmlTextWriterAttribute.Class, sb.ToString ());
  622. }
  623. void BeginNodeTag (HtmlTextWriter writer, FolderNode node) {
  624. if (node.ToolTip.Length > 0)
  625. writer.AddAttribute ("title", node.ToolTip);
  626. if (!String.IsNullOrEmpty (node.NavigateUrl)) {
  627. string navUrl = ResolveClientUrl (node.NavigateUrl);
  628. writer.AddAttribute ("href", navUrl);
  629. writer.RenderBeginTag (HtmlTextWriterTag.A);
  630. }
  631. else
  632. writer.RenderBeginTag (HtmlTextWriterTag.Span);
  633. }
  634. string GetNodeClientId (FolderNode node, string sufix) {
  635. return ClientID + "_" + node.ClientID + (sufix != null ? "_" + sufix : "");
  636. }
  637. string GetNodeImageUrl (string shape) {
  638. if (!ShowLines) {
  639. if (shape == "Expand") {
  640. if (!String.IsNullOrEmpty (ExpandImageUrl))
  641. return ResolveClientUrl (ExpandImageUrl);
  642. }
  643. else if (shape == "Collapse") {
  644. if (!String.IsNullOrEmpty (CollapseImageUrl))
  645. return ResolveClientUrl (CollapseImageUrl);
  646. }
  647. else if (shape == "NoExpand") {
  648. if (!String.IsNullOrEmpty (NoExpandImageUrl))
  649. return ResolveClientUrl (NoExpandImageUrl);
  650. }
  651. }
  652. return Page.ClientScript.GetWebResourceUrl (typeof (Page), "TreeView_Default_" + shape + ".gif");
  653. }
  654. string GetNodeIconUrl (string icon) {
  655. return Page.ClientScript.GetWebResourceUrl (typeof (TreeView), icon + ".gif");
  656. }
  657. string GetClientExpandEvent (FolderNode node) {
  658. return "javascript:" + ClientScriptReference + ".ToggleExpand (\"" + node.ClientID + "\")";
  659. }
  660. string GetNodePath (FolderNode node, ArrayList levelLines) {
  661. StringBuilder arg = new StringBuilder ();
  662. for (int i = 0; i < levelLines.Count; i++)
  663. if (levelLines [i] == null)
  664. arg.Append ('0');
  665. else
  666. arg.Append ('1');
  667. arg.Append ('|');
  668. arg.Append (node.ValuePath);
  669. return arg.ToString ();
  670. }
  671. sealed class FolderNode
  672. {
  673. Collection<FolderNode> _nodes;
  674. readonly FolderTree _owner;
  675. FolderNode _parent;
  676. int _index = -1;
  677. int _depth = -1;
  678. string _clientId;
  679. string _valuePath;
  680. string _imageUrl;
  681. string _navigateUrl;
  682. string _value;
  683. string _text;
  684. string _tooltip;
  685. bool _expanded;
  686. bool _selected;
  687. bool _hidden;
  688. public FolderNode (FolderTree owner) {
  689. _owner = owner;
  690. }
  691. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  692. [Browsable (false)]
  693. public int Depth {
  694. get {
  695. if (_depth != -1)
  696. return _depth;
  697. _depth = 0;
  698. FolderNode node = _parent;
  699. while (node != null) {
  700. _depth++;
  701. node = node.Parent;
  702. }
  703. return _depth;
  704. }
  705. }
  706. public Collection<FolderNode> ChildNodes {
  707. get {
  708. if (_nodes == null) {
  709. _nodes = new FolderNodeCollection (this);
  710. }
  711. return _nodes;
  712. }
  713. }
  714. public bool Expanded {
  715. get { return _expanded; }
  716. }
  717. public bool Hidden {
  718. get { return _hidden; }
  719. set { _hidden = value; }
  720. }
  721. public string ImageUrl {
  722. get { return _imageUrl ?? String.Empty; }
  723. set { _imageUrl = value; }
  724. }
  725. public string NavigateUrl {
  726. get { return _navigateUrl ?? String.Empty; }
  727. set { _navigateUrl = value; }
  728. }
  729. public string Text {
  730. get { return _text ?? (_value ?? String.Empty); }
  731. set { _text = value; }
  732. }
  733. public string ToolTip {
  734. get { return _tooltip ?? String.Empty; }
  735. set { _tooltip = value; }
  736. }
  737. public string Value {
  738. get { return _value ?? (_text ?? String.Empty); }
  739. set { _value = value; }
  740. }
  741. [DefaultValue (false)]
  742. public bool Selected {
  743. get { return _selected; }
  744. set { _selected = value; }
  745. }
  746. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  747. [Browsable (false)]
  748. public FolderNode Parent {
  749. get { return _parent; }
  750. }
  751. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  752. [Browsable (false)]
  753. public string ValuePath {
  754. get {
  755. if (_owner == null)
  756. return Value;
  757. if (_valuePath == null) {
  758. StringBuilder sb = new StringBuilder (Value);
  759. FolderNode node = Parent;
  760. if (node != null) {
  761. sb.Insert (0, _owner.PathSeparator);
  762. sb.Insert (0, node.ValuePath);
  763. node = node.Parent;
  764. }
  765. _valuePath = sb.ToString ();
  766. }
  767. return _valuePath;
  768. }
  769. set {
  770. _valuePath = value;
  771. }
  772. }
  773. internal int Index {
  774. get {
  775. if (_index < 0) {
  776. _index = 0;
  777. if (Parent != null)
  778. _index = Parent.ChildNodes.IndexOf (this);
  779. }
  780. return _index;
  781. }
  782. }
  783. internal void SetParent (FolderNode node) {
  784. _parent = node;
  785. _index = -1;
  786. _depth = -1;
  787. _clientId = null;
  788. _valuePath = null;
  789. }
  790. internal string ClientID {
  791. get {
  792. if (_clientId == null) {
  793. _clientId = _owner.Controller.GetPathHashCode (ValuePath);
  794. }
  795. return _clientId;
  796. }
  797. }
  798. public void Expand () {
  799. if (Expanded)
  800. return;
  801. _expanded = true;
  802. _owner.OnFolderPopulate (this);
  803. }
  804. }
  805. class FolderNodeCollection : Collection<FolderNode>
  806. {
  807. readonly FolderNode _owner;
  808. public FolderNodeCollection (FolderNode owner) {
  809. _owner = owner;
  810. }
  811. protected override void InsertItem (int index, FolderNode item) {
  812. base.InsertItem (index, item);
  813. item.SetParent (_owner);
  814. }
  815. protected override void SetItem (int index, FolderNode item) {
  816. base.SetItem (index, item);
  817. item.SetParent (_owner);
  818. }
  819. }
  820. }
  821. }