// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using Tango.Scripting.Editors.Utils; namespace Tango.Scripting.Editors.Document { /// /// Contains predefined offset change mapping types. /// public enum OffsetChangeMappingType { /// /// Normal replace. /// Anchors in front of the replaced region will stay in front, anchors after the replaced region will stay after. /// Anchors in the middle of the removed region will be deleted. If they survive deletion, /// they move depending on their AnchorMovementType. /// /// /// This is the default implementation of DocumentChangeEventArgs when OffsetChangeMap is null, /// so using this option usually works without creating an OffsetChangeMap instance. /// This is equivalent to an OffsetChangeMap with a single entry describing the replace operation. /// Normal, /// /// First the old text is removed, then the new text is inserted. /// Anchors immediately in front (or after) the replaced region may move to the other side of the insertion, /// depending on the AnchorMovementType. /// /// /// This is implemented as an OffsetChangeMap with two entries: the removal, and the insertion. /// RemoveAndInsert, /// /// The text is replaced character-by-character. /// Anchors keep their position inside the replaced text. /// Anchors after the replaced region will move accordingly if the replacement text has a different length than the replaced text. /// If the new text is shorter than the old text, anchors inside the old text that would end up behind the replacement text /// will be moved so that they point to the end of the replacement text. /// /// /// On the OffsetChangeMap level, growing text is implemented by replacing the last character in the replaced text /// with itself and the additional text segment. A simple insertion of the additional text would have the undesired /// effect of moving anchors immediately after the replaced text into the replacement text if they used /// AnchorMovementStyle.BeforeInsertion. /// Shrinking text is implemented by removing the text segment that's too long; but in a special mode that /// causes anchors to always survive irrespective of their setting. /// If the text keeps its old size, this is implemented as OffsetChangeMap.Empty. /// CharacterReplace, /// /// Like 'Normal', but anchors with = Default will stay in front of the /// insertion instead of being moved behind it. /// KeepAnchorBeforeInsertion } /// /// Describes a series of offset changes. /// [Serializable] [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification="It's a mapping old offsets -> new offsets")] public sealed class OffsetChangeMap : Collection { /// /// Immutable OffsetChangeMap that is empty. /// [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification="The Empty instance is immutable")] public static readonly OffsetChangeMap Empty = new OffsetChangeMap(Empty.Array, true); /// /// Creates a new OffsetChangeMap with a single element. /// /// The entry. /// Returns a frozen OffsetChangeMap with a single entry. public static OffsetChangeMap FromSingleElement(OffsetChangeMapEntry entry) { return new OffsetChangeMap(new OffsetChangeMapEntry[] { entry }, true); } bool isFrozen; /// /// Creates a new OffsetChangeMap instance. /// public OffsetChangeMap() { } internal OffsetChangeMap(int capacity) : base(new List(capacity)) { } private OffsetChangeMap(IList entries, bool isFrozen) : base(entries) { this.isFrozen = isFrozen; } /// /// Gets the new offset where the specified offset moves after this document change. /// public int GetNewOffset(int offset, AnchorMovementType movementType) { IList items = this.Items; int count = items.Count; for (int i = 0; i < count; i++) { offset = items[i].GetNewOffset(offset, movementType); } return offset; } /// /// Gets whether this OffsetChangeMap is a valid explanation for the specified document change. /// public bool IsValidForDocumentChange(int offset, int removalLength, int insertionLength) { int endOffset = offset + removalLength; foreach (OffsetChangeMapEntry entry in this) { // check that ChangeMapEntry is in valid range for this document change if (entry.Offset < offset || entry.Offset + entry.RemovalLength > endOffset) return false; endOffset += entry.InsertionLength - entry.RemovalLength; } // check that the total delta matches return endOffset == offset + insertionLength; } /// /// Calculates the inverted OffsetChangeMap (used for the undo operation). /// public OffsetChangeMap Invert() { if (this == Empty) return this; OffsetChangeMap newMap = new OffsetChangeMap(this.Count); for (int i = this.Count - 1; i >= 0; i--) { OffsetChangeMapEntry entry = this[i]; // swap InsertionLength and RemovalLength newMap.Add(new OffsetChangeMapEntry(entry.Offset, entry.InsertionLength, entry.RemovalLength)); } return newMap; } /// protected override void ClearItems() { CheckFrozen(); base.ClearItems(); } /// protected override void InsertItem(int index, OffsetChangeMapEntry item) { CheckFrozen(); base.InsertItem(index, item); } /// protected override void RemoveItem(int index) { CheckFrozen(); base.RemoveItem(index); } /// protected override void SetItem(int index, OffsetChangeMapEntry item) { CheckFrozen(); base.SetItem(index, item); } void CheckFrozen() { if (isFrozen) throw new InvalidOperationException("This instance is frozen and cannot be modified."); } /// /// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe. /// public bool IsFrozen { get { return isFrozen; } } /// /// Freezes this instance. /// public void Freeze() { isFrozen = true; } } /// /// An entry in the OffsetChangeMap. /// This represents the offset of a document change (either insertion or removal, not both at once). /// [Serializable] public struct OffsetChangeMapEntry : IEquatable { readonly int offset; // MSB: DefaultAnchorMovementIsBeforeInsertion readonly uint insertionLengthWithMovementFlag; // MSB: RemovalNeverCausesAnchorDeletion; other 31 bits: RemovalLength readonly uint removalLengthWithDeletionFlag; /// /// The offset at which the change occurs. /// public int Offset { get { return offset; } } /// /// The number of characters inserted. /// Returns 0 if this entry represents a removal. /// public int InsertionLength { get { return (int)(insertionLengthWithMovementFlag & 0x7fffffff); } } /// /// The number of characters removed. /// Returns 0 if this entry represents an insertion. /// public int RemovalLength { get { return (int)(removalLengthWithDeletionFlag & 0x7fffffff); } } /// /// Gets whether the removal should not cause any anchor deletions. /// public bool RemovalNeverCausesAnchorDeletion { get { return (removalLengthWithDeletionFlag & 0x80000000) != 0; } } /// /// Gets whether default anchor movement causes the anchor to stay in front of the caret. /// public bool DefaultAnchorMovementIsBeforeInsertion { get { return (insertionLengthWithMovementFlag & 0x80000000) != 0; } } /// /// Gets the new offset where the specified offset moves after this document change. /// public int GetNewOffset(int oldOffset, AnchorMovementType movementType) { int insertionLength = this.InsertionLength; int removalLength = this.RemovalLength; if (!(removalLength == 0 && oldOffset == offset)) { // we're getting trouble (both if statements in here would apply) // if there's no removal and we insert at the offset // -> we'd need to disambiguate by movementType, which is handled after the if // offset is before start of change: no movement if (oldOffset <= offset) return oldOffset; // offset is after end of change: movement by normal delta if (oldOffset >= offset + removalLength) return oldOffset + insertionLength - removalLength; } // we reach this point if // a) the oldOffset is inside the deleted segment // b) there was no removal and we insert at the caret position if (movementType == AnchorMovementType.AfterInsertion) return offset + insertionLength; else if (movementType == AnchorMovementType.BeforeInsertion) return offset; else return this.DefaultAnchorMovementIsBeforeInsertion ? offset : offset + insertionLength; } /// /// Creates a new OffsetChangeMapEntry instance. /// public OffsetChangeMapEntry(int offset, int removalLength, int insertionLength) { ThrowUtil.CheckNotNegative(offset, "offset"); ThrowUtil.CheckNotNegative(removalLength, "removalLength"); ThrowUtil.CheckNotNegative(insertionLength, "insertionLength"); this.offset = offset; this.removalLengthWithDeletionFlag = (uint)removalLength; this.insertionLengthWithMovementFlag = (uint)insertionLength; } /// /// Creates a new OffsetChangeMapEntry instance. /// public OffsetChangeMapEntry(int offset, int removalLength, int insertionLength, bool removalNeverCausesAnchorDeletion, bool defaultAnchorMovementIsBeforeInsertion) : this(offset, removalLength, insertionLength) { if (removalNeverCausesAnchorDeletion) this.removalLengthWithDeletionFlag |= 0x80000000; if (defaultAnchorMovementIsBeforeInsertion) this.insertionLengthWithMovementFlag |= 0x80000000; } /// public override int GetHashCode() { unchecked { return offset + 3559 * (int)insertionLengthWithMovementFlag + 3571 * (int)removalLengthWithDeletionFlag; } } /// public override bool Equals(object obj) { return obj is OffsetChangeMapEntry && this.Equals((OffsetChangeMapEntry)obj); } /// public bool Equals(OffsetChangeMapEntry other) { return offset == other.offset && insertionLengthWithMovementFlag == other.insertionLengthWithMovementFlag && removalLengthWithDeletionFlag == other.removalLengthWithDeletionFlag; } /// /// Tests the two entries for equality. /// public static bool operator ==(OffsetChangeMapEntry left, OffsetChangeMapEntry right) { return left.Equals(right); } /// /// Tests the two entries for inequality. /// public static bool operator !=(OffsetChangeMapEntry left, OffsetChangeMapEntry right) { return !left.Equals(right); } } }
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{D0CE8122-077D-42A2-9490-028AE4769B52}</ProjectGuid>
    <OutputType>library</OutputType>
    <RootNamespace>Tango.MachineStudio.MachineDesigner</RootNamespace>
    <AssemblyName>Tango.MachineStudio.MachineDesigner</AssemblyName>
    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\..\..\Build\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\..\..\Build\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="FontAwesome.WPF, Version=4.7.0.37774, Culture=neutral, PublicKeyToken=0758b07a11a4f466, processorArchitecture=MSIL">
      <HintPath>..\..\..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll</HintPath>
    </Reference>
    <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL">
      <HintPath>..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath>
    </Reference>
    <Reference Include="MaterialDesignColors, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll</HintPath>
    </Reference>
    <Reference Include="MaterialDesignThemes.Wpf, Version=2.3.1.953, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
    </Reference>
    <Reference Include="SimpleValidator, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\..\..\packages\Expression.Blend.Sdk.1.0.2\lib\net45\System.Windows.Interactivity.dll</HintPath>
    </Reference>
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs">
      <Link>GlobalVersionInfo.cs</Link>
    </Compile>
    <Compile Include="AutoComplete\MachinesProvider.cs" />
    <Compile Include="AutoComplete\MachineVersionsProvider.cs" />
    <Compile Include="ViewModelLocator.cs" />
    <Compile Include="ViewModels\MachineVersionDialogVM.cs" />
    <Compile Include="ViewModels\MainViewVM.cs" />
    <Compile Include="Views\MachineVersionDialog.xaml.cs">
      <DependentUpon>MachineVersionDialog.xaml</DependentUpon>
    </Compile>
    <Compile Include="Views\MachineView.xaml.cs">
      <DependentUpon>MachineView.xaml</DependentUpon>
    </Compile>
    <Compile Include="Views\MainView.xaml.cs">
      <DependentUpon>MainView.xaml</DependentUpon>
    </Compile>
    <Compile Include="MachineDesignerModule.cs" />
    <Page Include="Views\MachineVersionDialog.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="Views\MachineView.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="Views\MainView.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <None Include="app.config" />
    <None Include="packages.config" />
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj">
      <Project>{bb2abb74-ba58-4812-83aa-ec8171f42df4}</Project>
      <Name>Tango.AutoComplete</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.BL\Tango.BL.csproj">
      <Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
      <Name>Tango.BL</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.ColorPicker\Tango.ColorPicker.csproj">
      <Project>{a2f5af44-29ff-45d6-9d25-ecda5cce88b5}</Project>
      <Name>Tango.ColorPicker</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj">
      <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
      <Name>Tango.Core</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.DAL.Remote\Tango.DAL.Remote.csproj">
      <Project>{38197109-8610-4d3f-92b9-16d48df94d7c}</Project>
      <Name>Tango.DAL.Remote</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.DragAndDrop\Tango.DragAndDrop.csproj">
      <Project>{b112d89a-a106-41ae-a0c1-4abc84c477f5}</Project>
      <Name>Tango.DragAndDrop</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.Integration\Tango.Integration.csproj">
      <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project>
      <Name>Tango.Integration</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj">
      <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
      <Name>Tango.Logging</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.PMR\Tango.PMR.csproj">
      <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
      <Name>Tango.PMR</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.Settings\Tango.Settings.csproj">
      <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
      <Name>Tango.Settings</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.SharedUI\Tango.SharedUI.csproj">
      <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
      <Name>Tango.SharedUI</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.Synchronization\Tango.Synchronization.csproj">
      <Project>{7ada4e86-cad7-4968-a210-3a8a9e5153ab}</Project>
      <Name>Tango.Synchronization</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\..\Tango.Transport\Tango.Transport.csproj">
      <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
      <Name>Tango.Transport</Name>
    </ProjectReference>
    <ProjectReference Include="..\..\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj">
      <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project>
      <Name>Tango.MachineStudio.Common</Name>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\machine-full-fx.png" />
    <Resource Include="Images\machine-sketch.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\mid-tank.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\dispenser.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\ti-tm4c129x.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\cartridge.png" />
    <Resource Include="Images\injection.png" />
    <Resource Include="Images\liquid.png" />
    <Resource Include="Images\tank.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\embedded.png" />
    <Resource Include="Images\tablet.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\app.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\embedded-software.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\android.png" />
    <Resource Include="Images\hardware.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\application-firmware.png" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\machine-designer-module.jpg" />
  </ItemGroup>
  <ItemGroup>
    <Resource Include="Images\formula.png" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
    </VisualStudio>
  </ProjectExtensions>
</Project>