| 0: | // ProjectBrowser.cs | |
| 1: | // Copyright (C) 2000 Mike Krueger | |
| 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: | ||
| 17: | using System; | |
| 18: | using System.IO; | |
| 19: | using System.ComponentModel; | |
| 20: | using System.Windows.Forms; | |
| 21: | using System.Drawing; | |
| 22: | using System.Diagnostics; | |
| 23: | using System.Collections; | |
| 24: | using System.Xml; | |
| 25: | using System.Resources; | |
| 26: | ||
| 27: | using SharpDevelop.Internal.Project; | |
| 28: | using SharpDevelop.Tool.Function; | |
| 29: | using SharpDevelop.Tool.Data; | |
| 30: | using SharpDevelop.Gui.Window; | |
| 31: | using SharpDevelop.Gui.Dialogs; | |
| 32: | ||
| 33: | namespace SharpDevelop.Gui.Navigation.ProjectBrowser { | |
| 34: | ||
| 35: | /// <summary> | |
| 36: | /// This class is the project scout tree view | |
| 37: | /// </summary> | |
| 38: | public class ProjectBrowser : TreeView | |
| 39: | { | |
| 40: | Combine combine = null; | |
| 41: | MainWindow mainwindow = null; | |
| 42: | ||
| 43: | ProjectBrowserEventHandler eventhandler = null; | |
| 44: | ||
| 45: | string projectfilename = ""; | |
| 46: | ||
| 47: | public IProject CurrentProject { | |
| 48: | get { | |
| 49: | ProjectBrowserNode node = (ProjectBrowserNode)SelectedNode; | |
| 50: | if (node == null || node.Project == null) { | |
| 51: | if (combine == null) { | |
| 52: | return null; | |
| 53: | } | |
| 54: | return GetFirstProject(combine); | |
| 55: | } | |
| 56: | return node.Project; | |
| 57: | } | |
| 58: | } | |
| 59: | ||
| 60: | IProject GetFirstProject(Combine combine) | |
| 61: | { | |
| 62: | foreach (CombineEntry entry in combine.Entries) { | |
| 63: | if (entry is ProjectCombineEntry) { | |
| 64: | return ((ProjectCombineEntry)entry).Project; | |
| 65: | } else { | |
| 66: | return GetFirstProject(((CombineCombineEntry)entry).Combine); | |
| 67: | } | |
| 68: | } | |
| 69: | return null; | |
| 70: | } | |
| 71: | ||
| 72: | public Combine Combine { | |
| 73: | get { | |
| 74: | return combine; | |
| 75: | } | |
| 76: | } | |
| 77: | ||
| 78: | public ProjectBrowser(MainWindow mainwindow) | |
| 79: | { | |
| 80: | ||
| 81: | this.mainwindow = mainwindow; | |
| 82: | ||
| 83: | LabelEdit = true; | |
| 84: | // HotTracking = true; | |
| 85: | AllowDrop = true; | |
| 86: | HideSelection = false; | |
| 87: | ||
| 88: | InitImageList(); | |
| 89: | eventhandler = new ProjectBrowserEventHandler(mainwindow, this); | |
| 90: | } | |
| 91: | ||
| 92: | void InitImageList() | |
| 93: | { | |
| 94: | ImageList imglist = new ImageList(); | |
| 95: | ||
| 96: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.CombineIcon")); | |
| 97: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.ClosedFolderBitmap")); | |
| 98: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.OpenFolderBitmap")); | |
| 99: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.ClosedReferenceFolder")); | |
| 100: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.OpenReferenceFolder")); | |
| 101: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.ClosedResourceFolder")); | |
| 102: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.OpenResourceFolder")); | |
| 103: | imglist.Images.Add(Resource.GetBitmap("Icons.16x16.Reference")); | |
| 104: | ||
| 105: | foreach (Image img in FileUtility.ImageList.Images) | |
| 106: | imglist.Images.Add(img); | |
| 107: | ||
| 108: | ImageList = imglist; | |
| 109: | } | |
| 110: | ||
| 111: | ProjectBrowserNode GetNodeFromCollection(TreeNodeCollection collection, string title) | |
| 112: | { | |
| 113: | foreach (ProjectBrowserNode node in collection) | |
| 114: | if (node.Name == title) | |
| 115: | return node; | |
| 116: | return null; | |
| 117: | } | |
| 118: | ||
| 119: | ProjectBrowserNode GetNodeFromCollectionTreeByFileName(TreeNodeCollection collection, string fileName) | |
| 120: | { | |
| 121: | foreach (ProjectBrowserNode node in collection) { | |
| 122: | if (node.FileName == fileName) | |
| 123: | return node; | |
| 124: | ProjectBrowserNode childnode = GetNodeFromCollectionTreeByFileName(node.Nodes, fileName); | |
| 125: | if (childnode != null) | |
| 126: | return childnode; | |
| 127: | } | |
| 128: | return null; | |
| 129: | } | |
| 130: | ||
| 131: | void ConvertTreeToProject(ProjectBrowserNode node) | |
| 132: | { | |
| 133: | FileInformation finfo = null; | |
| 134: | ||
| 135: | switch (node.ProjectNodeType) { | |
| 136: | ||
| 137: | case ProjectNodeType.Combine: | |
| 138: | goto default; | |
| 139: | ||
| 140: | case ProjectNodeType.Project: | |
| 141: | node.Project.Files.Clear(); | |
| 142: | node.Project.Directories.Clear(); | |
| 143: | node.Project.References.Clear(); | |
| 144: | foreach (string file in node.ExcludeFiles) { | |
| 145: | node.Project.Files.Add(new FileInformation(file, BuildAction.Exclude)); | |
| 146: | } | |
| 147: | goto default; | |
| 148: | ||
| 149: | case ProjectNodeType.Reference: | |
| 150: | node.Project.References.Add(new ReferenceInformation(ReferenceType.Assembly, node.FileName)); | |
| 151: | break; | |
| 152: | ||
| 153: | case ProjectNodeType.ResourceFile: | |
| 154: | // if (!node.Project.IsFileInProject(node.FileName)) { | |
| 155: | finfo = new FileInformation(node.FileName); | |
| 156: | finfo.BuildAction = BuildAction.EmbedAsResource; | |
| 157: | node.Project.Files.Add(finfo); | |
| 158: | // } | |
| 159: | break; | |
| 160: | ||
| 161: | case ProjectNodeType.TextFile: | |
| 162: | // if (!node.Project.IsFileInProject(node.FileName)) { | |
| 163: | finfo = new FileInformation(node.FileName); | |
| 164: | if (node.FileInformation != null) { | |
| 165: | finfo.BuildAction = node.FileInformation.BuildAction; | |
| 166: | } else { | |
| 167: | finfo.BuildAction = node.BuildAction; | |
| 168: | } | |
| 169: | node.FileInformation = finfo; | |
| 170: | node.Project.Files.Add(finfo); | |
| 171: | // } | |
| 172: | break; | |
| 173: | ||
| 174: | default: | |
| 175: | if (node.Nodes.Count == 0 && node.ProjectNodeType == ProjectNodeType.Folder) | |
| 176: | node.Project.Directories.Add(node.FileName); | |
| 177: | else | |
| 178: | foreach (ProjectBrowserNode childnode in node.Nodes) | |
| 179: | ConvertTreeToProject(childnode); | |
| 180: | break; | |
| 181: | } | |
| 182: | } | |
| 183: | ||
| 184: | public ProjectBrowserNode GetPath(string filename, ProjectBrowserNode root, bool create) | |
| 185: | { | |
| 186: | string directory = Path.GetDirectoryName(filename); | |
| 187: | string[] treepath = directory.Split(new char[] { Path.DirectorySeparatorChar }); | |
| 188: | ProjectBrowserNode curpathnode = root; | |
| 189: | ||
| 190: | foreach (string path in treepath) { | |
| 191: | if (path.Length == 0 || path[0] == '.') | |
| 192: | continue; | |
| 193: | ProjectBrowserNode node = GetNodeFromCollection(curpathnode.Nodes, path); | |
| 194: | if (node == null) { | |
| 195: | if (create) { | |
| 196: | ProjectBrowserNode newnode = new ProjectBrowserNode(curpathnode.Project, ProjectNodeType.Folder, path); | |
| 197: | curpathnode.Nodes.Add(newnode); | |
| 198: | curpathnode = newnode; | |
| 199: | continue; | |
| 200: | } else { | |
| 201: | return null; | |
| 202: | } | |
| 203: | } | |
| 204: | curpathnode = node; | |
| 205: | } | |
| 206: | return curpathnode; | |
| 207: | } | |
| 208: | ||
| 209: | public void AddProjectTree(object obj, TreeNodeCollection parent) | |
| 210: | { | |
| 211: | if (obj is IProject) { | |
| 212: | IProject project = (IProject)obj; | |
| 213: | ProjectBrowserNode projectnode = new ProjectBrowserNode(project, ProjectNodeType.Project, project.Name); | |
| 214: | ProjectBrowserNode resfilenode = new ProjectBrowserNode(project, ProjectNodeType.ResourceFolder, Resource.GetString("ProjectComponent.ResourceFilesString")); | |
| 215: | ProjectBrowserNode referencefilenode = new ProjectBrowserNode(project, ProjectNodeType.ReferenceFolder, Resource.GetString("ProjectComponent.ReferencesString")); | |
| 216: | ||
| 217: | projectnode.Nodes.Add(resfilenode); | |
| 218: | projectnode.Nodes.Add(referencefilenode); | |
| 219: | ||
| 220: | for (int i = 0; i < project.Directories.Count; ++i) { | |
| 221: | string relativefile = FileUtility.AbsoluteToRelativePath(project.BaseDirectory, project.Directories[i].ToString()); | |
| 222: | string filename = Path.GetFileName(project.Directories[i].ToString()); | |
| 223: | ProjectBrowserNode curpathnode = GetPath(relativefile, projectnode, true); | |
| 224: | curpathnode.Nodes.Add(new ProjectBrowserNode(project, ProjectNodeType.Folder, filename)); | |
| 225: | } | |
| 226: | ||
| 227: | for (int i = 0; i < project.Files.Count; ++i) { | |
| 228: | FileInformation finfo = (FileInformation)project.Files[i]; | |
| 229: | string relativefile = FileUtility.AbsoluteToRelativePath(project.BaseDirectory, finfo.Name); | |
| 230: | string filename = Path.GetFileName(finfo.Name); | |
| 231: | switch (finfo.BuildAction) { | |
| 232: | case BuildAction.EmbedAsResource: | |
| 233: | resfilenode.Nodes.Add(new ProjectBrowserNode(project, ProjectNodeType.ResourceFile, filename)); | |
| 234: | break; | |
| 235: | case BuildAction.Exclude: | |
| 236: | projectnode.ExcludeFiles.Add(finfo.Name); | |
| 237: | break; | |
| 238: | default: | |
| 239: | ProjectBrowserNode curpathnode = GetPath(relativefile, projectnode, true); | |
| 240: | ||
| 241: | ProjectBrowserNode newNode = new ProjectBrowserNode(project, filename); | |
| 242: | newNode.FileInformation = finfo; | |
| 243: | ||
| 244: | curpathnode.Nodes.Add(newNode); | |
| 245: | break; | |
| 246: | } | |
| 247: | } | |
| 248: | ||
| 249: | for (int i = 0; i < project.References.Count; ++i) { | |
| 250: | ReferenceInformation refinfo = (ReferenceInformation)project.References[i]; | |
| 251: | ||
| 252: | string name = refinfo.ReferenceType == ReferenceType.Assembly ? refinfo.AssemblyName : refinfo.ProjectName; | |
| 253: | referencefilenode.Nodes.Add(new ProjectBrowserNode(project, ProjectNodeType.Reference, name)); | |
| 254: | } | |
| 255: | ||
| 256: | parent.Add(projectnode); | |
| 257: | } else { // object is combine | |
| 258: | // go through all combine members and insert them in the tree | |
| 259: | Combine c = (Combine)obj; | |
| 260: | ProjectBrowserNode pbn = new ProjectBrowserNode(c, ProjectNodeType.Combine, c.Name); | |
| 261: | parent.Add(pbn); | |
| 262: | foreach (CombineEntry entry in c.Entries) | |
| 263: | AddProjectTree(entry.Entry, pbn.Nodes); | |
| 264: | } | |
| 265: | } | |
| 266: | ||
| 267: | void PopulateTreeView() | |
| 268: | { | |
| 269: | Nodes.Clear(); | |
| 270: | ||
| 271: | if (combine == null) | |
| 272: | return; | |
| 273: | AddProjectTree(combine, Nodes); | |
| 274: | } | |
| 275: | ||
| 276: | public void NewProject() | |
| 277: | { | |
| 278: | projectfilename = null; | |
| 279: | mainwindow.Text = "SharpDevelop"; | |
| 280: | mainwindow.ClassBrowser.Nodes.Clear(); | |
| 281: | mainwindow.OpenTaskView.Items.Clear(); | |
| 282: | Nodes.Clear(); | |
| 283: | } | |
| 284: | ||
| 285: | void OpenCombine(string filename) | |
| 286: | { | |
| 287: | if (!FSTypeUtility.TestFileExists(filename)) | |
| 288: | return; | |
| 289: | ||
| 290: | projectfilename = filename; | |
| 291: | ||
| 292: | combine = new Combine(); | |
| 293: | combine.LoadCombine(filename); | |
| 294: | PopulateTreeView(); | |
| 295: | ||
| 296: | // TODO : Hope this works :) | |
| 297: | mainwindow.ClassBrowser.Parse(combine); | |
| 298: | ||
| 299: | mainwindow.ProjectMode = true; | |
| 300: | mainwindow.RecentOpen.AddLastProject(filename); | |
| 301: | ||
| 302: | CombinePreferences.RestoreCombinePreferences(mainwindow, combine, filename); | |
| 303: | ||
| 304: | IProject curPrj = CurrentProject; | |
| 305: | if (curPrj != null) { | |
| 306: | mainwindow.Text = curPrj.Name + " - SharpDevelop"; | |
| 307: | } | |
| 308: | ||
| 309: | mainwindow.OpenTaskView.Items.Clear(); | |
| 310: | } | |
| 311: | ||
| 312: | public void OpenProject(string filename) | |
| 313: | { | |
| 314: | if (mainwindow.ProjectMode) { | |
| 315: | SaveProject(); | |
| 316: | } | |
| 317: | BeginUpdate(); | |
| 318: | if (!FSTypeUtility.TestFileExists(filename)) | |
| 319: | return; | |
| 320: | projectfilename = filename; | |
| 321: | ||
| 322: | if (Path.GetExtension(filename).ToUpper() == ".PRJX") { | |
| 323: | string validcombine = Path.ChangeExtension(filename, ".cmbx"); | |
| 324: | if (File.Exists(validcombine)) { | |
| 325: | OpenCombine(validcombine); | |
| 326: | EndUpdate(); | |
| 327: | return; | |
| 328: | } else { | |
| 329: | combine = new Combine(); | |
| 330: | IProject project = (IProject)combine.AddEntry(filename); | |
| 331: | if (project == null) { | |
| 332: | NewProject(); | |
| 333: | EndUpdate(); | |
| 334: | return; | |
| 335: | } | |
| 336: | combine.Name = project.Name; | |
| 337: | combine.SaveCombine(validcombine); | |
| 338: | mainwindow.RecentOpen.AddLastProject(filename); | |
| 339: | projectfilename = validcombine; | |
| 340: | } | |
| 341: | } else { | |
| 342: |