Navegação com Cursor

Ao trabalhar com um documento, mesmo que seja curto ou longo, você precisará navegar pelo documento. A navegação com um cursor virtual representa a capacidade de navegar entre diferentes nós num documento.

Em um documento curto, mover-se em um documento é simples, pois você pode mover o ponto de inserção mesmo usando as teclas de seta do teclado ou clicando no mouse para localizar o ponto de inserção onde quiser. Mas uma vez que você tenha um documento grande que tenha muitas páginas, essas técnicas básicas serão insuficientes.

Este artigo explica como se deslocar num documento e navegar com um cursor virtual para diferentes partes do mesmo.

Detectando A Posição Atual Do Cursor

Antes de iniciar o processo de navegação pelo seu documento, você precisará obter o nó atualmente selecionado. Pode obter a posição exacta do cursor num nó seleccionado utilizando a propriedade CurrentNode. Além disso, em vez de obter o nó atual, você pode obter o parágrafo atualmente selecionado ou a seção atualmente selecionada usando as propriedades CurrentParagraph e CurrentSection.

Todas as operações de inserção que executar utilizando o DocumentBuilder serão inseridas antes do CurrentNode. Quando o parágrafo atual está vazio ou o cursor é posicionado imediatamente antes do final do parágrafo, o CurrentNode retorna nullptr.

Métodos de navegação num documento

Quando você está editando texto, é importante saber como navegar em seu documento e para onde exatamente se mover nele. Aspose.Words permite – lhe deslocar-se num documento e navegar para as suas diferentes secções e partes-isto é semelhante à funcionalidade do Painel de navegação em Microsoft Word para ir para uma página ou título num documento do Word sem deslocar-se.

O método principal é poder mover a posição do cursor para um nó específico no seu documento, você pode conseguir isso usando o método MoveTo.

O exemplo de código a seguir mostra como mover o DocumentBuilder para diferentes nós em um documento:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Start a bookmark and add content to it using a DocumentBuilder.
builder->StartBookmark(u"MyBookmark");
builder->Writeln(u"Bookmark contents.");
builder->EndBookmark(u"MyBookmark");
// The node that the DocumentBuilder is currently at is past the boundaries of the bookmark.
ASSERT_EQ(doc->get_Range()->get_Bookmarks()->idx_get(0)->get_BookmarkEnd(), builder->get_CurrentParagraph()->get_FirstChild());
// If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this.
builder->MoveToBookmark(u"MyBookmark");
// Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it.
ASSERT_EQ(doc->get_Range()->get_Bookmarks()->idx_get(0)->get_BookmarkStart(), builder->get_CurrentParagraph()->get_FirstChild());
// We can move the builder to an individual node,
// which in this case will be the first node of the first paragraph, like this.
builder->MoveTo(doc->get_FirstSection()->get_Body()->get_FirstParagraph()->GetChildNodes(NodeType::Any, false)->idx_get(0));
ASSERT_EQ(NodeType::BookmarkStart, builder->get_CurrentNode()->get_NodeType());
ASSERT_TRUE(builder->get_IsAtStartOfParagraph());
// A shorter way of moving the very start/end of a document is with these methods.
builder->MoveToDocumentEnd();
ASSERT_TRUE(builder->get_IsAtEndOfParagraph());
builder->MoveToDocumentStart();
ASSERT_TRUE(builder->get_IsAtStartOfParagraph());

Mas, além do método básico MoveTo, existem outros mais específicos.

Pode ir para o início ou para o fim do documento utilizando os métodos MoveToDocumentStart e MoveToDocumentEnd.

O exemplo de código a seguir mostra como mover a posição do cursor para o início ou o fim de um documento:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>(inputDataDir + u"Document.docx");
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Move the cursor position to the beginning of your document.
builder->MoveToDocumentStart();
builder->Writeln(u"This is the beginning of the document.");
// Move the cursor position to the end of your document.
builder->MoveToDocumentEnd();
builder->Writeln(u"This is the end of the document.");

Você pode marcar um lugar que deseja encontrar e mover-se para ele novamente facilmente. Você pode inserir quantos marcadores desejar em seu documento e, em seguida, navegar por eles identificando os marcadores com nomes exclusivos. Pode mover-se para um marcador utilizando o método MoveToBookmark.

Os exemplos de código a seguir mostram como mover uma posição do cursor para um marcador:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Start a bookmark and add content to it using a DocumentBuilder.
builder->StartBookmark(u"MyBookmark");
builder->Writeln(u"Bookmark contents.");
builder->EndBookmark(u"MyBookmark");
// If we wish to revise the content of our bookmark with the DocumentBuilder, we can move back to it like this.
builder->MoveToBookmark(u"MyBookmark");
// Now we're located between the bookmark's BookmarkStart and BookmarkEnd nodes, so any text the builder adds will be within it.
ASSERT_EQ(doc->get_Range()->get_Bookmarks()->idx_get(0)->get_BookmarkStart(), builder->get_CurrentParagraph()->get_FirstChild());
// We can move the builder to an individual node,
// which in this case will be the first node of the first paragraph, like this.
builder->MoveTo(doc->get_FirstSection()->get_Body()->get_FirstParagraph()->GetChildNodes(NodeType::Any, false)->idx_get(0));
ASSERT_EQ(NodeType::BookmarkStart, builder->get_CurrentNode()->get_NodeType());

Você pode mover para uma célula da tabela usando o método MoveToCell. Este método permite-lhe navegar o cursor para qualquer célula de uma tabela específica. Além disso, você pode especificar um índice para mover o cursor para qualquer posição ou caractere especificado em uma célula dentro do método MoveToCell.

O exemplo de código a seguir mostra como mover uma posição do cursor para uma célula de tabela especificada:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>(inputDataDir + u"Tables.docx");
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Move the builder to row 3, cell 4 of the first table.
builder->MoveToCell(0, 2, 3, 0);
builder->Write(u"\nCell contents added by DocumentBuilder");
auto table = System::DynamicCast<Tables::Table>(doc->GetChild(NodeType::Table, 0, true));
ASSERT_EQ(table->get_Rows()->idx_get(2)->get_Cells()->idx_get(3), builder->get_CurrentNode()->get_ParentNode()->get_ParentNode());
ASSERT_EQ(table->get_Rows()->idx_get(2)->get_Cells()->idx_get(2)->GetText().Trim(), u"Cell contents added by DocumentBuilderCell 3 contents\a");

Pode mover - se para um campo específico no documento utilizando o método MoveToField. Além disso, você pode mover para um campo de mesclagem específico usando o método MoveToMergeField.

O exemplo de código a seguir mostra como mover o cursor do construtor de documentos para um campo específico:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Insert a field using the DocumentBuilder and add a run of text after it.
auto field = builder->InsertField(u"MERGEFIELD field");
builder->Write(u" Text after the field.");
// The builder's cursor is currently at end of the document.
ASSERT_EQ(builder->get_CurrentNode(), nullptr);
// We can move the builder to a field like this, placing the cursor at immediately after the field.
builder->MoveToField(field, true);
// Note that the cursor is at a place past the FieldEnd node of the field, meaning that we are not actually inside the field.
// If we wish to move the DocumentBuilder to inside a field,
// we will need to move it to a field's FieldStart or FieldSeparator node using the DocumentBuilder.MoveTo() method.
ASSERT_EQ(field->get_End(), builder->get_CurrentNode()->get_PreviousSibling());
builder->Write(u" Text immediately after the field.");

Pode mover-se para o início de um cabeçalho ou rodapé utilizando o método MoveToHeaderFooter.

O exemplo de código a seguir mostra como mover o cursor do construtor de documentos para um cabeçalho ou rodapé de Documento:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Specify that we want headers and footers different for first, even and odd pages.
builder->get_PageSetup()->set_DifferentFirstPageHeaderFooter(true);
builder->get_PageSetup()->set_OddAndEvenPagesHeaderFooter(true);
// Create the headers.
builder->MoveToHeaderFooter(HeaderFooterType::HeaderFirst);
builder->Write(u"Header for the first page");
builder->MoveToHeaderFooter(HeaderFooterType::HeaderEven);
builder->Write(u"Header for even pages");
builder->MoveToHeaderFooter(HeaderFooterType::HeaderPrimary);
builder->Write(u"Header for all other pages");
// Create two pages in the document.
builder->MoveToSection(0);
builder->Writeln(u"Page1");
builder->InsertBreak(BreakType::PageBreak);
builder->Writeln(u"Page2");
System::String outputPath = outputDataDir + u"DocumentBuilderMovingCursor.HeadersAndFooters.doc";
doc->Save(outputPath);

Pode mover-se para uma secção ou parágrafo específico utilizando os métodos MoveToParagraph ou MoveToSection. Além disso, você pode especificar um índice para mover o cursor para qualquer posição ou um caractere especificado em um parágrafo dentro do método MoveToParagraph.

O exemplo de código a seguir mostra como mover para uma seção específica e um parágrafo específico em um documento:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Create a blank document and append a section to it, giving it two sections.
auto doc = System::MakeObject<Document>();
doc->AppendChild(System::MakeObject<Section>(doc));
// Move a DocumentBuilder to the second section and add text.
auto builder = System::MakeObject<DocumentBuilder>(doc);
builder->MoveToSection(1);
builder->Writeln(u"Text added to the 2nd section.");
// Create document with paragraphs.
auto doc = System::MakeObject<Document>(inputDataDir + u"Paragraphs.docx");
auto paragraphs = doc->get_FirstSection()->get_Body()->get_Paragraphs();
ASSERT_EQ(paragraphs->get_Count(), 22);
// When we create a DocumentBuilder for a document, its cursor is at the very beginning of the document by default,
// and any content added by the DocumentBuilder will just be prepended to the document.
auto builder = System::MakeObject<DocumentBuilder>(doc);
ASSERT_EQ(paragraphs->IndexOf(builder->get_CurrentParagraph()), 0);
// You can move the cursor to any position in a paragraph.
builder->MoveToParagraph(0, 14);
ASSERT_EQ(paragraphs->IndexOf(builder->get_CurrentParagraph()), 2);
builder->Writeln(u"This is a new third paragraph. ");
ASSERT_EQ(paragraphs->IndexOf(builder->get_CurrentParagraph()), 3);