diff --git a/ArmA.Studio.sln b/ArmA.Studio.sln index 11caf33..34a7f47 100644 --- a/ArmA.Studio.sln +++ b/ArmA.Studio.sln @@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arma.Studio.CallstackWindow EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arma.Studio.ImmediateWindow", "Arma.Studio.ImmediateWindow\Arma.Studio.ImmediateWindow.csproj", "{5CB6E39A-BD21-4819-B2A2-5F2456B726FB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arma.Studio.ErrorWindow", "Arma.Studio.ErrorWindow\Arma.Studio.ErrorWindow.csproj", "{19BA0777-B414-4C19-9E73-47D6B1B78AF8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -157,6 +159,18 @@ Global {5CB6E39A-BD21-4819-B2A2-5F2456B726FB}.Release|x64.Build.0 = Release|Any CPU {5CB6E39A-BD21-4819-B2A2-5F2456B726FB}.Release|x86.ActiveCfg = Release|Any CPU {5CB6E39A-BD21-4819-B2A2-5F2456B726FB}.Release|x86.Build.0 = Release|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Debug|x64.ActiveCfg = Debug|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Debug|x64.Build.0 = Debug|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Debug|x86.ActiveCfg = Debug|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Debug|x86.Build.0 = Debug|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Release|Any CPU.Build.0 = Release|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Release|x64.ActiveCfg = Release|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Release|x64.Build.0 = Release|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Release|x86.ActiveCfg = Release|Any CPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -172,6 +186,7 @@ Global {B978950C-CB04-4F70-BF10-DDE1AE83CA05} = {094C7162-5575-4781-A174-116E78B5B04B} {CC899ACD-E1A8-406C-AF70-22A6FE5228A0} = {094C7162-5575-4781-A174-116E78B5B04B} {5CB6E39A-BD21-4819-B2A2-5F2456B726FB} = {094C7162-5575-4781-A174-116E78B5B04B} + {19BA0777-B414-4C19-9E73-47D6B1B78AF8} = {094C7162-5575-4781-A174-116E78B5B04B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {70BCA3AD-C46B-45A2-A847-960793B49531} diff --git a/Arma.Studio.Data/TextEditor/LintInfo.cs b/Arma.Studio.Data/TextEditor/LintInfo.cs index 4ec6630..d887f22 100644 --- a/Arma.Studio.Data/TextEditor/LintInfo.cs +++ b/Arma.Studio.Data/TextEditor/LintInfo.cs @@ -12,5 +12,7 @@ public class LintInfo public int Line { get; set; } public int Column { get; set; } public int Length { get; set; } + public string File { get; set; } + public string Description { get; set; } } } diff --git a/Arma.Studio.ErrorWindow/Arma.Studio.ErrorWindow.csproj b/Arma.Studio.ErrorWindow/Arma.Studio.ErrorWindow.csproj new file mode 100644 index 0000000..0e94db4 --- /dev/null +++ b/Arma.Studio.ErrorWindow/Arma.Studio.ErrorWindow.csproj @@ -0,0 +1,86 @@ + + + + + Debug + AnyCPU + {19BA0777-B414-4C19-9E73-47D6B1B78AF8} + Library + Properties + Arma.Studio.ErrorWindow + Arma.Studio.ErrorWindow + v4.6.1 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + True + True + Language.resx + + + + + MSBuild:Compile + Designer + + + PublicResXFileCodeGenerator + Language.Designer.cs + + + + + {05a55f19-86ee-46a1-875a-15bbfe31a4ab} + Arma.Studio.Data + + + + + +if not exist "$(SolutionDir)Arma.Studio\$(OutDir)Plugins" mkdir ""$(SolutionDir)Arma.Studio\$(OutDir)Plugins"" +if not exist "$(SolutionDir)Arma.Studio\$(OutDir)Plugins\ErrorWindow" mkdir ""$(SolutionDir)Arma.Studio\$(OutDir)Plugins\ErrorWindow"" +xcopy /Y "$(TargetDir)*" "$(SolutionDir)Arma.Studio\$(OutDir)Plugins\ErrorWindow" +( + echo ^<plugin^> + echo ^<library^>$(TargetFileName)^</library^> + echo ^</plugin^> +) > "$(SolutionDir)Arma.Studio\$(OutDir)Plugins\ErrorWindow\plugin.xml" + + + \ No newline at end of file diff --git a/Arma.Studio.ErrorWindow/ErrorWindow.xaml b/Arma.Studio.ErrorWindow/ErrorWindow.xaml new file mode 100644 index 0000000..2b267f4 --- /dev/null +++ b/Arma.Studio.ErrorWindow/ErrorWindow.xaml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arma.Studio.ErrorWindow/ErrorWindowDataContext.cs b/Arma.Studio.ErrorWindow/ErrorWindowDataContext.cs new file mode 100644 index 0000000..eaa7ba0 --- /dev/null +++ b/Arma.Studio.ErrorWindow/ErrorWindowDataContext.cs @@ -0,0 +1,83 @@ +using Arma.Studio.Data; +using Arma.Studio.Data.TextEditor; +using Arma.Studio.Data.UI; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; + +namespace Arma.Studio.ErrorWindow +{ + public class ErrorWindowDataContext : DockableBase + { + public override string Title { get => Properties.Language.ErrorWindow; set => throw new NotSupportedException(); } + public ObservableCollection LintInfos => Instanceable.Instance.LintInfos; + + #region Property: CurrentErrorCount (System.Int32) + public int CurrentErrorCount + { + get => this._CurrentErrorCount; + set + { + this._CurrentErrorCount = value; + this.RaisePropertyChanged(); + } + } + private int _CurrentErrorCount; + #endregion + #region Property: CurrentWarningCount (System.Int32) + public int CurrentWarningCount + { + get => this._CurrentWarningCount; + set + { + this._CurrentWarningCount = value; + this.RaisePropertyChanged(); + } + } + private int _CurrentWarningCount; + #endregion + #region Property: CurrentInfoCount (System.Int32) + public int CurrentInfoCount + { + get => this._CurrentInfoCount; + set + { + this._CurrentInfoCount = value; + this.RaisePropertyChanged(); + } + } + private int _CurrentInfoCount; + #endregion + + public ICommand CmdEntryOnDoubleClick => new RelayCommand((lintinfo) => + { + if ((Application.Current as IApp).MainWindow.FileManagement.ContainsKey(lintinfo.File)) + { + var file = (Application.Current as IApp).MainWindow.FileManagement[lintinfo.File] as Data.IO.File; + (Application.Current as IApp).MainWindow.OpenFile(file).ContinueWith((textDocument) => + { + textDocument.Result.ScrollTo((int)lintinfo.Line, (int)lintinfo.Column); + }, TaskContinuationOptions.OnlyOnRanToCompletion); + } + }); + public ErrorWindowDataContext() + { + this.LintInfos.CollectionChanged += this.LintInfos_CollectionChanged; + this.CurrentErrorCount = this.LintInfos.Count((it) => it.Severity == ESeverity.Error); + this.CurrentWarningCount = this.LintInfos.Count((it) => it.Severity == ESeverity.Warning); + this.CurrentInfoCount = this.LintInfos.Count((it) => it.Severity == ESeverity.Info || it.Severity == ESeverity.Diagnostic || it.Severity == ESeverity.Trace); + } + + private void LintInfos_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + this.CurrentErrorCount = this.LintInfos.Count((it) => it.Severity == ESeverity.Error); + this.CurrentWarningCount = this.LintInfos.Count((it) => it.Severity == ESeverity.Warning); + this.CurrentInfoCount = this.LintInfos.Count((it) => it.Severity == ESeverity.Info || it.Severity == ESeverity.Diagnostic || it.Severity == ESeverity.Trace); + } + } +} diff --git a/Arma.Studio.ErrorWindow/PluginMain.cs b/Arma.Studio.ErrorWindow/PluginMain.cs new file mode 100644 index 0000000..4ac9f5c --- /dev/null +++ b/Arma.Studio.ErrorWindow/PluginMain.cs @@ -0,0 +1,87 @@ +using Arma.Studio.Data; +using Arma.Studio.Data.Dockable; +using Arma.Studio.Data.Log; +using Arma.Studio.Data.UI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Arma.Studio.ErrorWindow +{ + public class PluginMain : IPlugin, IDockableProvider + { + internal static LoggerCollection Loggers { get; private set; } + #region IPlugin + public Version Version => new Version(1, 0, 0, 0); + public string Name => Properties.Language.ErrorWindow_Name; + public string Description => String.Empty; + public Task CheckForUpdate(CancellationToken cancellationToken) => Task.Run(() => default(IUpdateInfo)); + public Task Initialize(string pluginPath, CancellationToken cancellationToken) + { + Instanceable.Instance = this; + this.GetApplication().MainWindow.FileManagement.CollectionChanged += this.FileManagement_CollectionChanged; + return Task.CompletedTask; + } + #endregion + #region IDockableProvider + public IEnumerable Dockables => new DockableInfo[] { + DockableInfo.Create(Properties.Language.ErrorWindow, ECreationMode.Anchorable, () => new ErrorWindowDataContext()) + }; + public void AddDataTemplates(GenericDataTemplateSelector selector) + { + selector.AddAllDataTemplatesInAssembly(typeof(PluginMain).Assembly, (s) => s.StartsWith("Arma.Studio.ErrorWindow")); + } + #endregion + + public System.Collections.ObjectModel.ObservableCollection LintInfos { get; } = new System.Collections.ObjectModel.ObservableCollection(); + + private void FileManagement_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + foreach (Data.IO.PBO pbo in e.NewItems??Array.Empty()) + { + this.GetApplication().MainWindow.BusyContainerManager.Run(async (cancellationToken, busyContainer) => { + var editor = this.GetApplication().MainWindow.TextEditorInfos.FirstOrDefault((tei) => tei.Extensions.Contains(".sqf")); + if (editor is null) + { + return; + } + var files = pbo.GetAll((file) => file.Extension == ".sqf").ToArray(); + foreach (var file in files) + { + Data.TextEditor.ITextEditor instance; + if (editor.IsAsync) + { + instance = await editor.CreateAsyncFunc(); + } + else + { + instance = editor.CreateFunc(); + } + if (!(instance is Data.TextEditor.ILintable lintable)) + { + return; + } + instance.File = file; + var doc = this.GetApplication().MainWindow + .GetDocuments() + .Where((it) => it is ITextDocument) + .Cast() + .FirstOrDefault((d) => d.TextEditorInstance.File == file); + if (doc != null) + { + continue; + } + var lintinfos = await lintable.GetLintInfos(file.GetText(), CancellationToken.None); + foreach (var it in lintinfos) + { + this.LintInfos.Add(it); + } + } + }, String.Format(Properties.Language.PBO_LintingFiles_0file, pbo.Name)); + } + } + } +} diff --git a/Arma.Studio.ErrorWindow/Properties/AssemblyInfo.cs b/Arma.Studio.ErrorWindow/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2662809 --- /dev/null +++ b/Arma.Studio.ErrorWindow/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("Arma.Studio.ErrorWindow")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Arma.Studio.ErrorWindow")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("19ba0777-b414-4c19-9e73-47d6b1b78af8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// 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("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Arma.Studio.ErrorWindow/Properties/Language.Designer.cs b/Arma.Studio.ErrorWindow/Properties/Language.Designer.cs new file mode 100644 index 0000000..0017805 --- /dev/null +++ b/Arma.Studio.ErrorWindow/Properties/Language.Designer.cs @@ -0,0 +1,180 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Arma.Studio.ErrorWindow.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Language { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Language() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Arma.Studio.ErrorWindow.Properties.Language", typeof(Language).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Column. + /// + public static string Column { + get { + return ResourceManager.GetString("Column", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string Description { + get { + return ResourceManager.GetString("Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error. + /// + public static string Error { + get { + return ResourceManager.GetString("Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Errors. + /// + public static string Errors { + get { + return ResourceManager.GetString("Errors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error Window. + /// + public static string ErrorWindow { + get { + return ResourceManager.GetString("ErrorWindow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Arma.Studio - Error Window. + /// + public static string ErrorWindow_Name { + get { + return ResourceManager.GetString("ErrorWindow_Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File. + /// + public static string File { + get { + return ResourceManager.GetString("File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Info. + /// + public static string Info { + get { + return ResourceManager.GetString("Info", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Infos. + /// + public static string Infos { + get { + return ResourceManager.GetString("Infos", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Line. + /// + public static string Line { + get { + return ResourceManager.GetString("Line", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Linting files of '{0}'. + /// + public static string PBO_LintingFiles_0file { + get { + return ResourceManager.GetString("PBO_LintingFiles_0file", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warning. + /// + public static string Warning { + get { + return ResourceManager.GetString("Warning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warnings. + /// + public static string Warnings { + get { + return ResourceManager.GetString("Warnings", resourceCulture); + } + } + } +} diff --git a/Arma.Studio.ErrorWindow/Properties/Language.resx b/Arma.Studio.ErrorWindow/Properties/Language.resx new file mode 100644 index 0000000..b5c2435 --- /dev/null +++ b/Arma.Studio.ErrorWindow/Properties/Language.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Column + + + Description + + + Error + + + Errors + + + Error Window + + + Arma.Studio - Error Window + + + File + + + Info + + + Infos + + + Line + + + Linting files of '{0}' + + + Warning + + + Warnings + + \ No newline at end of file diff --git a/Arma.Studio.SqfEditor/SqfEditor.cs b/Arma.Studio.SqfEditor/SqfEditor.cs index 180b6d7..df867b3 100644 --- a/Arma.Studio.SqfEditor/SqfEditor.cs +++ b/Arma.Studio.SqfEditor/SqfEditor.cs @@ -157,7 +157,9 @@ void Virtualmachine_OnLog(object sender, SqfVm.LogEventArgs eventArgs) Length = 1, Line = line, Column = column, - Severity = ESeverity.Error + Severity = ESeverity.Error, + File = file, + Description = message }); } } diff --git a/Arma.Studio/PluginManager.cs b/Arma.Studio/PluginManager.cs index c662486..4cf0b1f 100644 --- a/Arma.Studio/PluginManager.cs +++ b/Arma.Studio/PluginManager.cs @@ -66,6 +66,10 @@ public Assembly LoadAssemblySafe(string path) var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach(var it in assemblies) { + if (it.IsDynamic) + { + continue; + } try { var versioninfoOther = FileVersionInfo.GetVersionInfo(it.Location); diff --git a/libraries/clrBridge.dll b/libraries/clrBridge.dll index eb8f170..a69e24e 100644 Binary files a/libraries/clrBridge.dll and b/libraries/clrBridge.dll differ