Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ void IDocumentTypeFeature<TDocumentType>.ChangeDocumentType(TDocumentType newTyp
try
{
Package.ChangeDocumentTypeInternal(CreateMainPart());
OnDocumentTypeChanged(newType);
}
Comment thread
iamcymentho marked this conversation as resolved.
catch (OpenXmlPackageException e)
{
Expand All @@ -116,5 +117,13 @@ void IDocumentTypeFeature<TDocumentType>.ChangeDocumentType(TDocumentType newTyp

protected abstract TMainPart CreateMainPart();

/// <summary>
/// Called after the document type has been changed. Subclasses can override to perform
/// cleanup such as removing parts that are not valid for the new document type.
/// </summary>
protected virtual void OnDocumentTypeChanged(TDocumentType newType)
{
}

bool IKnownDataPartFeature.IsKnown(string relationshipId) => false;
}
15 changes: 15 additions & 0 deletions src/DocumentFormat.OpenXml/Packaging/WordprocessingDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,21 @@ public WordprocessingDocumentFeatures(OpenXmlPackage package)
"application/vnd.ms-word.template.macroEnabledTemplate.main+xml" => WordprocessingDocumentType.MacroEnabledTemplate,
_ => default,
};

protected override void OnDocumentTypeChanged(WordprocessingDocumentType newType)
{
if (newType is WordprocessingDocumentType.MacroEnabledDocument
or WordprocessingDocumentType.MacroEnabledTemplate)
{
return;
}

if (MainPart is { } mainPart)
{
mainPart.DeletePartsRecursivelyOfTypeBase<VbaProjectPart>();
mainPart.DeletePartsRecursivelyOfTypeBase<CustomizationPart>();
}
Comment thread
iamcymentho marked this conversation as resolved.
}
}
}
}
44 changes: 44 additions & 0 deletions test/DocumentFormat.OpenXml.Tests/DocxTests01.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,50 @@ public void W039_ChangeDocumentType()
}
}

[Fact]
public void ChangeDocumentType_MacroEnabledToDocument_RemovesVbaParts()
{
using var stream = new MemoryStream();

// Create a macro-enabled document with a VbaProjectPart
using (var doc = WordprocessingDocument.Create(stream, WordprocessingDocumentType.MacroEnabledDocument))
{
var mainPart = doc.AddMainDocumentPart();
mainPart.Document = new W.Document(new W.Body(new W.Paragraph(new W.Run(new W.Text("Test")))));

// Add a VbaProjectPart (the part that causes the issue)
mainPart.AddNewPart<VbaProjectPart>();

Assert.NotNull(mainPart.VbaProjectPart);
Assert.Equal(WordprocessingDocumentType.MacroEnabledDocument, doc.DocumentType);
}

// Re-open and change type to a standard document
stream.Position = 0;

using (var doc = WordprocessingDocument.Open(stream, true))
{
Assert.Equal(WordprocessingDocumentType.MacroEnabledDocument, doc.DocumentType);
Assert.NotNull(doc.MainDocumentPart.VbaProjectPart);

doc.ChangeDocumentType(WordprocessingDocumentType.Document);

Assert.Equal(WordprocessingDocumentType.Document, doc.DocumentType);

// After changing to a non-macro type, VbaProjectPart should be removed
Assert.Null(doc.MainDocumentPart.VbaProjectPart);
}

// Re-open and verify the VBA part is no longer present
stream.Position = 0;

using (var doc = WordprocessingDocument.Open(stream, false))
{
Assert.Null(doc.MainDocumentPart.VbaProjectPart);
Assert.Empty(doc.MainDocumentPart.GetPartsOfType<VbaProjectPart>());
}
}

[Fact]
public void W038_DocxCreation_Package()
{
Expand Down