We will be migrating from Ask to Discourse on the first week of August, read the details here

# Change position of existing figure caption

I have documents with hundreds of images and the captions are below the images.

• The images are anchored "as character" and the holding paragraph has style AAAA.
• The caption has style Caption
• The wrapping frame is also anchored as character. (no other contents inside the frame besides the caption and the image)

I need to put the caption on top of the existing image in the frame.

A small macro that acts on a selected image and swap position with the caption is welcome.

edit retag close merge delete

Thanks for the very clear description of the situation.
Less clear it is to me for what reason and in what way you got into this situation.
You surely know that you can insert an image's caption Below or Above.However, this isn't a setting you can change later. It only modiies the process of insertion.
I may assume the document was created by somebody else, and you want to harmonize the captioning your way.

( 2021-03-21 16:35:59 +0200 )edit

Sort by » oldest newest most voted

Code:

Sub putCaptionAboveCharAnchoredObject() REM VERY special, VERY raw!
REM You can use this for a single selected caption frame.
REM. The frame itself must be selected!
doc = ThisComponent
cCtrl = doc.CurrentController
frame = cCtrl.Selection
text = frame.Text
tc = text.createTextCursorByRange(text.Start)
tc.goRight(1, True)
cCtrl.select(tc)
testSel = doc.CurrentSelection(0)
If Len(testSel.String)=0 Then REM Strange but useful:
REM Is there an object selected which is anchored 'As Character'?
trans = cCtrl.getTransferable()
tc.String = ""
cCtrl.select(Text.End)
cCtrl.insertTransferable(trans)
End If
cCtrl.select(frame)
End Sub

Sub moveCaptionAboveAllObjectsAnchoredAsFirstCharacterInFrame()
REM The Sub doesn't test if there is a caption TextField. It simply takes the text below.
doc = ThisComponent
cCtrl = doc.CurrentController
uMgr = doc.UndoManager
sel = doc.CurrentSelection
textFrames = doc.TextFrames
uTF = textFrames.Count - 1
uMgr.EnterUndoContext("Put Captions Above")
For j = 0 To uTF
j_tf = textFrames(j)
cCtrl.select(j_tf)
putCaptionAboveCharAnchoredObject()
Next j
uMgr.LeaveUndoContext()
cCtrl.select(sel)
End Sub

more

Thanks for the code. I will use pieces of it while traversing the TextFrame collection of the document.

( 2021-04-07 22:27:13 +0200 )edit

The difficulty comes from the As character anchor of the outer frame. But let's take things in order.

Insert>Caption creates a frame around the images. This outer frames takes anchoring and type properties from the image, i.e. it is anchored As character so that there is no change in formatting. Inside the frame, the image becomes anchored to the caption paragraph in To paragraph mode.

This would suggest that playing with Position properties in Type could move the image below the paragraph caption. Indeed it does, but there is no way to set wrapping so that it does not interfere with text surrounding the outer frame. This is probably because wrapping in taken into account only within the outer frame. Since the outer frame is As character, it behaves like a huge character. I bet that for simplicity the layout engine considers only the (outer) frame rectangle to compute text flow, ignoring out of frame elements (which logically makes sense) unless Allow overlap is unchecked.

To avoid this, I usually anchor my images To Paragraph (unless there is a good reason to consider them as big characters, in which case I have no caption).

While experimenting, I could not find a way to shift the caption through style modification. Every attempt resulted in the situation becoming worse and worse.

I am afraid that you can't but reinsert your image and selecting Insert>Caption with Position Start instead of End. To avoid future issues, take care to anchor your images To paragraph. This will make your images more independent from the text and will allow to position them easily through styles.

To show the community your question has been answered, click the ✓ next to the correct answer, and "upvote" by clicking on the ^ arrow of any helpful answers. These are the mechanisms for communicating the quality of the Q&A on this site. Thanks!

In case you need clarification, edit your question (not an answer which is reserved for solutions) or comment the relevant answer.

more

Sub SwapCaption
vCursor = Thiscomponent.CurrentController.getViewCursor()
oGrafEnum = ThisComponent.GraphicObjects.createEnumeration()
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Do While oGrafEnum.hasMoreElements()
oGraf = oGrafEnum.nextElement()
vCursor.gotoRange(oGraf.Anchor.Start,false)
rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:MoveDown", "", 0, Array())
Loop
End Sub

more