search/mag_sel search/close
Aspose::Words::Comment Class Referencefinal

Represents a container for text of a comment.

A comment is an annotation which is anchored to a region of text or to a position in text. A comment can contain an arbitrary amount of block-level content.

If a Comment object occurs on its own, the comment is anchored to the position of the Comment object.

To anchor a comment to a region of text three objects are required: Comment, CommentRangeStart and CommentRangeEnd. All three objects need to share the same Id value.

Comment is an inline-level node and can only be a child of Paragraph.

Comment can contain Paragraph and Table child nodes.

See also
Aspose::Words::CommentRangeStart
Aspose::Words::CommentRangeEnd
Examples

Shows how to add a comment to a document, and then reply to it.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
auto comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"My comment.");
// Place the comment at a node in the document's body.
// This comment will show up at the location of its paragraph,
// outside the right-side margin of the page, and with a dotted line connecting it to its paragraph.
builder->get_CurrentParagraph()->AppendChild(comment);
// Add a reply, which will show up under its parent comment.
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"New reply");
// Comments and replies are both Comment nodes.
ASSERT_EQ(2, doc->GetChildNodes(NodeType::Comment, true)->get_Count());
// Comments that do not reply to other comments are "top-level". They have no ancestor comments.
ASSERT_TRUE(comment->get_Ancestor() == nullptr);
// Replies have an ancestor top-level comment.
ASPOSE_ASSERT_EQ(comment, comment->get_Replies()->idx_get(0)->get_Ancestor());
doc->Save(ArtifactsDir + u"Comment.AddCommentWithReply.docx");

Shows how to add a comment to a paragraph.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->Write(u"Hello world!");
auto comment = MakeObject<Comment>(doc, u"John Doe", u"JD", System::DateTime::get_Today());
builder->get_CurrentParagraph()->AppendChild(comment);
builder->MoveTo(comment->AppendChild(MakeObject<Paragraph>(doc)));
builder->Write(u"Comment text.");
ASSERT_EQ(System::DateTime::get_Today(), comment->get_DateTime());
// In Microsoft Word, we can right-click this comment in the document body to edit it, or reply to it.
doc->Save(ArtifactsDir + u"InlineStory.AddComment.docx");

#include <Aspose.Words.Cpp/Comment.h>

+ Inheritance diagram for Aspose::Words::Comment:

Public Member Functions

 Comment (SharedPtr< DocumentBase > doc)
 Initializes a new instance of the Comment class. More...
 
 Comment (SharedPtr< DocumentBase > doc, String author, String initial, DateTime dateTime)
 Initializes a new instance of the Comment class. More...
 
bool Accept (SharedPtr< DocumentVisitor > visitor) override
 Accepts a visitor. More...
 
SharedPtr< CommentAddReply (String author, String initial, DateTime dateTime, String text)
 Adds a reply to this comment. More...
 
SharedPtr< Commentget_Ancestor ()
 Returns the parent Comment object. Returns null for top-level comments. More...
 
String get_Author () const
 Returns or sets the author name for a comment. More...
 
DateTime get_DateTime () const
 Gets the date and time that the comment was made. More...
 
bool get_Done () const
 Gets or sets flag indicating that the comment has been marked done. More...
 
int32_t get_Id () const
 Gets the comment identifier. More...
 
String get_Initial () const
 Returns or sets the initials of the user associated with a specific comment. More...
 
NodeType get_NodeType () const override
 Returns NodeType.Comment. More...
 
SharedPtr< CommentCollectionget_Replies ()
 Returns a collection of Comment objects that are immediate children of the specified comment. More...
 
StoryType get_StoryType () override
 Returns StoryType.Comments. More...
 
virtual const TypeInfoGetType () const override
 
virtual bool Is (const TypeInfo &target) const override
 
void RemoveAllReplies ()
 Removes all replies to this comment. More...
 
void RemoveMoveRevisions () override
 
void RemoveReply (SharedPtr< Comment > reply)
 Removes the specified reply to this comment. More...
 
void set_Author (String value)
 Setter for get_Author. More...
 
void set_DateTime (DateTime value)
 Setter for get_DateTime. More...
 
void set_Done (bool value)
 Setter for get_Done. More...
 
void set_Initial (String value)
 Setter for get_Initial. More...
 
void SetText (String text)
 This is a convenience method that allows to easily set text of the comment. More...
 
- Public Member Functions inherited from InlineStory
void EnsureMinimum ()
 If the last child is not a paragraph, creates and appends one empty paragraph. More...
 
SharedPtr< Paragraphget_FirstParagraph ()
 Gets the first paragraph in the story. More...
 
SharedPtr< Fontget_Font ()
 Provides access to the font formatting of the anchor character of this object. More...
 
bool get_IsDeleteRevision ()
 Returns true if this object was deleted in Microsoft Word while change tracking was enabled. More...
 
bool get_IsInsertRevision ()
 Returns true if this object was inserted in Microsoft Word while change tracking was enabled. More...
 
bool get_IsMoveFromRevision ()
 Returns true if this object was moved (deleted) in Microsoft Word while change tracking was enabled. More...
 
bool get_IsMoveToRevision ()
 Returns true if this object was moved (inserted) in Microsoft Word while change tracking was enabled. More...
 
SharedPtr< Paragraphget_LastParagraph ()
 Gets the last paragraph in the story. More...
 
SharedPtr< ParagraphCollectionget_Paragraphs ()
 Gets a collection of paragraphs that are immediate children of the story. More...
 
SharedPtr< Paragraphget_ParentParagraph ()
 Retrieves the parent Paragraph of this node. More...
 
SharedPtr< TableCollectionget_Tables ()
 Gets a collection of tables that are immediate children of the story. More...
 
- Public Member Functions inherited from CompositeNode
SharedPtr< NodeAppendChild (SharedPtr< Node > newChild)
 Adds the specified node to the end of the list of child nodes for this node. More...
 
SharedPtr< NodeCollectionget_ChildNodes ()
 Gets all immediate child nodes of this node. More...
 
SharedPtr< CompositeNodeget_Container () override
 
int32_t get_Count ()
 Gets the number of immediate children of this node. More...
 
SharedPtr< Nodeget_FirstChild () const
 Gets the first child of the node. More...
 
bool get_HasChildNodes ()
 Returns true if this node has any child nodes. More...
 
bool get_IsComposite () override
 Returns true as this node can have child nodes. More...
 
SharedPtr< Nodeget_LastChild () const
 Gets the last child of the node. More...
 
SharedPtr< NodeGetChild (NodeType nodeType, int32_t index, bool isDeep)
 Returns an Nth child node that matches the specified type. More...
 
SharedPtr< NodeCollectionGetChildNodes (NodeType nodeType, bool isDeep)
 Returns a live collection of child nodes that match the specified type. More...
 
SharedPtr< NodeGetCurrentNode () override
 
SharedPtr< IEnumerator< SharedPtr< Node > > > GetEnumerator () override
 Provides support for the for each style iteration over the child nodes of this node. More...
 
SharedPtr< NodeGetNextMatchingNode (SharedPtr< Node > curNode) override
 
String GetText () override
 Gets the text of this node and of all its children. More...
 
int32_t IndexOf (SharedPtr< Node > child)
 Returns the index of the specified child node in the child node array. More...
 
SharedPtr< NodeInsertAfter (SharedPtr< Node > newChild, SharedPtr< Node > refChild)
 Inserts the specified node immediately after the specified reference node. More...
 
SharedPtr< NodeInsertBefore (SharedPtr< Node > newChild, SharedPtr< Node > refChild)
 Inserts the specified node immediately before the specified reference node. More...
 
SharedPtr< NodePrependChild (SharedPtr< Node > newChild)
 Adds the specified node to the beginning of the list of child nodes for this node. More...
 
void RemoveAllChildren ()
 Removes all the child nodes of the current node. More...
 
SharedPtr< NodeRemoveChild (SharedPtr< Node > oldChild)
 Removes the specified child node. More...
 
void RemoveSmartTags ()
 Removes all SmartTag descendant nodes of the current node. More...
 
SharedPtr< NodeListSelectNodes (String xpath)
 Selects a list of nodes matching the XPath expression. More...
 
SharedPtr< NodeSelectSingleNode (String xpath)
 Selects the first Node that matches the XPath expression. More...
 
- Public Member Functions inherited from Node
SharedPtr< NodeClone (bool isCloneChildren)
 Creates a duplicate of the node. More...
 
int32_t get_CustomNodeId () const
 Specifies custom node identifier. More...
 
virtual SharedPtr< DocumentBaseget_Document () const
 Gets the document to which this node belongs. More...
 
SharedPtr< Nodeget_NextSibling ()
 Gets the node immediately following this node. More...
 
SharedPtr< CompositeNodeget_ParentNode ()
 Gets the immediate parent of this node. More...
 
SharedPtr< Nodeget_PreviousSibling ()
 Gets the node immediately preceding this node. More...
 
SharedPtr< Rangeget_Range ()
 Returns a Range object that represents the portion of a document that is contained in this node. More...
 
SharedPtr< CompositeNodeGetAncestor (NodeType ancestorType)
 Gets the first ancestor of the specified NodeType. More...
 
template<typename T >
GetAncestorOf ()
 
SharedPtr< NodeNextPreOrder (SharedPtr< Node > rootNode)
 Gets next node according to the pre-order tree traversal algorithm. More...
 
SharedPtr< NodePreviousPreOrder (SharedPtr< Node > rootNode)
 Gets the previous node according to the pre-order tree traversal algorithm. More...
 
void Remove ()
 Removes itself from the parent. More...
 
void set_CustomNodeId (int32_t value)
 Setter for get_CustomNodeId. More...
 
String ToString (SaveFormat saveFormat)
 Exports the content of the node into a string in the specified format. More...
 
String ToString (SharedPtr< SaveOptions > saveOptions)
 Exports the content of the node into a string using the specified save options. More...
 

Static Public Member Functions

static const TypeInfoType ()
 
- Static Public Member Functions inherited from InlineStory
static const TypeInfoType ()
 
- Static Public Member Functions inherited from CompositeNode
static const TypeInfoType ()
 
- Static Public Member Functions inherited from Node
static String NodeTypeToString (NodeType nodeType)
 A utility method that converts a node type enum value into a user friendly string. More...
 
static const TypeInfoType ()
 

Constructor & Destructor Documentation

◆ Comment() [1/2]

Aspose::Words::Comment::Comment ( System::SharedPtr< Aspose::Words::DocumentBase doc)

Initializes a new instance of the Comment class.

When Comment is created, it belongs to the specified document, but is not yet part of the document and ParentNode is null.

To append Comment to the document use InsertAfter or InsertBefore on the paragraph where you want the comment inserted.

After creating a comment, don't forget to set its Author, Initial and DateTime properties.

Parameters
docThe owner document.
Examples

Shows how print the contents of all comments and their comment ranges using a document visitor.

void CreateCommentsAndPrintAllInfo()
{
auto doc = MakeObject<Document>();
auto newComment = MakeObject<Comment>(doc);
newComment->set_Author(u"VDeryushev");
newComment->set_Initial(u"VD");
newComment->set_DateTime(System::DateTime::get_Now());
newComment->SetText(u"Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
SharedPtr<Paragraph> para = doc->get_FirstSection()->get_Body()->get_FirstParagraph();
para->AppendChild(MakeObject<CommentRangeStart>(doc, newComment->get_Id()));
para->AppendChild(MakeObject<Run>(doc, u"Commented text."));
para->AppendChild(MakeObject<CommentRangeEnd>(doc, newComment->get_Id()));
para->AppendChild(newComment);
// Add two replies to the comment.
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"New reply.");
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"Another reply.");
PrintAllCommentInfo(doc->GetChildNodes(NodeType::Comment, true));
}
static void PrintAllCommentInfo(SharedPtr<NodeCollection> comments)
{
auto commentVisitor = MakeObject<ExComment::CommentInfoPrinter>();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
std::function<bool(SharedPtr<Node> c)> haveNoAncestor = [](SharedPtr<Node> c)
{
return (System::DynamicCast<Comment>(c))->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver<Comment>(comments->LINQ_Where(haveNoAncestor)))
{
// First, visit the start of the comment range.
auto commentRangeStart = System::DynamicCast<CommentRangeStart>(comment->get_PreviousSibling()->get_PreviousSibling()->get_PreviousSibling());
commentRangeStart->Accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment->Accept(commentVisitor);
for (const auto& reply : System::IterateOver<Comment>(comment->get_Replies()))
{
reply->Accept(commentVisitor);
}
// Finally, visit the end of the comment range, and then print the visitor's text contents.
auto commentRangeEnd = System::DynamicCast<CommentRangeEnd>(comment->get_PreviousSibling());
commentRangeEnd->Accept(commentVisitor);
std::cout << commentVisitor->GetText() << std::endl;
}
}
class CommentInfoPrinter : public DocumentVisitor
{
public:
CommentInfoPrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->get_Text() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(String(u"[Comment range end] ID: ") + commentRangeEnd->get_Id() + u"\n");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ Comment() [2/2]

Aspose::Words::Comment::Comment ( System::SharedPtr< Aspose::Words::DocumentBase doc,
System::String  author,
System::String  initial,
System::DateTime  dateTime 
)

Initializes a new instance of the Comment class.

Parameters
docThe owner document.
authorThe author name for the comment. Cannot be null.
initialThe author initials for the comment. Cannot be null.
dateTimeThe date and time for the comment.
Examples

Shows how to add a comment to a paragraph.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->Write(u"Hello world!");
auto comment = MakeObject<Comment>(doc, u"John Doe", u"JD", System::DateTime::get_Today());
builder->get_CurrentParagraph()->AppendChild(comment);
builder->MoveTo(comment->AppendChild(MakeObject<Paragraph>(doc)));
builder->Write(u"Comment text.");
ASSERT_EQ(System::DateTime::get_Today(), comment->get_DateTime());
// In Microsoft Word, we can right-click this comment in the document body to edit it, or reply to it.
doc->Save(ArtifactsDir + u"InlineStory.AddComment.docx");

Member Function Documentation

◆ Accept()

bool Aspose::Words::Comment::Accept ( System::SharedPtr< Aspose::Words::DocumentVisitor visitor)
overridevirtual

Accepts a visitor.

Enumerates over this node and all of its children. Each node calls a corresponding method on DocumentVisitor.

For more info see the Visitor design pattern.

Parameters
visitorThe visitor that will visit the nodes.
Returns
True if all nodes were visited; false if DocumentVisitor stopped the operation before visiting all nodes.
Examples

Shows how print the contents of all comments and their comment ranges using a document visitor.

void CreateCommentsAndPrintAllInfo()
{
auto doc = MakeObject<Document>();
auto newComment = MakeObject<Comment>(doc);
newComment->set_Author(u"VDeryushev");
newComment->set_Initial(u"VD");
newComment->set_DateTime(System::DateTime::get_Now());
newComment->SetText(u"Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
SharedPtr<Paragraph> para = doc->get_FirstSection()->get_Body()->get_FirstParagraph();
para->AppendChild(MakeObject<CommentRangeStart>(doc, newComment->get_Id()));
para->AppendChild(MakeObject<Run>(doc, u"Commented text."));
para->AppendChild(MakeObject<CommentRangeEnd>(doc, newComment->get_Id()));
para->AppendChild(newComment);
// Add two replies to the comment.
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"New reply.");
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"Another reply.");
PrintAllCommentInfo(doc->GetChildNodes(NodeType::Comment, true));
}
static void PrintAllCommentInfo(SharedPtr<NodeCollection> comments)
{
auto commentVisitor = MakeObject<ExComment::CommentInfoPrinter>();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
std::function<bool(SharedPtr<Node> c)> haveNoAncestor = [](SharedPtr<Node> c)
{
return (System::DynamicCast<Comment>(c))->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver<Comment>(comments->LINQ_Where(haveNoAncestor)))
{
// First, visit the start of the comment range.
auto commentRangeStart = System::DynamicCast<CommentRangeStart>(comment->get_PreviousSibling()->get_PreviousSibling()->get_PreviousSibling());
commentRangeStart->Accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment->Accept(commentVisitor);
for (const auto& reply : System::IterateOver<Comment>(comment->get_Replies()))
{
reply->Accept(commentVisitor);
}
// Finally, visit the end of the comment range, and then print the visitor's text contents.
auto commentRangeEnd = System::DynamicCast<CommentRangeEnd>(comment->get_PreviousSibling());
commentRangeEnd->Accept(commentVisitor);
std::cout << commentVisitor->GetText() << std::endl;
}
}
class CommentInfoPrinter : public DocumentVisitor
{
public:
CommentInfoPrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->get_Text() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(String(u"[Comment range end] ID: ") + commentRangeEnd->get_Id() + u"\n");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

Implements Aspose::Words::Node.

◆ AddReply()

System::SharedPtr<Aspose::Words::Comment> Aspose::Words::Comment::AddReply ( System::String  author,
System::String  initial,
System::DateTime  dateTime,
System::String  text 
)

Adds a reply to this comment.

Parameters
authorThe author name for the reply.
initialThe author initials for the reply.
dateTimeThe date and time for the reply.
textThe reply text.
Returns
The created Comment node for the reply.
Examples

Shows how to add a comment to a document, and then reply to it.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
auto comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"My comment.");
// Place the comment at a node in the document's body.
// This comment will show up at the location of its paragraph,
// outside the right-side margin of the page, and with a dotted line connecting it to its paragraph.
builder->get_CurrentParagraph()->AppendChild(comment);
// Add a reply, which will show up under its parent comment.
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"New reply");
// Comments and replies are both Comment nodes.
ASSERT_EQ(2, doc->GetChildNodes(NodeType::Comment, true)->get_Count());
// Comments that do not reply to other comments are "top-level". They have no ancestor comments.
ASSERT_TRUE(comment->get_Ancestor() == nullptr);
// Replies have an ancestor top-level comment.
ASPOSE_ASSERT_EQ(comment, comment->get_Replies()->idx_get(0)->get_Ancestor());
doc->Save(ArtifactsDir + u"Comment.AddCommentWithReply.docx");

◆ get_Ancestor()

System::SharedPtr<Aspose::Words::Comment> Aspose::Words::Comment::get_Ancestor ( )

Returns the parent Comment object. Returns null for top-level comments.

Examples

Shows how to print all of a document's comments and their replies.

auto doc = MakeObject<Document>(MyDir + u"Comments.docx");
SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
auto hasNullAncestor = [](SharedPtr<Comment> c)
{
return c->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver(comments->LINQ_OfType<SharedPtr<Comment>>()->LINQ_Where(hasNullAncestor)))
{
std::cout << "Top-level comment:" << std::endl;
std::cout << "\t\"" << comment->GetText().Trim() << "\", by " << comment->get_Author() << std::endl;
std::cout << "Has " << comment->get_Replies()->get_Count() << " replies" << std::endl;
for (const auto& commentReply : System::IterateOver<Comment>(comment->get_Replies()))
{
std::cout << "\t\"" << commentReply->GetText().Trim() << "\", by " << commentReply->get_Author() << std::endl;
}
std::cout << std::endl;
}

◆ get_Author()

System::String Aspose::Words::Comment::get_Author ( ) const

Returns or sets the author name for a comment.

Cannot be null.

Default is empty string.

Examples

Shows how to print all of a document's comments and their replies.

auto doc = MakeObject<Document>(MyDir + u"Comments.docx");
SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
auto hasNullAncestor = [](SharedPtr<Comment> c)
{
return c->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver(comments->LINQ_OfType<SharedPtr<Comment>>()->LINQ_Where(hasNullAncestor)))
{
std::cout << "Top-level comment:" << std::endl;
std::cout << "\t\"" << comment->GetText().Trim() << "\", by " << comment->get_Author() << std::endl;
std::cout << "Has " << comment->get_Replies()->get_Count() << " replies" << std::endl;
for (const auto& commentReply : System::IterateOver<Comment>(comment->get_Replies()))
{
std::cout << "\t\"" << commentReply->GetText().Trim() << "\", by " << commentReply->get_Author() << std::endl;
}
std::cout << std::endl;
}

◆ get_DateTime()

System::DateTime Aspose::Words::Comment::get_DateTime ( ) const

Gets the date and time that the comment was made.

Default is MinValue.

Examples

Shows how print the contents of all comments and their comment ranges using a document visitor.

void CreateCommentsAndPrintAllInfo()
{
auto doc = MakeObject<Document>();
auto newComment = MakeObject<Comment>(doc);
newComment->set_Author(u"VDeryushev");
newComment->set_Initial(u"VD");
newComment->set_DateTime(System::DateTime::get_Now());
newComment->SetText(u"Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
SharedPtr<Paragraph> para = doc->get_FirstSection()->get_Body()->get_FirstParagraph();
para->AppendChild(MakeObject<CommentRangeStart>(doc, newComment->get_Id()));
para->AppendChild(MakeObject<Run>(doc, u"Commented text."));
para->AppendChild(MakeObject<CommentRangeEnd>(doc, newComment->get_Id()));
para->AppendChild(newComment);
// Add two replies to the comment.
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"New reply.");
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"Another reply.");
PrintAllCommentInfo(doc->GetChildNodes(NodeType::Comment, true));
}
static void PrintAllCommentInfo(SharedPtr<NodeCollection> comments)
{
auto commentVisitor = MakeObject<ExComment::CommentInfoPrinter>();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
std::function<bool(SharedPtr<Node> c)> haveNoAncestor = [](SharedPtr<Node> c)
{
return (System::DynamicCast<Comment>(c))->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver<Comment>(comments->LINQ_Where(haveNoAncestor)))
{
// First, visit the start of the comment range.
auto commentRangeStart = System::DynamicCast<CommentRangeStart>(comment->get_PreviousSibling()->get_PreviousSibling()->get_PreviousSibling());
commentRangeStart->Accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment->Accept(commentVisitor);
for (const auto& reply : System::IterateOver<Comment>(comment->get_Replies()))
{
reply->Accept(commentVisitor);
}
// Finally, visit the end of the comment range, and then print the visitor's text contents.
auto commentRangeEnd = System::DynamicCast<CommentRangeEnd>(comment->get_PreviousSibling());
commentRangeEnd->Accept(commentVisitor);
std::cout << commentVisitor->GetText() << std::endl;
}
}
class CommentInfoPrinter : public DocumentVisitor
{
public:
CommentInfoPrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->get_Text() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(String(u"[Comment range end] ID: ") + commentRangeEnd->get_Id() + u"\n");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ get_Done()

bool Aspose::Words::Comment::get_Done ( ) const

Gets or sets flag indicating that the comment has been marked done.

Examples

Shows how to mark a comment as "done".

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->Writeln(u"Helo world!");
// Insert a comment to point out an error.
auto comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"Fix the spelling error!");
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->AppendChild(comment);
// Comments have a "Done" flag, which is set to "false" by default.
// If a comment suggests that we make a change within the document,
// we can apply the change, and then also set the "Done" flag afterwards to indicate the correction.
ASSERT_FALSE(comment->get_Done());
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Hello world!");
comment->set_Done(true);
// Comments that are "done" will differentiate themselves
// from ones that are not "done" with a faded text color.
comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"Add text to this paragraph.");
builder->get_CurrentParagraph()->AppendChild(comment);
doc->Save(ArtifactsDir + u"Comment.Done.docx");

Shows how print the contents of all comments and their comment ranges using a document visitor.

void CreateCommentsAndPrintAllInfo()
{
auto doc = MakeObject<Document>();
auto newComment = MakeObject<Comment>(doc);
newComment->set_Author(u"VDeryushev");
newComment->set_Initial(u"VD");
newComment->set_DateTime(System::DateTime::get_Now());
newComment->SetText(u"Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
SharedPtr<Paragraph> para = doc->get_FirstSection()->get_Body()->get_FirstParagraph();
para->AppendChild(MakeObject<CommentRangeStart>(doc, newComment->get_Id()));
para->AppendChild(MakeObject<Run>(doc, u"Commented text."));
para->AppendChild(MakeObject<CommentRangeEnd>(doc, newComment->get_Id()));
para->AppendChild(newComment);
// Add two replies to the comment.
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"New reply.");
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"Another reply.");
PrintAllCommentInfo(doc->GetChildNodes(NodeType::Comment, true));
}
static void PrintAllCommentInfo(SharedPtr<NodeCollection> comments)
{
auto commentVisitor = MakeObject<ExComment::CommentInfoPrinter>();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
std::function<bool(SharedPtr<Node> c)> haveNoAncestor = [](SharedPtr<Node> c)
{
return (System::DynamicCast<Comment>(c))->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver<Comment>(comments->LINQ_Where(haveNoAncestor)))
{
// First, visit the start of the comment range.
auto commentRangeStart = System::DynamicCast<CommentRangeStart>(comment->get_PreviousSibling()->get_PreviousSibling()->get_PreviousSibling());
commentRangeStart->Accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment->Accept(commentVisitor);
for (const auto& reply : System::IterateOver<Comment>(comment->get_Replies()))
{
reply->Accept(commentVisitor);
}
// Finally, visit the end of the comment range, and then print the visitor's text contents.
auto commentRangeEnd = System::DynamicCast<CommentRangeEnd>(comment->get_PreviousSibling());
commentRangeEnd->Accept(commentVisitor);
std::cout << commentVisitor->GetText() << std::endl;
}
}
class CommentInfoPrinter : public DocumentVisitor
{
public:
CommentInfoPrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->get_Text() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(String(u"[Comment range end] ID: ") + commentRangeEnd->get_Id() + u"\n");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ get_Id()

int32_t Aspose::Words::Comment::get_Id ( ) const

Gets the comment identifier.

The comment identifier allows to anchor a comment to a region of text in the document. The region must be demarcated using the CommentRangeStart and CommentRangeEnd object sharing the same identifier value as the Comment object.

You would use this value when looking for the CommentRangeStart and CommentRangeEnd nodes that are linked to this comment.

Comment identifiers are supposed to be unique across a document and Aspose.Words automatically maintains comment identifiers when loading, saving and combining documents.

Examples

Shows how print the contents of all comments and their comment ranges using a document visitor.

void CreateCommentsAndPrintAllInfo()
{
auto doc = MakeObject<Document>();
auto newComment = MakeObject<Comment>(doc);
newComment->set_Author(u"VDeryushev");
newComment->set_Initial(u"VD");
newComment->set_DateTime(System::DateTime::get_Now());
newComment->SetText(u"Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
SharedPtr<Paragraph> para = doc->get_FirstSection()->get_Body()->get_FirstParagraph();
para->AppendChild(MakeObject<CommentRangeStart>(doc, newComment->get_Id()));
para->AppendChild(MakeObject<Run>(doc, u"Commented text."));
para->AppendChild(MakeObject<CommentRangeEnd>(doc, newComment->get_Id()));
para->AppendChild(newComment);
// Add two replies to the comment.
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"New reply.");
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"Another reply.");
PrintAllCommentInfo(doc->GetChildNodes(NodeType::Comment, true));
}
static void PrintAllCommentInfo(SharedPtr<NodeCollection> comments)
{
auto commentVisitor = MakeObject<ExComment::CommentInfoPrinter>();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
std::function<bool(SharedPtr<Node> c)> haveNoAncestor = [](SharedPtr<Node> c)
{
return (System::DynamicCast<Comment>(c))->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver<Comment>(comments->LINQ_Where(haveNoAncestor)))
{
// First, visit the start of the comment range.
auto commentRangeStart = System::DynamicCast<CommentRangeStart>(comment->get_PreviousSibling()->get_PreviousSibling()->get_PreviousSibling());
commentRangeStart->Accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment->Accept(commentVisitor);
for (const auto& reply : System::IterateOver<Comment>(comment->get_Replies()))
{
reply->Accept(commentVisitor);
}
// Finally, visit the end of the comment range, and then print the visitor's text contents.
auto commentRangeEnd = System::DynamicCast<CommentRangeEnd>(comment->get_PreviousSibling());
commentRangeEnd->Accept(commentVisitor);
std::cout << commentVisitor->GetText() << std::endl;
}
}
class CommentInfoPrinter : public DocumentVisitor
{
public:
CommentInfoPrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->get_Text() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(String(u"[Comment range end] ID: ") + commentRangeEnd->get_Id() + u"\n");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ get_Initial()

System::String Aspose::Words::Comment::get_Initial ( ) const

Returns or sets the initials of the user associated with a specific comment.

Cannot be null.

Default is empty string.

Examples

Shows how print the contents of all comments and their comment ranges using a document visitor.

void CreateCommentsAndPrintAllInfo()
{
auto doc = MakeObject<Document>();
auto newComment = MakeObject<Comment>(doc);
newComment->set_Author(u"VDeryushev");
newComment->set_Initial(u"VD");
newComment->set_DateTime(System::DateTime::get_Now());
newComment->SetText(u"Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
SharedPtr<Paragraph> para = doc->get_FirstSection()->get_Body()->get_FirstParagraph();
para->AppendChild(MakeObject<CommentRangeStart>(doc, newComment->get_Id()));
para->AppendChild(MakeObject<Run>(doc, u"Commented text."));
para->AppendChild(MakeObject<CommentRangeEnd>(doc, newComment->get_Id()));
para->AppendChild(newComment);
// Add two replies to the comment.
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"New reply.");
newComment->AddReply(u"John Doe", u"JD", System::DateTime::get_Now(), u"Another reply.");
PrintAllCommentInfo(doc->GetChildNodes(NodeType::Comment, true));
}
static void PrintAllCommentInfo(SharedPtr<NodeCollection> comments)
{
auto commentVisitor = MakeObject<ExComment::CommentInfoPrinter>();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
std::function<bool(SharedPtr<Node> c)> haveNoAncestor = [](SharedPtr<Node> c)
{
return (System::DynamicCast<Comment>(c))->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver<Comment>(comments->LINQ_Where(haveNoAncestor)))
{
// First, visit the start of the comment range.
auto commentRangeStart = System::DynamicCast<CommentRangeStart>(comment->get_PreviousSibling()->get_PreviousSibling()->get_PreviousSibling());
commentRangeStart->Accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment->Accept(commentVisitor);
for (const auto& reply : System::IterateOver<Comment>(comment->get_Replies()))
{
reply->Accept(commentVisitor);
}
// Finally, visit the end of the comment range, and then print the visitor's text contents.
auto commentRangeEnd = System::DynamicCast<CommentRangeEnd>(comment->get_PreviousSibling());
commentRangeEnd->Accept(commentVisitor);
std::cout << commentVisitor->GetText() << std::endl;
}
}
class CommentInfoPrinter : public DocumentVisitor
{
public:
CommentInfoPrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->get_Text() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(String(u"[Comment range end] ID: ") + commentRangeEnd->get_Id() + u"\n");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ get_NodeType()

Aspose::Words::NodeType Aspose::Words::Comment::get_NodeType ( ) const
overridevirtual

Returns NodeType.Comment.

Examples

Shows how to traverse a composite node's tree of child nodes.

void RecurseChildren()
{
auto doc = MakeObject<Document>(MyDir + u"Paragraphs.docx");
// Any node that can contain child nodes, such as the document itself, is composite.
ASSERT_TRUE(doc->get_IsComposite());
// Invoke the recursive function that will go through and print all the child nodes of a composite node.
TraverseAllNodes(doc, 0);
}
void TraverseAllNodes(SharedPtr<CompositeNode> parentNode, int depth)
{
for (SharedPtr<Node> childNode = parentNode->get_FirstChild(); childNode != nullptr; childNode = childNode->get_NextSibling())
{
std::cout << (String(u'\t', depth)) << Node::NodeTypeToString(childNode->get_NodeType());
// Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node.
if (childNode->get_IsComposite())
{
std::cout << std::endl;
TraverseAllNodes(System::DynamicCast<CompositeNode>(childNode), depth + 1);
}
else if (System::ObjectExt::Is<Inline>(childNode))
{
std::cout << " - \"" << childNode->GetText().Trim() << "\"" << std::endl;
}
else
{
std::cout << std::endl;
}
}
}

Implements Aspose::Words::Node.

◆ get_Replies()

System::SharedPtr<Aspose::Words::CommentCollection> Aspose::Words::Comment::get_Replies ( )

Returns a collection of Comment objects that are immediate children of the specified comment.

Examples

Shows how to print all of a document's comments and their replies.

auto doc = MakeObject<Document>(MyDir + u"Comments.docx");
SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
auto hasNullAncestor = [](SharedPtr<Comment> c)
{
return c->get_Ancestor() == nullptr;
};
for (auto comment : System::IterateOver(comments->LINQ_OfType<SharedPtr<Comment>>()->LINQ_Where(hasNullAncestor)))
{
std::cout << "Top-level comment:" << std::endl;
std::cout << "\t\"" << comment->GetText().Trim() << "\", by " << comment->get_Author() << std::endl;
std::cout << "Has " << comment->get_Replies()->get_Count() << " replies" << std::endl;
for (const auto& commentReply : System::IterateOver<Comment>(comment->get_Replies()))
{
std::cout << "\t\"" << commentReply->GetText().Trim() << "\", by " << commentReply->get_Author() << std::endl;
}
std::cout << std::endl;
}

◆ get_StoryType()

Aspose::Words::StoryType Aspose::Words::Comment::get_StoryType ( )
overridevirtual

Returns StoryType.Comments.

Examples

Shows how to insert InlineStory nodes.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
SharedPtr<Footnote> footnote = builder->InsertFootnote(FootnoteType::Footnote, nullptr);
// Table nodes have an "EnsureMinimum()" method that makes sure the table has at least one cell.
auto table = MakeObject<Table>(doc);
table->EnsureMinimum();
// We can place a table inside a footnote, which will make it appear at the referencing page's footer.
ASSERT_EQ(0, footnote->get_Tables()->get_Count());
footnote->AppendChild(table);
ASSERT_EQ(1, footnote->get_Tables()->get_Count());
ASSERT_EQ(NodeType::Table, footnote->get_LastChild()->get_NodeType());
// An InlineStory has an "EnsureMinimum()" method as well, but in this case,
// it makes sure the last child of the node is a paragraph,
// for us to be able to click and write text easily in Microsoft Word.
footnote->EnsureMinimum();
ASSERT_EQ(NodeType::Paragraph, footnote->get_LastChild()->get_NodeType());
// Edit the appearance of the anchor, which is the small superscript number
// in the main text that points to the footnote.
footnote->get_Font()->set_Name(u"Arial");
footnote->get_Font()->set_Color(System::Drawing::Color::get_Green());
// All inline story nodes have their respective story types.
ASSERT_EQ(StoryType::Footnotes, footnote->get_StoryType());
// A comment is another type of inline story.
auto comment = System::DynamicCast<Comment>(
builder->get_CurrentParagraph()->AppendChild(MakeObject<Comment>(doc, u"John Doe", u"J. D.", System::DateTime::get_Now())));
// The parent paragraph of an inline story node will be the one from the main document body.
ASPOSE_ASSERT_EQ(doc->get_FirstSection()->get_Body()->get_FirstParagraph(), comment->get_ParentParagraph());
// However, the last paragraph is the one from the comment text contents,
// which will be outside the main document body in a speech bubble.
// A comment will not have any child nodes by default,
// so we can apply the EnsureMinimum() method to place a paragraph here as well.
ASSERT_TRUE(comment->get_LastParagraph() == nullptr);
comment->EnsureMinimum();
ASSERT_EQ(NodeType::Paragraph, comment->get_LastChild()->get_NodeType());
// Once we have a paragraph, we can move the builder to do it and write our comment.
builder->MoveTo(comment->get_LastParagraph());
builder->Write(u"My comment.");
ASSERT_EQ(StoryType::Comments, comment->get_StoryType());
doc->Save(ArtifactsDir + u"InlineStory.InsertInlineStoryNodes.docx");

Implements Aspose::Words::InlineStory.

◆ GetType()

virtual const System::TypeInfo& Aspose::Words::Comment::GetType ( ) const
overridevirtual

Reimplemented from Aspose::Words::InlineStory.

◆ Is()

virtual bool Aspose::Words::Comment::Is ( const System::TypeInfo target) const
overridevirtual

Reimplemented from Aspose::Words::InlineStory.

◆ RemoveAllReplies()

void Aspose::Words::Comment::RemoveAllReplies ( )

Removes all replies to this comment.

Examples

Shows how to remove comment replies.

auto doc = MakeObject<Document>();
auto comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"My comment.");
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->AppendChild(comment);
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"New reply");
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"Another reply");
ASSERT_EQ(2, comment->get_Replies()->LINQ_Count());
// Below are two ways of removing replies from a comment.
// 1 - Use the "RemoveReply" method to remove replies from a comment individually:
comment->RemoveReply(comment->get_Replies()->idx_get(0));
ASSERT_EQ(1, comment->get_Replies()->LINQ_Count());
// 2 - Use the "RemoveAllReplies" method to remove all replies from a comment at once:
comment->RemoveAllReplies();
ASSERT_EQ(0, comment->get_Replies()->LINQ_Count());

◆ RemoveMoveRevisions()

void Aspose::Words::Comment::RemoveMoveRevisions ( )
override

◆ RemoveReply()

void Aspose::Words::Comment::RemoveReply ( System::SharedPtr< Aspose::Words::Comment reply)

Removes the specified reply to this comment.

Parameters
replyThe comment node of the deleting reply.
Examples

Shows how to remove comment replies.

auto doc = MakeObject<Document>();
auto comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"My comment.");
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->AppendChild(comment);
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"New reply");
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"Another reply");
ASSERT_EQ(2, comment->get_Replies()->LINQ_Count());
// Below are two ways of removing replies from a comment.
// 1 - Use the "RemoveReply" method to remove replies from a comment individually:
comment->RemoveReply(comment->get_Replies()->idx_get(0));
ASSERT_EQ(1, comment->get_Replies()->LINQ_Count());
// 2 - Use the "RemoveAllReplies" method to remove all replies from a comment at once:
comment->RemoveAllReplies();
ASSERT_EQ(0, comment->get_Replies()->LINQ_Count());

◆ set_Author()

void Aspose::Words::Comment::set_Author ( System::String  value)

◆ set_DateTime()

void Aspose::Words::Comment::set_DateTime ( System::DateTime  value)

◆ set_Done()

void Aspose::Words::Comment::set_Done ( bool  value)

◆ set_Initial()

void Aspose::Words::Comment::set_Initial ( System::String  value)

◆ SetText()

void Aspose::Words::Comment::SetText ( System::String  text)

This is a convenience method that allows to easily set text of the comment.

This method allows to quickly set text of a comment from a string. The string can contain paragraph breaks, this will create paragraphs of text in the comment accordingly. If you want to insert more complex elements into the comment, for example bookmarks or tables or apply rich formatting, then you need to use the appropriate node classes to build up the comment text.

Parameters
textThe new text of the comment.
Examples

Shows how to add a comment to a document, and then reply to it.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
auto comment = MakeObject<Comment>(doc, u"John Doe", u"J.D.", System::DateTime::get_Now());
comment->SetText(u"My comment.");
// Place the comment at a node in the document's body.
// This comment will show up at the location of its paragraph,
// outside the right-side margin of the page, and with a dotted line connecting it to its paragraph.
builder->get_CurrentParagraph()->AppendChild(comment);
// Add a reply, which will show up under its parent comment.
comment->AddReply(u"Joe Bloggs", u"J.B.", System::DateTime::get_Now(), u"New reply");
// Comments and replies are both Comment nodes.
ASSERT_EQ(2, doc->GetChildNodes(NodeType::Comment, true)->get_Count());
// Comments that do not reply to other comments are "top-level". They have no ancestor comments.
ASSERT_TRUE(comment->get_Ancestor() == nullptr);
// Replies have an ancestor top-level comment.
ASPOSE_ASSERT_EQ(comment, comment->get_Replies()->idx_get(0)->get_Ancestor());
doc->Save(ArtifactsDir + u"Comment.AddCommentWithReply.docx");

◆ Type()

static const System::TypeInfo& Aspose::Words::Comment::Type ( )
static