early working version of history recycle logic + mac Save As dialog
This commit is contained in:
parent
7ead01b0b0
commit
d4ac1fe93e
|
@ -539,7 +539,7 @@ namespace SparkleLib.Git {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void RevertFile (string path, string revision)
|
public override void RestoreFile (string path, string revision, string target_file_path)
|
||||||
{
|
{
|
||||||
if (path == null)
|
if (path == null)
|
||||||
throw new ArgumentNullException ("path");
|
throw new ArgumentNullException ("path");
|
||||||
|
@ -614,7 +614,7 @@ namespace SparkleLib.Git {
|
||||||
path = path.Replace ("\\", "/");
|
path = path.Replace ("\\", "/");
|
||||||
|
|
||||||
git = new SparkleGit (LocalPath, "log -" + count + " --raw --find-renames --date=iso " +
|
git = new SparkleGit (LocalPath, "log -" + count + " --raw --find-renames --date=iso " +
|
||||||
"--format=medium --no-color --no-merges -- " + path);
|
"--format=medium --no-color --no-merges -- \"" + path + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
string output = git.StartAndReadStandardOutput ();
|
string output = git.StartAndReadStandardOutput ();
|
||||||
|
@ -681,13 +681,16 @@ namespace SparkleLib.Git {
|
||||||
if (entry_line.StartsWith (":")) {
|
if (entry_line.StartsWith (":")) {
|
||||||
string type_letter = entry_line [37].ToString ();
|
string type_letter = entry_line [37].ToString ();
|
||||||
string file_path = entry_line.Substring (39);
|
string file_path = entry_line.Substring (39);
|
||||||
|
bool change_is_folder = false;
|
||||||
if (file_path.EndsWith (".empty"))
|
|
||||||
file_path = file_path.Substring (0, file_path.Length - ".empty".Length);
|
|
||||||
|
|
||||||
if (file_path.Equals (".sparkleshare"))
|
if (file_path.Equals (".sparkleshare"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (file_path.EndsWith (".empty")) {
|
||||||
|
file_path = file_path.Substring (0, file_path.Length - ".empty".Length);
|
||||||
|
change_is_folder = true;
|
||||||
|
}
|
||||||
|
|
||||||
file_path = EnsureSpecialCharacters (file_path);
|
file_path = EnsureSpecialCharacters (file_path);
|
||||||
file_path = file_path.Replace ("\\\"", "\"");
|
file_path = file_path.Replace ("\\\"", "\"");
|
||||||
|
|
||||||
|
@ -702,15 +705,20 @@ namespace SparkleLib.Git {
|
||||||
file_path = file_path.Replace ("\\\"", "\"");
|
file_path = file_path.Replace ("\\\"", "\"");
|
||||||
to_file_path = to_file_path.Replace ("\\\"", "\"");
|
to_file_path = to_file_path.Replace ("\\\"", "\"");
|
||||||
|
|
||||||
if (file_path.EndsWith (".empty"))
|
if (file_path.EndsWith (".empty")) {
|
||||||
file_path = file_path.Substring (0, file_path.Length - 6);
|
file_path = file_path.Substring (0, file_path.Length - 6);
|
||||||
|
change_is_folder = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (to_file_path.EndsWith (".empty"))
|
if (to_file_path.EndsWith (".empty")) {
|
||||||
to_file_path = to_file_path.Substring (0, to_file_path.Length - 6);
|
to_file_path = to_file_path.Substring (0, to_file_path.Length - 6);
|
||||||
|
change_is_folder = true;
|
||||||
|
}
|
||||||
|
|
||||||
change_set.Changes.Add (
|
change_set.Changes.Add (
|
||||||
new SparkleChange () {
|
new SparkleChange () {
|
||||||
Path = file_path,
|
Path = file_path,
|
||||||
|
IsFolder = change_is_folder,
|
||||||
MovedToPath = to_file_path,
|
MovedToPath = to_file_path,
|
||||||
Timestamp = change_set.Timestamp,
|
Timestamp = change_set.Timestamp,
|
||||||
Type = SparkleChangeType.Moved
|
Type = SparkleChangeType.Moved
|
||||||
|
@ -730,6 +738,7 @@ namespace SparkleLib.Git {
|
||||||
change_set.Changes.Add (
|
change_set.Changes.Add (
|
||||||
new SparkleChange () {
|
new SparkleChange () {
|
||||||
Path = file_path,
|
Path = file_path,
|
||||||
|
IsFolder = change_is_folder,
|
||||||
Timestamp = change_set.Timestamp,
|
Timestamp = change_set.Timestamp,
|
||||||
Type = change_type
|
Type = change_type
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace SparkleLib {
|
||||||
public abstract bool SyncDown ();
|
public abstract bool SyncDown ();
|
||||||
public abstract List<SparkleChangeSet> GetChangeSets (int count);
|
public abstract List<SparkleChangeSet> GetChangeSets (int count);
|
||||||
public abstract List<SparkleChangeSet> GetChangeSets (string path, int count);
|
public abstract List<SparkleChangeSet> GetChangeSets (string path, int count);
|
||||||
public abstract void RevertFile (string path, string revision);
|
public abstract void RestoreFile (string path, string revision, string target_file_path);
|
||||||
|
|
||||||
public event SyncStatusChangedEventHandler SyncStatusChanged = delegate { };
|
public event SyncStatusChangedEventHandler SyncStatusChanged = delegate { };
|
||||||
public delegate void SyncStatusChangedEventHandler (SyncStatus new_status);
|
public delegate void SyncStatusChangedEventHandler (SyncStatus new_status);
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public SparkleChangeType Type;
|
public SparkleChangeType Type;
|
||||||
public DateTime Timestamp;
|
public DateTime Timestamp;
|
||||||
|
public bool IsFolder = false;
|
||||||
|
|
||||||
public string Path;
|
public string Path;
|
||||||
public string MovedToPath;
|
public string MovedToPath;
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small, small a {
|
||||||
font-size: <!-- $small-font-size -->;
|
font-size: <!-- $small-font-size -->;
|
||||||
color: <!-- $secondary-font-color -->;
|
color: <!-- $secondary-font-color -->;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,52 @@
|
||||||
|
|
||||||
.moved {
|
.moved {
|
||||||
background-image: url('<!-- $document-moved-background-image -->');
|
background-image: url('<!-- $document-moved-background-image -->');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
padding: 18px 32px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.name {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.time {
|
||||||
|
font-size: <!-- $small-font-size -->;
|
||||||
|
color: <!-- $secondary-font-color -->;
|
||||||
|
padding-right: 9px;
|
||||||
|
width: 20px;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.date {
|
||||||
|
font-size: <!-- $small-font-size -->;
|
||||||
|
color: <!-- $secondary-font-color -->;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 6px;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.restore {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.avatar {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.avatar img {
|
||||||
|
margin-top: 2px;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body oncontextmenu="return false;">
|
<body oncontextmenu="return false;">
|
||||||
|
|
|
@ -228,7 +228,7 @@ namespace SparkleShare {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Controller.UpdateSizeInfoEvent += delegate (string size, string history_size) {
|
Controller.UpdateSizeInfoEvent += delegate (string size, string history_size) {
|
||||||
using (var a = new NSAutoreleasePool ())
|
using (var a = new NSAutoreleasePool ())
|
||||||
{
|
{
|
||||||
|
@ -238,6 +238,27 @@ namespace SparkleShare {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Controller.ShowSaveDialogEvent += delegate (string file_name, string target_folder_path) {
|
||||||
|
using (var a = new NSAutoreleasePool ())
|
||||||
|
{
|
||||||
|
InvokeOnMainThread (() => {
|
||||||
|
// TODO: Make this a sheet
|
||||||
|
NSSavePanel panel = new NSSavePanel () {
|
||||||
|
DirectoryUrl = new NSUrl (target_folder_path, true),
|
||||||
|
NameFieldStringValue = file_name,
|
||||||
|
ParentWindow = this,
|
||||||
|
Title = "Restore from History",
|
||||||
|
PreventsApplicationTerminationWhenModal = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((NSPanelButtonType) panel.RunModal ()== NSPanelButtonType.Ok)
|
||||||
|
Controller.SaveDialogCompleted ("f");
|
||||||
|
else
|
||||||
|
Controller.SaveDialogCancelled ();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -346,6 +367,7 @@ namespace SparkleShare {
|
||||||
html = html.Replace ("<!-- $body-font-size -->", "13.4px");
|
html = html.Replace ("<!-- $body-font-size -->", "13.4px");
|
||||||
html = html.Replace ("<!-- $secondary-font-color -->", "#bbb");
|
html = html.Replace ("<!-- $secondary-font-color -->", "#bbb");
|
||||||
html = html.Replace ("<!-- $small-color -->", "#ddd");
|
html = html.Replace ("<!-- $small-color -->", "#ddd");
|
||||||
|
html = html.Replace ("<!-- $small-font-size -->", "10px");
|
||||||
html = html.Replace ("<!-- $day-entry-header-background-color -->", "#f5f5f5");
|
html = html.Replace ("<!-- $day-entry-header-background-color -->", "#f5f5f5");
|
||||||
html = html.Replace ("<!-- $a-color -->", "#0085cf");
|
html = html.Replace ("<!-- $a-color -->", "#0085cf");
|
||||||
html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
|
html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
|
||||||
|
|
|
@ -19,6 +19,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using SparkleLib;
|
using SparkleLib;
|
||||||
|
@ -36,12 +37,16 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public event UpdateChooserEventHandler UpdateChooserEvent = delegate { };
|
public event UpdateChooserEventHandler UpdateChooserEvent = delegate { };
|
||||||
public delegate void UpdateChooserEventHandler (string [] folders);
|
public delegate void UpdateChooserEventHandler (string [] folders);
|
||||||
|
|
||||||
public event UpdateSizeInfoEventHandler UpdateSizeInfoEvent = delegate { };
|
public event UpdateSizeInfoEventHandler UpdateSizeInfoEvent = delegate { };
|
||||||
public delegate void UpdateSizeInfoEventHandler (string size, string history_size);
|
public delegate void UpdateSizeInfoEventHandler (string size, string history_size);
|
||||||
|
|
||||||
|
public event ShowSaveDialogEventHandler ShowSaveDialogEvent = delegate { };
|
||||||
|
public delegate void ShowSaveDialogEventHandler (string file_name, string target_folder_path);
|
||||||
|
|
||||||
|
|
||||||
private string selected_folder;
|
private string selected_folder;
|
||||||
|
private RevisionInfo restore_revision_info;
|
||||||
|
|
||||||
|
|
||||||
public bool WindowIsOpen { get; private set; }
|
public bool WindowIsOpen { get; private set; }
|
||||||
|
@ -220,10 +225,113 @@ namespace SparkleShare {
|
||||||
|
|
||||||
} else if (url.StartsWith ("http")) {
|
} else if (url.StartsWith ("http")) {
|
||||||
Program.Controller.OpenWebsite (url);
|
Program.Controller.OpenWebsite (url);
|
||||||
|
|
||||||
|
|
||||||
|
} else if (url.StartsWith ("restore://") && this.restore_revision_info == null) {
|
||||||
|
Regex regex = new Regex ("restore://(.+)/([a-f0-9]+)/(.+)", RegexOptions.Compiled);
|
||||||
|
Match match = regex.Match (url);
|
||||||
|
|
||||||
|
if (match.Success) {
|
||||||
|
this.restore_revision_info = new RevisionInfo () {
|
||||||
|
Folder = new SparkleFolder (match.Groups [1].Value),
|
||||||
|
Revision = match.Groups [2].Value,
|
||||||
|
FilePath = match.Groups [3].Value
|
||||||
|
};
|
||||||
|
|
||||||
|
string file_name = Path.GetFileNameWithoutExtension (this.restore_revision_info.FilePath) +
|
||||||
|
" (restored)" + Path.GetExtension (this.restore_revision_info.FilePath);
|
||||||
|
|
||||||
|
string target_folder_path = Path.Combine (this.restore_revision_info.Folder.FullPath,
|
||||||
|
Path.GetDirectoryName (this.restore_revision_info.FilePath));
|
||||||
|
|
||||||
|
ShowSaveDialogEvent (file_name, target_folder_path);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// TODO: remove
|
||||||
|
Program.UI.Bubbles.Controller.ShowBubble ("no match", url, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else if (url.StartsWith ("history://")) {
|
||||||
|
string html = "";
|
||||||
|
string folder = url.Replace ("history://", "").Split ("/".ToCharArray ()) [0];
|
||||||
|
string path = url.Replace ("history://" + folder + "/", "");
|
||||||
|
|
||||||
|
// TODO: put html into page
|
||||||
|
|
||||||
|
foreach (SparkleRepoBase repo in Program.Controller.Repositories) {
|
||||||
|
if (repo.Name.Equals (folder)) {
|
||||||
|
List<SparkleChangeSet> change_sets = repo.GetChangeSets (path, 30);
|
||||||
|
|
||||||
|
html += "<div class='day-entry-header'>Revisions for “"
|
||||||
|
+ Path.GetFileName (path) + "”</div>";
|
||||||
|
|
||||||
|
|
||||||
|
html += "<table>";
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
foreach (SparkleChangeSet change_set in change_sets) {
|
||||||
|
count++;
|
||||||
|
if (count == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (SparkleChange change in change_set.Changes) {
|
||||||
|
if (change.Type == SparkleChangeType.Deleted && change.Path.Equals (path))
|
||||||
|
continue; // TODO: in repo?
|
||||||
|
}
|
||||||
|
|
||||||
|
string change_set_avatar = Program.Controller.GetAvatar (change_set.User.Email, 24);
|
||||||
|
|
||||||
|
if (change_set_avatar != null)
|
||||||
|
change_set_avatar = "file://" + change_set_avatar.Replace ("\\", "/");
|
||||||
|
else
|
||||||
|
change_set_avatar = "file://<!-- $pixmaps-path -->/user-icon-default.png";
|
||||||
|
|
||||||
|
html += "<tr>" +
|
||||||
|
"<td class='avatar'><img src='" + change_set_avatar + "'></td>" +
|
||||||
|
"<td class='name'><b>" + change_set.User.Name + "</b></td>" +
|
||||||
|
"<td class='date'>" + change_set.Timestamp.ToString ("d MMM yyyy") + "</td>" +
|
||||||
|
"<td class='time'>" + change_set.Timestamp.ToString ("HH:mm") + "</td>" +
|
||||||
|
"<td class='restore'><a href='restore://" + change_set.Folder.Name + "/" + change_set.Revision + "/" + path + "' title='restore://" + change_set.Folder.Name + "/" + change_set.Revision + "/" + path + "'>Restore...</a></td>" +
|
||||||
|
"</tr>";
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
html += "</table>";
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UpdateContentEvent (Program.Controller.EventLogHTML.Replace ("<!-- $event-log-content -->", html));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SaveDialogCompleted (string target_file_path)
|
||||||
|
{
|
||||||
|
foreach (SparkleRepoBase repo in Program.Controller.Repositories) {
|
||||||
|
if (repo.Name.Equals (this.restore_revision_info.Folder.Name)) {
|
||||||
|
repo.RestoreFile (this.restore_revision_info.FilePath,
|
||||||
|
this.restore_revision_info.Revision, target_file_path);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.restore_revision_info = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SaveDialogCancelled ()
|
||||||
|
{
|
||||||
|
this.restore_revision_info = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<SparkleChangeSet> GetLog ()
|
private List<SparkleChangeSet> GetLog ()
|
||||||
{
|
{
|
||||||
List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
|
List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
|
||||||
|
@ -307,7 +415,16 @@ namespace SparkleShare {
|
||||||
foreach (SparkleChange change in change_set.Changes) {
|
foreach (SparkleChange change in change_set.Changes) {
|
||||||
if (change.Type != SparkleChangeType.Moved) {
|
if (change.Type != SparkleChangeType.Moved) {
|
||||||
event_entry += "<dd class='" + change.Type.ToString ().ToLower () + "'>";
|
event_entry += "<dd class='" + change.Type.ToString ().ToLower () + "'>";
|
||||||
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> ";
|
|
||||||
|
if (!change.IsFolder) {
|
||||||
|
event_entry += "<small><a href=\"history://" + change_set.Folder.Name + "/" +
|
||||||
|
change.Path + "\" title=\"View revisions\">" + change.Timestamp.ToString ("HH:mm") +
|
||||||
|
"</a></small> ";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") + "</small> ";
|
||||||
|
}
|
||||||
|
|
||||||
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.Path);
|
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.Path);
|
||||||
event_entry += "</dd>";
|
event_entry += "</dd>";
|
||||||
|
|
||||||
|
@ -444,5 +561,12 @@ namespace SparkleShare {
|
||||||
Date = new DateTime (date_time.Year, date_time.Month, date_time.Day);
|
Date = new DateTime (date_time.Year, date_time.Month, date_time.Day);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class RevisionInfo {
|
||||||
|
public SparkleFolder Folder;
|
||||||
|
public string FilePath;
|
||||||
|
public string Revision;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue