ダイアログの部品の一つにImageControlがある。ダイアログに複数の画像を表示する機能を持ったコントロールである。いろんな使い道がありそうであるがここでは多数のクリップアートを表示する一種のカタログを作ってみることにする。
上図のようにCalcのシート上にクリップアートのタイトルと画像ファイルへのpathが書かれたものがあるとする。マクロではこのシート上のデータを読み込んでダイアログ上にこれらのクリップアートが閲覧できる一種のカタログを作る。
ImageControlの詳細はここにある。特に重要な属性は
- ImageURL:イメージデータのある場所をURL形式で指定する。
- ScaleMode:ダイアログ上の決められた枠にどのように画像を表示するかを指定する。この値が2であると兎に角画像をこの枠に納めて表示する(ANISOTROPIC)。この値が1であると画像のアスペクト比を保持して表示する(ISOTROPIC)。
ファイルpathのURL形式への変換(またはその逆)はPythonでは以下のunoモジュールが使える:
path = "/home/foo/Documents/file.odt"
url = uno.systemPathToFileUrl(path)
path = uno.fileUrlToSystemPath(url)
カタログはダイアログ画面に納まらないので垂直スクロールの機能を付ける。
【実行画面】
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.awt import XAdjustmentListener
#「スクロールバー」の処理
class MyAdjustmentListener(unohelper.Base, XAdjustmentListener):
def __init__(self, dlgHgt, catHgt, labs, imcs):
self.labs = labs
self.imcs = imcs
self.scrollVMax=100
self.dlgHgt=dlgHgt
self.catHgt=catHgt
self.labsPositionY0 = []
self.imcsPositionY0 = []
for i, lab in enumerate(labs):
print(lab.PositionY, imcs[i].PositionY)
self.labsPositionY0.append(lab.PositionY)
self.imcsPositionY0.append(imcs[i].PositionY)
def adjustmentValueChanged(self, event):
ratio = event.Value/self.scrollVMax
print(ratio)
for i,lab in enumerate(self.labs):
lab.PositionY = self.labsPositionY0[i]-(self.catHgt - self.dlgHgt)*ratio
self.imcs[i].PositionY = self.imcsPositionY0[i]-(self.catHgt - self.dlgHgt)*ratio
#print(event.Type)
#print(event.Value)
def python_macro_clipart(*arg):
#
#シート
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#データのある行数を調べる
sRange = sheet.getCellRangeByName("A1")
sCursor=sheet.createCursorByRange(sRange)
sCursor.collapseToCurrentRegion()
MaxDataRow = sCursor.Rows.Count-1
ui.Print(MaxDataRow)
items=[]
filePaths=[]
for i in range(MaxDataRow):
item = sheet.getCellByPosition(0, i+1 ).String
filePath = sheet.getCellByPosition(1, i+1 ).String
#ui.Print(item)
#ui.Print(filePath)
items.append(item)
filePaths.append(filePath)
#
#ダイアログ
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dialogM = smgr.createInstance('com.sun.star.awt.UnoControlDialogModel')
# Size of DialogM
dlgWth = 150
dlgHgt = 200
dialogM.Width = dlgWth
dialogM.Height = dlgHgt
dialogM.Title = "クリップアート・カタログ"
#
#コントロールの作成・登録
tabIndex = 0
#スクロールバー
scb1 = dialogM.createInstance('com.sun.star.awt.UnoControlScrollBarModel')
tabIndex += 1
scrollVMin=0
scrollVMax=100
scb1.Name = 'ScrollBar'
scb1.TabIndex = tabIndex
scb1.PositionX = dlgWth-10
scb1.PositionY = 0
scb1.Width = 10
scb1.Height = dlgHgt
scb1.Orientation=1
scb1.ScrollValueMin = scrollVMin
scb1.ScrollValueMax = scrollVMax
scb1.LiveScroll= 1
dialogM.insertByName('ScrollBar', scb1)
#タイトル・画像の登録
imageX = 100
imageY = int(imageX*3/4)
labs=[]
imcs=[]
for i in range(MaxDataRow):
#タイトル
lab2 = dialogM.createInstance('com.sun.star.awt.UnoControlFixedTextModel')
labY=10+(imageY+10+10)*i
tabIndex += 1
lab2.Name = items[i]
lab2.TabIndex = tabIndex
lab2.PositionX =10
lab2.PositionY =labY
lab2.Width = dlgWth - 10
lab2.Height = 10
lab2.Label = items[i]
lab2.Align = 0 # 0 : Left / 1 : Center / 2 : Right
lab2.Border = 0
dialogM.insertByName(items[i], lab2)
labs.append(lab2)
#画像
imc2 = dialogM.createInstance('com.sun.star.awt.UnoControlImageControlModel')
imcY = labY+10
tabIndex += 1
imc2.Name = items[i]
imc2.TabIndex = tabIndex
imc2.PositionX = 10
imc2.PositionY = imcY
imc2.Width = imageX
imc2.Height = imageY
imc2.ImageURL = uno.systemPathToFileUrl(filePaths[i])
imc2.ScaleMode = 1
dialogM.insertByName(items[i]+'image', imc2)
imcs.append(imc2)
#最終的なチェックボックス表の高さ
catHgt=imcY + (imageY + 10)
# Create the dialog and set the model
#ダイアログの生成とモデルの登録
dialog = smgr.createInstance('com.sun.star.awt.UnoControlDialog')
dialog.setModel(dialogM)
#コントロールの登録
cmdScb1 = dialog.getControl('ScrollBar')
#エヴェント監視(スクロールバー)
scb1_listener = MyAdjustmentListener(dlgHgt, catHgt, labs, imcs)
cmdScb1.addAdjustmentListener(scb1_listener)
#
#窓の生成そしてこの窓をダイアログ画面として使う
window = smgr.createInstance('com.sun.star.awt.Toolkit')
dialog.createPeer(window,None) # None : OK / none : NG
#
dialog.execute()
dialog.dispose()