String GlyphsSelection::GetXMLCopy() { // handle single-text case bool singleText = (firstGlyph.textNode == lastGlyph.textNode); if (singleText) { int startOffset = firstGlyph.StartOffset(); int endOffset = lastGlyph.EndOffset(); return firstGlyph.textNode->GetText()->SubstringData(startOffset, endOffset - startOffset); } // get info about the structure DisplayNode* ancestor = firstGlyph.CommonAncestorWith(lastGlyph); bool startsWithText = (firstGlyph.textNode->Parent() == ancestor); bool endsWithText = (lastGlyph.textNode->Parent() == ancestor); // find out where the first and last embedded elements are // first ElementDisplayNode* firstElementDisplayNode = NULL; if (!startsWithText) { // it's the element the first glyph is in DisplayNode* firstElementNode = firstGlyph.textNode; while (firstElementNode) { if (firstElementNode->Parent() == ancestor) break; firstElementNode = firstElementNode->Parent(); } firstElementDisplayNode = dynamic_cast<ElementDisplayNode*>(firstElementNode); } else { firstElementDisplayNode = dynamic_cast<ElementDisplayNode*>(firstGlyph.textNode->NextSibling()); } if (firstElementDisplayNode == NULL) throw InternalException("GlyphsSelection::GetXMLCopy: Couldn't find firstElementNode."); Node* firstElement = firstElementDisplayNode->GetElement(); // last ElementDisplayNode* lastElementDisplayNode = NULL; if (!endsWithText) { // it's the element the last glyph is in DisplayNode* lastElementNode = lastGlyph.textNode; while (lastElementNode) { if (lastElementNode->Parent() == ancestor) break; lastElementNode = lastElementNode->Parent(); } lastElementDisplayNode = dynamic_cast<ElementDisplayNode*>(lastElementNode); } else { lastElementDisplayNode = dynamic_cast<ElementDisplayNode*>(lastGlyph.textNode->PreviousSibling()); } if (lastElementDisplayNode == NULL) throw InternalException("GlyphsSelection::GetXMLCopy: Couldn't find lastElementNode."); Node* lastElement = lastElementDisplayNode->GetElement(); // write the selection XMLStringWriter writer(NULL); if (startsWithText) { Text* startText = firstGlyph.textNode->GetText(); int startOffset = firstGlyph.StartOffset(); String startData = startText->SubstringData(startOffset, startText->Length() - startOffset); writer.AppendString(startData); } for (Node* node = firstElement; ; node = node->NextSibling()) { writer.AppendNode(node); if (node == lastElement) break; } if (endsWithText) { Text* endText = lastGlyph.textNode->GetText(); int endOffset = lastGlyph.EndOffset(); String endData = endText->SubstringData(0, endOffset); writer.AppendString(endData); } return writer.GetString(); }