Redid the tree again.
[Gitrdone.git] / UI / RepoTreeView.cs
blobddc2befd8145ecf8fb23fe2493588ad7dc318f23
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Text;
7 using System.Windows.Forms;
8 using System.IO;
9 using Git;
11 namespace Gitrdone
13 public partial class RepoTreeView : UserControl
15 ImageList m_imageList = new ImageList();
16 TreeNode m_rootNode;
17 protected Dictionary<string, string> m_expandedPaths = new Dictionary<string, string>();
18 protected int m_selectedTypes = -1;
19 Repo m_currentRepo;
20 protected Dictionary<string, Git.File> m_knownFiles = new Dictionary<string,Git.File>();
22 public RepoTreeView()
24 InitializeComponent();
25 m_workspaceTree.BeforeExpand += new TreeViewCancelEventHandler(OnBeforeExpand);
26 m_workspaceTree.AfterCollapse += new TreeViewEventHandler(OnAfterCollapse);
27 m_workspaceTree.ImageList = m_imageList;
28 m_workspaceTree.TreeViewNodeSorter = new Gitrdone.NodeSorter();
29 m_workspaceTree.FullRowSelect = true;
30 m_workspaceTree.AfterSelect += new TreeViewEventHandler(OnNodeSelected);
31 PopulateImageList();
34 void OnNodeSelected(object sender, TreeViewEventArgs e)
36 EnableModifyButtons(m_workspaceTree.SelectedNode != null);
39 protected void EnableModifyButtons(bool bEnable)
41 m_addFileButton.Enabled = bEnable;
42 m_removeFiles.Enabled = bEnable;
43 m_revertFiles.Enabled = bEnable;
46 void OnAfterCollapse(object sender, TreeViewEventArgs e)
48 if (Enabled)
50 m_expandedPaths.Remove((string)e.Node.Tag);
54 protected void PopulateImageList()
56 System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
57 System.Resources.ResourceManager m = new System.Resources.ResourceManager("Gitrdone.Properties.Resources", a);
58 Image im = (System.Drawing.Image)m.GetObject("folder");
59 m_imageList.Images.Add("folder", im);
61 im = (System.Drawing.Image)m.GetObject("page");
62 m_imageList.Images.Add("normal", im);
63 im = (System.Drawing.Image)m.GetObject("page_edit");
64 m_imageList.Images.Add("modified", im);
65 im = (System.Drawing.Image)m.GetObject("page_add");
66 m_imageList.Images.Add("added", im);
67 im = (System.Drawing.Image)m.GetObject("page_delete");
68 m_imageList.Images.Add("delete", im);
69 im = (System.Drawing.Image)m.GetObject("page_error");
70 m_imageList.Images.Add("unmerged", im);
71 im = (System.Drawing.Image)m.GetObject("disconnect");
72 m_imageList.Images.Add("unknown", im);
74 im = (System.Drawing.Image)m.GetObject("page_error");
75 m_imageList.Images.Add("broken", im);
76 im = (System.Drawing.Image)m.GetObject("page_lightning");
77 m_imageList.Images.Add("modechanged", im);
78 im = (System.Drawing.Image)m.GetObject("page_copy");
79 m_imageList.Images.Add("copied", im);
80 im = (System.Drawing.Image)m.GetObject("page_go");
81 m_imageList.Images.Add("renamed", im);
83 m_imageList.Images.Add("empty", new Bitmap(16, 16));
86 protected void SetNodeImage(TreeNode n, Git.File f)
88 switch (f.State)
90 case FileState.Normal:
91 n.ImageKey = "normal";
92 n.SelectedImageKey = "normal";
93 break;
94 case FileState.Deleted:
95 n.ImageKey = "delete";
96 n.SelectedImageKey = "delete";
97 break;
98 case FileState.Modified:
99 n.ImageKey = "modified";
100 n.SelectedImageKey = "modified";
101 break;
102 case FileState.Unknown:
103 n.ImageKey = "unknown";
104 n.SelectedImageKey = "unknown";
105 break;
106 case FileState.Unmerged:
107 n.ImageKey = "unmerged";
108 n.SelectedImageKey = "unmerged";
109 break;
110 case FileState.Added:
111 n.ImageKey = "added";
112 n.SelectedImageKey = "added";
113 break;
114 case FileState.Copied:
115 n.ImageKey = "copied";
116 n.SelectedImageKey = "copied";
117 break;
118 case FileState.ModeChanged:
119 n.ImageKey = "modechanged";
120 n.SelectedImageKey = "modechanged";
121 break;
122 case FileState.Broken:
123 n.ImageKey = "broken";
124 n.SelectedImageKey = "broken";
125 break;
126 case FileState.Renamed:
127 n.ImageKey = "renamed";
128 n.SelectedImageKey = "renamed";
129 break;
130 default:
131 n.ImageKey = "unknown";
132 n.SelectedImageKey = "unknown";
133 break;
138 protected void AddNewFileNode(TreeNode n, Git.File f)
140 if (((int)f.State & m_selectedTypes) != 0)
142 TreeNode subNode = n.Nodes.Add(f.Name, f.Name);
143 subNode.Tag = f;
144 SetNodeImage(subNode, f);
148 protected TreeNode AddNewDirNode(TreeNode n, string subpath, string tag)
150 TreeNode subNode = n.Nodes.Add(subpath, subpath);
151 subNode.ImageIndex = 0;
152 subNode.Tag = tag;
153 subNode.Nodes.Add(new TreeNode());
154 return subNode;
157 void OnBeforeExpand(object sender, TreeViewCancelEventArgs e)
159 m_workspaceTree.SelectedNode = e.Node;
160 string path = (string)e.Node.Tag;
161 if (Enabled && !m_expandedPaths.ContainsKey(path))
163 m_expandedPaths.Add((string)e.Node.Tag, null);
165 if (e.Node.FirstNode.Tag != null)
167 return;
169 e.Node.Nodes.Clear();
170 m_workspaceTree.BeginUpdate();
171 DirectoryInfo dir = new DirectoryInfo(m_currentRepo.Path + Repo.DirectorySeparator + path);
172 FileInfo[] files = dir.GetFiles();
173 DirectoryInfo[] subDirs = dir.GetDirectories();
174 foreach (DirectoryInfo subDir in subDirs)
176 string fullPath = subDir.Name;
177 if (!String.IsNullOrEmpty(path))
179 fullPath = path + Repo.DirectorySeparator + subDir.Name;
181 if (path.Length == 0 && fullPath == m_currentRepo.GitDir)
183 continue;
185 AddNewDirNode(e.Node, subDir.Name, fullPath);
188 foreach (FileInfo file in files)
190 string fullPath = file.Name;
191 if (!String.IsNullOrEmpty(path))
193 fullPath = path + Repo.DirectorySeparator + file.Name;
195 Git.File f;
196 if (!m_knownFiles.TryGetValue(fullPath, out f))
198 f = new Git.File("", fullPath);
199 f.State = FileState.Normal;
201 AddNewFileNode(e.Node, f);
203 if (e.Node.Nodes.Count == 0)
205 TreeNode n = new TreeNode();
206 n.ImageKey = "empty";
207 n.SelectedImageKey = null;
208 e.Node.Nodes.Add(n);
210 m_workspaceTree.EndUpdate();
213 public bool SetRepoTree(Repo repo)
215 m_currentRepo = repo;
216 m_workspaceTree.BeginUpdate();
217 m_workspaceTree.Nodes.Clear();
218 m_rootNode = new TreeNode("root");
219 m_rootNode.Tag = "";
220 m_rootNode.ImageIndex = 0;
221 m_workspaceTree.Nodes.Add(m_rootNode);
222 m_rootNode.Nodes.Add(new TreeNode());
223 m_knownFiles.Clear();
224 List<Git.File> unmanagedFiles = repo.ListFiles(true);
225 foreach (Git.File f in unmanagedFiles)
227 m_knownFiles.Add(f.RelativePath + Repo.DirectorySeparator + f.Name, f);
229 m_currentRepo.DiffIndex(m_knownFiles, "");
230 m_workspaceTree.EndUpdate();
231 m_treeStrip.Enabled = true;
232 return true;
235 protected void OnShowNormal(object sender, EventArgs e)
237 if (((ToolStripMenuItem)sender).Checked)
239 m_selectedTypes = m_selectedTypes | (int)Git.FileState.Normal;
241 else
243 m_selectedTypes = m_selectedTypes & (int)~Git.FileState.Normal;
245 OnRefreshTree(null, null);
248 protected void OnShowEdited(object sender, EventArgs e)
250 if (((ToolStripButton)sender).Checked)
252 m_selectedTypes = m_selectedTypes | (int)Git.FileState.Modified;
254 else
256 m_selectedTypes = m_selectedTypes & (int)~Git.FileState.Modified;
258 OnRefreshTree(null, null);
261 protected void OnShowDeleted(object sender, EventArgs e)
263 if (((ToolStripButton)sender).Checked)
265 m_selectedTypes = m_selectedTypes | (int)Git.FileState.Deleted;
267 else
269 m_selectedTypes = m_selectedTypes & (int)~Git.FileState.Deleted;
271 OnRefreshTree(null, null);
274 protected void OnShowOther(object sender, EventArgs e)
276 if (((ToolStripButton)sender).Checked)
278 m_selectedTypes = m_selectedTypes | (int)Git.FileState.Unknown;
280 else
282 m_selectedTypes = m_selectedTypes & (int)~Git.FileState.Unknown;
284 OnRefreshTree(null, null);
287 protected void OnShowUnmerged(object sender, EventArgs e)
289 if (((ToolStripButton)sender).Checked)
291 m_selectedTypes = m_selectedTypes | (int)Git.FileState.Unmerged;
293 else
295 m_selectedTypes = m_selectedTypes & (int)~Git.FileState.Unmerged;
297 OnRefreshTree(null, null);
300 protected void ExpandPath(string s)
302 string[] parts = s.Split(Repo.DirectorySeparator.ToCharArray());
303 TreeNode currentNode = m_rootNode;
304 m_rootNode.Expand();
305 foreach (string part in parts)
307 int idx = currentNode.Nodes.IndexOfKey(part);
308 if (idx > -1)
310 currentNode = currentNode.Nodes[idx];
311 currentNode.Expand();
316 protected void OnRefreshTree(object sender, EventArgs e)
318 if (null != m_workspaceTree.SelectedNode)
320 object o = m_workspaceTree.SelectedNode.Tag;
321 SetRepoTree(m_currentRepo);
322 this.Enabled = false;
323 foreach (string s in m_expandedPaths.Keys)
325 ExpandPath(s);
327 this.Enabled = true;
331 protected void OnAddFiles(object sender, EventArgs e)
333 Enabled = false;
334 if (m_workspaceTree.SelectedNode.Tag is Git.File)
336 Git.File f = (Git.File)m_workspaceTree.SelectedNode.Tag;
337 List<string> paths = new List<string>();
338 if (f.RelativePath.Length > 0)
340 paths.Add(f.RelativePath + Repo.DirectorySeparator + f.Name);
342 else
344 paths.Add(f.Name);
346 List<Git.File> files;
347 if (m_currentRepo.Add(paths, out files))
349 Git.File updatedFile = files[0];
350 if (0 != ((int)updatedFile.State & m_selectedTypes))
352 m_workspaceTree.SelectedNode.Tag = files[0];
353 SetNodeImage(m_workspaceTree.SelectedNode, files[0]);
357 Enabled = true;
360 protected void OnDeleteFiles(object sender, EventArgs e)
362 Enabled = false;
363 if (m_workspaceTree.SelectedNode.Tag is Git.File)
365 Git.File f = (Git.File)m_workspaceTree.SelectedNode.Tag;
366 List<string> paths = new List<string>();
367 if (f.RelativePath.Length > 0)
369 paths.Add(f.RelativePath + Repo.DirectorySeparator + f.Name);
371 else
373 paths.Add(f.Name);
375 List<Git.File> files;
376 if (m_currentRepo.Remove(paths, out files))
378 m_workspaceTree.SelectedNode.Tag = files[0];
379 SetNodeImage(m_workspaceTree.SelectedNode, files[0]);
382 Enabled = true;
385 protected void OnRevertFiles(object sender, EventArgs e)
387 if (m_workspaceTree.SelectedNode.Tag is Git.File)
389 Git.File f = (Git.File)m_workspaceTree.SelectedNode.Tag;
390 List<string> paths = new List<string>();
391 if (f.RelativePath.Length > 0)
393 paths.Add(f.RelativePath + Repo.DirectorySeparator + f.Name);
395 else
397 paths.Add(f.Name);
399 List<Git.File> files;
400 if (m_currentRepo.Revert(paths, out files))
402 m_workspaceTree.SelectedNode.Tag = files[0];
403 SetNodeImage(m_workspaceTree.SelectedNode, files[0]);
408 protected void OnCopyFiles(object sender, EventArgs e)
413 protected void OnMoveFiles(object sender, EventArgs e)
418 protected void OnShowAdded(object sender, EventArgs e)
423 protected void OnShowCopied(object sender, EventArgs e)
428 protected void OnShowRenamed(object sender, EventArgs e)
433 protected void OnShowUnmanaged(object sender, EventArgs e)
438 public void Clear()
440 m_expandedPaths.Clear();