利便性が高いとディジタル化が叫ばれている。
ディジタル化で失われるものもある。それが多様性だ。
ものごとのディジタル化に際して規格化がされる。規格化は篩いにかけることである。篩いの目が粗いと篩いに残ったものは質が均質で扱いやすくディジタルシステムの利便性は大きくなる。しかし篩いの目からこぼれてしまったものも多い。これがものごとの多様性を担っている部分である。
利便性だけを追い求めるとますます多様性が失われる。
利便性が高いとディジタル化が叫ばれている。
ディジタル化で失われるものもある。それが多様性だ。
ものごとのディジタル化に際して規格化がされる。規格化は篩いにかけることである。篩いの目が粗いと篩いに残ったものは質が均質で扱いやすくディジタルシステムの利便性は大きくなる。しかし篩いの目からこぼれてしまったものも多い。これがものごとの多様性を担っている部分である。
利便性だけを追い求めるとますます多様性が失われる。
熟旨(じゅくうま)と曙光(しょこう)も台所にあった食品に付けられていた商標である。
熟旨にはかなが振ってあって「じゅくうま」と読ませる。曙光は「しょこう」とかなが振ってある。
曙光(しょこう)が音だけで読ませるのに対して、「熟旨(じゅくうま)は最初の漢字は音で、二番目は訓で読ませる。じゅくうま」はいわゆる重箱読みである。熟旨は音だけで読むと「じゅくし」となる。こちらの方が美味しそうかな。
このシリーズの最終回である。
LibreOfficeのユーザインタフェースとしてダイアログとフォームがある。
「日付フィールドに日付を入力して<Enter>キーを入力するとその日付の年・月・日がシートに代入される」
これをCalcの画面に付けたフォームで行うときのマクロは以下のようになる(これは日付フィールドのイヴェント表の中の「キーを押したとき」のイヴェント処理である):
#coding: utf-8
import uno
import screen_io as ui
row=0
doc = XSCRIPTCONTEXT.getDocument()
ctrl =doc.getCurrentController()
sheet = doc.Sheets[0]
form = sheet.DrawPage.Forms[0]
datef1 = form['datefield1']
def keyPressed_macro(event):
global row
k = event.KeyCode
c = event.KeyChar.value
mods = event.Modifiers
# mods are additive
# 0 - None
# 1 - Shift
# 2 - Ctrl
# 4 - Alt
# 8 - Super_R
print(k, c, mods)
if k == 1280: #Enterキー
#print(datef1.IsDate)
year = datef1.Date.Year
month = datef1.Date.Month
day = datef1.Date.Day
#表への書き出し
row+=1
print(row)
print(year, month, day)
sheet.getCellByPosition(0,row).Value=year
sheet.getCellByPosition(1,row).Value=month
sheet.getCellByPosition(2,row).Value=day
return
実行画面
同じことをダイアログで行う例はここにある。
【まとめ】
セル上でマウスをダブルクリックする前回のイヴェントの作例ではマウスのイベントの監視はLibreOffice側で行うようになっていた。今回はそこの部分もマクロで行うようにした。
マウスのボタンが押された・放されたというイヴェントは親クラスXMouseClickHandlerを使う。このクラスにはmousePressedとmouseReleasedメソッドが定義されているのでこれを再定義して使う。
作例の意図は「セル上でマウスの左ボタンをダブルクリックするとそのセルの背景色は赤になる」である。
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XMouseClickHandler
from com.sun.star.awt import MouseButton
class MouseClickHandler(unohelper.Base, XMouseClickHandler):
def __init__(self, subj, doc, sheet):
self.subj = subj
self.args = doc, sheet
def mousePressed(self, mouseevent):
doc, sheet = self.args
if mouseevent.Buttons==MouseButton.LEFT:
if mouseevent.ClickCount==2: #
target = doc.getCurrentSelection()
if target.supportsService("com.sun.star.sheet.SheetCell"):
address = target.getCellAddress()
Row = address.Row
Column = address.Column
#msg = str(Row) + ' ' + str(Column)
#ui.Print(msg)
cell = sheet.getCellByPosition(Column, Row)
cell.CellBackColor = 0xff0000
return False
def mouseReleased(self, mouseevent):
return False
def createDialog():
#ダイアログの登録
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
#シートの登録
doc = XSCRIPTCONTEXT.getDocument()
ctrl = doc.getCurrentController()
sheet = doc.Sheets[0]
#エヴェント監視
mouseclickhandler = MouseClickHandler(ctrl, doc, sheet)
ctrl.addMouseClickHandler(mouseclickhandler) # EnhancedMouseClickHandler
「左マウスのダブルクリックか」や「マウスがセル上にあるか」の判定は再定義したmousePressedメソッドの先頭で行っている。このマクロはCalcが起動しシート画面が出た時点で起動できる(プルダウンメニュ「ツール」->「カスタマイズ」と行き、イヴェント一覧から「文書を開いたとき」を選び当該マクロとを繋ぐ)。
なお、この作例を作るにあたってはここが参考になった。
LibreOfficeのCalcのシートで発生するイヴェントには様々なものがあるが、ここではその一つである「セルをマウスでダブルクリック」で起こるイヴェントを処理してみる。
意図したことは「シート上の任意のセルをマウスでダブルクリックするとそのセルの背景色が赤に変わる」である。
【準備】
Calcのシート名を右マウスでクリックすると設定メニュが出る。その一つの「シートイベント」を選択する。イベントの種類を対応するイヴェント処理マクロを繋げる表のなかで「マウスでダブルクリック」を選択。マクロ欄で対応するマクロ名を選択する。
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#
def OnDoubleClicked(event):
CellAddress = event.getCellAddress()
Row = CellAddress.Row
Column = CellAddress.Column
msg = str(Row) + ' ' + str(Column)
cell = sheet.getCellByPosition(Column, Row)
cell.CellBackColor = 0xff0000
ui.Print(msg)
return
チェックボックスは多数の選択肢がありそれから複数を選択するコントロールである。よくアンケートなどで見かけるもの。フォームのコントロールにもチェックボックスがあるので使ってみた。多数の選択肢をきれいに配置することに手数がかかる。この点はフォームを使わずにCalc画面で直接コントロールを配置する方が楽である。フォームのよいところは細かな制御ができることである。今回は8個のチェックボックス、2個のボタンをフォームに配置した。
【フォームの画像】
ボタン「確認」は選択した結果をシートへ反映されるため、ボタン「リセット」は選択した結果を廃棄し無選択の状態にするためのものである。
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
class FinishedListener(unohelper.Base, XActionListener):
def __init__(self, ckbxs, sheet):
self.ckbxs = ckbxs
def actionPerformed(self, evnt):
for ckbx in self.ckbxs:
print(ckbx.State)
class ResetListener(unohelper.Base, XActionListener):
def __init__(self, ckbxs):
self.ckbxs = ckbxs
def actionPerformed(self, evnt):
for ckbx in self.ckbxs:
ckbx.State=0
def createDialog():
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
dialog = dp.createDialog("vnd.sun.star.script:Standard.Dialog4?location=application")
sheet = 0
#コントロールの登録
cmdbtn1 = dialog.getControl("CommandButton1")
cmdbtn2 = dialog.getControl("CommandButton2")
ckbx1 = dialog.getControl("CheckBox1")
ckbx2 = dialog.getControl("CheckBox2")
ckbx3 = dialog.getControl("CheckBox3")
ckbx4 = dialog.getControl("CheckBox4")
ckbx5 = dialog.getControl("CheckBox5")
ckbx6 = dialog.getControl("CheckBox6")
ckbx7 = dialog.getControl("CheckBox7")
ckbx8 = dialog.getControl("CheckBox8")
ckbxs = (ckbx1, ckbx2, ckbx3, ckbx4, ckbx5, ckbx6, ckbx7, ckbx8)
#エヴェント監視(ボタンが押されたとき)
btn1_listener = FinishedListener(ckbxs, sheet)
cmdbtn1.addActionListener(btn1_listener)
btn2_listener = ResetListener(ckbxs)
cmdbtn2.addActionListener(btn2_listener)
dialog.execute()
dialog.dispose()
ダイアログのコントロール(部品)に日付フィールドというものがある。形式に従って日付けを入力すると年、月、日に自動的に分解しくれる。
作例では誕生日を入力して<Enter>キーを入力すると入力の終わりを意味し結果はCalcのシートに表示される。
【ダイアログ上の日付フィールド】
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XKeyListener
class MyKeyListener(unohelper.Base, XKeyListener):
def __init__(self, sheet, datef1):
self.sheet = sheet
self.datef1 = datef1
self.row = 0
def keyPressed( self, event ):
k = event.KeyCode
c = event.KeyChar.value
mods = event.Modifiers
# mods are additive
# 0 - None
# 1 - Shift
# 2 - Ctrl
# 4 - Alt
# 8 - Super_R
print(k, c, mods)
if k == 1280: #Enterキー
#print(self.datef1.IsDate)
year = self.datef1.Date.Year
month = self.datef1.Date.Month
day = self.datef1.Date.Day
#表への書き出し
self.row+=1
print(self.row)
print(year, month, day)
self.sheet.getCellByPosition(0,self.row).Value=year
self.sheet.getCellByPosition(1,self.row).Value=month
self.sheet.getCellByPosition(2,self.row).Value=day
def createDialog():
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
dialog = dp.createDialog("vnd.sun.star.script:Standard.Dialog3?location=application")
#表
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#コントロールの登録
datef1 = dialog.getControl("DateField1")
#エヴェント監視(Enterキーを検出)
datef1_listener = MyKeyListener(sheet, datef1)
datef1.addKeyListener(datef1_listener)
dialog.execute()
dialog.dispose()
<\div>
「ラジオボタン」というコントロールがある(libreOfficeではオプションボタンと呼んでいる)。名前の由来は古いラジオには選局用のボタンが複数付いており、選局はそのボタンの一つを押すとその局の放送が聞けるようになっていた。当然他の局のボタンはオフの状態になる。つまり複数のボタンの一つをオンにするとその他のボタンは自動的にオフになるような複数のボタンがラジオボタンである。
【配置】今回は「ラジオボタン」を三つ、普通の「ボタン」を一つ、そして「テキストボックス」を一つ配置する。詳細は省くがこのままでは三つの「ラジオボックス」はそれぞれ独立して動く。この三つの「ラジオボックス」をコントロールの一つである「グループボックス」で囲ってやると、この三つは連動して動く。
【マクロ】このダイアログの意図していることは「ラジオボタンの一つを選択し、「確認」ボタンを押すと選択したボタンのラベルが表示される」である。
試作したマクロを示す:
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
class MyActionListener(unohelper.Base, XActionListener):
def __init__(self, rbtns, langs):
self.rbtns = rbtns
self.langs = langs
def actionPerformed(self, evnt):
for i, rbtn in enumerate(self.rbtns):
if rbtn.State:
print(self.langs[i])
msg = 'やっぱり'+self.langs[i] + 'ですね'
ui.Print(msg)
def createDialog():
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
dialog = dp.createDialog("vnd.sun.star.script:Standard.Dialog1?location=application")
#コントロールの登録
rbtn1 = dialog.getControl("radioButton1")
rbtn2 = dialog.getControl("radioButton2")
rbtn3 = dialog.getControl("radioButton3")
rbtns =[rbtn1, rbtn2, rbtn3]
langs = ['Python', 'Java', 'Perl']
cmdbtn1 = dialog.getControl("commandButton1")
#エヴェント監視(ボタンが押されたとき)
btn1_listener = MyActionListener(rbtns, langs)
cmdbtn1.addActionListener(btn1_listener)
dialog.execute()
dialog.dispose()
各ラジオボタンのオン。オフの状態は各ボタンの属性Stateの値で判定できる。
Pythonでマクロ(4):ダイアログ(フォーム)の配置で配置したダイアログ上にある部品(コントロール)を制御する。
このダイアログには「テキストボックス」と「ボタン」の二つのコントロールが配置されている。
このダイアログの意図していることは
『ユーザが「テキストボックス」に語句を入力し、「ボタン」をクリックするとこの語句が別の窓に表示される』という簡単なものである。
マクロは以下のようになる:
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
class MyActionListener(unohelper.Base, XActionListener):
def __init__(self, ctrl):
self.ctrl = ctrl
def actionPerformed(self, evnt):
ui.Print(self.ctrl.Text)
def createDialog():
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
dialog = dp.createDialog("vnd.sun.star.script:Standard.Dialog2?location=application")
#コントロールの登録
txtf1 = dialog.getControl("TextField1")
cmdbtn1 = dialog.getControl("CommandButton1")
#エヴェント監視(ボタンが押されたとき)
btn1_listener = MyActionListener(txtf1)
cmdbtn1.addActionListener(btn1_listener)
dialog.execute()
dialog.dispose()
ダイアログ自体の登録は以前紹介したマクロと同じである。新たに登録したものはテキストボックス(名称:TextField1)とボタン(名称:CommandButtam1)の二つのコントロールである。
クラスMyActionListenerは親クラスunohelper.Baseと XActionListenerを継承している。。この新たなクラスは親クラスXActionListenerで定義されているメソッドactionPerformedを再定義するためのものである。メソッドactionPerformedはコントロール(今の場合はボタン)をマウスの左ボタンでクリックしたときのイヴェントを処理するメソッドである。コントロール「ボタン」で起こり得るイヴェントはこれ以外にも沢山ある(15個)。例えばmouseEntered 。これはマウスがそのコントロールに入ったときのイヴェントで、親クラスはXMouseListenerである。詳細はここで。
メソッドactionPerformedではクラスMyActionListenerのインスタンスbtn1_listenerの引数として渡されたコントロールtxtf1の属性Textの中身をPrint文で表示する。各コントロールが持つ属性の詳細はここで。
作成したダイアログをLibreOffice:Calcのシート画面上に配置するだけのマクロである。
【ダイアログの作成】
シート画面のプロダウンメニュ「ツール」->「ダイアログの管理」と進む。管理画面で配置ツリーから「マイダイアログ」-> 「Standard」と進み、それをクリックすると連番号のダイアログ名(今はDialog2)が現れる。「新規作成」のボタンを選ぶとマッサラなダイアログ画面がでる。
この画面にいろんな部品(コントロールと呼ぶ)を配置する。
作例では「テキストボックス」(名称:TextField1)と「ボタン」(名称:CommandButtom1)を配置した。プレビューで実際のダイアログの画面が現れる。作例の画面を示す:
上のコントロールが「テキストボックス」で、下のコントロールが「ボタン」である。このダイアログはユーザが「テキストボックス」に字句を入力して「ボタン」を押すとその字句がプログラムで使える(例えばその字句をCalcの表に表示する)。
【配置】
このダイアログをCalcのシート上に配置するマクロを作ってみる。マクロの全体は以下のようになる:
#coding: utf-8
import uno
import unohelper
def dialog_example(*args):
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dp = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
dialog = dp.createDialog("vnd.sun.star.script:Standard.Dialog2?location=application")
dialog.execute()
dialog.dispose()
Basicのマクロ記述に比較すると結構複雑な記述になる。Transfer from Basic to Pythonに詳しい説明がある。