| 0: | // ExportProjectToHtmlDialog.cs | |
| 1: | // Copyright (C) 2001 Mike Krueger | |
| 2: | // | |
| 3: | // This program is free software; you can redistribute it and/or | |
| 4: | // modify it under the terms of the GNU General Public License | |
| 5: | // as published by the Free Software Foundation; either version 2 | |
| 6: | // of the License, or 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: | ||
| 17: | using System; | |
| 18: | using System.Drawing; | |
| 19: | using System.Collections; | |
| 20: | using System.Collections.Specialized; | |
| 21: | using System.ComponentModel; | |
| 22: | using System.Windows.Forms; | |
| 23: | using System.Data; | |
| 24: | using System.Threading; | |
| 25: | using System.IO; | |
| 26: | using SharpDevelop.Tool.Data; | |
| 27: | using SharpDevelop.Tool.Function; | |
| 28: | using SharpDevelop.Tool.Text; | |
| 29: | using SharpDevelop.Internal.Text; | |
| 30: | ||
| 31: | using SharpDevelop.Internal.Project; | |
| 32: | ||
| 33: | namespace SharpDevelop.Gui.Dialogs { | |
| 34: | ||
| 35: | public class ExportProjectToHtmlDialog : Form | |
| 36: | { | |
| 37: | TextBox path = new TextBox(); | |
| 38: | Label label1 = new Label(); | |
| 39: | Button okButton = new Button(); | |
| 40: | Button cancelButton = new Button(); | |
| 41: | Button browseButton = new Button(); | |
| 42: | ||
| 43: | ProgressBar progressBar = new ProgressBar(); | |
| 44: | ||
| 45: | IProject project; | |
| 46: | int filesExported = 0; | |
| 47: | ||
| 48: | int FilesExported { | |
| 49: | get { | |
| 50: | return filesExported; | |
| 51: | } | |
| 52: | set { | |
| 53: | progressBar.Value = filesExported = value; | |
| 54: | } | |
| 55: | } | |
| 56: | ||
| 57: | void StartExporting() | |
| 58: | { | |
| 59: | Controls.Clear(); | |
| 60: | ||
| 61: | progressBar.Location = new Point(8, 8); | |
| 62: | progressBar.Size = new Size(Width - 16, 16); | |
| 63: | progressBar.Minimum = 0; | |
| 64: | progressBar.Maximum = project.Files.Count; | |
| 65: | ||
| 66: | Controls.Add(progressBar); | |
| 67: | ||
| 68: | cancelButton = new Button(); | |
| 69: | cancelButton.Location = new Point(188 + 80, 36); | |
| 70: | cancelButton.Size = new Size(74, 23); | |
| 71: | cancelButton.Text = Resource.GetString("Global.CancelButtonText"); | |
| 72: | cancelButton.Click += new EventHandler(StopThread); | |
| 73: | Controls.Add(cancelButton); | |
| 74: | } | |
| 75: | public ExportProjectToHtmlDialog(IProject project) | |
| 76: | { | |
| 77: | this.project = project; | |
| 78: | ||
| 79: | label1.Location = new Point(8, 8); | |
| 80: | label1.Size = new Size(60,16); | |
| 81: | label1.Text = Resource.GetString("Dialog.ExportProjectToHtml.FolderLabel"); | |
| 82: | Controls.Add(label1); | |
| 83: | ||
| 84: | path.Location = new Point(70, 8); | |
| 85: | path.Size = new Size(230,16); | |
| 86: | Controls.Add(path); | |
| 87: | ||
| 88: | browseButton.Location = new Point(310, 8); | |
| 89: | browseButton.Size = new Size(32,23); | |
| 90: | browseButton.Text = "..."; | |
| 91: | browseButton.Click += new EventHandler(BrowseDirectories); | |
| 92: | Controls.Add(browseButton); | |
| 93: | ||
| 94: | okButton.Location = new Point(188, 36); | |
| 95: | okButton.Size = new Size(74, 23); | |
| 96: | okButton.Text = Resource.GetString("Global.OKButtonText"); | |
| 97: | okButton.Click += new EventHandler(ExportProject); | |
| 98: | Controls.Add(okButton); | |
| 99: | ||
| 100: | cancelButton.Location = new Point(188 + 80, 36); | |
| 101: | cancelButton.Size = new Size(74, 23); | |
| 102: | cancelButton.Text = Resource.GetString("Global.CancelButtonText"); | |
| 103: | cancelButton.DialogResult = DialogResult.Cancel; | |
| 104: | Controls.Add(cancelButton); | |
| 105: | ||
| 106: | Icon = null; | |
| 107: | FormBorderStyle = FormBorderStyle.FixedDialog; | |
| 108: | Size = new Size(350, 88); | |
| 109: | StartPosition = FormStartPosition.CenterParent; | |
| 110: | ShowInTaskbar = false; | |
| 111: | MinimizeBox = MaximizeBox = false; | |
| 112: | ||
| 113: | Text = Resource.GetString("Dialog.ExportProjectToHtml.DialogName"); | |
| 114: | ||
| 115: | } | |
| 116: | ||
| 117: | void BrowseDirectories(object sender, EventArgs e) | |
| 118: | { | |
| 119: | FolderDialog fd = new FolderDialog(); | |
| 120: | ||
| 121: | if(fd.DisplayDialog(Resource.GetString("Dialog.ExportProjectToHtml.SelectTargetDirInfo")) == DialogResult.OK) { | |
| 122: | path.Text = fd.Path; | |
| 123: | } | |
| 124: | } | |
| 125: | ||
| 126: | Hashtable projectTable = new Hashtable(); | |
| 127: | Hashtable bitmapTable = new Hashtable(); | |
| 128: | int bitmapIconIndex = 0; | |
| 129: | int indexFileIndex = 0; | |
| 130: | ||
| 131: | public Hashtable GetPath(string filename, Hashtable table, bool create) | |
| 132: | { | |
| 133: | string directory = Path.GetDirectoryName(filename); | |
| 134: | string[] treepath = directory.Split(new char[] { Path.DirectorySeparatorChar }); | |
| 135: | Hashtable curTable = table; | |
| 136: | ||
| 137: | foreach (string path in treepath) { | |
| 138: | if (path.Length == 0 || path[0] == '.') | |
| 139: | continue; | |
| 140: | ||
| 141: | object node = curTable[path]; | |
| 142: | ||
| 143: | if (node == null) { | |
| 144: | if (create) { | |
| 145: | Hashtable newTable = new Hashtable(); | |
| 146: | curTable[path] = newTable; | |
| 147: | curTable = newTable; | |
| 148: | continue; | |
| 149: | } else { | |
| 150: | return null; | |
| 151: | } | |
| 152: | } | |
| 153: | curTable = (Hashtable)node; | |
| 154: | } | |
| 155: | return curTable; | |
| 156: | } | |
| 157: | int GetImageIndex(string filename) | |
| 158: | { | |
| 159: | if (filename != null) { | |
| 160: | return FileUtility.GetImageIndexFor(filename); | |
| 161: | } | |
| 162: | return -1; | |
| 163: | } | |
| 164: | ||
| 165: | class Descriptor | |
| 166: | { | |
| 167: | public string title; | |
| 168: | public string url; | |
| 169: | public Descriptor(string title, string url) | |
| 170: | { | |
| 171: | this.title = title; | |
| 172: | this.url = url; | |
| 173: | } | |
| 174: | } | |
| 175: | ||
| 176: | StreamWriter curFileStream = null; | |
| 177: | Stack curIndexStreamStack = new Stack(); | |
| 178: | int curSpanNumber = 0; | |
| 179: | Hashtable Spans = new Hashtable(); | |
| 180: | ||
| 181: | string ExportFile(string fileName, string targetPath) | |
| 182: | { | |
| 183: | string targetFile = FileUtility.AbsoluteToRelativePath(project.BaseDirectory, fileName).Substring(2).Replace(Path.DirectorySeparatorChar.ToString(), "") + ".html"; | |
| 184: | ||
| 185: | TextBuffer buffer = new TextBuffer(); | |
| 186: | buffer.SetHighlightingFor(fileName); | |
| 187: | buffer.Load(fileName); | |
| 188: | ||
| 189: | curFileStream = File.CreateText(targetPath + Path.DirectorySeparatorChar + targetFile); | |
| 190: | curFileStream.Write("<html>\r\n"); | |
| 191: | curFileStream.Write("<head>\r\n"); | |
| 192: | curFileStream.Write("<link rel=\"stylesheet\" type=\"text/css\" href=\"sdcss.css\">\r\n"); | |
| 193: | curFileStream.Write("<title>" + Path.GetFileName(fileName) + "</title>\r\n"); | |
| 194: | curFileStream.Write("</head>\r\n"); | |
| 195: | curFileStream.Write("<body>\r\n"); | |
| 196: | ||
| 197: | curFileStream.Write("<div class=\"code\"><TABLE SUMMARY=\"SourceCode\" BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\">\r\n"); | |
| 198: | curFileStream.Write(" <TR BGCOLOR=\"#FFFFFF\">\r\n"); | |
| 199: | curFileStream.Write(" <TH WIDTH=\"50\" NOWRAP ALIGN=LEFT></TH>\r\n"); | |
| 200: | curFileStream.Write(" <TH WIDTH=\"1%\" NOWRAP ALIGN=LEFT></TH>\r\n"); | |
| 201: | curFileStream.Write(" <TH VALIGN=TOP ALIGN=LEFT> \r\n"); | |
| 202: | curFileStream.Write(" </TH>\r\n"); | |
| 203: | ||
| 204: | curFileStream.Write(" </TR>\r\n"); | |
| 205: | for (int i = 0; i < buffer.Length; ++i) { | |
| 206: | TextLine words = buffer[i]; | |
| 207: | curFileStream.Write(" <TR BGCOLOR=\"#FFFFFF\" VALIGN=TOP>\r\n"); | |
| 208: | curFileStream.Write(" <TD NOWRAP VALIGN=TOP ALIGN=RIGHT>" + i + ":</TD>\r\n"); | |
| 209: | curFileStream.Write(" <TD NOWRAP VALIGN=TOP ALIGN=LEFT> \r\n"); | |
| 210: | bool spanOpen = false; | |
| 211: | Color curColor = Color.Black; | |
| 212: | bool oldItalic = false; | |
| 213: | bool oldBold = false; | |
| 214: | bool firstSpan = true; | |
| 215: | for (int j = 0; j < words.Length; ++j) { | |
| 216: | switch (words[j].Type) { | |
| 217: | case TextWordType.Space: | |
| 218: | curFileStream.Write(" "); | |
| 219: | break; | |
| 220: | ||
| 221: | case TextWordType.Tab: | |
| 222: | for (int k = 0; k < buffer.BufferOptions.TabIndent; ++k) { | |
| 223: | curFileStream.Write(" "); | |
| 224: | } | |
| 225: | break; | |
| 226: | ||
| 227: | case TextWordType.Word: | |
| 228: | Color c = words[j].Color; | |
| 229: | string colorstr = c.R + ", " + c.G + ", " + c.B; | |
| 230: | ||
| 231: | if (words[j].Font.Italic) { | |
| 232: | colorstr = "i" + colorstr; | |
| 233: | } | |
| 234: | if (words[j].Font.Bold) { | |
| 235: | colorstr = "b" + colorstr; | |
| 236: | } | |
| 237: | if (Spans[colorstr] == null) { | |
| 238: | Spans[colorstr] = "span" + ++curSpanNumber; | |
| 239: | } | |
| 240: | bool newColor = c != curColor || oldItalic != words[j].Font.Italic || oldBold != words[j].Font.Bold; | |
| 241: | if (newColor) { | |
| 242: | if (!firstSpan) { | |
| 243: | curFileStream.Write("</span>" ); | |
| 244: | } | |
| 245: | ||
| 246: | curFileStream.Write("<span class=\"" + Spans[colorstr].ToString() + "\">" ); | |
| 247: | spanOpen = true; | |
| 248: | firstSpan = false; | |
| 249: | } | |
| 250: | curFileStream.Write(HtmlLize(words[j].Word)); | |
| 251: | ||
| 252: | if (newColor) { | |
| 253: | curColor = c; | |
| 254: | oldItalic = words[j].Font.Italic; | |
| 255: | oldBold = words[j].Font.Bold; | |
| 256: | } | |
| 257: | break; | |
| 258: | } | |
| 259: | } | |
| 260: | if (spanOpen) { | |
| 261: | curFileStream.Write("</span>" ); | |
| 262: | } | |
| 263: | curFileStream.Write("</TD>\r\n"); | |
| 264: | curFileStream.Write("</TR>\r\n"); | |
| 265: | } | |
| 266: | curFileStream.Write("</TABLE></div>\r\n"); | |
| 267: | ||
| 268: | ||
| 269: | curFileStream.Write("<P>\r\n"); | |
| 270: | curFileStream.Write("This page was automatically generated by \r\n"); | |
| 271: | curFileStream.Write("<A TARGET=\"_blank\" HREF=\"http://www.icsharpcode.net/OpenSource/SD\">SharpDevelop</A>.\r\n"); | |
| 272: | curFileStream.Write("</p>\r\n"); | |
| 273: | curFileStream.Write("</body>\r\n"); | |
| 274: | curFileStream.Write("</html>\r\n"); | |
| 275: | curFileStream.Close(); | |
| 276: | return targetFile; | |
| 277: | } | |
| 278: | ||
| 279: | string HtmlLize(string str) | |
| 280: | { | |
| 281: | return str.Replace("<", "<").Replace(">", ">").Replace("&", "&"); | |
| 282: | } | |
| 283: | ||
| 284: | void WriteIndexTable(string fileName, string name, ArrayList nameList, Hashtable table) | |
| 285: | { | |
| 286: | curIndexStreamStack.Push(File.CreateText(fileName)); | |
| 287: | StreamWriter curIndexStream = (StreamWriter)curIndexStreamStack.Peek(); | |
| 288: | ||
| 289: | curIndexStream.Write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n"); | |
| 290: | curIndexStream.Write("<html>\r\n"); | |
| 291: | curIndexStream.Write("<head>\r\n"); | |
| 292: | curIndexStream.Write("<title>" + project.Name + "</title>\r\n"); | |
| 293: | curIndexStream.Write("</head>\r\n"); | |
| 294: | ||
| 295: | curIndexStream.Write("<body>\r\n"); | |
| 296: | curIndexStream.Write("<p>Location : "); | |
| 297: | foreach (Descriptor d in nameList) { | |
| 298: | curIndexStream.Write("<a href=\""+ d.url + "\">" + d.title + "</a>/"); | |
| 299: | } | |
| 300: | curIndexStream.Write(name); | |
| 301: | curIndexStream.Write("</p>\r\n"); | |
| 302: | ||
| 303: | nameList.Add(new Descriptor(name, Path.GetFileName(fileName))); | |
| 304: | ||
| 305: | curIndexStream.Write("<TABLE SUMMARY=\"Directory\" BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\">\r\n"); | |
| 306: | curIndexStream.Write(" <TR BGCOLOR=\"#F38C00\">\r\n"); | |
| 307: | curIndexStream.Write(" <TH WIDTH=\"1%\"> </TH>\r\n"); | |
| 308: | curIndexStream.Write(" <TH WIDTH=\"1%\" NOWRAP ALIGN=LEFT>Name</TH>\r\n"); | |
| 309: | curIndexStream.Write(" <TH WIDTH=\"1%\" NOWRAP ALIGN=RIGHT>Size</TH>\r\n"); | |
| 310: | curIndexStream.Write(" <TH WIDTH=\"1%\" NOWRAP ALIGN=LEFT>Date</TH>\r\n"); | |
| 311: | curIndexStream.Write(" <TH VALIGN=TOP ALIGN=LEFT> \r\n"); | |
| 312: | curIndexStream.Write(" </TH>\r\n"); | |
| 313: | curIndexStream.Write(" </TR>\r\n"); | |
| 314: | ||
| 315: | bool coloring = false; | |
| 316: | foreach (DictionaryEntry entry in table) { | |
| 317: | if (entry.Value is Hashtable) { | |
| 318: | string filename = "index" + ++indexFileIndex + ".html"; | |
| 319: | WriteIndexTable(Path.GetDirectoryName(fileName) + Path.DirectorySeparatorChar + filename, entry.Key.ToString(), nameList, (Hashtable)entry.Value); | |
| 320: | nameList.RemoveAt(nameList.Count - 1); | |
| 321: | curIndexStream.Write(" <TR BGCOLOR=\"" + (coloring ? "#FFFFFF" : "#EEEEEE") + "\" VALIGN=TOP>\r\n"); | |
| 322: | curIndexStream.Write(" <TD NOWRAP VALIGN=TOP ALIGN=RIGHT><a href=\"" + filename + "\"><IMG ALIGN=ABSBOTTOM BORDER=0 WIDTH=16 HEIGHT=16 SRC=\"folderbitmap.png\"></a></TD>\r\n"); | |
| 323: | curIndexStream.Write(" <TD NOWRAP VALIGN=TOP ALIGN=LEFT><a href=\""+ filename + "\">" + entry.Key.ToString() + "</a> </TD>\r\n"); | |
| 324: | curIndexStream.Write(" <TD NOWRAP VALIGN=TOP ALIGN=RIGHT>-</TD>\r\n"); | |
| 325: | curIndexStream.Write(" <TD NOWRAP VALIGN=TOP ALIGN=RIGHT>-</TD>\r\n"); | |
| 326: |   |