Bug 106984 - Searching the CharEscapement attribute does not work from macro
Summary: Searching the CharEscapement attribute does not work from macro
Status: NEW
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Writer (show other bugs)
Version:
(earliest affected)
Inherited From OOo
Hardware: All All
: medium minor
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: Macro-UNOAPI
  Show dependency treegraph
 
Reported: 2017-04-06 07:17 UTC by Butch
Modified: 2021-11-29 10:06 UTC (History)
1 user (show)

See Also:
Crash report or crash signature:
Regression By:


Attachments
Document demonstrating the bug, macro embedded (12.87 KB, application/vnd.oasis.opendocument.text)
2017-04-06 07:17 UTC, Butch
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Butch 2017-04-06 07:17:17 UTC
Created attachment 132363 [details]
Document demonstrating the bug, macro embedded

See the attached document:

"Here is a x in superscript.

This superscript is implemented by writing x, selecting it and applying the superscript button from the toolbar.

According to Format > Character > Position: x is raised by 33% (Automatic).

The embedded macro ReplaceFormatting should replace superscript by normal text
by searching:
SrchAttributes(0).Name = "CharEscapement"
SrchAttributes(0).Value = 33

But it does nothing!

Is this an ancient bug??? See https://bz.apache.org/ooo/show_bug.cgi?id=31212"
Comment 1 Butch 2017-04-06 07:29:51 UTC
Note: 
Searching for value 0 (normal text) works perfectly!
All normal text is identified, superscript is exculded.
Comment 2 Butch 2017-04-06 11:31:34 UTC
Note:
If superscript is defined explicitely by Position 
Raise by: 33% (not automatic)
Relative font size: 58%
(which seems to be the default for superscript)
it is NOT FOUND.
But if defined by
Raise by: 33% (not automatic)
Relative font size: 100%
it is FOUND!!!
Comment 3 Buovjaga 2017-04-23 14:14:13 UTC
Reproduced.

Arch Linux 64-bit, KDE Plasma 5
Version: 5.4.0.0.alpha0+
Build ID: d69e6321fbb2c9f5b4d30890074a230ee6b39d2d
CPU threads: 8; OS: Linux 4.10; UI render: default; VCL: kde4; 
Locale: fi-FI (fi_FI.UTF-8); Calc: group
Built on April 17th 2016
Comment 4 QA Administrators 2018-04-24 02:33:12 UTC Comment hidden (obsolete)
Comment 5 Buovjaga 2019-08-11 11:54:29 UTC
Still repro with file

Arch Linux 64-bit
Version: 6.4.0.0.alpha0+
Build ID: 37fc9f51a8de11d40632e8cda17ccf1fa4b1f503
CPU threads: 8; OS: Linux 5.2; UI render: default; VCL: gtk3; 
Locale: fi-FI (fi_FI.UTF-8); UI-Language: en-US
Calc: threaded
Built on 6 August 2019
Comment 6 Andreas Heinisch 2019-12-30 10:56:41 UTC
I investigate the issue and I need an advice how LO should behave in this case:

If you search for:
SrchAttributes(0).Name  = "CharEscapement"
SrchAttributes(0).Value = 33

LO searches for CharEscapement 33% and for the default value on CharEscapementHeight, which is 100% and therefore it does not find the superscript attribute which is CharEscapement 33% and CharEscapementHeight 58%.

However, if you search for:

Dim SrchAttributes(1) as new com.sun.star.beans.PropertyValue
SrchAttributes(0).Name  = "CharEscapement"
SrchAttributes(0).Value = 33
SrchAttributes(1).Name  = "CharEscapementHeight"
SrchAttributes(1).Value = 58

Everything works fine.

The whole script looks like:
REM  *****  BASIC  *****

Sub Main

End Sub


Sub ReplaceFormatting()
  Dim oDocument As Object
  Dim oReplace As Object
  Dim SrchAttributes(1) as new com.sun.star.beans.PropertyValue
  Dim ReplAttributes(0) as new com.sun.star.beans.PropertyValue

  oDocument = ThisComponent
  oReplace = oDocument.createReplaceDescriptor
   
  oReplace.SearchString = ".*"
  oReplace.ReplaceString = "<sup>&</sup>"
  oReplace.SearchRegularExpression=True
  oReplace.searchStyles=True
  oReplace.searchAll=True

  REM This is the attribute to find
  SrchAttributes(0).Name  = "CharEscapement"
  SrchAttributes(0).Value = 33
  SrchAttributes(1).Name  = "CharEscapementHeight"
  SrchAttributes(1).Value = 58
  
  REM This is the attribute to replace it with
  ReplAttributes(0).Name  = "CharEscapement"
  ReplAttributes(0).Value = 0

  oReplace.SetSearchAttributes(SrchAttributes())
  oReplace.SetReplaceAttributes(ReplAttributes())

  oDocument.replaceAll(oReplace)
End Sub
Comment 7 Buovjaga 2020-02-13 10:55:39 UTC
Andreas asked for opinions in the QA chat, I will include the messages, so we can refer to them:

If you search for superscripts the LO searches for CharEscapement AND CharEscapementHeight

But if you only define one attribute, in this case CharEscapement, then the other property is set to its default value

So there are two options for a fix: either you specify always both properties or you search for just the one set
Comment 8 Michael Stahl (allotropia) 2020-02-13 11:53:42 UTC
the problem is that there is one item SvxEscapementItem for both CharEscapement and CharEscapementHeight and the search looks for an equal item so it's not obvious how to fix this because the SvxEscapementItem always compares 2 properties...
Comment 9 Andreas Heinisch 2020-02-13 12:14:47 UTC
There could be some check, that if the Item is not explicitly set, it receives a NULL or an empty value.
Comment 10 Mike Kaganski 2020-02-13 13:35:17 UTC
There are a lot of user-visible properties in LO that don't map to a single SfxPoolItem object. E.g., both CharEscapement and CharEscapementHeight are two fields of SvxEscapementItem. So when you set one, you always get (some default) value for another in the itemset that will be used in matching - see SwSearchProperties_Impl::FillItemSet. Then these items will be compared directly for equality to corresponding items of text. For those properties that happen to map to a single item, the equality is the correct check; those text runs that happen to have searched items with all other fields default, will also get found (accidentally); bit for those which have non-default values for fields that are not in search, the lookup will fail.

I suppose that you either might try to introduce special "doesn't matter" values for such item fields, and set it when preparing search items, then modify operator == to ignore left object's field if right object's corresponding field has "doesn't matter" value; or introduce e.g. a child class of SvxEscapementItem with an own equality operator taking into account which fields were actually set.