Browse Source

Track feature use in UDC: snippets, NewLineConsistencyCheck, ClassMemberBookmark menu.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6298 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Daniel Grunwald 15 years ago
parent
commit
6ebd91edac
  1. 5
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  2. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
  3. 18
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs
  4. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs
  5. 8
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
  6. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs
  7. 14
      src/Main/Base/Project/Src/Bookmarks/ClassMemberBookmark.cs
  8. 2
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  9. 2
      src/Main/Base/Project/Src/Project/BuildEngine.cs
  10. 2
      src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs
  11. 2
      src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs
  12. 18
      src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs
  13. 7
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
  14. 18
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
  15. 4
      src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs

5
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -285,9 +285,14 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -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,

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs

@ -141,6 +141,8 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -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;

18
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/NewLineConsistencyCheck.cs

@ -115,13 +115,25 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -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";

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/QuickClassBrowser.cs

@ -9,7 +9,7 @@ using System; @@ -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 @@ -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 @@ -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);
}
}

8
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs

@ -240,5 +240,13 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -240,5 +240,13 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
return function(input);
}
}
/// <summary>
/// Reports the snippet usage to UDC
/// </summary>
internal void TrackUsage(string activationMethod)
{
Core.AnalyticsMonitorService.TrackFeature(typeof(CodeSnippet), IsUserModified ? "usersnippet" : Name, activationMethod);
}
}
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs

@ -74,6 +74,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -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 {

14
src/Main/Base/Project/Src/Bookmarks/ClassMemberBookmark.cs

@ -8,7 +8,7 @@ @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;
}
}

2
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -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) {

2
src/Main/Base/Project/Src/Project/BuildEngine.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -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,

2
src/Main/Base/Project/Src/Project/Converter/UpgradeView.xaml.cs

@ -209,7 +209,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -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;

2
src/Main/Base/Project/Src/Project/Converter/UpgradeViewContent.cs

@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter @@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Project.Converter
{
var projects = solution.Projects.OfType<IUpgradableProject>().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));
}
}

18
src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs

@ -80,5 +80,23 @@ namespace ICSharpCode.Core @@ -80,5 +80,23 @@ namespace ICSharpCode.Core
{
}
}
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureClass">Class containing the feature</param>
/// <param name="featureName">Name of the feature</param>
/// <param name="activationMethod">Method used to 'activate' the feature (e.g. Menu, Toolbar, Shortcut, etc.)</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
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);
}
}
}

7
src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs

@ -123,8 +123,11 @@ namespace ICSharpCode.Core.Presentation @@ -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 @@ -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);
}
}

18
src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs

@ -106,14 +106,14 @@ namespace ICSharpCode.Core.Presentation @@ -106,14 +106,14 @@ namespace ICSharpCode.Core.Presentation
public static ContextMenu CreateContextMenu(object owner, string addInTreePath)
{
IList items = CreateUnexpandedMenuItems(null, AddInTree.BuildItems<MenuItemDescriptor>(addInTreePath, owner, false));
IList items = CreateUnexpandedMenuItems(null, AddInTree.BuildItems<MenuItemDescriptor>(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 @@ -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<MenuItemDescriptor>(addInTreePath, owner, false));
IList items = CreateUnexpandedMenuItems(inputBindingOwner, AddInTree.BuildItems<MenuItemDescriptor>(addInTreePath, owner, false), activationMethod);
return ExpandMenuBuilders(items, false);
}
@ -156,12 +156,12 @@ namespace ICSharpCode.Core.Presentation @@ -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 @@ -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 @@ -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;

4
src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs

@ -72,9 +72,9 @@ namespace ICSharpCode.Core.Presentation @@ -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:

Loading…
Cancel
Save