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:
|
||||
- Fix endless loop when adding empty folders
|
||||
|
|
|
@ -19,7 +19,7 @@ using System;
|
|||
using System.Reflection;
|
||||
|
||||
[assembly:AssemblyTitle ("SparkleLib")]
|
||||
[assembly:AssemblyVersion ("0.9.3")]
|
||||
[assembly:AssemblyVersion ("0.9.4")]
|
||||
[assembly:AssemblyCopyright ("Copyright (c) 2010 Hylke Bons and others")]
|
||||
[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...
|
||||
SparkleGit git = new SparkleGit (TargetFolder, "branch -a");
|
||||
git.StartAndWaitForExit ();
|
||||
|
||||
string [] branches = git.StartAndReadStandardOutput ().Split (Environment.NewLine.ToCharArray ());
|
||||
// TODO double check env.newline ^
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
using SparkleLib;
|
||||
|
||||
|
@ -29,6 +30,7 @@ namespace SparkleLib.Git {
|
|||
|
||||
private bool user_is_set;
|
||||
private bool use_git_bin;
|
||||
private bool is_encrypted;
|
||||
|
||||
|
||||
public SparkleRepo (string path, SparkleConfig config) : base (path, config)
|
||||
|
@ -50,6 +52,11 @@ namespace SparkleLib.Git {
|
|||
git = new SparkleGit (LocalPath, "rebase --abort");
|
||||
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 ("|")) {
|
||||
speed = line.Substring (line.IndexOf ("|") + 1).Trim ();
|
||||
speed = speed.Replace (", done.", "").Trim ();
|
||||
speed = speed.Replace ("i", "");
|
||||
speed = speed.Replace ("KB/s", "ᴋʙ/s");
|
||||
speed = speed.Replace ("MB/s", "ᴍʙ/s");
|
||||
speed = speed.Replace ("KiB/s", "ᴋʙ/s");
|
||||
speed = speed.Replace ("MiB/s", "ᴍʙ/s");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,6 +474,7 @@ namespace SparkleLib.Git {
|
|||
foreach (string line in lines) {
|
||||
string conflicting_path = line.Substring (3);
|
||||
conflicting_path = EnsureSpecialCharacters (conflicting_path);
|
||||
conflicting_path = conflicting_path.Replace ("\"", "\\\"");
|
||||
|
||||
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)
|
||||
throw new ArgumentNullException ("path");
|
||||
|
@ -547,27 +554,58 @@ namespace SparkleLib.Git {
|
|||
if (revision == null)
|
||||
throw new ArgumentNullException ("revision");
|
||||
|
||||
path = path.Replace ("\\", "/");
|
||||
SparkleLogger.LogInfo ("Git", Name + " | Restoring \"" + path + "\" (revision " + revision + ")");
|
||||
|
||||
SparkleGit git = new SparkleGit (LocalPath, "checkout " + revision + " \"" + path + "\"");
|
||||
git.StartAndWaitForExit ();
|
||||
// FIXME: git-show doesn't decrypt objects, so we can't use it to retrieve
|
||||
// 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)
|
||||
SparkleLogger.LogInfo ("Git", Name + " | Checked out \"" + path + "\" (" + revision + ")");
|
||||
else
|
||||
SparkleLogger.LogInfo ("Git", Name + " | Failed to check out \"" + path + "\" (" + revision + ")");
|
||||
string local_file_path = Path.Combine (LocalPath, path);
|
||||
|
||||
// ...move it...
|
||||
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) {
|
||||
SparkleLogger.LogInfo ("Git", Name + " | Error status changed to " + Error);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
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> ();
|
||||
|
||||
SparkleGit git;
|
||||
|
||||
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");
|
||||
|
||||
} else {
|
||||
path = path.Replace ("\\", "/");
|
||||
|
||||
git = new SparkleGit (LocalPath, "log -" + count + " --raw --find-renames --date=iso " +
|
||||
"--format=medium --no-color --no-merges -- " + path);
|
||||
git = new SparkleGit (LocalPath, "log --raw --find-renames --date=iso " +
|
||||
"--format=medium --no-color --no-merges -- \"" + path + "\"");
|
||||
}
|
||||
|
||||
string output = git.StartAndReadStandardOutput ();
|
||||
|
@ -681,13 +715,16 @@ namespace SparkleLib.Git {
|
|||
if (entry_line.StartsWith (":")) {
|
||||
string type_letter = entry_line [37].ToString ();
|
||||
string file_path = entry_line.Substring (39);
|
||||
|
||||
if (file_path.EndsWith (".empty"))
|
||||
file_path = file_path.Substring (0, file_path.Length - ".empty".Length);
|
||||
bool change_is_folder = false;
|
||||
|
||||
if (file_path.Equals (".sparkleshare"))
|
||||
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 = file_path.Replace ("\\\"", "\"");
|
||||
|
||||
|
@ -702,15 +739,20 @@ namespace SparkleLib.Git {
|
|||
file_path = 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);
|
||||
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);
|
||||
change_is_folder = true;
|
||||
}
|
||||
|
||||
change_set.Changes.Add (
|
||||
new SparkleChange () {
|
||||
Path = file_path,
|
||||
IsFolder = change_is_folder,
|
||||
MovedToPath = to_file_path,
|
||||
Timestamp = change_set.Timestamp,
|
||||
Type = SparkleChangeType.Moved
|
||||
|
@ -730,6 +772,7 @@ namespace SparkleLib.Git {
|
|||
change_set.Changes.Add (
|
||||
new SparkleChange () {
|
||||
Path = file_path,
|
||||
IsFolder = change_is_folder,
|
||||
Timestamp = change_set.Timestamp,
|
||||
Type = change_type
|
||||
}
|
||||
|
|
|
@ -184,6 +184,7 @@ namespace SparkleLib {
|
|||
|
||||
if (File.Exists (identifier_path)) {
|
||||
Identifier = File.ReadAllText (identifier_path).Trim ();
|
||||
File.SetAttributes (identifier_path, FileAttributes.Hidden);
|
||||
|
||||
} else {
|
||||
Identifier = CreateIdentifier ();
|
||||
|
@ -220,9 +221,8 @@ namespace SparkleLib {
|
|||
"Any files you add or change in this folder will be automatically synced to " + n +
|
||||
uri_builder.ToString () + " and everyone connected to it." + n +
|
||||
n +
|
||||
"SparkleShare is an Open Source software program that helps people " + n +
|
||||
"collaborate and share files. If you like what we do, please consider a small " + n +
|
||||
"donation to support the project: http://www.sparkleshare.org/" + n +
|
||||
"SparkleShare is an Open Source software program that helps people collaborate and " + n +
|
||||
"share files. If you like what we do, consider buying us a beer: http://www.sparkleshare.org/" + n +
|
||||
n +
|
||||
"Have fun! :)" + n;
|
||||
}
|
||||
|
|
|
@ -54,9 +54,9 @@ namespace SparkleLib {
|
|||
public abstract bool HasRemoteChanges { get; }
|
||||
public abstract bool SyncUp ();
|
||||
public abstract bool SyncDown ();
|
||||
public abstract List<SparkleChangeSet> GetChangeSets (int count);
|
||||
public abstract List<SparkleChangeSet> GetChangeSets (string path, int count);
|
||||
public abstract void RevertFile (string path, string revision);
|
||||
public abstract List<SparkleChangeSet> GetChangeSets ();
|
||||
public abstract List<SparkleChangeSet> GetChangeSets (string path);
|
||||
public abstract void RestoreFile (string path, string revision, string target_file_path);
|
||||
|
||||
public event SyncStatusChangedEventHandler SyncStatusChanged = delegate { };
|
||||
public delegate void SyncStatusChangedEventHandler (SyncStatus new_status);
|
||||
|
@ -195,19 +195,17 @@ namespace SparkleLib {
|
|||
|
||||
// Sync up everything that changed
|
||||
// since we've been offline
|
||||
if (!this.is_syncing && (HasLocalChanges || HasUnsyncedChanges)) {
|
||||
SyncUpBase ();
|
||||
|
||||
while (HasLocalChanges)
|
||||
new Thread (() => {
|
||||
if (!this.is_syncing && (HasLocalChanges || HasUnsyncedChanges)) {
|
||||
SyncUpBase ();
|
||||
}
|
||||
|
||||
this.remote_timer.Start ();
|
||||
}
|
||||
while (HasLocalChanges && !this.is_syncing)
|
||||
SyncUpBase ();
|
||||
}
|
||||
|
||||
|
||||
public List<SparkleChangeSet> GetChangeSets () {
|
||||
return GetChangeSets (30);
|
||||
this.remote_timer.Start ();
|
||||
|
||||
}).Start ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -218,9 +216,11 @@ namespace SparkleLib {
|
|||
if (IsBuffering)
|
||||
return;
|
||||
|
||||
foreach (string exclude_path in ExcludePaths) {
|
||||
if (args.FullPath.Contains (exclude_path))
|
||||
return;
|
||||
if (args != null) {
|
||||
foreach (string exclude_path in ExcludePaths) {
|
||||
if (args.FullPath.Contains (exclude_path))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lock (this.buffer_lock) {
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace SparkleLib {
|
|||
|
||||
public SparkleChangeType Type;
|
||||
public DateTime Timestamp;
|
||||
public bool IsFolder = false;
|
||||
|
||||
public string Path;
|
||||
public string MovedToPath;
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
$('dl dd:nth-child(-n+10)').css('display', 'block');
|
||||
$('.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"));
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Update the Today and Yesterday labels after midnight
|
||||
|
@ -26,7 +27,7 @@
|
|||
}
|
||||
}, 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 () {
|
||||
var entry_count = $(this).parent ().find ('dl').children ().length;
|
||||
|
||||
|
@ -67,7 +68,6 @@
|
|||
|
||||
a.show {
|
||||
font-size: 80%;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
|
@ -76,7 +76,7 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
small {
|
||||
small, small a, small a:hover {
|
||||
font-size: <!-- $small-font-size -->;
|
||||
color: <!-- $secondary-font-color -->;
|
||||
}
|
||||
|
@ -91,13 +91,12 @@
|
|||
display: none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 90%;
|
||||
padding: 0 0 1px 20px;
|
||||
margin: 0 0 4px 0;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.day-entry-header {
|
||||
|
@ -107,13 +106,24 @@
|
|||
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 {
|
||||
padding: 24px 14px 14px 64px;
|
||||
margin: 0 32px 0 32px;
|
||||
border-bottom: 1px #ddd solid;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 36px 24px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.event-user-name {
|
||||
|
@ -152,7 +162,54 @@
|
|||
|
||||
.moved {
|
||||
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>
|
||||
</head>
|
||||
<body oncontextmenu="return false;">
|
||||
|
|
|
@ -131,12 +131,35 @@ namespace SparkleShare {
|
|||
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) {
|
||||
Application.Invoke (delegate {
|
||||
UpdateChooser (folders);
|
||||
});
|
||||
};
|
||||
|
||||
Controller.UpdateChooserEnablementEvent += delegate (bool enabled) {
|
||||
Application.Invoke (delegate {
|
||||
this.combo_box.Sensitive = enabled;
|
||||
});
|
||||
};
|
||||
|
||||
Controller.UpdateContentEvent += delegate (string html) {
|
||||
Application.Invoke (delegate {
|
||||
|
@ -168,7 +191,7 @@ namespace SparkleShare {
|
|||
|
||||
|
||||
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)
|
||||
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 ("<!-- $secondary-font-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 ("<!-- $document-added-background-image -->",
|
||||
|
|
|
@ -83,5 +83,5 @@ SparkleShare/Windows/SparkleShare.wxs
|
|||
|
||||
### 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))
|
||||
};
|
||||
|
||||
|
||||
this.hidden_close_button = new NSButton () {
|
||||
KeyEquivalentModifierMask = NSEventModifierMask.CommandKeyMask,
|
||||
KeyEquivalent = "w"
|
||||
|
@ -197,7 +198,7 @@ namespace SparkleShare {
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Controller.UpdateChooserEvent += delegate (string [] folders) {
|
||||
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) {
|
||||
using (var a = new NSAutoreleasePool ())
|
||||
{
|
||||
|
@ -228,7 +238,7 @@ namespace SparkleShare {
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Controller.UpdateSizeInfoEvent += delegate (string size, string history_size) {
|
||||
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 ("<!-- $secondary-font-color -->", "#bbb");
|
||||
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 ("<!-- $a-color -->", "#0085cf");
|
||||
html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
|
||||
|
@ -372,7 +407,7 @@ namespace SparkleShare {
|
|||
|
||||
this.web_view.MainFrame.LoadHtmlString (html, new NSUrl (""));
|
||||
|
||||
web_view.PolicyDelegate = new SparkleWebPolicyDelegate ();
|
||||
this.web_view.PolicyDelegate = new SparkleWebPolicyDelegate ();
|
||||
ContentView.AddSubview (this.web_view);
|
||||
|
||||
(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_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_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_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_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.status_item.Image = this.syncing_idle_image;
|
||||
|
|
|
@ -260,6 +260,7 @@ namespace SparkleShare {
|
|||
CheckRepositories ();
|
||||
RepositoriesLoaded = true;
|
||||
FolderListChanged ();
|
||||
UpdateState ();
|
||||
|
||||
}).Start ();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
using SparkleLib;
|
||||
|
@ -33,15 +34,23 @@ namespace SparkleShare {
|
|||
|
||||
public event UpdateContentEventEventHandler UpdateContentEvent = delegate { };
|
||||
public delegate void UpdateContentEventEventHandler (string html);
|
||||
|
||||
|
||||
public event UpdateChooserEventHandler UpdateChooserEvent = delegate { };
|
||||
public delegate void UpdateChooserEventHandler (string [] folders);
|
||||
|
||||
|
||||
public event UpdateChooserEnablementEventHandler UpdateChooserEnablementEvent = delegate { };
|
||||
public delegate void UpdateChooserEnablementEventHandler (bool enabled);
|
||||
|
||||
public event UpdateSizeInfoEventHandler UpdateSizeInfoEvent = delegate { };
|
||||
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 RevisionInfo restore_revision_info;
|
||||
private bool history_view_active;
|
||||
|
||||
|
||||
public bool WindowIsOpen { get; private set; }
|
||||
|
@ -57,10 +66,10 @@ namespace SparkleShare {
|
|||
ContentLoadingEvent ();
|
||||
UpdateSizeInfoEvent ("…", "…");
|
||||
|
||||
Stopwatch watch = new Stopwatch ();
|
||||
watch.Start ();
|
||||
|
||||
new Thread (() => {
|
||||
Stopwatch watch = new Stopwatch ();
|
||||
watch.Start ();
|
||||
|
||||
string html = HTML;
|
||||
watch.Stop ();
|
||||
|
||||
|
@ -161,6 +170,7 @@ namespace SparkleShare {
|
|||
Thread.Sleep (delay - (int) watch.ElapsedMilliseconds);
|
||||
|
||||
UpdateChooserEvent (Folders);
|
||||
UpdateChooserEnablementEvent (true);
|
||||
UpdateContentEvent (html);
|
||||
UpdateSizeInfoEvent (Size, HistorySize);
|
||||
|
||||
|
@ -173,6 +183,9 @@ namespace SparkleShare {
|
|||
};
|
||||
|
||||
Program.Controller.OnIdle += delegate {
|
||||
if (this.history_view_active)
|
||||
return;
|
||||
|
||||
ContentLoadingEvent ();
|
||||
UpdateSizeInfoEvent ("…", "…");
|
||||
|
||||
|
@ -212,15 +225,98 @@ namespace SparkleShare {
|
|||
public void LinkClicked (string url)
|
||||
{
|
||||
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);
|
||||
|
||||
} 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)
|
||||
{
|
||||
if (change_sets.Count == 0)
|
||||
|
@ -307,12 +453,22 @@ namespace SparkleShare {
|
|||
foreach (SparkleChange change in change_set.Changes) {
|
||||
if (change.Type != SparkleChangeType.Moved) {
|
||||
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 += "</dd>";
|
||||
|
||||
} else {
|
||||
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 += "<br>";
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 credits_link = new SparkleLink ("Credits", Controller.CreditsLinkAddress);
|
||||
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 ();
|
||||
|
||||
|
@ -154,7 +154,7 @@ namespace SparkleShare {
|
|||
|
||||
canvas.Children.Add (debug_log_link);
|
||||
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);
|
||||
|
||||
Content = canvas;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see (http://www.gnu.org/licenses/).
|
||||
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
|
@ -26,6 +25,7 @@ using System.Windows.Controls;
|
|||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
using Microsoft.Win32;
|
||||
using Shapes = System.Windows.Shapes;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
@ -50,7 +50,7 @@ namespace SparkleShare {
|
|||
ResizeMode = ResizeMode.NoResize; // TODO
|
||||
Background = new SolidColorBrush (Color.FromRgb (240, 240, 240));
|
||||
AllowsTransparency = false;
|
||||
Icon = SparkleUIHelpers.GetImageSource("sparkleshare-app", "ico");
|
||||
Icon = SparkleUIHelpers.GetImageSource ("sparkleshare-app", "ico");
|
||||
|
||||
int x = (int) (SystemParameters.PrimaryScreenWidth * 0.61);
|
||||
int y = (int) (SystemParameters.PrimaryScreenHeight * 0.5 - (Height * 0.5));
|
||||
|
@ -104,6 +104,7 @@ namespace SparkleShare {
|
|||
|
||||
this.web_browser.ObjectForScripting = new SparkleScriptingObject ();
|
||||
|
||||
|
||||
spinner = new SparkleSpinner (22);
|
||||
|
||||
// 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) {
|
||||
Dispatcher.BeginInvoke ((Action) delegate {
|
||||
UpdateContent (html);
|
||||
|
@ -191,6 +198,25 @@ namespace SparkleShare {
|
|||
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 ("<!-- $secondary-font-color -->", "#bbb");
|
||||
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 ("<!-- $a-color -->", "#0085cf");
|
||||
html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
|
||||
|
@ -282,9 +309,10 @@ namespace SparkleShare {
|
|||
|
||||
Dispatcher.BeginInvoke ((Action) delegate {
|
||||
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)) {
|
||||
this.canvas.Children.Add (this.web_browser);
|
||||
Canvas.SetLeft (this.web_browser, 0);
|
||||
|
@ -322,8 +350,8 @@ namespace SparkleShare {
|
|||
string [] actions = new string [] {"added", "deleted", "edited", "moved"};
|
||||
|
||||
foreach (string action in actions) {
|
||||
BitmapSource image = SparkleUIHelpers.GetImageSource ("document-" + action + "-12");
|
||||
string file_path = Path.Combine (pixmaps_path, "document-" + action + "-12.png");
|
||||
image = SparkleUIHelpers.GetImageSource ("document-" + action + "-12");
|
||||
file_path = Path.Combine (pixmaps_path, "document-" + action + "-12.png");
|
||||
|
||||
using (FileStream stream = new FileStream (file_path, FileMode.Create))
|
||||
{
|
||||
|
@ -345,8 +373,8 @@ namespace SparkleShare {
|
|||
[DllImport ("urlmon.dll")]
|
||||
[PreserveSig]
|
||||
[return:MarshalAs (UnmanagedType.Error)]
|
||||
static extern int CoInternetSetFeatureEnabled (
|
||||
int feature, [MarshalAs (UnmanagedType.U4)] int flags, bool enable);
|
||||
static extern int CoInternetSetFeatureEnabled (int feature,
|
||||
[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">
|
||||
|
||||
<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'
|
||||
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_INIT([SparkleShare], sparkleshare_version)
|
||||
|
|
Loading…
Reference in a new issue