using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Configuration;
using System.Xml.Serialization;
using SvnShelve.Model;
namespace SvnShelve.Forms
{
public partial class ShelveForm : FormBase
{
public ShelveForm()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
}
private string _projectPath;
public string ProjectPath
{
get { return _projectPath; }
set { _projectPath = value; }
}
private void Form1_Load(object sender, EventArgs e)
{
_path.Text = this.ProjectPath;
_fileList.BasePath = ProjectPath;
_fileList.EnableDiff = true;
_fileList.EnableLog = true;
_fileList.EnableRepositoryBrowsing = true;
_fileList.EnableOpenFolder = true;
FolderInfo folderInfo = SVN.GetFolderInfo(ProjectPath);
_url.Text = folderInfo.Url;
_revision.Text = folderInfo.Revision.ToString();
timer1.Enabled = true;
this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
}
private List<FileStatusInfo> _files = new List<FileStatusInfo>();
private void LoadModificationList()
{
List<string> topFolders = new List<string>();
bool hasConflictedFiles = false;
if (IsAuthenticated)
{
FileStatusInfo[] fileList = SVN.GetStatus(this.ProjectPath);
foreach (FileStatusInfo file in fileList)
{
switch (file.State)
{
case FileStatusInfo.StatusEnum.Conflicted:
hasConflictedFiles = true;
break;
case FileStatusInfo.StatusEnum.Added:
case FileStatusInfo.StatusEnum.Deleted:
case FileStatusInfo.StatusEnum.Modified:
string checkFolder = null;
string[] parts = file.FilePath.Split('\\');
if (parts.Length > 1 && file.FilePath != this.ProjectPath)
{
string folder = parts[0];
if (!topFolders.Contains(folder))
{
topFolders.Add(folder);
checkFolder = ProjectPath + "\\" + folder;
}
}
else
{
if (!topFolders.Contains(string.Empty))
{
topFolders.Add(string.Empty);
checkFolder = ProjectPath;
}
}
if (checkFolder != null)
{
FolderInfo folderInfo = SVN.GetFolderInfo(checkFolder);
string url = folderInfo.Url;
if (!url.EndsWith("/"))
url += "/";
//this._fileList.Add(FileStatusInfo.StatusEnum.None, url);
}
_files.Add(file);
this._fileList.Add(file.State, file.FilePath);
break;
}
}
List<string> urls = new List<string>();
foreach (string folder in topFolders)
{
FolderInfo folderInfo = null;
if (folder.Length > 0)
folderInfo = SVN.GetFolderInfo(ProjectPath + "\\" + folder);
else
folderInfo = SVN.GetFolderInfo(ProjectPath);
string url = folderInfo.Url.TrimEnd(folder.ToCharArray());
if (!url.EndsWith("/"))
url += "/";
if (!urls.Contains(url))
urls.Add(url);
}
string errorMessage = string.Empty;
if (hasConflictedFiles)
{
errorMessage = string.Format("Folder '{0}' has conflicted files.", this.ProjectPath);
MessageBox.Show(errorMessage, "Folder is invalid to shelve", MessageBoxButtons.OK, MessageBoxIcon.Error);
this._description.Enabled = false;
}
else
{
if (urls.Count > 1)
{
foreach (string urlItem in urls)
{
errorMessage += "Url: " + urlItem + "\n";
}
}
if (errorMessage.Length > 0)
{
MessageBox.Show("Multiple Urls found. Only one supported.\n" + errorMessage +
"\n\nSelect folder, which has the same folder structure in SVN repository", "Folder is invalid to shelve", MessageBoxButtons.OK, MessageBoxIcon.Error);
this._description.Enabled = false;
}
}
}
}
private void _shelve_Click(object sender, EventArgs e)
{
using (StatusForm status = new StatusForm())
{
status.FormClosed += new FormClosedEventHandler(Shelve_FormClosed);
status.DoWork += new EventHandler<DoWorkEventArgs>(status_DoWork);
status.Text = string.Format("Shelve '{0}'", _path.Text);
status.ShowDialog(this);
}
}
void status_DoWork(object sender, DoWorkEventArgs e)
{
Shelve(sender as StatusForm);
}
private void Shelve(StatusForm status)
{
System.Collections.Specialized.StringCollection recent = Properties.Settings.Default.RecentDescriptionList;
if (recent == null)
recent = new System.Collections.Specialized.StringCollection();
if (!recent.Contains(_description.Text))
{
recent.Add(_description.Text);
Properties.Settings.Default.RecentDescriptionList = recent;
Properties.Settings.Default.Save();
}
FolderInfo folderInfo = SVN.GetFolderInfo(ProjectPath);
string targetFolder = string.Format("{0}\\{1}\\",
SVN.ShelveLocation,
Guid.NewGuid().ToString().Replace("-", string.Empty));
try
{
status.Add("", "");
status.Add("Step 1", "******************************************************************");
status.Add("Copy Files", "");
foreach (FileStatusInfo file in _files)
{
folderInfo.AddFile(file);
string sourceFile = null;
if (file.FilePath == "(root)")
sourceFile = this.ProjectPath;
else
sourceFile = this.ProjectPath + "\\" + file.FilePath;
if (file.State != FileStatusInfo.StatusEnum.Deleted)
{
if (SVN.IsWorkingCopy(sourceFile))
{
FolderInfo fileInfo = SVN.GetFolderInfo(sourceFile);
if (!fileInfo.Url.StartsWith(folderInfo.Url))
{
throw new ArgumentException(string.Format("SVN Location mismatch:\n" +
"File: '{0}'\n" +
"Url: '{1}'\n" +
"SVN Url: '{2}'.\n" +
"You have to shelve files, which are located under the same url as folder you have selected",
file.FilePath, fileInfo.Url, folderInfo.Url));
}
}
string targetFile = targetFolder + file.FilePath;
string dir = Path.GetDirectoryName(targetFile);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
if (!file.IsFolder)
{
status.Add("Copy", sourceFile);
File.Copy(sourceFile, targetFile, true);
string svnPath = Path.GetDirectoryName(sourceFile) + "\\.svn";
if(!Directory.Exists(svnPath))
svnPath = Path.GetDirectoryName(sourceFile) + "\\_svn";
if (Directory.Exists(svnPath))
{
string baseFile = svnPath + "\\text-base\\" + Path.GetFileName(sourceFile) + ".svn-base";
if (!File.Exists(baseFile))
{
baseFile = svnPath + "\\prop-base\\" + Path.GetFileName(sourceFile) + ".svn-base";
}
if (File.Exists(baseFile))
{
File.Copy(baseFile, targetFile + ".shelf-base", true);
}
}
}
else
{
status.Add("Create", sourceFile);
}
}
}
folderInfo.Description = _description.Text;
XmlSerializer s = new XmlSerializer(typeof(FolderInfo));
using (StreamWriter infoFile = File.CreateText(targetFolder + "\\info.xml"))
{
s.Serialize(infoFile, folderInfo);
infoFile.Close();
}
DialogResult result = MessageBox.Show("Do you want to restore Project folder to the point where it was before you made changes?",
"Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (result == DialogResult.Yes)
{
status.Add("", "");
status.Add("Step 2", "******************************************************************");
status.Add("Revert", this.ProjectPath);
string[] lines = SVN.Revert(this.ProjectPath);
status.PrintSvnResult(lines);
status.Add("", "");
status.Add("Step 3", "******************************************************************");
status.Add("Cleanup", this.ProjectPath);
foreach (FileStatusInfo file in _files)
{
try
{
switch (file.State)
{
case FileStatusInfo.StatusEnum.Added:
if (file.IsFolder)
{
string dir = null;
if (file.FilePath == "(root)")
dir = ProjectPath;
else
{
if (!file.FilePath.Contains(this.ProjectPath))
dir = this.ProjectPath + "\\" + file.FilePath;
else
dir = file.FilePath;
}
if (Directory.Exists(dir))
{
status.Add("Delete", dir);
Directory.Delete(dir, true);
}
}
else
{
string p = this.ProjectPath + "\\" + file.FilePath;
if (File.Exists(p))
{
status.Add("Delete", p);
File.Delete(p);
}
}
break;
}
}
catch
{
//ignore delete errors
}
}
}
if (SVN.IsWorkingCopy(SVN.ShelveLocation))
{
if (targetFolder.EndsWith("\\"))
targetFolder = targetFolder.Remove(targetFolder.Length - 1, 1);
SVN.Add(targetFolder);
status.Commit(string.Empty, _description.Text);
}
status.Add("", "");
status.Add("Complete", this.ProjectPath);
}
catch (Exception ex)
{
if (Directory.Exists(targetFolder))
{
if (SVN.IsWorkingCopy(targetFolder))
{
SVN.Delete(targetFolder);
}
else
{
Directory.Delete(targetFolder, true);
}
}
status.Add("", "");
status.Add("Failed", ex.Message);
MessageBox.Show(ex.Message, "Error while shelving your project", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
void Shelve_FormClosed(object sender, FormClosedEventArgs e)
{
this.Close();
}
private void _description_TextChanged(object sender, EventArgs e)
{
_shelve.Enabled = _description.Text.Trim().Length > 10;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
LoadModificationList();
this.Cursor = System.Windows.Forms.Cursors.Default;
_cancel.Enabled = true;
}
private void _cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void _recent_Click(object sender, EventArgs e)
{
RecentForm f = new RecentForm();
DialogResult result = f.ShowDialog(this);
if (result == DialogResult.OK)
{
_description.Text = f.SelectedItem;
}
}
}
}