Merge branch 'master' of ssh://github.com/hbons/SparkleShare
This commit is contained in:
commit
a679e29d4c
13
News.txt
13
News.txt
|
@ -1,4 +1,15 @@
|
||||||
0.9.3 for Linux, Mac and Windows (??? 2012)
|
0.9.4 for Linux, Mac and Windows (Fri Oct 19 2012)
|
||||||
|
|
||||||
|
Hylke:
|
||||||
|
- Remove Nautilus extension
|
||||||
|
- Restore previous revisions of files from the event log
|
||||||
|
- Fix Mac file system watcher not always triggering
|
||||||
|
- Add symbolic icon for GNOME 3 (by Lapo)
|
||||||
|
- New Bitbucket and default user icon
|
||||||
|
- For encrypted projects, use a different salt for each project
|
||||||
|
|
||||||
|
|
||||||
|
0.9.3 for Linux, Mac and Windows (Mon Oct 1 2012)
|
||||||
|
|
||||||
Hylke:
|
Hylke:
|
||||||
- Fix endless loop when adding empty folders
|
- Fix endless loop when adding empty folders
|
||||||
|
|
|
@ -19,7 +19,7 @@ using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly:AssemblyTitle ("SparkleLib")]
|
[assembly:AssemblyTitle ("SparkleLib")]
|
||||||
[assembly:AssemblyVersion ("0.9.3")]
|
[assembly:AssemblyVersion ("0.9.4")]
|
||||||
[assembly:AssemblyCopyright ("Copyright (c) 2010 Hylke Bons and others")]
|
[assembly:AssemblyCopyright ("Copyright (c) 2010 Hylke Bons and others")]
|
||||||
[assembly:AssemblyTrademark ("SparkleShare is a trademark of SparkleShare Ltd.")]
|
[assembly:AssemblyTrademark ("SparkleShare is a trademark of SparkleShare Ltd.")]
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace SparkleLib.Git {
|
||||||
|
|
||||||
// Check if the repo's salt is stored in a branch...
|
// Check if the repo's salt is stored in a branch...
|
||||||
SparkleGit git = new SparkleGit (TargetFolder, "branch -a");
|
SparkleGit git = new SparkleGit (TargetFolder, "branch -a");
|
||||||
|
git.StartAndWaitForExit ();
|
||||||
|
|
||||||
string [] branches = git.StartAndReadStandardOutput ().Split (Environment.NewLine.ToCharArray ());
|
string [] branches = git.StartAndReadStandardOutput ().Split (Environment.NewLine.ToCharArray ());
|
||||||
// TODO double check env.newline ^
|
// TODO double check env.newline ^
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
using SparkleLib;
|
using SparkleLib;
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ namespace SparkleLib.Git {
|
||||||
|
|
||||||
private bool user_is_set;
|
private bool user_is_set;
|
||||||
private bool use_git_bin;
|
private bool use_git_bin;
|
||||||
|
private bool is_encrypted;
|
||||||
|
|
||||||
|
|
||||||
public SparkleRepo (string path, SparkleConfig config) : base (path, config)
|
public SparkleRepo (string path, SparkleConfig config) : base (path, config)
|
||||||
|
@ -50,6 +52,11 @@ namespace SparkleLib.Git {
|
||||||
git = new SparkleGit (LocalPath, "rebase --abort");
|
git = new SparkleGit (LocalPath, "rebase --abort");
|
||||||
git.StartAndWaitForExit ();
|
git.StartAndWaitForExit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string password_file_path = Path.Combine (LocalPath, ".git", "password");
|
||||||
|
|
||||||
|
if (File.Exists (password_file_path))
|
||||||
|
this.is_encrypted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,9 +245,8 @@ namespace SparkleLib.Git {
|
||||||
if (line.Contains ("|")) {
|
if (line.Contains ("|")) {
|
||||||
speed = line.Substring (line.IndexOf ("|") + 1).Trim ();
|
speed = line.Substring (line.IndexOf ("|") + 1).Trim ();
|
||||||
speed = speed.Replace (", done.", "").Trim ();
|
speed = speed.Replace (", done.", "").Trim ();
|
||||||
speed = speed.Replace ("i", "");
|
speed = speed.Replace ("KiB/s", "ᴋʙ/s");
|
||||||
speed = speed.Replace ("KB/s", "ᴋʙ/s");
|
speed = speed.Replace ("MiB/s", "ᴍʙ/s");
|
||||||
speed = speed.Replace ("MB/s", "ᴍʙ/s");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,6 +474,7 @@ namespace SparkleLib.Git {
|
||||||
foreach (string line in lines) {
|
foreach (string line in lines) {
|
||||||
string conflicting_path = line.Substring (3);
|
string conflicting_path = line.Substring (3);
|
||||||
conflicting_path = EnsureSpecialCharacters (conflicting_path);
|
conflicting_path = EnsureSpecialCharacters (conflicting_path);
|
||||||
|
conflicting_path = conflicting_path.Replace ("\"", "\\\"");
|
||||||
|
|
||||||
SparkleLogger.LogInfo ("Git", Name + " | Conflict type: " + line);
|
SparkleLogger.LogInfo ("Git", Name + " | Conflict type: " + line);
|
||||||
|
|
||||||
|
@ -539,7 +546,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");
|
||||||
|
@ -547,27 +554,58 @@ namespace SparkleLib.Git {
|
||||||
if (revision == null)
|
if (revision == null)
|
||||||
throw new ArgumentNullException ("revision");
|
throw new ArgumentNullException ("revision");
|
||||||
|
|
||||||
path = path.Replace ("\\", "/");
|
SparkleLogger.LogInfo ("Git", Name + " | Restoring \"" + path + "\" (revision " + revision + ")");
|
||||||
|
|
||||||
SparkleGit git = new SparkleGit (LocalPath, "checkout " + revision + " \"" + path + "\"");
|
// FIXME: git-show doesn't decrypt objects, so we can't use it to retrieve
|
||||||
git.StartAndWaitForExit ();
|
// files from the index. This is a suboptimal workaround but it does the job
|
||||||
|
if (this.is_encrypted) {
|
||||||
|
// Restore the older file...
|
||||||
|
SparkleGit git = new SparkleGit (LocalPath, "checkout " + revision + " \"" + path + "\"");
|
||||||
|
git.StartAndWaitForExit ();
|
||||||
|
|
||||||
if (git.ExitCode == 0)
|
string local_file_path = Path.Combine (LocalPath, path);
|
||||||
SparkleLogger.LogInfo ("Git", Name + " | Checked out \"" + path + "\" (" + revision + ")");
|
|
||||||
else
|
// ...move it...
|
||||||
SparkleLogger.LogInfo ("Git", Name + " | Failed to check out \"" + path + "\" (" + revision + ")");
|
try {
|
||||||
|
File.Move (local_file_path, target_file_path);
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
SparkleLogger.LogInfo ("Git",
|
||||||
|
Name + " | Could not move \"" + local_file_path + "\" to \"" + target_file_path + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and restore the most recent revision
|
||||||
|
git = new SparkleGit (LocalPath, "checkout " + CurrentRevision + " \"" + path + "\"");
|
||||||
|
git.StartAndWaitForExit ();
|
||||||
|
|
||||||
|
// The correct way
|
||||||
|
} else {
|
||||||
|
path = path.Replace ("\"", "\\\"");
|
||||||
|
|
||||||
|
SparkleGit git = new SparkleGit (LocalPath, "show " + revision + ":\"" + path + "\"");
|
||||||
|
git.Start ();
|
||||||
|
|
||||||
|
FileStream stream = File.OpenWrite (target_file_path);
|
||||||
|
git.StandardOutput.BaseStream.CopyTo (stream);
|
||||||
|
stream.Close ();
|
||||||
|
|
||||||
|
git.WaitForExit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_file_path.StartsWith (LocalPath))
|
||||||
|
new Thread (() => OnFileActivity (null)).Start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override List<SparkleChangeSet> GetChangeSets (string path, int count)
|
public override List<SparkleChangeSet> GetChangeSets (string path)
|
||||||
{
|
{
|
||||||
return GetChangeSetsInternal (path, count);
|
return GetChangeSetsInternal (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override List<SparkleChangeSet> GetChangeSets (int count)
|
public override List<SparkleChangeSet> GetChangeSets ()
|
||||||
{
|
{
|
||||||
return GetChangeSetsInternal (null, count);
|
return GetChangeSetsInternal (null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -590,31 +628,27 @@ namespace SparkleLib.Git {
|
||||||
if (Error != ErrorStatus.None) {
|
if (Error != ErrorStatus.None) {
|
||||||
SparkleLogger.LogInfo ("Git", Name + " | Error status changed to " + Error);
|
SparkleLogger.LogInfo ("Git", Name + " | Error status changed to " + Error);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<SparkleChangeSet> GetChangeSetsInternal (string path, int count)
|
private List<SparkleChangeSet> GetChangeSetsInternal (string path)
|
||||||
{
|
{
|
||||||
if (count < 1)
|
|
||||||
throw new ArgumentOutOfRangeException ("count");
|
|
||||||
|
|
||||||
count = 150;
|
|
||||||
List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();
|
List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();
|
||||||
|
|
||||||
SparkleGit git;
|
SparkleGit git;
|
||||||
|
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
git = new SparkleGit (LocalPath, "log -" + count + " --raw --find-renames --date=iso " +
|
git = new SparkleGit (LocalPath, "log --since=1.month --raw --find-renames --date=iso " +
|
||||||
"--format=medium --no-color --no-merges");
|
"--format=medium --no-color --no-merges");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
path = path.Replace ("\\", "/");
|
path = path.Replace ("\\", "/");
|
||||||
|
|
||||||
git = new SparkleGit (LocalPath, "log -" + count + " --raw --find-renames --date=iso " +
|
git = new SparkleGit (LocalPath, "log --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 +715,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 +739,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 +772,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
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
if (File.Exists (identifier_path)) {
|
if (File.Exists (identifier_path)) {
|
||||||
Identifier = File.ReadAllText (identifier_path).Trim ();
|
Identifier = File.ReadAllText (identifier_path).Trim ();
|
||||||
|
File.SetAttributes (identifier_path, FileAttributes.Hidden);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Identifier = CreateIdentifier ();
|
Identifier = CreateIdentifier ();
|
||||||
|
@ -220,9 +221,8 @@ namespace SparkleLib {
|
||||||
"Any files you add or change in this folder will be automatically synced to " + n +
|
"Any files you add or change in this folder will be automatically synced to " + n +
|
||||||
uri_builder.ToString () + " and everyone connected to it." + n +
|
uri_builder.ToString () + " and everyone connected to it." + n +
|
||||||
n +
|
n +
|
||||||
"SparkleShare is an Open Source software program that helps people " + n +
|
"SparkleShare is an Open Source software program that helps people collaborate and " + n +
|
||||||
"collaborate and share files. If you like what we do, please consider a small " + n +
|
"share files. If you like what we do, consider buying us a beer: http://www.sparkleshare.org/" + n +
|
||||||
"donation to support the project: http://www.sparkleshare.org/" + n +
|
|
||||||
n +
|
n +
|
||||||
"Have fun! :)" + n;
|
"Have fun! :)" + n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,9 @@ namespace SparkleLib {
|
||||||
public abstract bool HasRemoteChanges { get; }
|
public abstract bool HasRemoteChanges { get; }
|
||||||
public abstract bool SyncUp ();
|
public abstract bool SyncUp ();
|
||||||
public abstract bool SyncDown ();
|
public abstract bool SyncDown ();
|
||||||
public abstract List<SparkleChangeSet> GetChangeSets (int count);
|
public abstract List<SparkleChangeSet> GetChangeSets ();
|
||||||
public abstract List<SparkleChangeSet> GetChangeSets (string path, int count);
|
public abstract List<SparkleChangeSet> GetChangeSets (string path);
|
||||||
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);
|
||||||
|
@ -195,19 +195,17 @@ namespace SparkleLib {
|
||||||
|
|
||||||
// Sync up everything that changed
|
// Sync up everything that changed
|
||||||
// since we've been offline
|
// since we've been offline
|
||||||
if (!this.is_syncing && (HasLocalChanges || HasUnsyncedChanges)) {
|
new Thread (() => {
|
||||||
SyncUpBase ();
|
if (!this.is_syncing && (HasLocalChanges || HasUnsyncedChanges)) {
|
||||||
|
|
||||||
while (HasLocalChanges)
|
|
||||||
SyncUpBase ();
|
SyncUpBase ();
|
||||||
}
|
|
||||||
|
|
||||||
this.remote_timer.Start ();
|
while (HasLocalChanges && !this.is_syncing)
|
||||||
}
|
SyncUpBase ();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.remote_timer.Start ();
|
||||||
public List<SparkleChangeSet> GetChangeSets () {
|
|
||||||
return GetChangeSets (30);
|
}).Start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,9 +216,11 @@ namespace SparkleLib {
|
||||||
if (IsBuffering)
|
if (IsBuffering)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (string exclude_path in ExcludePaths) {
|
if (args != null) {
|
||||||
if (args.FullPath.Contains (exclude_path))
|
foreach (string exclude_path in ExcludePaths) {
|
||||||
return;
|
if (args.FullPath.Contains (exclude_path))
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (this.buffer_lock) {
|
lock (this.buffer_lock) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
$('dl dd:nth-child(-n+10)').css('display', 'block');
|
$('dl dd:nth-child(-n+10)').css('display', 'block');
|
||||||
$('.day-entry-content .event-entry:last-child').css('border', 'none');
|
$('.day-entry-content .event-entry:last-child').css('border', 'none');
|
||||||
|
|
||||||
$('dd a.windows').click(function () {
|
$('a').click(function (event) {
|
||||||
window.external.LinkClicked($(this).attr("href"));
|
window.external.LinkClicked($(this).attr("href"));
|
||||||
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the Today and Yesterday labels after midnight
|
// Update the Today and Yesterday labels after midnight
|
||||||
|
@ -26,7 +27,7 @@
|
||||||
}
|
}
|
||||||
}, 60 * 1000);
|
}, 60 * 1000);
|
||||||
|
|
||||||
// Hide the 'Show all' link when there are less than 10 events
|
// Hide the 'Show all' link when there are fewer than 10 events
|
||||||
$('.show').each (function () {
|
$('.show').each (function () {
|
||||||
var entry_count = $(this).parent ().find ('dl').children ().length;
|
var entry_count = $(this).parent ().find ('dl').children ().length;
|
||||||
|
|
||||||
|
@ -67,7 +68,6 @@
|
||||||
|
|
||||||
a.show {
|
a.show {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
margin-bottom: 9px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small, small a, small a:hover {
|
||||||
font-size: <!-- $small-font-size -->;
|
font-size: <!-- $small-font-size -->;
|
||||||
color: <!-- $secondary-font-color -->;
|
color: <!-- $secondary-font-color -->;
|
||||||
}
|
}
|
||||||
|
@ -91,13 +91,12 @@
|
||||||
display: none;
|
display: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
padding: 0 0 1px 20px;
|
padding: 0 0 1px 20px;
|
||||||
margin: 0 0 4px 0;
|
margin: 0 0 4px 0;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center left;
|
background-position: center left;
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-entry-header {
|
.day-entry-header {
|
||||||
|
@ -107,13 +106,24 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history-header {
|
||||||
|
color: #aaa;
|
||||||
|
padding-top: 22px;
|
||||||
|
float: left;
|
||||||
|
width: 90%;
|
||||||
|
margin-left: 32px;
|
||||||
|
margin-right: 32px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.event-entry {
|
.event-entry {
|
||||||
padding: 24px 14px 14px 64px;
|
padding: 24px 14px 14px 64px;
|
||||||
margin: 0 32px 0 32px;
|
margin: 0 32px 0 32px;
|
||||||
border-bottom: 1px #ddd solid;
|
border-bottom: 1px #ddd solid;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 36px 24px;
|
background-position: 36px 24px;
|
||||||
min-height: 100px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.event-user-name {
|
.event-user-name {
|
||||||
|
@ -152,7 +162,54 @@
|
||||||
|
|
||||||
.moved {
|
.moved {
|
||||||
background-image: url('<!-- $document-moved-background-image -->');
|
background-image: url('<!-- $document-moved-background-image -->');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
padding: 64px 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.name {
|
||||||
|
font-weight: bold;
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.time {
|
||||||
|
color: <!-- $secondary-font-color -->;
|
||||||
|
padding-right: 9px;
|
||||||
|
font-size: <!-- $small-font-size -->;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.date {
|
||||||
|
color: <!-- $secondary-font-color -->;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 6px;
|
||||||
|
font-size: <!-- $small-font-size -->;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.restore {
|
||||||
|
text-align: right;
|
||||||
|
font-size: <!-- $small-font-size -->;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;">
|
||||||
|
|
|
@ -131,12 +131,35 @@ namespace SparkleShare {
|
||||||
Present ();
|
Present ();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Controller.ShowSaveDialogEvent += delegate (string file_name, string target_folder_path) {
|
||||||
|
Application.Invoke (delegate {
|
||||||
|
FileChooserDialog dialog = new FileChooserDialog ("Restore from History",
|
||||||
|
this, FileChooserAction.Save, "Cancel", ResponseType.Cancel, "Save", ResponseType.Ok);
|
||||||
|
|
||||||
|
dialog.CurrentName = file_name;
|
||||||
|
dialog.SetCurrentFolder (target_folder_path);
|
||||||
|
|
||||||
|
if (dialog.Run () == (int) ResponseType.Ok)
|
||||||
|
Controller.SaveDialogCompleted (dialog.Filename);
|
||||||
|
else
|
||||||
|
Controller.SaveDialogCancelled ();
|
||||||
|
|
||||||
|
dialog.Destroy ();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Controller.UpdateChooserEvent += delegate (string [] folders) {
|
Controller.UpdateChooserEvent += delegate (string [] folders) {
|
||||||
Application.Invoke (delegate {
|
Application.Invoke (delegate {
|
||||||
UpdateChooser (folders);
|
UpdateChooser (folders);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Controller.UpdateChooserEnablementEvent += delegate (bool enabled) {
|
||||||
|
Application.Invoke (delegate {
|
||||||
|
this.combo_box.Sensitive = enabled;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Controller.UpdateContentEvent += delegate (string html) {
|
Controller.UpdateContentEvent += delegate (string html) {
|
||||||
Application.Invoke (delegate {
|
Application.Invoke (delegate {
|
||||||
|
@ -168,7 +191,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
|
|
||||||
private void WebViewNavigationRequested (object o, WebKit.NavigationRequestedArgs args) {
|
private void WebViewNavigationRequested (object o, WebKit.NavigationRequestedArgs args) {
|
||||||
Controller.LinkClicked (args.Request.Uri.Substring (7));
|
Controller.LinkClicked (args.Request.Uri);
|
||||||
|
|
||||||
// Don't follow HREFs (as this would cause a page refresh)
|
// Don't follow HREFs (as this would cause a page refresh)
|
||||||
if (!args.Request.Uri.Equals ("file:"))
|
if (!args.Request.Uri.Equals ("file:"))
|
||||||
|
@ -260,7 +283,8 @@ namespace SparkleShare {
|
||||||
html = html.Replace ("<!-- $day-entry-header-background-color -->", SparkleUIHelpers.GdkColorToHex (Style.Background (StateType.Normal)));
|
html = html.Replace ("<!-- $day-entry-header-background-color -->", SparkleUIHelpers.GdkColorToHex (Style.Background (StateType.Normal)));
|
||||||
html = html.Replace ("<!-- $secondary-font-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
html = html.Replace ("<!-- $secondary-font-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
||||||
html = html.Replace ("<!-- $small-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
html = html.Replace ("<!-- $small-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
||||||
|
html = html.Replace ("<!-- $small-font-size -->", "85%");
|
||||||
|
|
||||||
html = html.Replace ("<!-- $pixmaps-path -->", pixmaps_path);
|
html = html.Replace ("<!-- $pixmaps-path -->", pixmaps_path);
|
||||||
|
|
||||||
html = html.Replace ("<!-- $document-added-background-image -->",
|
html = html.Replace ("<!-- $document-added-background-image -->",
|
||||||
|
|
|
@ -83,5 +83,5 @@ SparkleShare/Windows/SparkleShare.wxs
|
||||||
|
|
||||||
### Uninstalling
|
### Uninstalling
|
||||||
|
|
||||||
Simple remove the SparkleShare bundle.
|
Simply remove the SparkleShare bundle.
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ namespace SparkleShare {
|
||||||
new SizeF (ContentView.Frame.Width, ContentView.Frame.Height - 39))
|
new SizeF (ContentView.Frame.Width, ContentView.Frame.Height - 39))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.hidden_close_button = new NSButton () {
|
this.hidden_close_button = new NSButton () {
|
||||||
KeyEquivalentModifierMask = NSEventModifierMask.CommandKeyMask,
|
KeyEquivalentModifierMask = NSEventModifierMask.CommandKeyMask,
|
||||||
KeyEquivalent = "w"
|
KeyEquivalent = "w"
|
||||||
|
@ -197,7 +198,7 @@ namespace SparkleShare {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Controller.UpdateChooserEvent += delegate (string [] folders) {
|
Controller.UpdateChooserEvent += delegate (string [] folders) {
|
||||||
using (var a = new NSAutoreleasePool ())
|
using (var a = new NSAutoreleasePool ())
|
||||||
{
|
{
|
||||||
|
@ -207,6 +208,15 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Controller.UpdateChooserEnablementEvent += delegate (bool enabled) {
|
||||||
|
using (var a = new NSAutoreleasePool ())
|
||||||
|
{
|
||||||
|
InvokeOnMainThread (delegate {
|
||||||
|
this.popup_button.Enabled = enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Controller.UpdateContentEvent += delegate (string html) {
|
Controller.UpdateContentEvent += delegate (string html) {
|
||||||
using (var a = new NSAutoreleasePool ())
|
using (var a = new NSAutoreleasePool ())
|
||||||
{
|
{
|
||||||
|
@ -228,7 +238,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 +248,30 @@ 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) {
|
||||||
|
string target_file_path = Path.Combine (panel.DirectoryUrl.RelativePath, panel.NameFieldStringValue);
|
||||||
|
Controller.SaveDialogCompleted (target_file_path);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Controller.SaveDialogCancelled ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -346,6 +380,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");
|
||||||
|
@ -372,7 +407,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
this.web_view.MainFrame.LoadHtmlString (html, new NSUrl (""));
|
this.web_view.MainFrame.LoadHtmlString (html, new NSUrl (""));
|
||||||
|
|
||||||
web_view.PolicyDelegate = new SparkleWebPolicyDelegate ();
|
this.web_view.PolicyDelegate = new SparkleWebPolicyDelegate ();
|
||||||
ContentView.AddSubview (this.web_view);
|
ContentView.AddSubview (this.web_view);
|
||||||
|
|
||||||
(this.web_view.PolicyDelegate as SparkleWebPolicyDelegate).LinkClicked +=
|
(this.web_view.PolicyDelegate as SparkleWebPolicyDelegate).LinkClicked +=
|
||||||
|
|
|
@ -76,13 +76,13 @@ namespace SparkleShare {
|
||||||
this.syncing_idle_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-idle.png"));
|
this.syncing_idle_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-idle.png"));
|
||||||
this.syncing_up_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-up.png"));
|
this.syncing_up_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-up.png"));
|
||||||
this.syncing_down_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-down.png"));
|
this.syncing_down_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-down.png"));
|
||||||
this.syncing_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing.png"));
|
this.syncing_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing.png"));
|
||||||
this.syncing_error_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-error.png"));
|
this.syncing_error_image = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-error.png"));
|
||||||
|
|
||||||
this.syncing_idle_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-idle-active.png"));
|
this.syncing_idle_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-idle-active.png"));
|
||||||
this.syncing_up_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-up-active.png"));
|
this.syncing_up_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-up-active.png"));
|
||||||
this.syncing_down_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-down-active.png"));
|
this.syncing_down_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-down-active.png"));
|
||||||
this.syncing_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-active.png"));
|
this.syncing_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-active.png"));
|
||||||
this.syncing_error_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-error-active.png"));
|
this.syncing_error_image_active = new NSImage (Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "process-syncing-error-active.png"));
|
||||||
|
|
||||||
this.status_item.Image = this.syncing_idle_image;
|
this.status_item.Image = this.syncing_idle_image;
|
||||||
|
|
|
@ -260,6 +260,7 @@ namespace SparkleShare {
|
||||||
CheckRepositories ();
|
CheckRepositories ();
|
||||||
RepositoriesLoaded = true;
|
RepositoriesLoaded = true;
|
||||||
FolderListChanged ();
|
FolderListChanged ();
|
||||||
|
UpdateState ();
|
||||||
|
|
||||||
}).Start ();
|
}).Start ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -33,15 +34,23 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public event UpdateContentEventEventHandler UpdateContentEvent = delegate { };
|
public event UpdateContentEventEventHandler UpdateContentEvent = delegate { };
|
||||||
public delegate void UpdateContentEventEventHandler (string html);
|
public delegate void UpdateContentEventEventHandler (string html);
|
||||||
|
|
||||||
public event UpdateChooserEventHandler UpdateChooserEvent = delegate { };
|
public event UpdateChooserEventHandler UpdateChooserEvent = delegate { };
|
||||||
public delegate void UpdateChooserEventHandler (string [] folders);
|
public delegate void UpdateChooserEventHandler (string [] folders);
|
||||||
|
|
||||||
|
public event UpdateChooserEnablementEventHandler UpdateChooserEnablementEvent = delegate { };
|
||||||
|
public delegate void UpdateChooserEnablementEventHandler (bool enabled);
|
||||||
|
|
||||||
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;
|
||||||
|
private bool history_view_active;
|
||||||
|
|
||||||
|
|
||||||
public bool WindowIsOpen { get; private set; }
|
public bool WindowIsOpen { get; private set; }
|
||||||
|
@ -57,10 +66,10 @@ namespace SparkleShare {
|
||||||
ContentLoadingEvent ();
|
ContentLoadingEvent ();
|
||||||
UpdateSizeInfoEvent ("…", "…");
|
UpdateSizeInfoEvent ("…", "…");
|
||||||
|
|
||||||
Stopwatch watch = new Stopwatch ();
|
|
||||||
watch.Start ();
|
|
||||||
|
|
||||||
new Thread (() => {
|
new Thread (() => {
|
||||||
|
Stopwatch watch = new Stopwatch ();
|
||||||
|
watch.Start ();
|
||||||
|
|
||||||
string html = HTML;
|
string html = HTML;
|
||||||
watch.Stop ();
|
watch.Stop ();
|
||||||
|
|
||||||
|
@ -161,6 +170,7 @@ namespace SparkleShare {
|
||||||
Thread.Sleep (delay - (int) watch.ElapsedMilliseconds);
|
Thread.Sleep (delay - (int) watch.ElapsedMilliseconds);
|
||||||
|
|
||||||
UpdateChooserEvent (Folders);
|
UpdateChooserEvent (Folders);
|
||||||
|
UpdateChooserEnablementEvent (true);
|
||||||
UpdateContentEvent (html);
|
UpdateContentEvent (html);
|
||||||
UpdateSizeInfoEvent (Size, HistorySize);
|
UpdateSizeInfoEvent (Size, HistorySize);
|
||||||
|
|
||||||
|
@ -173,6 +183,9 @@ namespace SparkleShare {
|
||||||
};
|
};
|
||||||
|
|
||||||
Program.Controller.OnIdle += delegate {
|
Program.Controller.OnIdle += delegate {
|
||||||
|
if (this.history_view_active)
|
||||||
|
return;
|
||||||
|
|
||||||
ContentLoadingEvent ();
|
ContentLoadingEvent ();
|
||||||
UpdateSizeInfoEvent ("…", "…");
|
UpdateSizeInfoEvent ("…", "…");
|
||||||
|
|
||||||
|
@ -212,15 +225,98 @@ namespace SparkleShare {
|
||||||
public void LinkClicked (string url)
|
public void LinkClicked (string url)
|
||||||
{
|
{
|
||||||
url = url.Replace ("%20", " ");
|
url = url.Replace ("%20", " ");
|
||||||
|
|
||||||
if (url.StartsWith (Path.VolumeSeparatorChar.ToString ()) ||
|
|
||||||
url.Substring (1, 1).Equals (":")) {
|
|
||||||
|
|
||||||
Program.Controller.OpenFile (url);
|
|
||||||
|
|
||||||
} else if (url.StartsWith ("http")) {
|
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]+)/(.+)/(.{3} [0-9]+ [0-9]+h[0-9]+)/(.+)", RegexOptions.Compiled);
|
||||||
|
Match match = regex.Match (url);
|
||||||
|
|
||||||
|
if (match.Success) {
|
||||||
|
string author_name = match.Groups [3].Value;
|
||||||
|
string timestamp = match.Groups [4].Value;
|
||||||
|
|
||||||
|
this.restore_revision_info = new RevisionInfo () {
|
||||||
|
Folder = new SparkleFolder (match.Groups [1].Value),
|
||||||
|
Revision = match.Groups [2].Value,
|
||||||
|
FilePath = match.Groups [5].Value
|
||||||
|
};
|
||||||
|
|
||||||
|
string file_name = Path.GetFileNameWithoutExtension (this.restore_revision_info.FilePath) +
|
||||||
|
" (" + author_name + " " + timestamp + ")" + 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 if (url.StartsWith ("back://")) {
|
||||||
|
this.history_view_active = false;
|
||||||
|
SelectedFolder = this.selected_folder; // TODO: Return to the same position on the page
|
||||||
|
|
||||||
|
UpdateChooserEnablementEvent (true);
|
||||||
|
|
||||||
|
} else if (url.StartsWith ("history://")) {
|
||||||
|
this.history_view_active = true;
|
||||||
|
|
||||||
|
ContentLoadingEvent ();
|
||||||
|
UpdateSizeInfoEvent ("…", "…");
|
||||||
|
UpdateChooserEnablementEvent (false);
|
||||||
|
|
||||||
|
string folder = url.Replace ("history://", "").Split ("/".ToCharArray ()) [0];
|
||||||
|
string file_path = url.Replace ("history://" + folder + "/", "");
|
||||||
|
|
||||||
|
foreach (SparkleRepoBase repo in Program.Controller.Repositories) {
|
||||||
|
if (!repo.Name.Equals (folder))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
new Thread (() => {
|
||||||
|
Stopwatch watch = new Stopwatch ();
|
||||||
|
watch.Start ();
|
||||||
|
|
||||||
|
List<SparkleChangeSet> change_sets = repo.GetChangeSets (file_path);
|
||||||
|
string html = GetHistoryHTMLLog (change_sets, file_path);
|
||||||
|
|
||||||
|
watch.Stop ();
|
||||||
|
int delay = 500;
|
||||||
|
|
||||||
|
if (watch.ElapsedMilliseconds < delay)
|
||||||
|
Thread.Sleep (delay - (int) watch.ElapsedMilliseconds);
|
||||||
|
|
||||||
|
UpdateContentEvent (html);
|
||||||
|
|
||||||
|
}).Start ();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Program.Controller.OpenFile (url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
Program.Controller.OpenFolder (Path.GetDirectoryName (target_file_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SaveDialogCancelled ()
|
||||||
|
{
|
||||||
|
this.restore_revision_info = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,6 +357,56 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string GetHistoryHTMLLog (List<SparkleChangeSet> change_sets, string file_path)
|
||||||
|
{
|
||||||
|
string html = "<div class='history-header'>" +
|
||||||
|
"<a class='windows' href='back://'>« Back</a> | ";
|
||||||
|
|
||||||
|
if (change_sets.Count > 1)
|
||||||
|
html += "Revisions for <b>“";
|
||||||
|
else
|
||||||
|
html += "No revisions for <b>“";
|
||||||
|
|
||||||
|
html += Path.GetFileName (file_path) + "”</b>";
|
||||||
|
html += "</div><div class='table-wrapper'><table>";
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
foreach (SparkleChangeSet change_set in change_sets) {
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (count == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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'>" + change_set.User.Name + "</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 + "/" + change_set.User.Name + "/" +
|
||||||
|
change_set.Timestamp.ToString ("MMM d H\\hmm") + "/" +
|
||||||
|
file_path + "'>Restore…</a>" +
|
||||||
|
"</td>" +
|
||||||
|
"</tr>";
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "</table></div>";
|
||||||
|
html = Program.Controller.EventLogHTML.Replace ("<!-- $event-log-content -->", html);
|
||||||
|
|
||||||
|
return html.Replace ("<!-- $midnight -->", "100000000");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
|
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
|
||||||
{
|
{
|
||||||
if (change_sets.Count == 0)
|
if (change_sets.Count == 0)
|
||||||
|
@ -307,12 +453,22 @@ 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>";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
event_entry += "<dd class='moved'>";
|
event_entry += "<dd class='moved'>";
|
||||||
|
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 += "<br>";
|
event_entry += "<br>";
|
||||||
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> ";
|
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> ";
|
||||||
|
@ -444,5 +600,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace SparkleShare {
|
||||||
SparkleLink website_link = new SparkleLink ("Website", Controller.WebsiteLinkAddress);
|
SparkleLink website_link = new SparkleLink ("Website", Controller.WebsiteLinkAddress);
|
||||||
SparkleLink credits_link = new SparkleLink ("Credits", Controller.CreditsLinkAddress);
|
SparkleLink credits_link = new SparkleLink ("Credits", Controller.CreditsLinkAddress);
|
||||||
SparkleLink report_problem_link = new SparkleLink ("Report a problem", Controller.ReportProblemLinkAddress);
|
SparkleLink report_problem_link = new SparkleLink ("Report a problem", Controller.ReportProblemLinkAddress);
|
||||||
SparkleLink debug_log_link = new SparkleLink ("Debig log", Controller.DebugLogLinkAddress);
|
SparkleLink debug_log_link = new SparkleLink ("Debug log", Controller.DebugLogLinkAddress);
|
||||||
|
|
||||||
Canvas canvas = new Canvas ();
|
Canvas canvas = new Canvas ();
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
canvas.Children.Add (debug_log_link);
|
canvas.Children.Add (debug_log_link);
|
||||||
Canvas.SetLeft (debug_log_link, 289 + website_link.ActualWidth + credits_link.ActualWidth +
|
Canvas.SetLeft (debug_log_link, 289 + website_link.ActualWidth + credits_link.ActualWidth +
|
||||||
report_problem_link.ActualWidth + 180);
|
report_problem_link.ActualWidth + 220);
|
||||||
Canvas.SetTop (debug_log_link, 222);
|
Canvas.SetTop (debug_log_link, 222);
|
||||||
|
|
||||||
Content = canvas;
|
Content = canvas;
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see (http://www.gnu.org/licenses/).
|
// along with this program. If not, see (http://www.gnu.org/licenses/).
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -26,6 +25,7 @@ using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
using Microsoft.Win32;
|
||||||
using Shapes = System.Windows.Shapes;
|
using Shapes = System.Windows.Shapes;
|
||||||
|
|
||||||
namespace SparkleShare {
|
namespace SparkleShare {
|
||||||
|
@ -50,7 +50,7 @@ namespace SparkleShare {
|
||||||
ResizeMode = ResizeMode.NoResize; // TODO
|
ResizeMode = ResizeMode.NoResize; // TODO
|
||||||
Background = new SolidColorBrush (Color.FromRgb (240, 240, 240));
|
Background = new SolidColorBrush (Color.FromRgb (240, 240, 240));
|
||||||
AllowsTransparency = false;
|
AllowsTransparency = false;
|
||||||
Icon = SparkleUIHelpers.GetImageSource("sparkleshare-app", "ico");
|
Icon = SparkleUIHelpers.GetImageSource ("sparkleshare-app", "ico");
|
||||||
|
|
||||||
int x = (int) (SystemParameters.PrimaryScreenWidth * 0.61);
|
int x = (int) (SystemParameters.PrimaryScreenWidth * 0.61);
|
||||||
int y = (int) (SystemParameters.PrimaryScreenHeight * 0.5 - (Height * 0.5));
|
int y = (int) (SystemParameters.PrimaryScreenHeight * 0.5 - (Height * 0.5));
|
||||||
|
@ -104,6 +104,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
this.web_browser.ObjectForScripting = new SparkleScriptingObject ();
|
this.web_browser.ObjectForScripting = new SparkleScriptingObject ();
|
||||||
|
|
||||||
|
|
||||||
spinner = new SparkleSpinner (22);
|
spinner = new SparkleSpinner (22);
|
||||||
|
|
||||||
// Disable annoying IE clicking sound
|
// Disable annoying IE clicking sound
|
||||||
|
@ -177,6 +178,12 @@ namespace SparkleShare {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Controller.UpdateChooserEnablementEvent += delegate (bool enabled) {
|
||||||
|
Dispatcher.BeginInvoke ((Action) delegate {
|
||||||
|
this.combo_box.IsEnabled = enabled;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Controller.UpdateContentEvent += delegate (string html) {
|
Controller.UpdateContentEvent += delegate (string html) {
|
||||||
Dispatcher.BeginInvoke ((Action) delegate {
|
Dispatcher.BeginInvoke ((Action) delegate {
|
||||||
UpdateContent (html);
|
UpdateContent (html);
|
||||||
|
@ -191,6 +198,25 @@ namespace SparkleShare {
|
||||||
this.canvas.Children.Remove (this.web_browser);
|
this.canvas.Children.Remove (this.web_browser);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Controller.ShowSaveDialogEvent += delegate (string file_name, string target_folder_path) {
|
||||||
|
Dispatcher.BeginInvoke ((Action) delegate {
|
||||||
|
SaveFileDialog dialog = new SaveFileDialog () {
|
||||||
|
FileName = file_name,
|
||||||
|
InitialDirectory = target_folder_path,
|
||||||
|
Title = "Restore from History",
|
||||||
|
DefaultExt = "." + Path.GetExtension (file_name),
|
||||||
|
Filter = "All Files|*.*"
|
||||||
|
};
|
||||||
|
|
||||||
|
Nullable<bool> result = dialog.ShowDialog (this);
|
||||||
|
|
||||||
|
if (result == true)
|
||||||
|
Controller.SaveDialogCompleted (dialog.FileName);
|
||||||
|
else
|
||||||
|
Controller.SaveDialogCancelled ();
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -262,6 +288,7 @@ namespace SparkleShare {
|
||||||
html = html.Replace ("<!-- $body-font-size -->", "12px");
|
html = html.Replace ("<!-- $body-font-size -->", "12px");
|
||||||
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 -->", "90%");
|
||||||
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");
|
||||||
|
@ -282,9 +309,10 @@ namespace SparkleShare {
|
||||||
|
|
||||||
Dispatcher.BeginInvoke ((Action) delegate {
|
Dispatcher.BeginInvoke ((Action) delegate {
|
||||||
this.spinner.Stop ();
|
this.spinner.Stop ();
|
||||||
|
|
||||||
this.web_browser.NavigateToString (html);
|
this.web_browser.ObjectForScripting = new SparkleScriptingObject ();
|
||||||
|
this.web_browser.NavigateToString (html);
|
||||||
|
|
||||||
if (!this.canvas.Children.Contains (this.web_browser)) {
|
if (!this.canvas.Children.Contains (this.web_browser)) {
|
||||||
this.canvas.Children.Add (this.web_browser);
|
this.canvas.Children.Add (this.web_browser);
|
||||||
Canvas.SetLeft (this.web_browser, 0);
|
Canvas.SetLeft (this.web_browser, 0);
|
||||||
|
@ -322,8 +350,8 @@ namespace SparkleShare {
|
||||||
string [] actions = new string [] {"added", "deleted", "edited", "moved"};
|
string [] actions = new string [] {"added", "deleted", "edited", "moved"};
|
||||||
|
|
||||||
foreach (string action in actions) {
|
foreach (string action in actions) {
|
||||||
BitmapSource image = SparkleUIHelpers.GetImageSource ("document-" + action + "-12");
|
image = SparkleUIHelpers.GetImageSource ("document-" + action + "-12");
|
||||||
string file_path = Path.Combine (pixmaps_path, "document-" + action + "-12.png");
|
file_path = Path.Combine (pixmaps_path, "document-" + action + "-12.png");
|
||||||
|
|
||||||
using (FileStream stream = new FileStream (file_path, FileMode.Create))
|
using (FileStream stream = new FileStream (file_path, FileMode.Create))
|
||||||
{
|
{
|
||||||
|
@ -345,8 +373,8 @@ namespace SparkleShare {
|
||||||
[DllImport ("urlmon.dll")]
|
[DllImport ("urlmon.dll")]
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
[return:MarshalAs (UnmanagedType.Error)]
|
[return:MarshalAs (UnmanagedType.Error)]
|
||||||
static extern int CoInternetSetFeatureEnabled (
|
static extern int CoInternetSetFeatureEnabled (int feature,
|
||||||
int feature, [MarshalAs (UnmanagedType.U4)] int flags, bool enable);
|
[MarshalAs (UnmanagedType.U4)] int flags, bool enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||||
|
|
||||||
<Product Name='SparkleShare' Id='184950D5-67F6-4D06-9717-7E2F1607A7B0' UpgradeCode='D3DF1D99-87F5-47A7-A349-863DD6E4B73A'
|
<Product Name='SparkleShare' Id='184950D5-67F6-4D06-9717-7E2F1607A7B0' UpgradeCode='D3DF1D99-87F5-47A7-A349-863DD6E4B73A'
|
||||||
Language='1033' Codepage='1252' Version='0.9.3' Manufacturer='SparkleShare'>
|
Language='1033' Codepage='1252' Version='0.9.4' Manufacturer='SparkleShare'>
|
||||||
|
|
||||||
<Package Id='*' Keywords='Installer' Description="SparkleShare Setup" Manufacturer='SparkleShare'
|
<Package Id='*' Keywords='Installer' Description="SparkleShare Setup" Manufacturer='SparkleShare'
|
||||||
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
|
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
m4_define([sparkleshare_version], [0.9.3])
|
m4_define([sparkleshare_version], [0.9.4])
|
||||||
|
|
||||||
AC_PREREQ([2.54])
|
AC_PREREQ([2.54])
|
||||||
AC_INIT([SparkleShare], sparkleshare_version)
|
AC_INIT([SparkleShare], sparkleshare_version)
|
||||||
|
|
Loading…
Reference in a new issue