Changing font size in text element of cell [CONNECT MDL C++]

Hello guys! I have a question.

I want to do following: 

  1. Retrieve element descriptor of a given cell and duplicate it.
  2. This cell contains text elements, I want to modify their font size. 
  3. During whole process, display said element descriptor in temporary mode.

Before I was working with V8I implementation, here everything worked fine :

I iterate through said cell descriptor. Whenever I found element with type TEXT_ELM, I changed its font size.

For extraction I used:

mdlText_extract(to extract TextSize from element).
Change parameters in extracted TextSize structure.
Recreate element with new font size, using mdlText_createW(myElement,myElement,NULL,NULL,NULL,&extractedSize,NULL,NULL,modelRef)

And all worked fine. However, in CONNECT it doesn´t work as expected. I managed it to work, so it changes the font size, but styling and transform suddenly disappears, so I´ve decided to check the new way with EditElementHandle and TextBlock API.

What I tried to do was (simple test to replace existing text) : 

    ElementHandle eh(out,modelRefP); //out is my MSElement extracted from MSElementDescr iteration i talked before
    EditElementHandle eeh(out, modelRefP);


    // Check if the selection is a Text element.
    ITextQueryCP textQuery = eh.GetITextQuery();
    if (!textQuery || !textQuery->IsTextElement(eh))
        return 1;

    // Extract the TextBlock from the Text element.
    ITextPartIdPtr textPart;
    TextBlockPtr textBlock = textQuery->GetTextPart(eh, *textPart);
    if (textBlock.IsNull() || textBlock->IsEmpty())
        return 1;


    // Get the string from the Text block.
    WString str = textBlock->ToString();
    if (str.empty())
        return 1;

    RunPropertiesPtr runPropP = textBlock->GetRunPropertiesForAdd().Clone();
    
    DPoint2d fontSize = runPropP->GetFontSize();
    fontSize.x = 20;
    fontSize.y = 20;
    runPropP->SetFontSize(fontSize);
    textBlock->SetRunPropertiesForAdd(*runPropP);

    CaretPtr searchStart = textBlock->CreateStartCaret();
    CaretPtr end = textBlock->CreateEndCaret();
    textBlock->Remove(*searchStart,*end);

    EditElementHandle eeh2;
    textBlock->AppendText(L"Test");
    TextBlockToElementResult res2 = TextHandlerBase::CreateElement(eeh2, nullptr, *textBlock);

My idea was to remove and re-enter same text with different properties, because I couldn´t find a way to do it without that (maybe there is some? Remapping doesn´t involve font size) and changing the RunProperties affects only actions that happen after it is set...

And, as you maybe expected, nothing happens, the text is same. I know that you can call AddToModel (then it appears in model, but the original is still same). I also saw ReplaceInModel function, but the elements have no ElementRef yet.

I´ve tried this (with a little hope):

*out = *eeh2.getElementP();

But i got segfault during the iteration of next elements

Do you guys know how to approach something like this?

  • Stop!  Forget element descriptors — they are so 20th century.  Work with ElementHandles and EditElementHandles when writing C++ for CONNECT
    And, as Jon wrote, never use element descriptor :-)

    I know you guys would say that. As I´m working with older codebase, I´m using foundation where some methods work with descriptors. So i´m trying to make smallest changes as possible, to avoid influencing big part of the system.

    I assume there are more ways how to do it, depending whether your text is simple one or complex, but methods like GetRunPropertiesForAd and SetRunPropertiesForAd should help you.

    But what about modifying element? RunPropertiesForAdd take effect only if you for example add text to existing element, it doesn´t change the property of existing text. Or maybe I´m missing something

  • Hi Lubo,

    Changing font size in text element of cell

    in my opinion to modify text inside cell is one from the most demanding operation in CE API ;-)

    ... and e.g. in NET I was not able to find a way how to do it (there are several discussions in this forum about this topic), but I am not sure whether the problem is in native API or in the wrapper to CE.

    I recommend to split the solution into several independent steps / tests and when everything is working, to merge the code together:

    • Write code to modify any simple element (e.g. line) inside cell.
    • Write code to modify text (simple text or text node).
    • Merge this two codes together.

    And, as Jon wrote, never use element descriptor :-)

    My idea was to remove and re-enter same text with different properties, because I couldn´t find a way to do it without that

    It's not the right approach. Search for discussions targeting this topic (e.g. this recent one).

    I assume there are more ways how to do it, depending whether your text is simple one or complex, but methods like GetRunPropertiesForAd and SetRunPropertiesForAd should help you.

    Regards,

      Jan

  • Retrieve element descriptor

    Stop!  Forget element descriptors — they are so 20th century.  Work with ElementHandles and EditElementHandles when writing C++ for CONNECT.

    Those are smart pointers that encapsulate an element descriptor and manage its lifetime, so you don't have to.

    I´ve tried this (with a little hope):

    *out = *eeh2.getElementP();

    Use the ChildElemIter.

     
    Regards, Jon Summers
    LA Solutions