Cache changesets in the backend

This commit is contained in:
Hylke Bons 2012-04-29 15:19:36 +01:00
parent bcfdb0bab4
commit 9800bcf421
10 changed files with 130 additions and 77 deletions

View file

@ -161,7 +161,7 @@ namespace SparkleLib.Git {
{ {
get { get {
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes..."); SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
SparkleGit git = new SparkleGit (LocalPath, "ls-remote \"" + Url + "\" master"); SparkleGit git = new SparkleGit (LocalPath, "ls-remote \"" + RemoteUrl + "\" master");
git.Start (); git.Start ();
git.WaitForExit (); git.WaitForExit ();
@ -196,7 +196,7 @@ namespace SparkleLib.Git {
SparkleGit git = new SparkleGit (LocalPath, SparkleGit git = new SparkleGit (LocalPath,
"push --progress " + // Redirects progress stats to standarderror "push --progress " + // Redirects progress stats to standarderror
"\"" + Url + "\" master"); "\"" + RemoteUrl + "\" master");
git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardError = true;
git.Start (); git.Start ();
@ -253,6 +253,7 @@ namespace SparkleLib.Git {
git.WaitForExit (); git.WaitForExit ();
UpdateSizes (); UpdateSizes ();
ChangeSets = GetChangeSets ();
if (git.ExitCode == 0) if (git.ExitCode == 0)
return true; return true;
@ -263,7 +264,7 @@ namespace SparkleLib.Git {
public override bool SyncDown () public override bool SyncDown ()
{ {
SparkleGit git = new SparkleGit (LocalPath, "fetch --progress \"" + Url + "\" master"); SparkleGit git = new SparkleGit (LocalPath, "fetch --progress \"" + RemoteUrl + "\" master");
git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardError = true;
git.Start (); git.Start ();
@ -322,10 +323,13 @@ namespace SparkleLib.Git {
Path.Combine (LocalPath, ".sparkleshare"), Path.Combine (LocalPath, ".sparkleshare"),
FileAttributes.Hidden FileAttributes.Hidden
); );
ChangeSets = GetChangeSets ();
return true; return true;
} else { } else {
ChangeSets = GetChangeSets ();
return false; return false;
} }
} }
@ -450,7 +454,7 @@ namespace SparkleLib.Git {
private void ResolveConflict () private void ResolveConflict ()
{ {
// This is al list of conflict status codes that Git uses, their // This is a list of conflict status codes that Git uses, their
// meaning, and how SparkleShare should handle them. // meaning, and how SparkleShare should handle them.
// //
// DD unmerged, both deleted -> Do nothing // DD unmerged, both deleted -> Do nothing
@ -558,7 +562,7 @@ namespace SparkleLib.Git {
// Returns a list of the latest change sets // Returns a list of the latest change sets
public override List <SparkleChangeSet> GetChangeSets (int count) public override List<SparkleChangeSet> GetChangeSets (int count)
{ {
if (count < 1) if (count < 1)
count = 30; count = 30;
@ -637,7 +641,7 @@ namespace SparkleLib.Git {
change_set.Revision = match.Groups [1].Value; change_set.Revision = match.Groups [1].Value;
change_set.User = new SparkleUser (match.Groups [2].Value, match.Groups [3].Value); change_set.User = new SparkleUser (match.Groups [2].Value, match.Groups [3].Value);
change_set.IsMagical = is_merge_commit; change_set.IsMagical = is_merge_commit;
change_set.Url = Url; change_set.RemoteUrl = RemoteUrl;
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value), change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value), int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),

View file

@ -30,7 +30,7 @@ namespace SparkleLib {
public DateTime Timestamp; public DateTime Timestamp;
public DateTime FirstTimestamp; public DateTime FirstTimestamp;
public bool IsMagical = false; public bool IsMagical = false;
public Uri Url; public Uri RemoteUrl;
public List<string> Added = new List<string> (); public List<string> Added = new List<string> ();
public List<string> Deleted = new List<string> (); public List<string> Deleted = new List<string> ();

View file

@ -74,7 +74,8 @@ namespace SparkleLib {
public readonly string LocalPath; public readonly string LocalPath;
public readonly string Name; public readonly string Name;
public readonly Uri Url; public readonly Uri RemoteUrl;
public List<SparkleChangeSet> ChangeSets { get; protected set; }
public abstract string ComputeIdentifier (); public abstract string ComputeIdentifier ();
public abstract string CurrentRevision { get; } public abstract string CurrentRevision { get; }
@ -88,6 +89,9 @@ namespace SparkleLib {
public abstract bool SyncDown (); public abstract bool SyncDown ();
public abstract List<SparkleChangeSet> GetChangeSets (int count); public abstract List<SparkleChangeSet> GetChangeSets (int count);
public List<SparkleChangeSet> GetChangeSets () {
return GetChangeSets (30);
}
public bool ServerOnline { public bool ServerOnline {
get { get {
@ -157,7 +161,7 @@ namespace SparkleLib {
{ {
LocalPath = path; LocalPath = path;
Name = Path.GetFileName (LocalPath); Name = Path.GetFileName (LocalPath);
Url = new Uri (SparkleConfig.DefaultConfig.GetUrlForFolder (Name)); RemoteUrl = new Uri (SparkleConfig.DefaultConfig.GetUrlForFolder (Name));
this.poll_interval = this.short_interval; this.poll_interval = this.short_interval;
@ -169,7 +173,8 @@ namespace SparkleLib {
if (CurrentRevision == null) if (CurrentRevision == null)
CreateInitialChangeSet (); CreateInitialChangeSet ();
ChangeSets = GetChangeSets ();
CreateWatcher (); CreateWatcher ();
CreateListener (); CreateListener ();
@ -347,14 +352,12 @@ namespace SparkleLib {
this.server_online = true; this.server_online = true;
if (!pre_sync_revision.Equals (CurrentRevision)) { if (!pre_sync_revision.Equals (CurrentRevision)) {
List<SparkleChangeSet> change_sets = GetChangeSets (1); if (ChangeSets != null &&
ChangeSets.Count > 0 &&
if (change_sets != null && !ChangeSets [0].Added.Contains (".sparkleshare")) {
change_sets.Count > 0 &&
!change_sets [0].Added.Contains (".sparkleshare")) {
if (NewChangeSet != null) if (NewChangeSet != null)
NewChangeSet (change_sets [0]); NewChangeSet (ChangeSets [0]);
} }
} }
@ -541,7 +544,7 @@ namespace SparkleLib {
"Congratulations, you've successfully created a SparkleShare repository!" + n + "Congratulations, you've successfully created a SparkleShare repository!" + n +
"" + n + "" + n +
"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 +
Url + " and everyone connected to it." + n + RemoteUrl + " and everyone connected to it." + n +
"" + n + "" + n +
"SparkleShare is a Free and Open Source software program that helps people " + n + "SparkleShare is a Free and Open Source software program that helps people " + n +
"collaborate and share files. If you like what we do, please consider a small " + n + "collaborate and share files. If you like what we do, please consider a small " + n +

View file

@ -32,6 +32,7 @@ namespace SparkleShare {
private Gdk.Pixbuf [] animation_frames; private Gdk.Pixbuf [] animation_frames;
private Menu menu; private Menu menu;
private MenuItem recent_events_item;
private MenuItem quit_item; private MenuItem quit_item;
private MenuItem state_item; private MenuItem state_item;
@ -99,13 +100,20 @@ namespace SparkleShare {
}); });
}; };
Controller.UpdateQuitItemEvent += delegate (bool quit_item_enabled) { Controller.UpdateQuitItemEvent += delegate (bool item_enabled) {
Application.Invoke (delegate { Application.Invoke (delegate {
this.quit_item.Sensitive = quit_item_enabled; this.quit_item.Sensitive = item_enabled;
this.quit_item.ShowAll (); this.quit_item.ShowAll ();
}); });
}; };
Controller.UpdateOpenRecentEventsItemEvent += delegate (bool item_enabled) {
Application.Invoke (delegate {
this.recent_events_item.Sensitive = item_enabled;
this.recent_events_item.ShowAll ();
});
};
Controller.UpdateMenuEvent += delegate (IconState state) { Controller.UpdateMenuEvent += delegate (IconState state) {
Application.Invoke (delegate { Application.Invoke (delegate {
CreateMenu (); CreateMenu ();
@ -199,15 +207,15 @@ namespace SparkleShare {
this.menu.Add (sync_item); this.menu.Add (sync_item);
MenuItem recent_events_item = new MenuItem (_("View Recent Changes…")); this.recent_events_item = new MenuItem (_("View Recent Changes…"));
recent_events_item.Sensitive = (Controller.Folders.Length > 0); this.recent_events_item.Sensitive = Controller.OpenRecentEventsItemEnabled;
recent_events_item.Activated += delegate { this.recent_events_item.Activated += delegate {
Controller.OpenRecentEventsClicked (); Controller.OpenRecentEventsClicked ();
}; };
this.menu.Add (recent_events_item); this.menu.Add (this.recent_events_item);
this.menu.Add (new SeparatorMenuItem ()); this.menu.Add (new SeparatorMenuItem ());
CheckMenuItem notify_item = new CheckMenuItem (_("Notifications")) { CheckMenuItem notify_item = new CheckMenuItem (_("Notifications")) {

View file

@ -33,13 +33,6 @@ namespace SparkleShare {
{ {
Controller.ShowBubbleEvent += delegate (string title, string subtext, string image_path) { Controller.ShowBubbleEvent += delegate (string title, string subtext, string image_path) {
InvokeOnMainThread (delegate { InvokeOnMainThread (delegate {
if (!GrowlApplicationBridge.IsGrowlRunning ()) {
NSApplication.SharedApplication.RequestUserAttention (
NSRequestUserAttentionType.InformationalRequest);
return;
}
if (NSApplication.SharedApplication.DockTile.BadgeLabel == null) { if (NSApplication.SharedApplication.DockTile.BadgeLabel == null) {
NSApplication.SharedApplication.DockTile.BadgeLabel = "1"; NSApplication.SharedApplication.DockTile.BadgeLabel = "1";
@ -48,6 +41,13 @@ namespace SparkleShare {
NSApplication.SharedApplication.DockTile.BadgeLabel = (events + 1).ToString (); NSApplication.SharedApplication.DockTile.BadgeLabel = (events + 1).ToString ();
} }
if (!GrowlApplicationBridge.IsGrowlRunning ()) {
NSApplication.SharedApplication.RequestUserAttention (
NSRequestUserAttentionType.InformationalRequest);
return;
}
if (image_path != null) { if (image_path != null) {
NSData image_data = NSData.FromFile (image_path); NSData image_data = NSData.FromFile (image_path);
GrowlApplicationBridge.Notify (title, subtext, GrowlApplicationBridge.Notify (title, subtext,

View file

@ -135,6 +135,15 @@ namespace SparkleShare {
}); });
} }
}; };
Controller.UpdateOpenRecentEventsItemEvent += delegate (bool events_item_enabled) {
using (var a = new NSAutoreleasePool ())
{
InvokeOnMainThread (delegate {
this.recent_events_item.Enabled = events_item_enabled;
});
}
};
} }
@ -173,7 +182,7 @@ namespace SparkleShare {
this.recent_events_item = new NSMenuItem () { this.recent_events_item = new NSMenuItem () {
Title = "View Recent Changes…", Title = "View Recent Changes…",
Enabled = (Controller.Folders.Length > 0) Enabled = Controller.OpenRecentEventsItemEnabled
}; };
if (Controller.Folders.Length > 0) { if (Controller.Folders.Length > 0) {

View file

@ -43,6 +43,8 @@ namespace SparkleShare {
} }
} }
public bool RepositoriesLoaded { get; private set;}
public List<SparkleRepoBase> repositories = new List<SparkleRepoBase> (); public List<SparkleRepoBase> repositories = new List<SparkleRepoBase> ();
public readonly string SparklePath = SparkleConfig.DefaultConfig.FoldersPath; public readonly string SparklePath = SparkleConfig.DefaultConfig.FoldersPath;
@ -220,6 +222,7 @@ namespace SparkleShare {
RemoveRepository (folder_path); RemoveRepository (folder_path);
} }
} }
if (FolderListChanged != null) if (FolderListChanged != null)
FolderListChanged (); FolderListChanged ();
} }
@ -304,7 +307,7 @@ namespace SparkleShare {
List<SparkleChangeSet> list = new List<SparkleChangeSet> (); List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
foreach (SparkleRepoBase repo in Repositories) { foreach (SparkleRepoBase repo in Repositories) {
List<SparkleChangeSet> change_sets = repo.GetChangeSets (30); List<SparkleChangeSet> change_sets = repo.ChangeSets;
if (change_sets != null) if (change_sets != null)
list.AddRange (change_sets); list.AddRange (change_sets);
@ -328,11 +331,12 @@ namespace SparkleShare {
return GetLog (); return GetLog ();
string path = new SparkleFolder (name).FullPath; string path = new SparkleFolder (name).FullPath;
int log_size = 50;
foreach (SparkleRepoBase repo in Repositories) { lock (this.repo_lock) {
if (repo.LocalPath.Equals (path)) foreach (SparkleRepoBase repo in Repositories) {
return repo.GetChangeSets (log_size); if (repo.LocalPath.Equals (path))
return repo.ChangeSets;
}
} }
return null; return null;
@ -360,9 +364,9 @@ namespace SparkleShare {
bool change_set_inserted = false; bool change_set_inserted = false;
foreach (ActivityDay stored_activity_day in activity_days) { foreach (ActivityDay stored_activity_day in activity_days) {
if (stored_activity_day.DateTime.Year == change_set.Timestamp.Year && if (stored_activity_day.Date.Year == change_set.Timestamp.Year &&
stored_activity_day.DateTime.Month == change_set.Timestamp.Month && stored_activity_day.Date.Month == change_set.Timestamp.Month &&
stored_activity_day.DateTime.Day == change_set.Timestamp.Day) { stored_activity_day.Date.Day == change_set.Timestamp.Day) {
bool squash = false; bool squash = false;
foreach (SparkleChangeSet existing_set in stored_activity_day) { foreach (SparkleChangeSet existing_set in stored_activity_day) {
@ -492,7 +496,7 @@ namespace SparkleShare {
.Replace ("<!-- $event-avatar-url -->", change_set_avatar) .Replace ("<!-- $event-avatar-url -->", change_set_avatar)
.Replace ("<!-- $event-time -->", timestamp) .Replace ("<!-- $event-time -->", timestamp)
.Replace ("<!-- $event-folder -->", change_set.Folder.Name) .Replace ("<!-- $event-folder -->", change_set.Folder.Name)
.Replace ("<!-- $event-url -->", change_set.Url.ToString ()) .Replace ("<!-- $event-url -->", change_set.RemoteUrl.ToString ())
.Replace ("<!-- $event-revision -->", change_set.Revision); .Replace ("<!-- $event-revision -->", change_set.Revision);
} }
@ -500,34 +504,34 @@ namespace SparkleShare {
DateTime today = DateTime.Now; DateTime today = DateTime.Now;
DateTime yesterday = DateTime.Now.AddDays (-1); DateTime yesterday = DateTime.Now.AddDays (-1);
if (today.Day == activity_day.DateTime.Day && if (today.Day == activity_day.Date.Day &&
today.Month == activity_day.DateTime.Month && today.Month == activity_day.Date.Month &&
today.Year == activity_day.DateTime.Year) { today.Year == activity_day.Date.Year) {
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
"<span id='today' name='" + activity_day.DateTime.ToString (_("dddd, MMMM d")) + "'>" "<span id='today' name='" + activity_day.Date.ToString (_("dddd, MMMM d")) + "'>"
+ _("Today") + "</span>"); + _("Today") + "</span>");
} else if (yesterday.Day == activity_day.DateTime.Day && } else if (yesterday.Day == activity_day.Date.Day &&
yesterday.Month == activity_day.DateTime.Month && yesterday.Month == activity_day.Date.Month &&
yesterday.Year == activity_day.DateTime.Year) { yesterday.Year == activity_day.Date.Year) {
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
"<span id='yesterday' name='" + activity_day.DateTime.ToString (_("dddd, MMMM d")) + "'>" "<span id='yesterday' name='" + activity_day.Date.ToString (_("dddd, MMMM d")) + "'>"
+ _("Yesterday") + "</span>"); + _("Yesterday") + "</span>");
} else { } else {
if (activity_day.DateTime.Year != DateTime.Now.Year) { if (activity_day.Date.Year != DateTime.Now.Year) {
// TRANSLATORS: This is the date in the event logs // TRANSLATORS: This is the date in the event logs
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
activity_day.DateTime.ToString (_("dddd, MMMM d, yyyy"))); activity_day.Date.ToString (_("dddd, MMMM d, yyyy")));
} else { } else {
// TRANSLATORS: This is the date in the event logs, without the year // TRANSLATORS: This is the date in the event logs, without the year
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
activity_day.DateTime.ToString (_("dddd, MMMM d"))); activity_day.Date.ToString (_("dddd, MMMM d")));
} }
} }
@ -638,9 +642,9 @@ namespace SparkleShare {
}; };
lock (this.repo_lock) { //lock (this.repo_lock) {
this.repositories.Add (repo); this.repositories.Add (repo);
} //}
repo.Initialize (); repo.Initialize ();
} }
@ -674,15 +678,19 @@ namespace SparkleShare {
// folders in the SparkleShare folder // folders in the SparkleShare folder
private void PopulateRepositories () private void PopulateRepositories ()
{ {
foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) { lock (this.repo_lock) {
string folder_path = new SparkleFolder (folder_name).FullPath; foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) {
string folder_path = new SparkleFolder (folder_name).FullPath;
if (Directory.Exists (folder_path)) if (Directory.Exists (folder_path))
AddRepository (folder_path); AddRepository (folder_path);
else else
SparkleConfig.DefaultConfig.RemoveFolder (folder_name); SparkleConfig.DefaultConfig.RemoveFolder (folder_name);
}
} }
RepositoriesLoaded = true;
if (FolderListChanged != null) if (FolderListChanged != null)
FolderListChanged (); FolderListChanged ();
} }
@ -1056,7 +1064,9 @@ namespace SparkleShare {
} TODO } TODO
*/ */
AddRepository (target_folder_path); lock (this.repo_lock) {
AddRepository (target_folder_path);
}
if (FolderFetched != null) if (FolderFetched != null)
FolderFetched (this.fetcher.RemoteUrl.ToString (), this.fetcher.Warnings.ToArray ()); FolderFetched (this.fetcher.RemoteUrl.ToString (), this.fetcher.Warnings.ToArray ());
@ -1111,11 +1121,8 @@ namespace SparkleShare {
private string FormatBreadCrumbs (string path_root, string path) private string FormatBreadCrumbs (string path_root, string path)
{ {
path_root = path_root.Replace ("/", path_root = path_root.Replace ("/", Path.DirectorySeparatorChar.ToString ());
Path.DirectorySeparatorChar.ToString ()); path = path.Replace ("/", Path.DirectorySeparatorChar.ToString ());
path = path.Replace ("/",
Path.DirectorySeparatorChar.ToString ());
string link = ""; string link = "";
string [] crumbs = path.Split (Path.DirectorySeparatorChar); string [] crumbs = path.Split (Path.DirectorySeparatorChar);
@ -1158,12 +1165,11 @@ namespace SparkleShare {
// All change sets that happened on a day // All change sets that happened on a day
public class ActivityDay : List <SparkleChangeSet> public class ActivityDay : List <SparkleChangeSet>
{ {
public DateTime DateTime; public DateTime Date;
public ActivityDay (DateTime date_time) public ActivityDay (DateTime date_time)
{ {
DateTime = date_time; Date = new DateTime (date_time.Year, date_time.Month, date_time.Day);
DateTime = new DateTime (DateTime.Year, DateTime.Month, DateTime.Day);
} }
} }
} }

View file

@ -72,7 +72,7 @@ namespace SparkleShare {
// A short delay is less annoying than // A short delay is less annoying than
// a flashing window // a flashing window
int delay = 1000; int delay = 500;
if (watch.ElapsedMilliseconds < delay) if (watch.ElapsedMilliseconds < delay)
Thread.Sleep (delay - (int) watch.ElapsedMilliseconds); Thread.Sleep (delay - (int) watch.ElapsedMilliseconds);

View file

@ -46,6 +46,9 @@ namespace SparkleShare {
public event UpdateQuitItemEventHandler UpdateQuitItemEvent; public event UpdateQuitItemEventHandler UpdateQuitItemEvent;
public delegate void UpdateQuitItemEventHandler (bool quit_item_enabled); public delegate void UpdateQuitItemEventHandler (bool quit_item_enabled);
public event UpdateOpenRecentEventsItemEventHandler UpdateOpenRecentEventsItemEvent;
public delegate void UpdateOpenRecentEventsItemEventHandler (bool open_recent_events_item_enabled);
public IconState CurrentState = IconState.Idle; public IconState CurrentState = IconState.Idle;
public string StateText = "Welcome to SparkleShare!"; public string StateText = "Welcome to SparkleShare!";
@ -111,6 +114,14 @@ namespace SparkleShare {
} }
} }
public bool OpenRecentEventsItemEnabled {
get {
return (Program.Controller.RepositoriesLoaded &&
Program.Controller.Folders.Count > 0);
}
}
private Timer animation; private Timer animation;
private int animation_frame_number; private int animation_frame_number;
@ -133,6 +144,9 @@ namespace SparkleShare {
if (UpdateStatusItemEvent != null) if (UpdateStatusItemEvent != null)
UpdateStatusItemEvent (StateText); UpdateStatusItemEvent (StateText);
if (UpdateOpenRecentEventsItemEvent != null)
UpdateOpenRecentEventsItemEvent (OpenRecentEventsItemEnabled);
if (UpdateMenuEvent != null) if (UpdateMenuEvent != null)
UpdateMenuEvent (CurrentState); UpdateMenuEvent (CurrentState);
}; };

View file

@ -37,7 +37,9 @@ namespace SparkleShare {
private Drawing.Bitmap error_icon; private Drawing.Bitmap error_icon;
private ContextMenu context_menu; private ContextMenu context_menu;
private SparkleMenuItem log_item;
private SparkleMenuItem state_item; private SparkleMenuItem state_item;
private SparkleMenuItem exit_item; private SparkleMenuItem exit_item;
@ -84,12 +86,19 @@ namespace SparkleShare {
}); });
}; };
Controller.UpdateQuitItemEvent += delegate (bool exit_item_enabled) { Controller.UpdateQuitItemEvent += delegate (bool item_enabled) {
Dispatcher.Invoke ((Action) delegate { Dispatcher.Invoke ((Action) delegate {
this.exit_item.IsEnabled = exit_item_enabled; this.exit_item.IsEnabled = item_enabled;
this.exit_item.UpdateLayout (); this.exit_item.UpdateLayout ();
}); });
}; };
Controller.UpdatOpenRecentEventsItemEvent += delegate (bool item_enabled) {
Dispatcher.Invoke ((Action) delegate {
this.log_item.IsEnabled = item_enabled;
this.log_item.UpdateLayout ();
});
};
} }
@ -127,12 +136,12 @@ namespace SparkleShare {
Controller.AddHostedProjectClicked (); Controller.AddHostedProjectClicked ();
}; };
SparkleMenuItem log_item = new SparkleMenuItem () { this.log_item = new SparkleMenuItem () {
Header = "View recent changes…", Header = "View recent changes…",
IsEnabled = (Program.Controller.Folders.Count > 0) IsEnabled = Controller.OpenRecentEventsItemEnabled;
}; };
log_item.Click += delegate { this.log_item.Click += delegate {
Controller.OpenRecentEventsClicked (); Controller.OpenRecentEventsClicked ();
}; };
@ -246,7 +255,7 @@ namespace SparkleShare {
this.context_menu.Items.Add (new Separator ()); this.context_menu.Items.Add (new Separator ());
this.context_menu.Items.Add (add_item); this.context_menu.Items.Add (add_item);
this.context_menu.Items.Add (log_item); this.context_menu.Items.Add (this.log_item);
this.context_menu.Items.Add (new Separator ()); this.context_menu.Items.Add (new Separator ());
this.context_menu.Items.Add (notify_item); this.context_menu.Items.Add (notify_item);
this.context_menu.Items.Add (new Separator ()); this.context_menu.Items.Add (new Separator ());