Browse Source

Add 'UsageDataCollector' AddIn.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4918 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
27fb3b652d
  1. 12
      SharpDevelop.Tests.sln
  2. 12
      SharpDevelop.sln
  3. 29
      src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml
  4. 97
      src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml.cs
  5. 88
      src/AddIns/Misc/StartPage/Project/Src/StartPageControl.xaml
  6. 67
      src/AddIns/Misc/StartPage/Project/Src/StartPageControl.xaml.cs
  7. 5
      src/AddIns/Misc/StartPage/Project/StartPage.addin
  8. 5
      src/AddIns/Misc/StartPage/Project/StartPage.csproj
  9. 144
      src/AddIns/Misc/UsageDataCollector/AnalyticsMonitor.cs
  10. 189
      src/AddIns/Misc/UsageDataCollector/AnalyticsSessionWriter.cs
  11. 16
      src/AddIns/Misc/UsageDataCollector/Configuration/AssemblyInfo.cs
  12. 13
      src/AddIns/Misc/UsageDataCollector/OptionPage.xaml
  13. 43
      src/AddIns/Misc/UsageDataCollector/OptionPage.xaml.cs
  14. 49
      src/AddIns/Misc/UsageDataCollector/StartPageMessage.xaml
  15. 53
      src/AddIns/Misc/UsageDataCollector/StartPageMessage.xaml.cs
  16. 35
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector.addin
  17. 101
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector.csproj
  18. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagReader.cs
  19. BIN
      src/Libraries/SQLite/System.Data.SQLite.dll
  20. 3634
      src/Libraries/SQLite/System.Data.SQLite.xml
  21. 7
      src/Main/Base/Project/Src/Project/BuildEngine.cs
  22. 7
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  23. 3
      src/Main/Core/Project/ICSharpCode.Core.csproj
  24. 84
      src/Main/Core/Project/Src/Services/AnalyticsMonitor/AnalyticsMonitorService.cs
  25. 21
      src/Main/Core/Project/Src/Services/AnalyticsMonitor/IAnalyticsMonitor.cs
  26. 101
      src/Main/ICSharpCode.Core.Presentation/CollapsiblePanel.cs
  27. 1
      src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
  28. 56
      src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs
  29. 19
      src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs
  30. 32
      src/Main/ICSharpCode.Core.Presentation/themes/generic.xaml
  31. 2
      src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs
  32. 2
      src/Main/ICSharpCode.Core.WinForms/ToolBar/ToolBarCommand.cs
  33. 5
      src/Main/ICSharpCode.SharpDevelop.Sda/Src/ExceptionBox.cs

12
SharpDevelop.Tests.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 10
# SharpDevelop 4.0.0.4894
# SharpDevelop 4.0.0.4915
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -311,6 +311,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{F3662720-9 @@ -311,6 +311,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{F3662720-9
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UsageDataCollector", "src\AddIns\Misc\UsageDataCollector\UsageDataCollector.csproj", "{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}"
ProjectSection(ProjectDependencies) = postProject
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace.Tests", "src\AddIns\Misc\SearchAndReplace\Test\SearchAndReplace.Tests.csproj", "{A569DCC1-C608-45FD-B770-4F79335EF154}"
ProjectSection(ProjectDependencies) = postProject
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
@ -879,6 +884,10 @@ Global @@ -879,6 +884,10 @@ Global
{70966F84-74C9-4067-A379-0C674A929233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70966F84-74C9-4067-A379-0C674A929233}.Release|Any CPU.Build.0 = Release|Any CPU
{70966F84-74C9-4067-A379-0C674A929233}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Release|Any CPU.Build.0 = Release|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -964,6 +973,7 @@ Global @@ -964,6 +973,7 @@ Global
{17F4D7E0-6933-4C2E-8714-FD7E98D625D5} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{DD9AE6A5-2B9D-443A-BC71-38BE578C36BD} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{A569DCC1-C608-45FD-B770-4F79335EF154} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{A4C858C8-51B6-4265-A695-A20FCEBA1D19} = {CDE0C5A4-2096-48B5-BEA3-74DBA0F0E1EF}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {CDE0C5A4-2096-48B5-BEA3-74DBA0F0E1EF}
{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {CDE0C5A4-2096-48B5-BEA3-74DBA0F0E1EF}

12
SharpDevelop.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 10
# SharpDevelop 4.0.0.4894
# SharpDevelop 4.0.0.4915
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -234,6 +234,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubversionAddIn", "src\AddI @@ -234,6 +234,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubversionAddIn", "src\AddI
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UsageDataCollector", "src\AddIns\Misc\UsageDataCollector\UsageDataCollector.csproj", "{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}"
ProjectSection(ProjectDependencies) = postProject
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display Bindings", "{11BF9245-88A3-4A0A-9A8A-EC9D98036B0F}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -699,6 +704,10 @@ Global @@ -699,6 +704,10 @@ Global
{70966F84-74C9-4067-A379-0C674A929233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70966F84-74C9-4067-A379-0C674A929233}.Release|Any CPU.Build.0 = Release|Any CPU
{70966F84-74C9-4067-A379-0C674A929233}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Release|Any CPU.Build.0 = Release|Any CPU
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -741,6 +750,7 @@ Global @@ -741,6 +750,7 @@ Global
{D332F2D1-2CF1-43B7-903C-844BD5211A7E} = {CA76F702-5B4E-4918-B8D8-7FF8382434FF}
{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {CDE0C5A4-2096-48B5-BEA3-74DBA0F0E1EF}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {CDE0C5A4-2096-48B5-BEA3-74DBA0F0E1EF}
{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{17F4D7E0-6933-4C2E-8714-FD7E98D625D5} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{3CA90546-3B4C-4663-9445-C4E9371750A7} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}
{461606BD-E824-4D0A-8CBA-01810B1F5E02} = {F3662720-9EA2-4591-BBC6-97361DCE50A9}

29
src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
<UserControl x:Class="ICSharpCode.StartPage.RecentProjectsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:core="http://icsharpcode.net/sharpdevelop/core">
<StackPanel Orientation="Vertical">
<ListView Name="lastProjectsListView" SelectionMode="Single" MouseDoubleClick="lastProjectsDoubleClick" KeyDown="lastProjectsKeyDown">
<ListView.Resources>
<DataTemplate x:Key="nameCellTemplate">
<TextBlock>
<Hyperlink Tag="{Binding}" Click="listViewHyperlinkClick">
<TextBlock Text="{Binding Path=Name}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn CellTemplate="{StaticResource nameCellTemplate}" Header="{core:Localize Global.Name}" />
<GridViewColumn DisplayMemberBinding="{Binding Path=LastModification}" Header="{core:Localize StartPage.StartMenu.ModifiedTable}" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Path}" Header="{core:Localize StartPage.StartMenu.LocationTable}" />
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Margin="0,20,0,0">
<Button Content="{core:Localize StartPage.StartMenu.OpenCombineButton}" Click="openSolutionClick" />
<Button Content="{core:Localize StartPage.StartMenu.NewCombineButton}" Click="newSolutionClick" Margin="8,0,0,0" />
</StackPanel>
</StackPanel>
</UserControl>

97
src/AddIns/Misc/StartPage/Project/Src/RecentProjectsControl.xaml.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.StartPage
{
/// <summary>
/// Interaction logic for RecentProjectsControl.xaml
/// </summary>
public partial class RecentProjectsControl : UserControl
{
public RecentProjectsControl()
{
InitializeComponent();
SetBinding(HeaderProperty, new LocalizeExtension("StartPage.StartMenu.BarNameName").CreateBinding());
BuildRecentProjectList();
}
public static readonly DependencyProperty HeaderProperty = HeaderedContentControl.HeaderProperty.AddOwner(typeof(RecentProjectsControl));
public object Header {
get { return GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
void BuildRecentProjectList()
{
List<RecentOpenItem> items = new List<RecentOpenItem>();
foreach (string path in FileService.RecentOpen.RecentProject) {
FileInfo file = new FileInfo(path);
if (file.Exists) {
items.Add(
new RecentOpenItem {
Name = System.IO.Path.GetFileNameWithoutExtension(path),
LastModification = file.LastWriteTime.ToShortDateString(),
Path = path
});
}
}
lastProjectsListView.ItemsSource = items;
}
class RecentOpenItem
{
public string Name { get; set; }
public string LastModification { get; set; }
public string Path { get; set; }
}
void lastProjectsDoubleClick(object sender, RoutedEventArgs e)
{
RecentOpenItem item = (RecentOpenItem)lastProjectsListView.SelectedItem;
if (item != null) {
ProjectService.LoadSolutionOrProject(item.Path);
}
}
void lastProjectsKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return) {
lastProjectsDoubleClick(null, null);
}
}
void listViewHyperlinkClick(object sender, RoutedEventArgs e)
{
RecentOpenItem item = (RecentOpenItem)((Hyperlink)sender).Tag;
ProjectService.LoadSolutionOrProject(item.Path);
}
void openSolutionClick(object sender, RoutedEventArgs e)
{
new ICSharpCode.SharpDevelop.Project.Commands.LoadSolution().Run();
}
void newSolutionClick(object sender, RoutedEventArgs e)
{
new ICSharpCode.SharpDevelop.Project.Commands.CreateNewSolution().Run();
}
}
}

88
src/AddIns/Misc/StartPage/Project/Src/StartPageControl.xaml

@ -2,6 +2,9 @@ @@ -2,6 +2,9 @@
<UserControl
x:Class="ICSharpCode.StartPage.StartPageControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:gui="clr-namespace:ICSharpCode.SharpDevelop.Gui;assembly=ICSharpCode.SharpDevelop" xmlns:core="http://icsharpcode.net/sharpdevelop/core"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Disabled">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
@ -12,7 +15,8 @@ @@ -12,7 +15,8 @@
Height="Auto" />
</Grid.RowDefinitions>
<DockPanel
Grid.Row="0">
Grid.Row="0"
Margin="0,0,0,4">
<Image
MaxWidth="292"
DockPanel.Dock="Left"
@ -27,17 +31,26 @@ @@ -27,17 +31,26 @@
Stretch="Fill"
Source="../Resources/balken_mitte.gif" />
</DockPanel>
<DockPanel
Grid.Row="1"
VerticalAlignment="Top">
<ItemsControl
Name="startPageItems"
Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Vertical">
<Border
DockPanel.Dock="Top"
Background="#A8C6E3"
Margin="4,20,4,0"
Margin="4,12,4,0"
CornerRadius="15,15,0,0"
Padding="15,0,15,0">
<TextBlock
Text="{core:Localize StartPage.StartMenu.BarNameName}"
Text="{Binding Control.Header}"
FontSize="11pt"
FontWeight="Bold"
Foreground="White"
@ -46,60 +59,25 @@ @@ -46,60 +59,25 @@
<Border
Background="#DCDDDE"
Margin="4,0,4,4"
CornerRadius="0,0,15,15">
<StackPanel
Orientation="Vertical"
Margin="15">
<ListView
Name="lastProjectsListView"
SelectionMode="Single"
MouseDoubleClick="lastProjectsDoubleClick"
KeyDown="lastProjectsKeyDown">
<ListView.Resources>
<DataTemplate x:Key="nameCellTemplate">
<TextBlock>
<Hyperlink Tag="{Binding}" Click="listViewHyperlinkClick">
<TextBlock Text="{Binding Path=Name}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn
CellTemplate="{StaticResource nameCellTemplate}"
Header="{core:Localize Global.Name}" />
<GridViewColumn
DisplayMemberBinding="{Binding Path=LastModification}"
Header="{core:Localize StartPage.StartMenu.ModifiedTable}" />
<GridViewColumn
DisplayMemberBinding="{Binding Path=Path}"
Header="{core:Localize StartPage.StartMenu.LocationTable}" />
</GridView>
</ListView.View>
</ListView>
<StackPanel
Orientation="Horizontal"
Margin="0,20,0,0">
<Button
Content="{core:Localize StartPage.StartMenu.OpenCombineButton}"
Click="openSolutionClick" />
<Button
Content="{core:Localize StartPage.StartMenu.NewCombineButton}"
Click="newSolutionClick"
Margin="8,0,0,0" />
</StackPanel>
</StackPanel>
CornerRadius="0,0,15,15"
Padding="15">
<ContentPresenter
Focusable="False"
Content="{Binding Control}" />
</Border>
</DockPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock
Background="#A8C6E3"
Grid.Row="2"
Padding="4,0,4,0"
TextWrapping="Wrap">
Copyright ©2000-2009
<Hyperlink NavigateUri="mailto:webmaster@icsharpcode.net">IC#SharpCode</Hyperlink>
<Run Text="{x:Static gui:AboutSharpDevelopTabPage.LicenseSentence}" />
</TextBlock>
<Hyperlink
NavigateUri="mailto:webmaster@icsharpcode.net">IC#SharpCode</Hyperlink><Run
Text="{x:Static gui:AboutSharpDevelopTabPage.LicenseSentence}" /></TextBlock>
</Grid>
</ScrollViewer>
</UserControl>

67
src/AddIns/Misc/StartPage/Project/Src/StartPageControl.xaml.cs

@ -7,14 +7,9 @@ @@ -7,14 +7,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Project;
using System.Windows.Input;
using ICSharpCode.Core;
namespace ICSharpCode.StartPage
{
@ -26,63 +21,15 @@ namespace ICSharpCode.StartPage @@ -26,63 +21,15 @@ namespace ICSharpCode.StartPage
public StartPageControl()
{
InitializeComponent();
BuildRecentProjectList();
}
void BuildRecentProjectList()
{
List<RecentOpenItem> items = new List<RecentOpenItem>();
foreach (string path in FileService.RecentOpen.RecentProject) {
FileInfo file = new FileInfo(path);
if (file.Exists) {
items.Add(
new RecentOpenItem {
Name = System.IO.Path.GetFileNameWithoutExtension(path),
LastModification = file.LastWriteTime.ToShortDateString(),
Path = path
});
}
}
lastProjectsListView.ItemsSource = items;
}
class RecentOpenItem
{
public string Name { get; set; }
public string LastModification { get; set; }
public string Path { get; set; }
}
void lastProjectsDoubleClick(object sender, RoutedEventArgs e)
{
RecentOpenItem item = (RecentOpenItem)lastProjectsListView.SelectedItem;
if (item != null) {
ProjectService.LoadSolutionOrProject(item.Path);
}
}
void lastProjectsKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return) {
lastProjectsDoubleClick(null, null);
}
}
void listViewHyperlinkClick(object sender, RoutedEventArgs e)
{
RecentOpenItem item = (RecentOpenItem)((Hyperlink)sender).Tag;
ProjectService.LoadSolutionOrProject(item.Path);
}
void openSolutionClick(object sender, RoutedEventArgs e)
{
new ICSharpCode.SharpDevelop.Project.Commands.LoadSolution().Run();
List<object> items = AddInTree.BuildItems<object>("/SharpDevelop/ViewContent/StartPage/Items", this, false);
// WPF does not use DataTemplates if the item already is a UIElement; so we 'box' it.
List<BoxEntry> entries = items.ConvertAll(control => new BoxEntry { Control = control } );
startPageItems.ItemsSource = entries;
}
void newSolutionClick(object sender, RoutedEventArgs e)
sealed class BoxEntry
{
new ICSharpCode.SharpDevelop.Project.Commands.CreateNewSolution().Run();
public object Control { get; set; }
}
}
}

5
src/AddIns/Misc/StartPage/Project/StartPage.addin

@ -33,4 +33,9 @@ @@ -33,4 +33,9 @@
<BrowserSchemeExtension id = "startpage"
class = "ICSharpCode.StartPage.StartPageScheme"/>
</Path>
<Path name = "/SharpDevelop/ViewContent/StartPage/Items">
<Class id="RecentProjects"
class="ICSharpCode.StartPage.RecentProjectsControl"/>
</Path>
</AddIn>

5
src/AddIns/Misc/StartPage/Project/StartPage.csproj

@ -55,6 +55,10 @@ @@ -55,6 +55,10 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="Src\RecentProjectsControl.xaml.cs">
<DependentUpon>RecentProjectsControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\ShowStartPageCommand.cs" />
<Resource Include="Resources\balken_links.gif" />
<Resource Include="Resources\balken_mitte.gif" />
@ -88,6 +92,7 @@ @@ -88,6 +92,7 @@
<Private>False</Private>
</ProjectReference>
<Folder Include="Resources" />
<Page Include="Src\RecentProjectsControl.xaml" />
<Page Include="Src\StartPageControl.xaml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />

144
src/AddIns/Misc/UsageDataCollector/AnalyticsMonitor.cs

@ -0,0 +1,144 @@ @@ -0,0 +1,144 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.Core.Services;
using ICSharpCode.SharpDevelop;
using System.IO;
namespace ICSharpCode.UsageDataCollector
{
/// <summary>
/// Main singleton class of the analytics. This class is thread-safe.
/// </summary>
public sealed class AnalyticsMonitor : IAnalyticsMonitor
{
public static readonly AnalyticsMonitor Instance = new AnalyticsMonitor();
public static bool EnabledIsUndecided {
get {
return string.IsNullOrEmpty(PropertyService.Get("ICSharpCode.UsageDataCollector.Enabled"));
}
}
public static bool Enabled {
get {
return string.Equals(PropertyService.Get("ICSharpCode.UsageDataCollector.Enabled"), bool.TrueString, StringComparison.OrdinalIgnoreCase);
}
set {
PropertyService.Set("ICSharpCode.UsageDataCollector.Enabled", value.ToString());
if (value) {
Instance.OpenSession();
} else {
Instance.CloseSession();
Instance.TryDeleteDatabase();
}
}
}
readonly object lockObj = new object();
string dbFileName;
AnalyticsSessionWriter session;
private AnalyticsMonitor()
{
var container = ServiceManager.Instance.GetRequiredService<ThreadSafeServiceContainer>();
container.TryAddService(typeof(IAnalyticsMonitor), this);
dbFileName = Path.Combine(PropertyService.ConfigDirectory, "usageData.dat");
SharpDevelop.Gui.WorkbenchSingleton.WorkbenchUnloaded += delegate { CloseSession(); };
}
public void OpenSession()
{
lock (lockObj) {
if (session == null) {
try {
session = new AnalyticsSessionWriter(dbFileName);
} catch (DatabaseTooNewException) {
LoggingService.Warn("Could not use AnalyticsMonitor: too new version of database");
}
}
}
}
void TryDeleteDatabase()
{
lock (lockObj) {
CloseSession();
try {
File.Delete(dbFileName);
} catch (IOException) {
} catch (AccessViolationException) {
}
}
}
public void CloseSession()
{
lock (lockObj) {
if (session != null) {
session.Dispose();
session = null;
}
}
}
public void TrackException(Exception exception)
{
lock (lockObj) {
if (session != null) {
// TODO: recognize inner exceptions
session.AddException(exception.GetType().FullName, exception.StackTrace);
}
}
}
public IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod)
{
TrackedFeature feature = new TrackedFeature();
lock (lockObj) {
if (session != null) {
feature.IsTracked = true;
feature.FeatureID = session.AddFeatureUse(featureName, activationMethod);
}
}
return feature;
}
void EndTracking(TrackedFeature feature)
{
lock (lockObj) {
if (session != null && feature.IsTracked) {
feature.IsTracked = false;
session.WriteEndTimeForFeature(feature.FeatureID);
}
}
}
sealed class TrackedFeature : IAnalyticsMonitorTrackedFeature
{
internal bool IsTracked;
internal long FeatureID;
public void EndTracking()
{
Instance.EndTracking(this);
}
}
}
public class AutoStartCommand : AbstractCommand
{
public override void Run()
{
if (AnalyticsMonitor.Enabled)
AnalyticsMonitor.Instance.OpenSession();
}
}
}

189
src/AddIns/Misc/UsageDataCollector/AnalyticsSessionWriter.cs

@ -0,0 +1,189 @@ @@ -0,0 +1,189 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.Core;
using System;
using System.Data.SQLite;
using System.Runtime.Serialization;
namespace ICSharpCode.UsageDataCollector
{
/// <summary>
/// Creates an analytics session.
/// </summary>
public class AnalyticsSessionWriter : IDisposable
{
SQLiteConnection connection;
long sessionID;
public AnalyticsSessionWriter(string databaseFileName)
{
SQLiteConnectionStringBuilder conn = new SQLiteConnectionStringBuilder();
conn.Add("Data Source", databaseFileName);
connection = new SQLiteConnection(conn.ConnectionString);
connection.Open();
InitializeTables();
StartSession();
}
/// <summary>
/// Creates or upgrades the database
/// </summary>
void InitializeTables()
{
using (SQLiteTransaction transaction = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Properties (
name TEXT NOT NULL PRIMARY KEY,
value TEXT NOT NULL
);
INSERT OR IGNORE INTO Properties (name, value) VALUES ('dbVersion', '1.0');
INSERT OR IGNORE INTO Properties (name, value) VALUES ('userID', '" + Guid.NewGuid().ToString() + @"');
";
cmd.ExecuteNonQuery();
}
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "SELECT value FROM Properties WHERE name = 'dbVersion';";
string version = (string)cmd.ExecuteScalar();
if (version == null)
throw new InvalidOperationException("Error retrieving database version");
if (version != "1.0") {
throw new DatabaseTooNewException();
}
}
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Sessions (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
startTime TEXT NOT NULL,
endTime TEXT,
appVersion TEXT,
platform TEXT,
osVersion TEXT,
processorCount INTEGER,
dotnetRuntime TEXT,
language TEXT
);
CREATE TABLE IF NOT EXISTS FeatureUses (
session INTEGER NOT NULL,
time TEXT NOT NULL,
endTime TEXT,
feature TEXT NOT NULL,
activationMethod TEXT
);
CREATE TABLE IF NOT EXISTS Exceptions (
session INTEGER NOT NULL,
time TEXT NOT NULL,
type TEXT NOT NULL,
stackTrace TEXT
);
";
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
void StartSession()
{
using (SQLiteTransaction transaction = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "INSERT INTO Sessions (startTime, appVersion, platform, osVersion, processorCount, dotnetRuntime, language)" +
" VALUES (datetime(), ?, ?, ?, ?, ?, ?);";
cmd.Parameters.Add(new SQLiteParameter { Value = RevisionClass.FullVersion });
cmd.Parameters.Add(new SQLiteParameter { Value = Environment.OSVersion.Platform.ToString() });
cmd.Parameters.Add(new SQLiteParameter { Value = Environment.OSVersion.Version.ToString() });
cmd.Parameters.Add(new SQLiteParameter { Value = Environment.ProcessorCount });
cmd.Parameters.Add(new SQLiteParameter { Value = Environment.Version.ToString() });
cmd.Parameters.Add(new SQLiteParameter { Value = ICSharpCode.Core.ResourceService.Language });
cmd.ExecuteNonQuery();
}
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "SELECT last_insert_rowid();";
sessionID = (long)cmd.ExecuteScalar();
}
transaction.Commit();
}
}
void EndSession()
{
using (SQLiteTransaction transaction = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "UPDATE Sessions SET endTime = datetime() WHERE id = ?;";
cmd.Parameters.Add(new SQLiteParameter { Value = sessionID });
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
public long AddFeatureUse(string featureName, string activationMethod)
{
long featureRowId;
using (SQLiteTransaction transaction = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "INSERT INTO FeatureUses (session, time, feature, activationMethod)" +
" VALUES (?, datetime(), ?, ?);";
cmd.Parameters.Add(new SQLiteParameter { Value = sessionID });
cmd.Parameters.Add(new SQLiteParameter { Value = featureName });
cmd.Parameters.Add(new SQLiteParameter { Value = activationMethod });
cmd.ExecuteNonQuery();
}
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "SELECT last_insert_rowid();";
featureRowId = (long)cmd.ExecuteScalar();
}
transaction.Commit();
}
return featureRowId;
}
public void WriteEndTimeForFeature(long featureID)
{
using (SQLiteTransaction transaction = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "UPDATE FeatureUses SET endTime = datetime() WHERE ROWID = ?;";
cmd.Parameters.Add(new SQLiteParameter { Value = featureID });
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
public void AddException(string exceptionType, string stacktrace)
{
using (SQLiteTransaction transaction = this.connection.BeginTransaction()) {
using (SQLiteCommand cmd = this.connection.CreateCommand()) {
cmd.CommandText = "INSERT INTO Exceptions (session, time, type, stackTrace)" +
" VALUES (?, datetime(), ?, ?);";
cmd.Parameters.Add(new SQLiteParameter { Value = sessionID });
cmd.Parameters.Add(new SQLiteParameter { Value = exceptionType });
cmd.Parameters.Add(new SQLiteParameter { Value = stacktrace });
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
public void Dispose()
{
EndSession();
connection.Close();
}
}
[Serializable]
public class DatabaseTooNewException : Exception
{
public DatabaseTooNewException() {}
protected DatabaseTooNewException(SerializationInfo info, StreamingContext context) : base(info, context) {}
}
}

16
src/AddIns/Misc/UsageDataCollector/Configuration/AssemblyInfo.cs

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
#endregion
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("UsageDataCollector")]
[assembly: AssemblyDescription("Collects usage data and sends it to the SharpDevelop team")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

13
src/AddIns/Misc/UsageDataCollector/OptionPage.xaml

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
<gui:OptionPanel x:Class="ICSharpCode.UsageDataCollector.OptionPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:gui="clr-namespace:ICSharpCode.SharpDevelop.Gui;assembly=ICSharpCode.SharpDevelop" xmlns:core="http://icsharpcode.net/sharpdevelop/core" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBlock TextWrapping="Wrap">
We need your help! To improve SharpDevelop in the future, we would like to know which features are used most.<LineBreak />
SharpDevelop can collect this information and upload it automatically.
</TextBlock>
<RadioButton Name="acceptRadio">I would like to participate - collect and upload usage data</RadioButton>
<RadioButton Name="declineRadio">I do not want to participate</RadioButton>
<TextBlock HorizontalAlignment="Left">
<Hyperlink NavigateUri="http://www.example.com/UsageData">Privacy Statement</Hyperlink>
</TextBlock>
</StackPanel>
</gui:OptionPanel>

43
src/AddIns/Misc/UsageDataCollector/OptionPage.xaml.cs

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.UsageDataCollector
{
/// <summary>
/// Interaction logic for OptionPage.xaml
/// </summary>
public partial class OptionPage : OptionPanel
{
public OptionPage()
{
InitializeComponent();
}
public override void LoadOptions()
{
base.LoadOptions();
if (!AnalyticsMonitor.EnabledIsUndecided) {
if (AnalyticsMonitor.Enabled)
acceptRadio.IsChecked = true;
else
declineRadio.IsChecked = true;
}
}
public override bool SaveOptions()
{
if (acceptRadio.IsChecked ?? false)
AnalyticsMonitor.Enabled = true;
else if (declineRadio.IsChecked ?? false)
AnalyticsMonitor.Enabled = false;
return base.SaveOptions();
}
}
}

49
src/AddIns/Misc/UsageDataCollector/StartPageMessage.xaml

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl
x:Class="ICSharpCode.UsageDataCollector.StartPageMessage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:core="http://icsharpcode.net/sharpdevelop/core">
<StackPanel>
<core:CollapsiblePanel
Name="mainPanel">
<StackPanel>
<TextBlock
TextWrapping="Wrap">
We need your help! To improve SharpDevelop in the future, we would like to know which features are used most.<LineBreak />
SharpDevelop can collect this information and upload it automatically.
</TextBlock>
<RadioButton
Name="acceptRadio"
Checked="Radio_Checked">I would like to participate - collect and upload usage data</RadioButton>
<RadioButton
Name="declineRadio"
Checked="Radio_Checked">I do not want to participate</RadioButton>
<Button
Name="saveButton"
IsEnabled="False"
HorizontalAlignment="Left"
Margin="16 4"
Width="75"
Height="23"
Click="SaveButton_Click">Save</Button>
</StackPanel>
</core:CollapsiblePanel>
<core:CollapsiblePanel
Name="acceptedMessage"
IsCollapsed="True">
<TextBlock>
Thank you for participating! You can still opt-out later using the SharpDevelop options.
</TextBlock>
</core:CollapsiblePanel>
<core:CollapsiblePanel
Name="declinedMessage"
IsCollapsed="True">
<TextBlock>
You can still opt-in later using the SharpDevelop options.
</TextBlock>
</core:CollapsiblePanel>
<TextBlock
HorizontalAlignment="Left">
<Hyperlink
NavigateUri="http://www.example.com/UsageData">Privacy Statement</Hyperlink>
</TextBlock>
</StackPanel>
</UserControl>

53
src/AddIns/Misc/UsageDataCollector/StartPageMessage.xaml.cs

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace ICSharpCode.UsageDataCollector
{
/// <summary>
/// Interaction logic for StartPageMessage.xaml
/// </summary>
public partial class StartPageMessage : UserControl
{
public StartPageMessage()
{
InitializeComponent();
this.Header = "Usage Data Collection";
}
void Radio_Checked(object sender, RoutedEventArgs e)
{
saveButton.IsEnabled = true;
}
void SaveButton_Click(object sender, RoutedEventArgs e)
{
bool accepted = acceptRadio.IsChecked ?? false;
AnalyticsMonitor.Enabled = accepted;
mainPanel.IsCollapsed = true;
acceptedMessage.IsCollapsed = !accepted;
declinedMessage.IsCollapsed = accepted;
}
public static readonly DependencyProperty HeaderProperty = HeaderedContentControl.HeaderProperty.AddOwner(typeof(StartPageMessage));
public object Header {
get { return GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
}
}

35
src/AddIns/Misc/UsageDataCollector/UsageDataCollector.addin

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
<AddIn name = "Usage Data Collector"
author = "Daniel Grunwald"
url = ""
description = "Collects usage data and sends it to the SharpDevelop team"
addInManagerHidden = "preinstalled">
<Manifest>
<Identity name = "ICSharpCode.UsageDataCollector"/>
</Manifest>
<Runtime>
<Import assembly = "UsageDataCollector.dll"/>
</Runtime>
<Path name = "/SharpDevelop/ViewContent/StartPage/Items">
<Condition name = "Compare" string = "${property:ICSharpCode.UsageDataCollector.Enabled}" equals = "">
<Class id = "UsageDataCollector"
insertbefore = "RecentProjects"
class = "ICSharpCode.UsageDataCollector.StartPageMessage"/>
</Condition>
</Path>
<Path name = "/Workspace/Autostart">
<Condition name = "Compare" string = "${property:ICSharpCode.UsageDataCollector.Enabled}" equals = "True">
<Class id = "UsageDataCollector"
class = "ICSharpCode.UsageDataCollector.AutoStartCommand"/>
</Condition>
</Path>
<Path name="/SharpDevelop/Dialogs/OptionsDialog/UIOptions">
<OptionPanel id = "UsageDataCollector"
label = "Usage Data Collector"
class = "ICSharpCode.UsageDataCollector.OptionPage" />
</Path>
</AddIn>

101
src/AddIns/Misc/UsageDataCollector/UsageDataCollector.csproj

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{6B1CFE35-DA17-4DEB-9C6E-227E5E251DA0}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<RootNamespace>ICSharpCode.UsageDataCollector</RootNamespace>
<AssemblyName>UsageDataCollector</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<OutputPath>..\..\..\..\AddIns\AddIns\Misc\UsageDataCollector\</OutputPath>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.SQLite">
<HintPath>..\..\..\Libraries\SQLite\System.Data.SQLite.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="UsageDataCollector.addin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AnalyticsMonitor.cs" />
<Compile Include="AnalyticsSessionWriter.cs" />
<Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="OptionPage.xaml.cs">
<DependentUpon>OptionPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="StartPageMessage.xaml.cs">
<DependentUpon>StartPageMessage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="OptionPage.xaml" />
<Page Include="StartPageMessage.xaml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\Main\Core\Project\ICSharpCode.Core.csproj">
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project>
<Name>ICSharpCode.Core</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj">
<Project>{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}</Project>
<Name>ICSharpCode.Core.Presentation</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TagReader.cs

@ -36,6 +36,7 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -36,6 +36,7 @@ namespace ICSharpCode.AvalonEdit.Xml
T cached = trackedSegments.GetCachedObject<T>(this.CurrentLocation, 0, condition);
if (cached != null) {
Skip(cached.Length);
AXmlParser.Assert(cached.Length > 0, "cached elements must not have zero length");
res = cached;
return true;
} else {

BIN
src/Libraries/SQLite/System.Data.SQLite.dll

Binary file not shown.

3634
src/Libraries/SQLite/System.Data.SQLite.xml

File diff suppressed because it is too large Load Diff

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

@ -9,6 +9,7 @@ using System; @@ -9,6 +9,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using System.Text;
@ -25,6 +26,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -25,6 +26,7 @@ namespace ICSharpCode.SharpDevelop.Project
{
#region Building in the SharpDevelop GUI
static CancellableProgressMonitor guiBuildProgressMonitor;
static IAnalyticsMonitorTrackedFeature guiBuildTrackedFeature;
/// <summary>
/// Starts to run a build inside the SharpDevelop GUI.
@ -48,6 +50,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -48,6 +50,7 @@ namespace ICSharpCode.SharpDevelop.Project
}
} else {
guiBuildProgressMonitor = new CancellableProgressMonitor(StatusBarService.CreateProgressMonitor());
guiBuildTrackedFeature = AnalyticsMonitorService.TrackFeature("Build");
Gui.WorkbenchSingleton.Workbench.GetPad(typeof(Gui.CompilerMessageView)).BringPadToFront();
ProjectService.RaiseEventBuildStarted(new BuildEventArgs(project, options));
StartBuild(project, options,
@ -106,6 +109,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -106,6 +109,10 @@ namespace ICSharpCode.SharpDevelop.Project
WorkbenchSingleton.SafeThreadAsyncCall(
delegate {
guiBuildProgressMonitor = null;
if (guiBuildTrackedFeature != null) {
guiBuildTrackedFeature.EndTracking();
guiBuildTrackedFeature = null;
}
ProjectService.RaiseEventBuildFinished(new BuildEventArgs(buildable, options, results));
});
}

7
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -97,11 +97,15 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -97,11 +97,15 @@ namespace ICSharpCode.SharpDevelop.Debugging
public static event EventHandler DebugStarted;
public static event EventHandler DebugStopped;
static IAnalyticsMonitorTrackedFeature debugFeature;
static void OnDebugStarting(object sender, EventArgs e)
{
WorkbenchSingleton.Workbench.WorkbenchLayout.StoreConfiguration();
LayoutConfiguration.CurrentLayoutName = "Debug";
debugFeature = AnalyticsMonitorService.TrackFeature("Debugger");
ClearDebugMessages();
if (DebugStarting != null)
@ -116,6 +120,9 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -116,6 +120,9 @@ namespace ICSharpCode.SharpDevelop.Debugging
static void OnDebugStopped(object sender, EventArgs e)
{
if (debugFeature != null)
debugFeature.EndTracking();
RemoveCurrentLineMarker();
WorkbenchSingleton.Workbench.WorkbenchLayout.StoreConfiguration();
LayoutConfiguration.CurrentLayoutName = oldLayoutConfiguration;

3
src/Main/Core/Project/ICSharpCode.Core.csproj

@ -85,6 +85,8 @@ @@ -85,6 +85,8 @@
<Compile Include="Src\AddInTree\AddInTreeNode.cs" />
<Compile Include="Src\AddInTree\TreePathNotFoundException.cs" />
<Compile Include="Src\CoreException.cs" />
<Compile Include="Src\Services\AnalyticsMonitor\AnalyticsMonitorService.cs" />
<Compile Include="Src\Services\AnalyticsMonitor\IAnalyticsMonitor.cs" />
<Compile Include="Src\Services\ApplicationStateInfoService.cs" />
<Compile Include="Src\Services\FileUtility\FileNameEventHandler.cs" />
<Compile Include="Src\Services\FileUtility\FileUtility.cs" />
@ -124,6 +126,7 @@ @@ -124,6 +126,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Src\Services\LoggingService" />
<Folder Include="Src\Services\AnalyticsMonitor" />
<Folder Include="Src\Services\ResourceService" />
<Content Include="..\..\..\..\data\schemas\AddIn.xsd">
<Link>Src\AddInTree\AddIn\AddIn.xsd</Link>

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

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.Core.Services;
using System;
namespace ICSharpCode.Core
{
/// <summary>
/// Allows marking the end-time of feature uses.
/// </summary>
/// <remarks>Implementations of this interface must be thread-safe.</remarks>
public interface IAnalyticsMonitorTrackedFeature
{
void EndTracking();
}
/// <summary>
/// Allows tracking feature use.
/// All methods on this class are thread-safe.
/// </summary>
public static class AnalyticsMonitorService
{
/// <summary>
/// Tracks an exception that has occurred.
/// </summary>
public static void TrackException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
IAnalyticsMonitor monitor = ServiceManager.Instance.GetService<IAnalyticsMonitor>();
if (monitor != null) {
monitor.TrackException(exception);
}
}
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <param name="featureName">Name of the feature</param>
/// <returns>Object that can be used to 'end' the feature use, if measuring time spans is desired.</returns>
public static IAnalyticsMonitorTrackedFeature TrackFeature(string featureName)
{
return TrackFeature(featureName, null);
}
/// <summary>
/// Tracks a feature use.
/// </summary>
/// <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(string featureName, string activationMethod)
{
if (featureName == null)
throw new ArgumentNullException("featureName");
if (activationMethod != null)
LoggingService.Debug("Activated feature '" + featureName + "', activation=" + activationMethod);
else
LoggingService.Debug("Activated feature '" + featureName + "'");
IAnalyticsMonitor monitor = ServiceManager.Instance.GetService<IAnalyticsMonitor>();
if (monitor != null) {
return monitor.TrackFeature(featureName, activationMethod) ?? DummyFeature.Instance;
} else {
return DummyFeature.Instance;
}
}
sealed class DummyFeature : IAnalyticsMonitorTrackedFeature
{
public static readonly DummyFeature Instance = new DummyFeature();
public void EndTracking()
{
}
}
}
}

21
src/Main/Core/Project/Src/Services/AnalyticsMonitor/IAnalyticsMonitor.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.Core.Services
{
/// <summary>
/// Interface for AnalyticsMonitorService.
/// </summary>
/// <remarks>Implementations of this interface must be thread-safe.</remarks>
public interface IAnalyticsMonitor
{
void TrackException(Exception exception);
IAnalyticsMonitorTrackedFeature TrackFeature(string featureName, string activationMethod);
}
}

101
src/Main/ICSharpCode.Core.Presentation/CollapsiblePanel.cs

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Animation;
namespace ICSharpCode.Core.Presentation
{
/// <summary>
/// Allows animated collapsing of the content of this panel.
/// </summary>
public class CollapsiblePanel : ContentControl
{
static CollapsiblePanel()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(typeof(CollapsiblePanel)));
}
public static readonly DependencyProperty IsCollapsedProperty = DependencyProperty.Register(
"IsCollapsed", typeof(bool), typeof(CollapsiblePanel),
new UIPropertyMetadata(false, new PropertyChangedCallback(OnIsCollapsedChanged)));
public bool IsCollapsed {
get { return (bool)GetValue(IsCollapsedProperty); }
set { SetValue(IsCollapsedProperty, value); }
}
public static readonly DependencyProperty DurationProperty = DependencyProperty.Register(
"Duration", typeof(TimeSpan), typeof(CollapsiblePanel),
new UIPropertyMetadata(TimeSpan.FromMilliseconds(500)));
/// <summary>
/// The duration in milliseconds of the animation.
/// </summary>
public TimeSpan Duration {
get { return (TimeSpan)GetValue(DurationProperty); }
set { SetValue(DurationProperty, value); }
}
protected internal static readonly DependencyProperty AnimationProgressProperty = DependencyProperty.Register(
"AnimationProgress", typeof(double), typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(1.0));
/// <summary>
/// Value between 0 and 1 specifying how far the animation currently is.
/// </summary>
protected internal double AnimationProgress {
get { return (double)GetValue(AnimationProgressProperty); }
set { SetValue(AnimationProgressProperty, value); }
}
static void OnIsCollapsedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((CollapsiblePanel)d).SetupAnimation((bool)e.NewValue);
}
void SetupAnimation(bool isCollapsed)
{
if (this.IsLoaded) {
// If the animation is already running, calculate remaining portion of the time
double currentProgress = AnimationProgress;
if (!isCollapsed) {
currentProgress = 1.0 - currentProgress;
}
DoubleAnimation animation = new DoubleAnimation();
animation.To = isCollapsed ? 0.0 : 1.0;
animation.Duration = TimeSpan.FromSeconds(Duration.TotalSeconds * currentProgress);
animation.FillBehavior = FillBehavior.HoldEnd;
this.BeginAnimation(AnimationProgressProperty, animation);
} else {
this.AnimationProgress = isCollapsed ? 0.0 : 1.0;
}
}
}
sealed class CollapsiblePanelProgressToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double)
return (double)value > 0 ? Visibility.Visible : Visibility.Collapsed;
else
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

1
src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj

@ -67,6 +67,7 @@ @@ -67,6 +67,7 @@
<Compile Include="..\GlobalAssemblyInfo.cs">
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="CollapsiblePanel.cs" />
<Compile Include="ConditionalSeparator.cs" />
<Compile Include="DropDownButton.cs" />
<Compile Include="GetBitmapExtension.cs" />

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

@ -98,7 +98,6 @@ namespace ICSharpCode.Core.Presentation @@ -98,7 +98,6 @@ namespace ICSharpCode.Core.Presentation
if (!commandCreated) {
CreateCommand();
}
LoggingService.Debug("Execute " + codon.Id);
if (CanExecute(parameter)) {
addInCommand.Run();
}
@ -130,10 +129,63 @@ namespace ICSharpCode.Core.Presentation @@ -130,10 +129,63 @@ namespace ICSharpCode.Core.Presentation
if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) {
KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]);
if (inputBindingOwner != null) {
inputBindingOwner.InputBindings.Add(new InputBinding(this.Command, kg));
var shortcutCommand = this.Command;
string featureName = GetFeatureName();
if (shortcutCommand != null && !string.IsNullOrEmpty(featureName))
shortcutCommand = new ShortcutCommandWrapper(shortcutCommand, featureName);
inputBindingOwner.InputBindings.Add(new InputBinding(shortcutCommand, kg));
}
this.InputGestureText = kg.GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture);
}
}
string GetFeatureName()
{
string commandName = codon.Properties["command"];
if (string.IsNullOrEmpty(commandName)) {
return codon.Properties["class"];
} else {
return commandName;
}
}
protected override void OnClick()
{
base.OnClick();
string feature = GetFeatureName();
if (!string.IsNullOrEmpty(feature)) {
AnalyticsMonitorService.TrackFeature(feature, "Menu");
}
}
sealed class ShortcutCommandWrapper : System.Windows.Input.ICommand
{
readonly System.Windows.Input.ICommand baseCommand;
readonly string featureName;
public ShortcutCommandWrapper(System.Windows.Input.ICommand baseCommand, string featureName)
{
Debug.Assert(baseCommand != null);
Debug.Assert(featureName != null);
this.baseCommand = baseCommand;
this.featureName = featureName;
}
public event EventHandler CanExecuteChanged {
add { baseCommand.CanExecuteChanged += value; }
remove { baseCommand.CanExecuteChanged -= value; }
}
public void Execute(object parameter)
{
AnalyticsMonitorService.TrackFeature(featureName, "Shortcut");
baseCommand.Execute(parameter);
}
public bool CanExecute(object parameter)
{
return baseCommand.CanExecute(parameter);
}
}
}
}

19
src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs

@ -41,6 +41,25 @@ namespace ICSharpCode.Core.Presentation @@ -41,6 +41,25 @@ namespace ICSharpCode.Core.Presentation
SetResourceReference(FrameworkElement.StyleProperty, ToolBar.ButtonStyleKey);
}
string GetFeatureName()
{
string commandName = codon.Properties["command"];
if (string.IsNullOrEmpty(commandName)) {
return codon.Properties["class"];
} else {
return commandName;
}
}
protected override void OnClick()
{
string feature = GetFeatureName();
if (!string.IsNullOrEmpty(feature)) {
AnalyticsMonitorService.TrackFeature(feature, "Toolbar");
}
base.OnClick();
}
public void UpdateText()
{
if (codon.Properties.Contains("tooltip")) {

32
src/Main/ICSharpCode.Core.Presentation/themes/generic.xaml

@ -144,4 +144,36 @@ @@ -144,4 +144,36 @@
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:CollapsiblePanel}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CollapsiblePanel">
<ControlTemplate.Resources>
<local:CollapsiblePanelProgressToVisibilityConverter x:Key="visibilityConverter"/>
</ControlTemplate.Resources>
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Name="PART_Border"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=AnimationProgress, Converter={StaticResource visibilityConverter}}"
>
<Border.LayoutTransform>
<ScaleTransform ScaleY="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=AnimationProgress}"/>
</Border.LayoutTransform>
<ContentPresenter
Margin="{TemplateBinding Control.Padding}"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

2
src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs

@ -127,7 +127,7 @@ namespace ICSharpCode.Core.WinForms @@ -127,7 +127,7 @@ namespace ICSharpCode.Core.WinForms
if (GetVisible() && Enabled) {
ICommand cmd = Command;
if (cmd != null) {
LoggingService.Info("Run command " + cmd.GetType().FullName);
AnalyticsMonitorService.TrackFeature(cmd.GetType().FullName, "Menu");
cmd.Run();
}
}

2
src/Main/ICSharpCode.Core.WinForms/ToolBar/ToolBarCommand.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.Core.WinForms @@ -45,7 +45,7 @@ namespace ICSharpCode.Core.WinForms
}
if (menuCommand != null) {
menuCommand.Owner = caller;
LoggingService.Info("Run command " + menuCommand.GetType().FullName);
AnalyticsMonitorService.TrackFeature(menuCommand.GetType().FullName, "Toolbar");
menuCommand.Run();
}
}

5
src/Main/ICSharpCode.SharpDevelop.Sda/Src/ExceptionBox.cs

@ -87,6 +87,11 @@ namespace ICSharpCode.SharpDevelop.Sda @@ -87,6 +87,11 @@ namespace ICSharpCode.SharpDevelop.Sda
return;
showingBox = true;
try {
try {
AnalyticsMonitorService.TrackException(exception);
} catch (Exception ex) {
LoggingService.Warn("Error tracking exception", ex);
}
using (ExceptionBox box = new ExceptionBox(exception, message, mustTerminate)) {
if (ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.InvokeRequired)
box.ShowDialog();

Loading…
Cancel
Save