Skip to content

Commit

Permalink
update x coordinate
Browse files Browse the repository at this point in the history
  • Loading branch information
ashahabov committed Nov 19, 2022
1 parent edbe738 commit ffd7e00
Show file tree
Hide file tree
Showing 17 changed files with 132 additions and 42 deletions.
Binary file modified ShapeCrawler.Tests/Resource/006_1 slides.pptx
Binary file not shown.
39 changes: 29 additions & 10 deletions ShapeCrawler.Tests/ShapeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using ShapeCrawler.Media;
using ShapeCrawler.Shapes;
using ShapeCrawler.Tests.Helpers;
using ShapeCrawler.Tests.Helpers.Attributes;
using ShapeCrawler.Tests.Properties;
using Xunit;

Expand Down Expand Up @@ -246,26 +247,44 @@ public void Y_Setter_updates_y_coordinate()
autoShape.Y.Should().Be(100);
}

[Theory]
[SlideShapeData("006_1 slides.pptx", 1, "Shape 1")]
[SlideShapeData("001.pptx", 1, "Head 1")]
public void X_Setter_sets_x_coordinate(IShape shape)
{
// Arrange
var pres = shape.SlideObject.Presentation;
var slideIndex = shape.SlideObject.Number - 1;
var shapeName = shape.Name;
var stream = new MemoryStream();

// Act
shape.X = 400;

// Assert
pres.SaveAs(stream);
pres = SCPresentation.Open(stream);
shape = pres.Slides[slideIndex].Shapes.GetByName<IShape>(shapeName);
shape.X.Should().Be(400);
}

[Fact]
public void XAndWidth_SetterSetXAndWidthOfTheShape()
public void Width_Setter_sets_width()
{
// Arrange
IPresentation presentation = SCPresentation.Open(Resources._006_1_slides);
IShape shape = presentation.Slides.First().Shapes.First(sp => sp.Id == 3);
Stream stream = new MemoryStream();
const int xPixels = 400;
var pres = SCPresentation.Open(Resources._006_1_slides);
var shape = pres.Slides.First().Shapes.First(sp => sp.Id == 3);
var stream = new MemoryStream();
const int widthPixels = 600;

// Act
shape.X = xPixels;
shape.Width = widthPixels;

// Assert
presentation.SaveAs(stream);
presentation = SCPresentation.Open(stream);
shape = presentation.Slides.First().Shapes.First(sp => sp.Id == 3);
pres.SaveAs(stream);
pres = SCPresentation.Open(stream);
shape = pres.Slides.First().Shapes.First(sp => sp.Id == 3);

shape.X.Should().Be(xPixels);
shape.Width.Should().Be(widthPixels);
}

Expand Down
19 changes: 18 additions & 1 deletion ShapeCrawler.Tests/TextFrameTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,24 @@ public void Autofit_Setter_sets_text_autofit_type()
errors.Should().BeEmpty();
}

[Theory]
[SlideShapeData("autoshape-case003.pptx", 1, "AutoShape 7")]
[SlideShapeData("001.pptx", 1, "Head 1")]
public void Autofit_Setter_sets_autofit_type(IShape shape)
{
// Arrange
var autoShape = (IAutoShape)shape;
var textFrame = autoShape.TextFrame!;

// Act
textFrame.AutofitType = SCAutofitType.Resize;

// Assert
textFrame.AutofitType.Should().Be(SCAutofitType.Resize);
var errors = PptxValidator.Validate(shape.SlideObject.Presentation);
errors.Should().BeEmpty();
}

[Fact]
public void Autofit_Setter_updates_height()
{
Expand All @@ -323,7 +341,6 @@ public void Autofit_Setter_updates_height()
textFrame.AutofitType = SCAutofitType.Resize;

// Assert
textFrame.AutofitType.Should().Be(SCAutofitType.Resize);
shape.Height.Should().Be(35);
var errors = PptxValidator.Validate(pres);
errors.Should().BeEmpty();
Expand Down
3 changes: 2 additions & 1 deletion ShapeCrawler.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,5 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=hypelink/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Numered/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Patt/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tahoma/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tahoma/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Xfrm/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
1 change: 1 addition & 0 deletions ShapeCrawler/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dotnet_diagnostic.CS8618.severity = error

# Stylecop
dotnet_diagnostic.SA1028.severity = none
dotnet_diagnostic.SA1117.severity = error
dotnet_diagnostic.SA1124.severity = none
dotnet_diagnostic.SA1200.severity = none
dotnet_diagnostic.SA1611.severity = none
Expand Down
4 changes: 3 additions & 1 deletion ShapeCrawler/AutoShapes/SlideAutoShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ internal class SlideAutoShape : SlideShape, IAutoShape, ITextFrameContainer
private readonly ResettableLazy<Dictionary<int, FontData>> lvlToFontData;
private readonly P.Shape pShape;

internal SlideAutoShape(P.Shape pShape, OneOf<SCSlide, SCSlideLayout, SCSlideMaster> oneOfSlide,
internal SlideAutoShape(
P.Shape pShape,
OneOf<SCSlide, SCSlideLayout, SCSlideMaster> oneOfSlide,
SCGroupShape groupShape)
: base(pShape, oneOfSlide, groupShape)
{
Expand Down
8 changes: 6 additions & 2 deletions ShapeCrawler/Collections/SCSlideCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ private static void AdjustLayoutIds(PresentationDocument sdkPresDocDest, uint ma
}
}

private static uint AddNewSlideMasterId(Presentation sdkPresDest, PresentationDocument sdkPresDocDest,
private static uint AddNewSlideMasterId(
Presentation sdkPresDest,
PresentationDocument sdkPresDocDest,
SlideMasterPart addedSlideMasterPart)
{
var masterId = CreateId(sdkPresDest.SlideMasterIdList!);
Expand All @@ -153,7 +155,9 @@ private static uint AddNewSlideMasterId(Presentation sdkPresDest, PresentationDo
return masterId;
}

private static void AddNewSlideId(Presentation sdkPresDest, PresentationDocument sdkPresDocDest,
private static void AddNewSlideId(
Presentation sdkPresDest,
PresentationDocument sdkPresDocDest,
SlidePart addedSdkSlidePart)
{
SlideId slideId = new ()
Expand Down
11 changes: 7 additions & 4 deletions ShapeCrawler/Collections/SlideMasterCollection.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using ShapeCrawler.SlideMasters;

namespace ShapeCrawler.Collections;

[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
internal class SlideMasterCollection : ISlideMasterCollection
{
private readonly List<ISlideMaster> slideMasters;
Expand All @@ -28,11 +30,12 @@ public IEnumerator<ISlideMaster> GetEnumerator()

internal static SlideMasterCollection Create(SCPresentation presentation)
{
IEnumerable<SlideMasterPart> slideMasterParts = presentation.SDKPresentationInternal.PresentationPart!.SlideMasterParts;
var slideMasters = new List<ISlideMaster>(slideMasterParts.Count());
foreach (SlideMasterPart slideMasterPart in slideMasterParts)
var masterParts = presentation.SDKPresentationInternal.PresentationPart!.SlideMasterParts;
var slideMasters = new List<ISlideMaster>(masterParts.Count());
var number = 1;
foreach (var slideMasterPart in masterParts)
{
slideMasters.Add(new SCSlideMaster(presentation, slideMasterPart.SlideMaster));
slideMasters.Add(new SCSlideMaster(presentation, slideMasterPart.SlideMaster, number++));
}

return new SlideMasterCollection(presentation, slideMasters);
Expand Down
6 changes: 4 additions & 2 deletions ShapeCrawler/Exceptions/PresentationIsLargeException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ private PresentationIsLargeException(string message)
internal static PresentationIsLargeException FromMax(int maxSize)
{
#if NET6_0
var message = ExceptionMessages.PresentationIsLarge.Replace("{0}",
maxSize.ToString(CultureInfo.CurrentCulture), StringComparison.OrdinalIgnoreCase);
var message = ExceptionMessages.PresentationIsLarge.Replace(
"{0}",
maxSize.ToString(CultureInfo.CurrentCulture),
StringComparison.OrdinalIgnoreCase);
#else
var message =
ExceptionMessages.PresentationIsLarge.Replace("{0}", maxSize.ToString(CultureInfo.CurrentCulture));
Expand Down
4 changes: 3 additions & 1 deletion ShapeCrawler/Exceptions/SlidesMuchMoreException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ private SlidesMuchMoreException(string message)
internal static SlidesMuchMoreException FromMax(int maxNum)
{
#if NET6_0
var message = ExceptionMessages.SlidesMuchMore.Replace("{0}", maxNum.ToString(CultureInfo.CurrentCulture),
var message = ExceptionMessages.SlidesMuchMore.Replace(
"{0}",
maxNum.ToString(CultureInfo.CurrentCulture),
StringComparison.OrdinalIgnoreCase);
#else
var message = ExceptionMessages.SlidesMuchMore.Replace("{0}", maxNum.ToString(CultureInfo.CurrentCulture));
Expand Down
23 changes: 23 additions & 0 deletions ShapeCrawler/Extensions/ShapePropertiesExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,27 @@ internal static A.SolidFill AddASolidFill(this P.ShapeProperties pShapePropertie

return aSolidFill;
}

internal static void AddAXfrm(this P.ShapeProperties pSpPr, long xEmu, long yEmu, long wEmu, long hEmu)
{
var aXfrm = pSpPr.Transform2D;
aXfrm?.Remove();

aXfrm = new A.Transform2D();
pSpPr.Append(aXfrm);

var aOff = new A.Offset
{
X = xEmu,
Y = yEmu
};
aXfrm.Append(aOff);

var aExt = new A.Extents
{
Cx = wEmu,
Cy = hEmu
};
aXfrm.Append(aExt);
}
}
5 changes: 0 additions & 5 deletions ShapeCrawler/PowerPoint/ISlide.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ namespace ShapeCrawler;
/// </summary>
public interface ISlide : ISlideObject
{
/// <summary>
/// Gets or sets slide number.
/// </summary>
int Number { get; set; }

/// <summary>
/// Gets background image if it exist, otherwise <see langword="null"/>.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion ShapeCrawler/PowerPoint/SCSlide.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal SCSlide(SCPresentation pres, SlidePart slidePart, SlideId slideId)

public IShapeCollection Shapes => this.shapes.Value;

public int Number
public override int Number
{
get => this.GetNumber();
set => this.SetNumber(value);
Expand Down
24 changes: 16 additions & 8 deletions ShapeCrawler/PowerPoint/Shape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ namespace ShapeCrawler;

internal abstract class Shape : IShape
{
protected Shape(OpenXmlCompositeElement pShapeTreeChild, OneOf<SCSlide, SCSlideLayout, SCSlideMaster> slideObject,
protected Shape(
OpenXmlCompositeElement pShapeTreeChild,
OneOf<SCSlide, SCSlideLayout, SCSlideMaster> slideObject,
Shape? groupShape)
: this(pShapeTreeChild, slideObject)
{
Expand Down Expand Up @@ -133,22 +135,28 @@ private bool DefineHidden()
return parsedHiddenValue is true;
}

private void SetXCoordinate(int value)
private void SetXCoordinate(int newXPixels)
{
if (this.GroupShape is not null)
{
throw new RuntimeDefinedPropertyException("X coordinate of grouped shape cannot be changed.");
}

var aOffset = this.PShapeTreesChild.Descendants<A.Offset>().FirstOrDefault();
if (aOffset == null)

var pSpPr = this.PShapeTreesChild.GetFirstChild<P.ShapeProperties>() !;
var aXfrm = pSpPr.Transform2D;
if (aXfrm is null)
{
var placeholderShape = ((Placeholder)this.Placeholder!).ReferencedShape;
placeholderShape.X = value;
var placeholder = (Placeholder)this.Placeholder!;
var referencedShape = placeholder.ReferencedShape;
var xEmu = UnitConverter.HorizontalPixelToEmu(newXPixels);
var yEmu = UnitConverter.HorizontalPixelToEmu(referencedShape.Y);
var wEmu = UnitConverter.VerticalPixelToEmu(referencedShape.Width);
var hEmu = UnitConverter.VerticalPixelToEmu(referencedShape.Height);
pSpPr.AddAXfrm(xEmu, yEmu, wEmu, hEmu);
}
else
{
aOffset.X = UnitConverter.HorizontalPixelToEmu(value);
aXfrm.Offset!.X = UnitConverter.HorizontalPixelToEmu(newXPixels);
}
}

Expand Down
7 changes: 6 additions & 1 deletion ShapeCrawler/PowerPoint/SlideObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ namespace ShapeCrawler;
/// </summary>
public interface ISlideObject : IPresentationComponent
{

/// <summary>
/// Gets or sets slide number.
/// </summary>
int Number { get; set; }
}

internal abstract class SlideObject : ISlideObject
Expand All @@ -19,6 +22,8 @@ protected SlideObject(IPresentation pres)
}

public IPresentation Presentation { get; init; }

public abstract int Number { get; set; }

internal SCPresentation PresentationInternal => (SCPresentation)this.Presentation;

Expand Down
5 changes: 4 additions & 1 deletion ShapeCrawler/SlideMasters/SCSlideLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@ internal class SCSlideLayout : SlideObject, ISlideLayout
private readonly ResettableLazy<ShapeCollection> shapes;
private readonly SCSlideMaster slideMaster;

internal SCSlideLayout(SCSlideMaster slideMaster, SlideLayoutPart slideLayoutPart)
internal SCSlideLayout(SCSlideMaster slideMaster, SlideLayoutPart slideLayoutPart, int number)
: base(slideMaster.Presentation)
{
this.slideMaster = slideMaster;
this.SlideLayoutPart = slideLayoutPart;
this.shapes = new ResettableLazy<ShapeCollection>(() =>
ShapeCollection.Create(slideLayoutPart, this));
this.Number = number;
}

public IShapeCollection Shapes => this.shapes.Value;

public ISlideMaster SlideMaster => this.slideMaster;

public override int Number { get; set; }

internal SlideLayoutPart SlideLayoutPart { get; }

Expand Down
13 changes: 9 additions & 4 deletions ShapeCrawler/SlideMasters/SCSlideMaster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,27 @@
namespace ShapeCrawler.SlideMasters;

[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "SC — ShapeCrawler")]
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
internal class SCSlideMaster : SlideObject, ISlideMaster
{
private readonly ResettableLazy<List<SCSlideLayout>> slideLayouts;

internal SCSlideMaster(SCPresentation pres, P.SlideMaster pSlideMaster)
internal SCSlideMaster(SCPresentation pres, P.SlideMaster pSlideMaster, int number)
: base(pres)
{
this.Presentation = pres;
this.PSlideMaster = pSlideMaster;
this.slideLayouts = new ResettableLazy<List<SCSlideLayout>>(this.GetSlideLayouts);
this.Number = number;
}

public IImage? Background => this.GetBackground();

public IReadOnlyList<ISlideLayout> SlideLayouts => this.slideLayouts.Value;

public IShapeCollection Shapes => ShapeCollection.Create(this.PSlideMaster.SlideMasterPart!, this);

public override int Number { get; set; }

internal P.SlideMaster PSlideMaster { get; }

Expand All @@ -40,7 +44,7 @@ internal SCSlideMaster(SCPresentation pres, P.SlideMaster pSlideMaster)
internal ThemePart ThemePart => this.PSlideMaster.SlideMasterPart!.ThemePart!;

internal ShapeCollection ShapesInternal => (ShapeCollection)this.Shapes;

internal override TypedOpenXmlPart TypedOpenXmlPart => this.PSlideMaster.SlideMasterPart!;

internal bool TryGetFontSizeFromBody(int paragraphLvl, out int fontSize)
Expand Down Expand Up @@ -86,12 +90,13 @@ internal bool TryGetFontSizeFromOther(int paragraphLvl, out int fontSize)

private List<SCSlideLayout> GetSlideLayouts()
{
var rIdList = this.PSlideMaster.SlideLayoutIdList!.OfType<P.SlideLayoutId>().Select(x => x.RelationshipId!);
var rIdList = this.PSlideMaster.SlideLayoutIdList!.OfType<P.SlideLayoutId>().Select(layoutId => layoutId.RelationshipId!);
var layouts = new List<SCSlideLayout>(rIdList.Count());
var number = 1;
foreach (var rId in rIdList)
{
var layoutPart = (SlideLayoutPart)this.PSlideMaster.SlideMasterPart!.GetPartById(rId.Value!);
layouts.Add(new SCSlideLayout(this, layoutPart));
layouts.Add(new SCSlideLayout(this, layoutPart, number++));
}

return layouts;
Expand Down

0 comments on commit ffd7e00

Please sign in to comment.