diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
index f5641c67b0..bb20aaf261 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
@@ -285,9 +285,14 @@ namespace ICSharpCode.AvalonEdit.AddIn
this.Encoding = reader.CurrentEncoding;
}
}
+ // raise event which allows removing existing NewLineConsistencyCheck overlays
+ if (LoadedFileContent != null)
+ LoadedFileContent(this, EventArgs.Empty);
NewLineConsistencyCheck.StartConsistencyCheck(this);
}
+ public event EventHandler LoadedFileContent;
+
public void Save(Stream stream)
{
// don't use TextEditor.Save here because that would touch the Modified flag,
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
index 98f7b9de67..1d553b4b95 100755
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
@@ -141,6 +141,8 @@ namespace ICSharpCode.AvalonEdit.AddIn
CodeSnippet snippet = SnippetManager.Instance.FindSnippet(Path.GetExtension(editor.Adapter.FileName),
word);
if (snippet != null) {
+ snippet.TrackUsage("CustomTabCommand");
+
editor.Adapter.Document.Remove(wordStart, editor.CaretOffset - wordStart);
snippet.CreateAvalonEditSnippet(editor.Adapter).Insert(editor.TextArea);
return;
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs
index ec6aec8ad1..e0a26fbd5a 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs
@@ -115,13 +115,25 @@ namespace ICSharpCode.AvalonEdit.AddIn
};
editor.Children.Add(groupBox);
- cancelButton.Click += delegate {
+ var featureUse = AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck));
+
+ EventHandler removeWarning = null;
+ removeWarning = delegate {
editor.Children.Remove(groupBox);
editor.PrimaryTextEditor.TextArea.Focus();
+ editor.LoadedFileContent -= removeWarning;
+
+ featureUse.EndTracking();
+ };
+
+ editor.LoadedFileContent += removeWarning;
+ cancelButton.Click += delegate {
+ AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck), "cancelButton");
+ removeWarning(null, null);
};
normalizeButton.Click += delegate {
- editor.Children.Remove(groupBox);
- editor.PrimaryTextEditor.TextArea.Focus();
+ AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck), "normalizeButton");
+ removeWarning(null, null);
TextDocument document = editor.Document;
string newNewLine = (unix.IsChecked == true) ? "\n" : "\r\n";
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
index 08b58465c9..6b60affc4e 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
@@ -9,7 +9,7 @@ using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
-
+using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
@@ -242,6 +242,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
memberItems.Sort();
if (jumpOnSelectionChange) {
+ AnalyticsMonitorService.TrackFeature(GetType(), "JumpToClass");
JumpTo(item, selectedClass.Region);
}
}
@@ -260,6 +261,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (item != null) {
IMember member = item.Entity as IMember;
if (member != null && jumpOnSelectionChange) {
+ AnalyticsMonitorService.TrackFeature(GetType(), "JumpToMember");
JumpTo(item, member.Region);
}
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
index 9a2ba18cc9..9161dd99c4 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
@@ -240,5 +240,13 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
return function(input);
}
}
+
+ ///
+ /// Reports the snippet usage to UDC
+ ///
+ internal void TrackUsage(string activationMethod)
+ {
+ Core.AnalyticsMonitorService.TrackFeature(typeof(CodeSnippet), IsUserModified ? "usersnippet" : Name, activationMethod);
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs
index 31c14e6d77..460a4a6ccc 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs
@@ -74,6 +74,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
using (context.Editor.Document.OpenUndoGroup()) {
if (context.CompletionChar == '\t' || AlwaysInsertSnippet) {
+ codeSnippet.TrackUsage("SnippetCompletionItem");
+
context.Editor.Document.Remove(context.StartOffset, context.Length);
CreateSnippet().Insert(textArea);
} else {
diff --git a/src/Main/Base/Project/Src/Bookmarks/ClassMemberBookmark.cs b/src/Main/Base/Project/Src/Bookmarks/ClassMemberBookmark.cs
index cdd871262d..3e79a8c1b4 100644
--- a/src/Main/Base/Project/Src/Bookmarks/ClassMemberBookmark.cs
+++ b/src/Main/Base/Project/Src/Bookmarks/ClassMemberBookmark.cs
@@ -8,7 +8,7 @@
using System;
using System.Windows;
using System.Windows.Input;
-
+using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop.Dom;
@@ -36,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
public const string ContextMenuPath = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassMemberContextMenu";
- public virtual IImage Image {
+ public virtual IImage Image {
get { return ClassBrowserIconService.GetIcon(member); }
}
@@ -47,7 +47,9 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
public virtual void MouseDown(MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left) {
- MenuService.ShowContextMenu(e.Source as UIElement, this, ContextMenuPath);
+ var f = AnalyticsMonitorService.TrackFeature("ICSharpCode.SharpDevelop.Bookmarks.ClassMemberBookmark.ShowContextMenu");
+ var ctx = MenuService.ShowContextMenu(e.Source as UIElement, this, ContextMenuPath);
+ ctx.Closed += delegate { f.EndTracking(); };
e.Handled = true;
}
}
@@ -73,7 +75,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
public const string ContextMenuPath = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu";
- public virtual IImage Image {
+ public virtual IImage Image {
get {
return ClassBrowserIconService.GetIcon(@class);
}
@@ -86,7 +88,9 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
public virtual void MouseDown(MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left) {
- MenuService.ShowContextMenu(e.Source as UIElement, this, ContextMenuPath);
+ var f = AnalyticsMonitorService.TrackFeature("ICSharpCode.SharpDevelop.Bookmarks.ClassBookmark.ShowContextMenu");
+ var ctx = MenuService.ShowContextMenu(e.Source as UIElement, this, ContextMenuPath);
+ ctx.Closed += delegate { f.EndTracking(); };
e.Handled = true;
}
}
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
index 33b07d9323..321bb94d1f 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
@@ -95,7 +95,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
- mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath);
+ mainMenu.ItemsSource = MenuService.CreateMenuItems(this, this, mainMenuPath, "MainMenu");
toolBars = ToolBarService.CreateToolBars(this, "/SharpDevelop/Workbench/ToolBar");
foreach (ToolBar tb in toolBars) {
diff --git a/src/Main/Base/Project/Src/Project/BuildEngine.cs b/src/Main/Base/Project/Src/Project/BuildEngine.cs
index 289c88e257..bba1cf57b1 100644
--- a/src/Main/Base/Project/Src/Project/BuildEngine.cs
+++ b/src/Main/Base/Project/Src/Project/BuildEngine.cs
@@ -55,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Project
} else {
guiBuildCancellation = new CancellationTokenSource();
IProgressMonitor progressMonitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor(guiBuildCancellation.Token);
- guiBuildTrackedFeature = AnalyticsMonitorService.TrackFeature("Build");
+ guiBuildTrackedFeature = AnalyticsMonitorService.TrackFeature("ICSharpCode.SharpDevelop.Project.BuildEngine.Build");
WorkbenchSingleton.StatusBar.SetMessage(StringParser.Parse("${res:MainWindow.CompilerMessages.BuildVerb}..."));
ProjectService.RaiseEventBuildStarted(new BuildEventArgs(project, options));
StartBuild(project, options,
diff --git a/src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs b/src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs
index 1be908abce..2892e0c48e 100644
--- a/src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs
+++ b/src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs
@@ -209,7 +209,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
void convertButton_Click(object sender, RoutedEventArgs e)
{
- Core.AnalyticsMonitorService.TrackFeature("UpgradeView.convertButton_Click");
+ Core.AnalyticsMonitorService.TrackFeature(GetType(), "convertButton_Click");
CompilerVersion selectedCompiler = newVersionComboBox.SelectedValue as CompilerVersion;
TargetFramework selectedFramework = newFrameworkComboBox.SelectedValue as TargetFramework;
diff --git a/src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs b/src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs
index 030bcb3970..09606673cd 100644
--- a/src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs
+++ b/src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs
@@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
{
var projects = solution.Projects.OfType().ToList();
if (projects.Count > 0 && projects.All(u => u.UpgradeDesired)) {
- Core.AnalyticsMonitorService.TrackFeature("UpgradeView opened automatically");
+ Core.AnalyticsMonitorService.TrackFeature(typeof(UpgradeView), "opened automatically");
WorkbenchSingleton.Workbench.ShowView(new UpgradeViewContent(solution));
}
}
diff --git a/src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs b/src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs
index 7a893c355f..499c7f42af 100644
--- a/src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs
+++ b/src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs
@@ -80,5 +80,23 @@ namespace ICSharpCode.Core
{
}
}
+
+
+ ///
+ /// Tracks a feature use.
+ ///
+ /// Class containing the feature
+ /// Name of the feature
+ /// Method used to 'activate' the feature (e.g. Menu, Toolbar, Shortcut, etc.)
+ /// Object that can be used to 'end' the feature use, if measuring time spans is desired.
+ public static IAnalyticsMonitorTrackedFeature TrackFeature(Type featureClass, string featureName = null, string activationMethod = null)
+ {
+ if (featureClass == null)
+ throw new ArgumentNullException("featureClass");
+ if (featureName != null)
+ return TrackFeature(featureClass.FullName + "/" + featureName, activationMethod);
+ else
+ return TrackFeature(featureClass.FullName, activationMethod);
+ }
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
index 24234be91c..2d997573e8 100644
--- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
@@ -123,8 +123,11 @@ namespace ICSharpCode.Core.Presentation
class MenuCommand : CoreMenuItem
{
- public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand) : base(codon, caller)
+ readonly string ActivationMethod;
+
+ public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand, string activationMethod) : base(codon, caller)
{
+ this.ActivationMethod = activationMethod;
this.Command = CommandWrapper.GetCommand(codon, caller, createCommand);
if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) {
KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]);
@@ -154,7 +157,7 @@ namespace ICSharpCode.Core.Presentation
base.OnClick();
string feature = GetFeatureName();
if (!string.IsNullOrEmpty(feature)) {
- AnalyticsMonitorService.TrackFeature(feature, "Menu");
+ AnalyticsMonitorService.TrackFeature(feature, ActivationMethod);
}
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
index 211fd14d5e..201745ed0f 100644
--- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
@@ -106,14 +106,14 @@ namespace ICSharpCode.Core.Presentation
public static ContextMenu CreateContextMenu(object owner, string addInTreePath)
{
- IList items = CreateUnexpandedMenuItems(null, AddInTree.BuildItems(addInTreePath, owner, false));
+ IList items = CreateUnexpandedMenuItems(null, AddInTree.BuildItems(addInTreePath, owner, false), "ContextMenu");
return CreateContextMenu(items);
}
public static ContextMenu ShowContextMenu(UIElement parent, object owner, string addInTreePath)
{
ContextMenu menu = new ContextMenu();
- menu.ItemsSource = CreateMenuItems(menu, owner, addInTreePath);
+ menu.ItemsSource = CreateMenuItems(menu, owner, addInTreePath, "ContextMenu");
menu.PlacementTarget = parent;
menu.IsOpen = true;
return menu;
@@ -131,9 +131,9 @@ namespace ICSharpCode.Core.Presentation
return contextMenu;
}
- public static IList CreateMenuItems(UIElement inputBindingOwner, object owner, string addInTreePath)
+ public static IList CreateMenuItems(UIElement inputBindingOwner, object owner, string addInTreePath, string activationMethod = null)
{
- IList items = CreateUnexpandedMenuItems(inputBindingOwner, AddInTree.BuildItems(addInTreePath, owner, false));
+ IList items = CreateUnexpandedMenuItems(inputBindingOwner, AddInTree.BuildItems(addInTreePath, owner, false), activationMethod);
return ExpandMenuBuilders(items, false);
}
@@ -156,12 +156,12 @@ namespace ICSharpCode.Core.Presentation
}
}
- internal static IList CreateUnexpandedMenuItems(UIElement inputBindingOwner, IEnumerable descriptors)
+ internal static IList CreateUnexpandedMenuItems(UIElement inputBindingOwner, IEnumerable descriptors, string activationMethod)
{
ArrayList result = new ArrayList();
if (descriptors != null) {
foreach (MenuItemDescriptor descriptor in descriptors) {
- result.Add(CreateMenuItemFromDescriptor(inputBindingOwner, descriptor));
+ result.Add(CreateMenuItemFromDescriptor(inputBindingOwner, descriptor, activationMethod));
}
}
return result;
@@ -191,7 +191,7 @@ namespace ICSharpCode.Core.Presentation
return result;
}
- static object CreateMenuItemFromDescriptor(UIElement inputBindingOwner, MenuItemDescriptor descriptor)
+ static object CreateMenuItemFromDescriptor(UIElement inputBindingOwner, MenuItemDescriptor descriptor, string activationMethod)
{
Codon codon = descriptor.Codon;
string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Command";
@@ -205,13 +205,13 @@ namespace ICSharpCode.Core.Presentation
//return new MenuCheckBox(codon, descriptor.Caller);
case "Item":
case "Command":
- return new MenuCommand(inputBindingOwner, codon, descriptor.Caller, createCommand);
+ return new MenuCommand(inputBindingOwner, codon, descriptor.Caller, createCommand, activationMethod);
case "Menu":
var item = new CoreMenuItem(codon, descriptor.Caller) {
ItemsSource = new object[1],
SetEnabled = true
};
- var subItems = CreateUnexpandedMenuItems(inputBindingOwner, descriptor.SubItems);
+ var subItems = CreateUnexpandedMenuItems(inputBindingOwner, descriptor.SubItems, activationMethod);
item.SubmenuOpened += (sender, args) => {
item.ItemsSource = ExpandMenuBuilders(subItems, true);
args.Handled = true;
diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs
index 3e3f949c34..a63ee22ea8 100644
--- a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs
@@ -72,9 +72,9 @@ namespace ICSharpCode.Core.Presentation
return "Label";
//return new ToolBarLabel(codon, caller);
case "DropDownButton":
- return new ToolBarDropDownButton(codon, caller, MenuService.CreateUnexpandedMenuItems(null, descriptor.SubItems));
+ return new ToolBarDropDownButton(codon, caller, MenuService.CreateUnexpandedMenuItems(null, descriptor.SubItems, "ToolbarDropDownMenu"));
case "SplitButton":
- return new ToolBarSplitButton(codon, caller, MenuService.CreateUnexpandedMenuItems(null, descriptor.SubItems));
+ return new ToolBarSplitButton(codon, caller, MenuService.CreateUnexpandedMenuItems(null, descriptor.SubItems, "ToolbarDropDownMenu"));
case "Builder":
return codon.AddIn.CreateObject(codon.Properties["class"]);
default: