Rework the RPCGen MSBuild updater to work properly when the <!--RPCGen--> markers are already on the file.

--- src/Tools/RPCGen/MSBuildUpdater.cs
+++ src/Tools/RPCGen/MSBuildUpdater.cs
@@ -2,55 +2,74 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;

 namespace Flood.Tools.RPCGen
 {
+    /// <summary>
+    /// This class is used to update the MSBuild project so that the generated
+    /// files appear in the IDE right when they are generated. This will most
+    /// likely be triggered by the build system in the post-build events.
+    /// </summary>
     class MSBuildUpdater
     {
-        private const string bof = "<!--RPCGen BOF-->\n";
-        private const string eof = "<!--RPCGen EOF-->\n";
+        static readonly string NewLine = Environment.NewLine;
+        static readonly string bof = "<!--RPCGen BOF-->" + NewLine;
+        static readonly string eof = "<!--RPCGen EOF-->" + NewLine;

         public static void UpdateMSBuild(string msbuildPath, List<string> addedFiles)
         {
             string msbuild = File.ReadAllText(msbuildPath);

-            int begin,end;
-
-            begin = msbuild.IndexOf(bof);
-            if(begin>0){
-                end = msbuild.IndexOf(eof);
-                end += eof.Count();
-            }else{
-                begin = end = msbuild.IndexOf("<ItemGroup>");
+            // Check if there is an item group.
+            var itemIndex = msbuild.IndexOf("<ItemGroup>", StringComparison.Ordinal);
+
+            if (itemIndex < 0)
+                throw new Exception("Empty MSBuild Project File");
+
+            // Check if there are the BOF and EOF XML markers.
+            int bofIndex = msbuild.IndexOf(bof, StringComparison.Ordinal);
+            int eofIndex = msbuild.IndexOf(eof, StringComparison.Ordinal);
+
+            var itemGroup = GenerateItemGroup(msbuildPath, addedFiles);
+            string newMSBuild = null;
+
+            // If we have the markers, then replace the contents between them.
+            if (bofIndex > 0 && eofIndex > 0)
+            {
+                newMSBuild = msbuild.Substring(0, bofIndex) + itemGroup
+                    + msbuild.Substring(eofIndex + eof.Count());
+            }
+            else
+            {
+                newMSBuild = msbuild.Insert(itemIndex, itemGroup);
             }

-            if (begin < 0)
-                throw new Exception("Empty MSBuild Project File");
+            // Do not rewrite the file if the generated contents have not changed.
+            if (msbuild == newMSBuild)
+                return;

-            var adds = bof;
-            adds += "<ItemGroup>\n";
+            File.WriteAllText(msbuildPath, newMSBuild);
+        }
+
+        private static string GenerateItemGroup(string msbuildPath, List<string> addedFiles)
+        {
+            var str = bof;
+            str += "<ItemGroup>" + NewLine;
             Uri msbuildURI = new Uri(msbuildPath);
-            foreach(var file in addedFiles)
+            foreach (var file in addedFiles)
             {
                 Uri fileURI = new Uri(file);
-                var relativePath = msbuildURI.MakeRelative(fileURI);
-                relativePath = relativePath.Replace('/',Path.DirectorySeparatorChar);
+                var relativePath = msbuildURI.MakeRelativeUri(fileURI).ToString();
+                relativePath = relativePath.Replace('/', Path.DirectorySeparatorChar);

-                adds += "    <Compile Include=\""+relativePath+"\">\n";
-                adds += string.Format("      <Link>{0}</Link>\n",
-                    Path.Combine("Generated",Path.GetFileName(relativePath)));
-                adds += "    </Compile>";
+                str += "    <Compile Include=\"" + relativePath + "\">" + NewLine;
+                str += string.Format("      <Link>{0}</Link>{1}",
+                    Path.Combine("Generated", Path.GetFileName(relativePath)), NewLine);
+                str += "    </Compile>" + NewLine;
             }
-            adds += "  </ItemGroup>\n";
-            adds += eof;
-
-            if(begin == end || adds != msbuild.Substring(begin, end-begin)){
-                var newMSBuild = msbuild.Substring(0, begin) + adds + msbuild.Substring(end, msbuild.Length-end);
-                File.WriteAllText(msbuildPath,newMSBuild);
-            }
-
+            str += "  </ItemGroup>" + NewLine;
+            str += eof;
+            return str;
         }
     }
 }


Ensure colour is updated on HSV changes even if not present

--- osu.Framework/Graphics/UserInterface/HSVColourPicker.cs
+++ osu.Framework/Graphics/UserInterface/HSVColourPicker.cs
@@ -69,6 +69,10 @@
         /// </summary>
         protected abstract SaturationValueSelector CreateSaturationValueSelector();

+        public override bool IsPresent => base.IsPresent
+                                          || saturationValueSelector.Scheduler.HasPendingTasks
+                                          || hueSelector.Scheduler.HasPendingTasks;
+
         protected override void LoadComplete()
         {
             base.LoadComplete();


Show 2 decimals for background filesize

Show 2 decimals for background filesize

--- osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs
+++ osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs
@@ -88,7 +88,7 @@
         public class IssueTemplateTooUncompressed : IssueTemplate
         {
             public IssueTemplateTooUncompressed(ICheck check)
-                : base(check, IssueType.Problem, "The background filesize ({0:0.#} MB) exceeds {1} MB.")
+                : base(check, IssueType.Problem, "The background filesize ({0:0.##} MB) exceeds {1} MB.")
             {
             }


Fix marshalling in C# bindings

Fix marshalling in C# bindings

During context creation, the context attributes' name and value were not marshalled correctly form native to managed memory, creating a crash when the GC collected gen2 heap memory.
Signed-off-by: Lehuraux, Max <ee438bf4c24716216b3a1bb6d818de03e3b46690@analog.com>
Co-Authored-By: cristi-iacob <c361ce5c29798c0927ba05e42d9bc24694c1e402@users.noreply.github.com>

--- bindings/csharp/Context.cs
+++ bindings/csharp/Context.cs
@@ -99,7 +99,7 @@
         private static extern uint iio_context_get_attrs_count(IntPtr ctx);

         [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)]
-        private static extern int iio_context_get_attr(IntPtr ctx, uint index, IntPtr name_ptr, IntPtr value_ptr);
+        private static extern int iio_context_get_attr(IntPtr ctx, uint index, out IntPtr name_ptr, out IntPtr value_ptr);

         [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)]
         private static extern IntPtr iio_context_find_device(IntPtr ctx, [In] string name);
@@ -199,19 +199,16 @@
             backend_version = new Version(major, minor, builder.ToString());

             attrs = new Dictionary<string, string>();
-
-            for (uint i = 0; i < iio_context_get_attrs_count(ctx); i++)
-            {
-                string attr_name = "";
-                GCHandle name_handle = GCHandle.Alloc(attr_name, GCHandleType.Pinned);
-                IntPtr name_ptr = GCHandle.ToIntPtr(name_handle);
-                string attr_value = "";
-                GCHandle value_handle = GCHandle.Alloc(attr_value, GCHandleType.Pinned);
-                IntPtr value_ptr = GCHandle.ToIntPtr(value_handle);
-
-                iio_context_get_attr(ctx, i, name_ptr, value_ptr);
-                attr_name = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(name_ptr));
-                attr_value = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(value_ptr));
+            uint nbAttrs = iio_context_get_attrs_count(ctx);
+
+            for (uint i = 0; i < nbAttrs; i++)
+            {
+                IntPtr name_ptr;
+                IntPtr value_ptr;
+
+                iio_context_get_attr(ctx, i, out name_ptr, out value_ptr);
+                string attr_name = Marshal.PtrToStringAnsi(name_ptr);
+                string attr_value = Marshal.PtrToStringAnsi(value_ptr);

                 attrs[attr_name] = attr_value;
             }


Added method for handling interrupted backups without remote backend verification.

--- Duplicati/Library/Main/Operation/FilelistProcessor.cs
+++ Duplicati/Library/Main/Operation/FilelistProcessor.cs
@@ -28,9 +28,53 @@
         /// Helper method that verifies uploaded volumes and updates their state in the database.
         /// Throws an error if there are issues with the remote storage
         /// </summary>
+        /// <param name="options">The options used</param>
+        /// <param name="database">The database to compare with</param>
+        /// <param name="log">The log instance to use</param>
+        public static void VerifyLocalList(BackendManager backend, Options options, LocalDatabase database, IBackendWriter log)
+        {
+            var locallist = database.GetRemoteVolumes();
+            foreach(var i in locallist)
+            {
+                switch (i.State)
+                {
+                    case RemoteVolumeState.Uploaded:
+                    case RemoteVolumeState.Verified:
+                    case RemoteVolumeState.Deleted:
+                        break;
+
+                    case RemoteVolumeState.Temporary:
+                    case RemoteVolumeState.Deleting:
+                    case RemoteVolumeState.Uploading:
+                        log.AddMessage(string.Format("removing remote file listed as {0}: {1}", i.State, i.Name));
+                        try
+                        {
+                            backend.Delete(i.Name, i.Size, true);
+                        }
+                        catch (Exception ex)
+                        {
+                            log.AddWarning(string.Format("Failed to erase file {0}, treating as deleted: {1}", i.Name, ex.Message), ex);
+                        }
+
+                        break;
+
+                    default:
+                        log.AddWarning(string.Format("unknown state for remote file listed as {0}: {1}", i.State, i.Name), null);
+                        break;
+                }
+
+                backend.FlushDbMessages();
+            }
+        }
+
+        /// <summary>
+        /// Helper method that verifies uploaded volumes and updates their state in the database.
+        /// Throws an error if there are issues with the remote storage
+        /// </summary>
         /// <param name="backend">The backend instance to use</param>
         /// <param name="options">The options used</param>
         /// <param name="database">The database to compare with</param>
+        /// <param name="log">The log instance to use</param>
         public static void VerifyRemoteList(BackendManager backend, Options options, LocalDatabase database, IBackendWriter log)
 		{
 			var tp = RemoteListAnalysis(backend, options, database, log);


Fixed a forgotten Dispose() call

Fixed a forgotten Dispose() call

git-svn-id: 6b7e1e5d0861e268462ba7828ef63c1bcab52a9b@77 d3cde5d6-82b8-4669-8b62-43054d6781d8

--- PanView/SpectrumAnalyzer.cs
+++ PanView/SpectrumAnalyzer.cs
@@ -388,6 +388,7 @@
             {
                 _buffer.Dispose();
                 _graphics.Dispose();
+                _bkgBuffer.Dispose();
                 _buffer = new Bitmap(Width, Height);
                 _graphics = Graphics.FromImage(_buffer);
                 _bkgBuffer = new Bitmap(Width, Height);


Added FontSize field

Added FontSize field

--- ParseLNK/Interop/Structs.cs
+++ ParseLNK/Interop/Structs.cs
@@ -356,6 +356,7 @@
             public ushort WindowOriginY;
             public int Unused1;
             public int Unused2;
+            public uint FontSize;
             public Enums.FontFamily FontFamily;
             public uint FontWeight;
             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]


Documented ToolTip.

Documented ToolTip.

--- Perspex.Controls/ToolTip.cs
+++ Perspex.Controls/ToolTip.cs
@@ -6,41 +6,81 @@

 namespace Perspex.Controls
 {
+    using Perspex.Input;
+    using Perspex.Threading;
     using System;
-    using System.Reactive;
     using System.Reactive.Linq;
     using System.Reactive.Subjects;
-    using Perspex.Input;
-    using Perspex.Threading;
-    using Perspex.VisualTree;

+    /// <summary>
+    /// A tooltip control.
+    /// </summary>
+    /// <remarks>
+    /// You will probably not want to create a <see cref="ToolTip"/> control directly: if added to
+    /// the tree it will act as a simple <see cref="ContentControl"/> styled to look like a tooltip.
+    /// To add a tooltip to a control, use the <see cref="TipProperty"/> attached property,
+    /// assigning the content that you want displayed.
+    /// </remarks>
     public class ToolTip : ContentControl
     {
+        /// <summary>
+        /// Defines the ToolTip.Tip attached property.
+        /// </summary>
         public static readonly PerspexProperty<object> TipProperty =
             PerspexProperty.RegisterAttached<ToolTip, Control, object>("Tip");

+        /// <summary>
+        /// The popup window used to display the active tooltip.
+        /// </summary>
         private static PopupRoot popup;

+        /// <summary>
+        /// The control that the currently visible tooltip is attached to.
+        /// </summary>
         private static Control current;

+        /// <summary>
+        /// Observable fired when a tooltip should be displayed for a control. The output from this
+        /// observable is throttled and calls <see cref="ShowToolTip(Control)"/> when the time
+        /// period expires.
+        /// </summary>
         private static Subject<Control> show = new Subject<Control>();

+        /// <summary>
+        /// Statically constructs the tooltip class.
+        /// </summary>
         static ToolTip()
         {
             TipProperty.Changed.Subscribe(TipChanged);
             show.Throttle(TimeSpan.FromSeconds(0.5), PerspexScheduler.Instance).Subscribe(ShowToolTip);
         }

+        /// <summary>
+        /// Gets the value of the ToolTip.Tip attached property.
+        /// </summary>
+        /// <param name="element">The control to get the property from.</param>
+        /// <returns>
+        /// The content to be displayed in the control's tooltip.
+        /// </returns>
         public static object GetTip(Control element)
         {
             return element.GetValue(TipProperty);
         }

+        /// <summary>
+        /// Sets the value of the ToolTip.Tip attached property.
+        /// </summary>
+        /// <param name="element">The control to get the property from.</param>
+        /// <param name="value">The content to be displayed in the control's tooltip.</param>
         public static void SetTip(Control element, object value)
         {
             element.SetValue(TipProperty, value);
         }

+        /// <summary>
+        /// called when the <see cref="TipProperty"/> property changes on a control.
+        /// </summary>
+        /// <param name="e"></param>
         private static void TipChanged(PerspexPropertyChangedEventArgs e)
         {
             var control = (Control)e.Sender;
@@ -58,6 +98,10 @@
             }
         }

+        /// <summary>
+        /// Shows a tooltip for the specified control.
+        /// </summary>
+        /// <param name="control">The control.</param>
         private static void ShowToolTip(Control control)
         {
             if (control != null)
@@ -82,12 +126,22 @@
             }
         }

+        /// <summary>
+        /// Called when the pointer enters a control with an attached tooltip.
+        /// </summary>
+        /// <param name="sender">The event sender.</param>
+        /// <param name="e">The event args.</param>
         private static void ControlPointerEnter(object sender, PointerEventArgs e)
         {
             current = (Control)sender;
             show.OnNext(current);
         }

+        /// <summary>
+        /// Called when the pointer leaves a control with an attached tooltip.
+        /// </summary>
+        /// <param name="sender">The event sender.</param>
+        /// <param name="e">The event args.</param>
         private static void ControlPointerLeave(object sender, PointerEventArgs e)
         {
             var control = (Control)sender;


Verify that issue #50 is not an issue.

Verify that issue #50 is not an issue.

--- source/tests/MyCouch.IntegrationTests.Net45/CoreTests/EntitiesTests.cs
+++ source/tests/MyCouch.IntegrationTests.Net45/CoreTests/EntitiesTests.cs
@@ -77,6 +77,16 @@
         }

         [MyFact(TestScenarios.EntitiesContext)]
+        public void When_POST_of_a_new_inherited_entity_with_unpopulated_id_Then_the_document_is_created()
+        {
+            var doc = new Issue50Session();
+
+            var response = SUT.PostAsync(doc).Result;
+
+            response.Should().BeSuccessfulPost(idAccessor: e => e.Id, revAccessor: e => e.Rev);
+        }
+
+        [MyFact(TestScenarios.EntitiesContext)]
         public void When_put_of_a_new_entity_Then_the_document_is_created()
         {
             var artist = ClientTestData.Artists.CreateArtist();
@@ -218,5 +228,17 @@
         {
             public string Value { get; set; }
         }
+
+        public abstract class Issue50
+        {
+            public string Id { get; set; }
+            public string Rev { get; set; }
+        }
+
+        public class Issue50Session : Issue50
+        {
+            public string MasterID { get; set; }
+            public string ClientAppID { get; set; }
+        }
     }
 }


Fix anonymous object tests

Fix anonymous object tests

--- ExpressionToCodeTest/AnonymousObjectFormattingTest.cs
+++ ExpressionToCodeTest/AnonymousObjectFormattingTest.cs
@@ -13,25 +13,25 @@
         [Fact]
         public void AnonymousObjectsRenderAsCode()
         {
-            Assert.Equal("\nnew {\n  A = 1,\n  Foo = \"Bar\",\n}", ObjectToCode.ComplexObjectToPseudoCode(new { A = 1, Foo = "Bar", }));
+            Assert.Equal("new {\n  A = 1,\n  Foo = \"Bar\",\n}", ObjectToCode.ComplexObjectToPseudoCode(new { A = 1, Foo = "Bar", }));
         }

         [Fact]
         public void AnonymousObjectsInArray()
         {
-            Assert.Equal("new[] {\nnew {\n  Val = 3,\n}, \nnew {\n  Val = 42,\n}}", ObjectToCode.ComplexObjectToPseudoCode(new[] { new { Val = 3, }, new { Val = 42 } }));
+            Assert.Equal("new[] {\n  new {\n          Val = 3,\n        },\n  new {\n          Val = 42,\n        },\n}", ObjectToCode.ComplexObjectToPseudoCode(new[] { new { Val = 3, }, new { Val = 42 } }));
         }

         [Fact]
         public void EnumerableInAnonymousObject()
         {
-            Assert.Equal("\nnew {\n  Nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...},\n}", ObjectToCode.ComplexObjectToPseudoCode(new { Nums = Enumerable.Range(1, 13) }));
+            Assert.Equal("new {\n  Nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...},\n}", ObjectToCode.ComplexObjectToPseudoCode(new { Nums = Enumerable.Range(1, 13) }));
         }

         [Fact]
         public void EnumInAnonymousObject()
         {
-            Assert.Equal("\nnew {\n  Enum = ConsoleKey.A,\n}", ObjectToCode.ComplexObjectToPseudoCode(new { Enum = ConsoleKey.A }));
+            Assert.Equal("new {\n  Enum = ConsoleKey.A,\n}", ObjectToCode.ComplexObjectToPseudoCode(new { Enum = ConsoleKey.A }));
         }
     }
-}
+}


Fixed that the CollectionChangeTracker would not add items to its lists.

--- Expressions/Expressions/Execution/ExecutionContext.cs
+++ Expressions/Expressions/Execution/ExecutionContext.cs
@@ -186,7 +186,7 @@
                     return;
                 foreach (var item in addedItems)
                 {
-                    if ((!_removedItems?.Remove(item) ?? false) && (!_replaceRemovedItems?.Remove(item) ?? false))
+                    if ((!_removedItems?.Remove(item) ?? true) && (!_replaceRemovedItems?.Remove(item) ?? true))
                     {
                         if (_addedItems == null)
                             _addedItems = new List<object>();
@@ -201,7 +201,7 @@
                     return;
                 foreach (var item in removedItems)
                 {
-                    if ((!_addedItems?.Remove(item) ?? false) && (!_replaceAddedItems?.Remove(item) ?? false))
+                    if ((!_addedItems?.Remove(item) ?? true) && (!_replaceAddedItems?.Remove(item) ?? true))
                     {
                         if (_removedItems == null)
                             _removedItems = new List<object>();
@@ -226,7 +226,7 @@
                     return;
                 foreach (var item in replacingItems)
                 {
-                    if ((!_removedItems?.Remove(item) ?? false) && (!_replaceRemovedItems?.Remove(item) ?? false))
+                    if ((!_removedItems?.Remove(item) ?? true) && (!_replaceRemovedItems?.Remove(item) ?? true))
                     {
                         if (_replaceAddedItems == null)
                             _replaceAddedItems = new List<object>();
@@ -236,7 +236,7 @@

                 foreach (var item in replacedItems)
                 {
-                    if ((!_addedItems?.Remove(item) ?? false) && (!_replaceAddedItems?.Remove(item) ?? false))
+                    if ((!_addedItems?.Remove(item) ?? true) && (!_replaceAddedItems?.Remove(item) ?? true))
                     {
                         if (_replaceRemovedItems == null)
                             _replaceRemovedItems = new List<object>();


Fixes FileAcessor not correctly working in Linux

--- Figlotech.Core/FileAccessAbstractions/FileAccessor.cs
+++ Figlotech.Core/FileAccessAbstractions/FileAccessor.cs
@@ -24,7 +24,7 @@
         public int MaxStreamBufferLength { get; set; } = 64 * 1024 * 1024;

         public String FixRel(ref string relative) {
-            return relative = relative?.Replace('\\', '/')
+            return relative = relative?.Replace(Path.DirectorySeparatorChar, '/')
                 .Replace("//", "/")
                 .Replace('/', S);
         }
@@ -216,15 +216,18 @@
             }
         }
         public IEnumerable<string> GetFilesIn(String relative) {
-            relative = relative.Replace('/', '\\');
+            relative = relative.Replace('/', Path.DirectorySeparatorChar);
             var WorkingDirectory = AssemblePath(RootDirectory, relative);
             if (!Directory.Exists(WorkingDirectory)) {
                 return new string[0];
+            }
+            if(!WorkingDirectory.EndsWith(Path.DirectorySeparatorChar.ToString())) {
+                WorkingDirectory += Path.DirectorySeparatorChar.ToString();
             }
             return Directory.GetFiles(WorkingDirectory).Select(
                     ((a) => {
                         var s = a.Substring(RootDirectory.Length);
-                        if (s.StartsWith("\\")) {
+                        if (s.StartsWith(System.IO.Path.DirectorySeparatorChar.ToString())) {
                             s = s.Substring(1);
                         }
                         return this.UnFixRel(ref s);
@@ -263,7 +266,7 @@
             }
         }
         public IEnumerable<string> GetDirectoriesIn(String relative) {
-            relative = relative.Replace('/', '\\');
+            relative = relative.Replace('/', Path.DirectorySeparatorChar);
             var WorkingDirectory = AssemblePath(RootDirectory, relative);
             if (!Directory.Exists(WorkingDirectory)) {
                 return new string[0];