LibreOfficeDrawのレイヤー並べ替えをマクロ化

ロゲイン地図作成にLibreOfficeDrawを使ってきて、ブログでも紹介しているのですが、このソフトのレイヤーって、とても中途半端です。

レイヤーがあるのなら、描く順番がどうだろうと、最前面のレイヤーに描いたら最前面に表示して欲しいと思います。しかし、このソフトは、レイヤーといっても、それ自身の属性として前後関係の表示順を持っていません。例外的に、コントロールというレイヤーが必ず最前面に表示されます。

地図作成の時は、より右にあるレイヤーがより前面にある事を想定して描き、そのように「変更メニュー」の操作で並べ替えるのですが、これがなんとも面倒くさい。

そこで今回なんとかマクロ化したので、メモを書いておきます。

LibreOffice のマクロは数種類の言語から使えるのですが、Basicから使う以外の時は、Javaのインストールが必須なので、自分はともかく公開するにはあまり適してないのが判りました。そこで、言語としてはBasicを採用。

Basicなんて殆ど実使用経験ありません。まあ、昔々のパソコンやプログラマブル電卓で使ったくらい、会社の社内講座で先生役したこともあるにはあるのですけどね。

Basicから、どう LibreOffice の機能を呼び出すかですが、LibreOffice のサイトを探しても非常に少なく、そこからのリンク先は、OpenOffice.org のサイトになっています。LibreOffice は OpenOffice.org から分かれたのですがマクロ関係は OpenOffice.org が相変わらず参考になるというのが判りました。

主に参考にしたのは以下の2サイトです。
http://hermione.s41.xrea.com/pukiwiki/
https://ja.wikibooks.org/wiki/OpenOffice.org_Basic


Sub Main
Dim oDoc As Object, oController As Object, oFrame As Object
Dim oLayerManager As Object
Dim aEmptyArr()
Dim oDispatch As Object
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  oFrame = oController.getFrame()
  oLayerManager = oDoc.getLayerManager()
  sLayerNames = oLayerManager.getElementNames()
Dim vIsLocked(UBound(sLayerNames)) As Boolean , vIsVisible(UBound(sLayerNames)) As Boolean

For i = 0 To UBound(sLayerNames) Step 1
  sLayerName = sLayerNames(i)
  If ((sLayerName = "layout") or (sLayerName = "background") or (sLayerName = "backgroundobjects") or (sLayerName = "controls") or (sLayerName = "measurelines")) Then
  Else
    oLayer = oLayerManager.getByName(sLayerName)
    vIsVisible(i) = oLayer.IsVisible
    vIsLocked(i) = oLayer.IsLocked
    oLayer.IsVisible = True
    oLayer.IsLocked = True
    'MsgBox sLayerName & " / " & oLayer.IsLocked
  End If
Next

For i = 0 To UBound(sLayerNames) Step 1
  sLayerName = sLayerNames(i)
  If ((sLayerName = "layout") or (sLayerName = "background") or (sLayerName = "backgroundobjects") or (sLayerName = "controls") or (sLayerName = "measurelines")) Then
  Else
    oLayer = oLayerManager.getByName(sLayerName)
    oLayer.IsLocked = False
    'MsgBox sLayerName & " / " & oLayer.IsLocked
    oDispatch = createUnoService("com.sun.star.frame.DispatchHelper")
    With oDispatch
      .executeDispatch(oFrame, ".uno:SelectAll", "", 0, aEmptyArr() )
      .executeDispatch(oFrame, ".uno:BringToFront", "", 0, aEmptyArr() )
    End With
    oLayer.IsLocked = True
  End If
Next

For i = 0 To UBound(sLayerNames) Step 1
  sLayerName = sLayerNames(i)
  If ((sLayerName = "layout") or (sLayerName = "background") or (sLayerName = "backgroundobjects") or (sLayerName = "controls") or (sLayerName = "measurelines")) Then
  Else
    oLayer = oLayerManager.getByName(sLayerName)
    oLayer.IsVisible = vIsVisible(i)
    oLayer.IsLocked = vIsLocked(i)
    'MsgBox sLayerName & " / " & oLayer.IsLocked
  End If
Next

End Sub

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です