Hello guys! I have a question.
I want to do following:
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?
Hi Lubo,
Lubo B said: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:
And, as Jon wrote, never use element descriptor :-)
Lubo B said: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
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Jon Summers said:Stop! Forget element descriptors — they are so 20th century. Work with ElementHandles and EditElementHandles when writing C++ for CONNECT
ElementHandle
EditElementHandle
Jan Ĺ legr said: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.
Jan Ĺ legr said: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
Lubo B said:But what about modifying element?
Many functions that create an element take a template as an argument. The template is an existing element. For example...
ElementHandle existingText = // get text element EditElementHandle replacementText; if (TEXTBLOCK_TO_ELEMENT_RESULT_Success == TextHandlerBase::CreateElement(replacementText, existingText, textBlock)) { // do something with replacementText // existingText provides an elementRef when replacing the text element }
Regards, Jon Summers LA Solutions