1

How can I get xTextFields from .odt document properly?

I tried something like that, but it doesn't work (Any returns a nullptr address):

Reference <XTextFieldsSupplier> xTextFieldsSupplier (xTextDoc, UNO_QUERY);
if (!xTextFieldsSupplier.is())
    return { };

Reference<XNameAccess> xTextFieldsInfo = xTextFieldsSupplier->getTextFieldMasters();
if (!xTextFieldsInfo.is())
    return { };

Sequence<OUString> xTextFieldsNames = xTextFieldsInfo->getElementNames();

Any any;
for (::rtl::OUString* field = xTextFieldsNames.begin();
        field != xTextFieldsNames.end();
        field++) {
    std::stringstream field_string;
    field_string << *field;
    QString fieldName = QString::fromStdString(field_string.str());
    any = xTextFieldsInfo->getByName(*field);

    Reference< XTextField > xField(any, UNO_QUERY);

    // other code to work with xField
}

UPD:

I got a solution that helped me here: Libreoffice API (UNO): need to change user's xTextField text

dkezling
  • 27
  • 6

1 Answers1

1

XTextFieldsSupplier has two methods, and it looks like you chose the wrong one. The method to get text fields is getTextFields().

Example code:

Reference< XEnumerationAccess > xFieldsEnumAccess = xTextFieldsSupplier->getTextFields();
Reference< XEnumeration > xFieldsEnum = xFieldsEnumAccess->createEnumeration();
Reference< XTextRange > xTextRange;
while ( xFieldsEnum->hasMoreElements() )
{
    Any aNextElement = xFieldsEnum->nextElement();
    Reference< XTextField > xField(aNextElement, UNO_QUERY);
    OUString presentation = xField->getPresentation(true);
    xTextRange = xText->getEnd();
    xTextRange->setString(presentation + OUString::createFromAscii("\n"));
}

If you want to deal with text field masters instead, then your code is mostly correct.

Any aFieldMaster;
aFieldMaster = xNamedFieldMasters->getByName(*field);

EDIT:

Here is where xText comes from.

Reference < XTextDocument > xTextDocument (xComponent,UNO_QUERY);
Reference< XText > xText = xTextDocument->getText();

EDIT 2:

Here is an example of changing a text field. Start with a new Writer document and go to Insert -> Field -> More Fields. Under the Functions tab, double-click Input Field. Enter "hello" in the text box area and press OK.

Then, run the following code.

Reference< XServiceInfo > xInfo (xField, UNO_QUERY);
OUString sContent;
if (xInfo->supportsService("com.sun.star.text.TextField.Input"))
{
    Reference< XPropertySet > xProps (xField, UNO_QUERY);
    Any aContent = xProps->getPropertyValue(OUString::createFromAscii("Content"));
    aContent >>= sContent;
    sContent += OUString::createFromAscii(" there");
    aContent <<= sContent;
    xProps->setPropertyValue(OUString::createFromAscii("Content"), aContent);
    Reference< XRefreshable > xRefreshable (xFieldsEnumAccess, UNO_QUERY);
    xRefreshable->refresh();
}

Now, the field contains "hello there".

For more information, please review Andrew's Macro Document section 5.18 User Fields.

Jim K
  • 12,824
  • 2
  • 22
  • 51
  • seems right, thanks. but what does xText variable stands for? where do you get it? – dkezling Jun 23 '20 at 18:20
  • I still don't get how could I change the text in the xTextField. Is there any way to do it? – dkezling Jul 06 '20 at 11:55
  • @dkezling: See edited answer. If this still doesn't help, then you may need to ask a new question, with a link to this one. Be specific about what is needed. – Jim K Jul 06 '20 at 18:53
  • I created new topic there https://stackoverflow.com/questions/62769483/libreoffice-api-uno-need-to-change-users-xtextfield-text with a same question – dkezling Jul 07 '20 at 09:56