Skip to content

Commit

Permalink
Persist enabled state
Browse files Browse the repository at this point in the history
Fixes #12
  • Loading branch information
citizenmatt committed Feb 12, 2016
1 parent aec377f commit d0e7299
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root = true

[*]
indent_style = space
indent_size = 4
2 changes: 1 addition & 1 deletion install/presentation-assistant.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<metadata>
<id>JetBrains.PresentationAssistant</id>
<title>Presentation Assistant</title>
<version>2.3.0</version>
<version>2.3.1</version>
<authors>JetBrains</authors>
<owners>JetBrains</owners>
<description>Shows the name and keyboard shortcuts of invoked actions.</description>
Expand Down
6 changes: 5 additions & 1 deletion src/resharper-presentation-assistant/ActionIdBlacklist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ public static class ActionIdBlacklist
"WordNextExtend",

// VS commands, not R# commands
"Edit.Up", "Edit.Down", "Edit.Left", "Edit.Right", "Edit.PageUp", "Edit.PageDown"
"Edit.Up", "Edit.Down", "Edit.Left", "Edit.Right", "Edit.PageUp", "Edit.PageDown",

// Make sure we don't try to show the presentation assistant popup just as we're
// killing the popups
PresentationAssistantAction.ActionId
};

public static bool IsBlacklisted(string actionId)
Expand Down
41 changes: 31 additions & 10 deletions src/resharper-presentation-assistant/PresentationAssistant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using JetBrains.Application.ActivityTrackingNew;
using JetBrains.Application.Parts;
using JetBrains.DataFlow;
using JetBrains.Threading;
using JetBrains.UI.ActionsRevised.Loader;

namespace JetBrains.ReSharper.Plugins.PresentationAssistant
Expand All @@ -15,51 +16,71 @@ public class PresentationAssistant : IActivityTracking
private readonly ActionFinder actionFinder;
private readonly PresentationAssistantWindowOwner presentationAssistantWindowOwner;
private readonly ShortcutFactory shortcutFactory;
private readonly PresentationAssistantSettingsStore settingsStore;

private DateTime lastDisplayed;
private string lastActionId;
private int multiplier;
private bool enabled;

public PresentationAssistant(Lifetime lifetime, ActionFinder actionFinder,
PresentationAssistantWindowOwner presentationAssistantWindowOwner,
ShortcutFactory shortcutFactory)
ShortcutFactory shortcutFactory, PresentationAssistantSettingsStore settingsStore,
IThreading threading)
{
this.actionFinder = actionFinder;
this.presentationAssistantWindowOwner = presentationAssistantWindowOwner;
this.shortcutFactory = shortcutFactory;
this.settingsStore = settingsStore;

Enabled = new Property<bool>(lifetime, "PresentationAssistant::Enabled");
Enabled.FlowInto(lifetime, presentationAssistantWindowOwner.Enabled);
// Post to the UI thread so that the app has time to start before we show the message
threading.ExecuteOrQueue("Presentation Assistant initial message", () =>
{
var settings = settingsStore.GetSettings();
UpdateSettings(!settings.WelcomeMessageShown);
settings.WelcomeMessageShown = true;
settingsStore.SetSettings(settings);
});

// Post to the UI thread because settings change are raised on a background thread.
// Has the unfortunate side effect that the action disabling the assistant is shown
// very briefly, so we blacklist it
settingsStore.SettingsChanged.Advise(lifetime, _ => threading.ExecuteOrQueue("Presentation Assistant update enabled", () => UpdateSettings(true)));
}

public Property<bool> Enabled { get; private set; }
private void UpdateSettings(bool showOwnActionImmediately)
{
var localSettings = settingsStore.GetSettings();
presentationAssistantWindowOwner.Enabled.SetValue(localSettings.Enabled);
enabled = localSettings.Enabled;

if (enabled && showOwnActionImmediately)
OnAction(PresentationAssistantAction.ActionId);
}

// Implementing IActivityTracking is better than subscribing to ActionEvents, as
// extensible workflow based actions (Refactor This, Navigate To, Generate, etc.)
// will notify activity tracking, but invoke the action manually, so it doesn't
// get reported by ActionEvents
public void TrackAction(string actionId)
{
if (!Enabled.Value)
if (!enabled || ActionIdBlacklist.IsBlacklisted(actionId))
return;

OnAction(actionId);
}

public void TrackActivity(string activityGroup, string activityId, int count = 1)
{
if (!Enabled.Value)
if (!enabled)
return;

if (activityGroup == "VsAction")
if (activityGroup == "VsAction" && !ActionIdBlacklist.IsBlacklisted(activityId))
OnAction(activityId);
}

private void OnAction(string actionId)
{
if (ActionIdBlacklist.IsBlacklisted(actionId))
return;

var def = actionFinder.Find(actionId);
if (def == null)
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@

namespace JetBrains.ReSharper.Plugins.PresentationAssistant
{
[Action("PresentationAssistant.Toggle", "Presentation Assistant", Description = "Enable and disable the presentation assistant", Id = 987987)]
[Action(ActionId, "Presentation Assistant", Description = "Enable and disable the presentation assistant", Id = 987987)]
public class PresentationAssistantAction : ICheckableAction, IInsertLast<ToolsMenu>
{
public const string ActionId = "PresentationAssistant.Toggle";

public bool Update(IDataContext context, CheckedActionPresentation presentation)
{
var presentationAssistant = context.GetComponent<PresentationAssistant>();
presentation.Checked = presentationAssistant.Enabled.Value;
var settings = context.GetComponent<PresentationAssistantSettingsStore>().GetSettings();
presentation.Checked = settings.Enabled;
return true;
}

public void Execute(IDataContext context)
{
var presentationAssistant = context.GetComponent<PresentationAssistant>();
presentationAssistant.Enabled.SetValue(!presentationAssistant.Enabled.Value);
var settingsStore = context.GetComponent<PresentationAssistantSettingsStore>();
var settings = settingsStore.GetSettings();
settings.Enabled = !settings.Enabled;
settingsStore.SetSettings(settings);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using JetBrains.Application.Settings;
using JetBrains.UI;

namespace JetBrains.ReSharper.Plugins.PresentationAssistant
{
[SettingsKey(typeof(UserInterfaceSettings), "Presentation Assistant settings")]
public class PresentationAssistantSettings
{
[SettingsEntry(true, "Enabled")]
public bool Enabled { get; set; }

[SettingsEntry(false, "Welcome message shown")]
public bool WelcomeMessageShown { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using JetBrains.Application;
using JetBrains.Application.DataContext;
using JetBrains.Application.Settings;
using JetBrains.DataFlow;

namespace JetBrains.ReSharper.Plugins.PresentationAssistant
{
[ShellComponent]
public class PresentationAssistantSettingsStore
{
private readonly ISettingsStore settingsStore;
private readonly DataContexts dataContexts;

public PresentationAssistantSettingsStore(Lifetime lifetime, ISettingsStore settingsStore, DataContexts dataContexts)
{
this.settingsStore = settingsStore;
this.dataContexts = dataContexts;

SettingsChanged = new SimpleSignal(lifetime, "Presentation Assistant settings changed");

var key = settingsStore.Schema.GetKey<PresentationAssistantSettings>();
settingsStore.Changed.Advise(lifetime, args =>
{
foreach (var changedEntry in args.ChangedEntries)
{
if (changedEntry.Parent == key)
{
if (changedEntry.LocalName == "Enabled")
SettingsChanged.Fire();
break;
}
}
});
}

public SimpleSignal SettingsChanged { get; private set; }

public PresentationAssistantSettings GetSettings()
{
var boundSettings = BindSettingsStore();
return boundSettings.GetKey<PresentationAssistantSettings>(SettingsOptimization.OptimizeDefault);
}

public void SetSettings(PresentationAssistantSettings settings)
{
var boundSettings = BindSettingsStore();
boundSettings.SetKey(settings, SettingsOptimization.OptimizeDefault);
}

private IContextBoundSettingsStore BindSettingsStore()
{
var store = settingsStore.BindToContextTransient(ContextRange.Smart((l, _) => dataContexts.CreateOnSelection(l)));
return store;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using JetBrains.Application;
using JetBrains.DataFlow;
using JetBrains.Interop.WinApi;
using JetBrains.Threading;
using JetBrains.UI.PopupWindowManager;
using JetBrains.UI.Theming;
Expand All @@ -14,7 +11,6 @@ namespace JetBrains.ReSharper.Plugins.PresentationAssistant
public class PresentationAssistantWindowOwner
{
private static readonly TimeSpan VisibleTimeSpan = TimeSpan.FromSeconds(4);
private static readonly TimeSpan TopmostTimeSpan = TimeSpan.FromMilliseconds(200);

private readonly IThreading threading;
private readonly PresentationAssistantPopupWindowContext context;
Expand Down Expand Up @@ -46,7 +42,6 @@ private void EnableShortcuts(Lifetime enabledLifetime)
var popupWindowLifetimeDefinition = Lifetimes.Define(enabledLifetime, "PresentationAssistant::PopupWindow");

var window = new PresentationAssistantWindow();
var windowInteropHelper = new WindowInteropHelper(window) { Owner = context.MainWindow.Handle };

theming.PopulateResourceDictionary(popupWindowLifetimeDefinition, window.Resources);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
[assembly: AssemblyTitle("resharper-presentation-assistant")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("JetBrains")]
[assembly: AssemblyProduct("resharper-presentation-assistant")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand All @@ -31,4 +31,4 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.3.0.*")]
[assembly: AssemblyVersion("2.3.1.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@
<Compile Include="PresentationAssistantAction.cs" />
<Compile Include="PresentationAssistantPopupWindowContext.cs" />
<Compile Include="OverriddenShortcutFinder.cs" />
<Compile Include="PresentationAssistantSettings.cs" />
<Compile Include="PresentationAssistantSettingsStore.cs" />
<Compile Include="VisualStudio\PresentationAssistantVsThemeColor.cs" />
<Compile Include="PresentationAssistantWindow.xaml.cs">
<DependentUpon>PresentationAssistantWindow.xaml</DependentUpon>
Expand Down

0 comments on commit d0e7299

Please sign in to comment.