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.

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.

I also have this problem

For a thesis, I put all my ‘figure’ captions at the top, but when it reviewed was told they need to be at the bottom.

The only way I’ve found to achieve this is to delete each figure+caption and recreate it.

A means of changing the vertical position in an existing text box would be most welcome. I note that you can already change the horizontal position with the familier Ctrl-l, Ctrl-r etc.

Tough it may work for you, this is not the correct way to do it. First, you must operate on each “target” individually. Second, this is **direct formatting resulting in more later problems.


Fix for you request depends on how you created the captions.

It is likely hat you Insert>Caption which triggers a set of macros which generate the final text, i.e. a frame containing caption text itself and picture. Though I found it convenient in the beginning, this one-size-fits-all automatic procedure leads to several difficulties, like the one you complain about (changing he order of caption vs. picture). Fixing it is quite tricky because of nested frames. It is simpler if frames are not nested (the picture frame inside the caption frame). This is why I now prefer to create manually my captions (with the same auto-numbering but without the extra frame).

The outer (caption) frame is styled Frame while the inner (picture) frame is styled Graphics. What you must do is to change the vertical Position parameter of Graphics from Top to Bottom (I know, this looks inverted but this is how to do it). However, frame style don’t behave as smoothly as the other styles. So you may have to apply temporarily a different style on the frame you selected to work with and reapply Graphics to see the change. Tools>Update>Update All may also be necessary. Also, if your caption frames are not correctly configured, the image frame may escape from the caption frame.

Unfortunately, from the wording of your question (use of CtrlL …), I fear you aren’t familiar at all with styles, even less frame styles, and your document is entirely direct formatted. In which case, fixing your issue is hopelessly manual.

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  

Exampleask299774relativeMoveCaptions.odt:

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

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.

Answering myself

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