Calc(56)追加できるリスナー一覧: その8

2018-01-03

旧ブログ

t f B! P L
セルに入力したときとプロパティを変更したときのリスナーの発火をみます。Calc(55)追加できるリスナー一覧: その7で作成したマクロを使っています。

前の関連記事:Calc(55)追加できるリスナー一覧: その7


セルに文字をキー入力するときに発火するリスナーのメソッド


マウスでA1セルを選択した後に、「ai」というキーを入力した後にEnterキーを押しました。

A1セルにはXChartDataChangeEventListenerXModifyListenerが追加してあります。

XKeyHandlerのメソッドが発火したときのログファイルの最後にKeyCharの値を出力するようにしています。

特殊文字は定数KeyからDOWN、UP、LEFT、RIGHT、HOME、END、RETURN、ESCAPE、TAB、BACKSPACE、SPACE、DELETEについては文字列にして出力しています。

EnterキーはRETURNキーのことになります。


RETURNキーを押している間にドキュメント、セル、シートに追加したXModifyListenerのmodified()メソッドが呼ばれています。

modified()メソッドの引数にはそれぞれリスナーを追加したオブジェクト、つまりそれぞれドキュメント、セル、シート、が入っていました。

このメソッドで得られる情報はリスナーを追加した対象のオブジェクト(つまりサブジェクト)に「変更があった」ということだけです。

引き続いてXChangesListenerのchangesOccurred()メソッドが呼ばれています。

このリスナーはLibreOffice5(52)Javaの例:ConfigExamplesをPythonにする その5でも出てきました。

changesOccurred()メソッドの引数のChangesEvent Structから変更したプロパティが取得できますが、セルへのキー入力ではプロパティは変更されていないので、変更した内容は取得できません。

またキー入力ではなくマクロでセルに文字列を入力したときはchangesOccurred()メソッドは発火しませんでした。

セルのプロパティを変更する例は下でやります。

セルに日本語入力をしたときはkeyPressed()メソッドは発火しない


日本語入力を有効にして「あい」と入力してみました。


linuxBean14.04ではこのようになりました。

RETURNキーのkeyPressed()メソッド以降は先ほどと同じです。

日本語入力の時はkeyPressed()メソッドが発火していませんでした。

RETURNキーのkeyPressed()メソッドの前のkeyReleased()メソッドは日本語入力(ローマ字入力)の確定のためのEnterキーです。

漢字変換を使った場合はSPACEでkeyReleased()が発火しました。

日本語キーボードの「変換」や「無変換」のキーを押した時のKeyCodeは0になっていました。

Windows10で日本語入力したときのKeyEvent StructのKeyCodeにはlinuxBeanと同じコード(定数Key)が入っていましたが KeyCharアトリビュートにはlinuxBeanと違って特殊なバイナリ(\0?)が入っているようです。

Windows10で取得したKeyCharの値をファイル名に入れるとValueError: embedded null characterがでてきますし、テキストファイルに入れるとファイル内のすべての文字が文字化けして読めませんでした。

ということでCalc(55)追加できるリスナー一覧: その7のマクロではWindowsのときはKeyCharの値を使用しないようにしています。

セルのプロパティの変更はXChangesListenerのchangesOccurred()メソッドで取得する


XChangesListenerのchangesOccurred()メソッドの引数のChangesEvent Structから変更したプロパティが取得できますが、取得する処理は少しやっかいです。
  changes = changesevent.Changes
  for change in changes:
   txts.append("Accessor: {}".format(change.Accessor))
   for element in change.Element:
    if hasattr(element, "Name") and hasattr(element, "Value"):
     propertyname, propertyvalue = element.Name, element.Value
     if "Color" in propertyname:  # 色の時は16進数で出力する。
      propertyvalue = hex(propertyvalue)
     txts.append("{}: {}".format(propertyname, propertyvalue))
ChangesEvent StructのChangesアトリビュートからElementChange Structのシークエンスを取り出します。

変更したプロパティはそのElementChange StructのElementアトリビュートにPropertyValue Structのシークエンスで入っています。

今回使っているマクロではログファイルに次の情報を書き出しています。

Base URL: vnd.sun.star.tdoc:/1/Scripts/python/listenersforcalc2.py
Accessor: attribute
CellBackColor: 0xff3333
IsCellBackgroundTransparent: False
ReplacedElement: Sheet1.A1

ChangesEvent StructのBaseアトリビュートにはドキュメントが入っているのでそのURLを取得しています。

ElementChange StructのAccessorアトリビュートには変更した種類の文字列が入っていてセルのプロパティを変更した今回はattributeが入っていました。

ElementChange StructのElementアトリビュートのPropertyValue StructのNameには変更したプロパティ名、Valueには変更したプロパティの値が入っているのでそれぞれ組にして書き出しています。

プロパティが色のときはlongを16進数に変換して書き出しています。

ElementChange StructのReplaceElementアトリビュートには変更対象のオブジェクトが入っており、今回はセルが入っていたのでその文字列アドレスを出力しています。

ちなみにセルに値を入力したときのAccessorアトリビュートにはcell-changeが入っていました。

またキー入力のときと同様にマクロでセルのプロパティを変更したときはchangesOccurred()メソッドは発火しませんでした。
(2018.8.2追記マクロでセルを変更したときに発火するときもある(ディスパッチコマンドのみ?)ようで、複数セルを変更したときはReplaceElementアトリビュートにセル範囲が入ってきました。)

(2018.11.11追記。ペーストしてもchangesOccurred()メソッドが発火しないのは、ソースに依存することがわかりました。シートからコピペしたときは発火しますが、プレインテキストをペーストしたときは発火しませんでした。)

行や列を挿入したときにもXChangesListenerのchangesOccurred()メソッドが発火する


行や列をシートに挿入したときに発火するリスナーに使えることがわかりました。

Base URL: vnd.sun.star.tdoc:/1/Scripts/python/listenersforcalc2.py
Accessor: insert-rows
ReplacedElement: Sheet1.A12:AMJ12

行12を選択して行を挿入するとAccessorにinsert-rowsが入り、ReplacedElementには挿入後に選択状態になるセル範囲が入っていました。

「上に行を挿入」でも「下に行を挿入」でもReplacedElementは同じです。

ということは「上に行を挿入」では挿入後の行が新たに選択され、「下に行を挿入」では挿入前の行が選択されたままであることなります。

Base URL: vnd.sun.star.tdoc:/1/Scripts/python/listenersforcalc2.py
Accessor: insert-columns
ReplacedElement: Sheet1.H1:H1048576

H列を選択して「左に列を挿入」をするとAccessorにinsert-columnsが入り、ReplacedElementには挿入後に選択状態になるセル範囲が入っていました。

「左に列を挿入」でも「右に列を挿入」でもReplacedElementは同じです。

つまり「左に列を挿入」では挿入後の列が新たに選択され、「右に列を挿入」では挿入前の列の選択のままであることになります。

ちなみに行を削除したときはAccessorにdelete-rows、列を削除したときはAccessorにdelete-columnsが入り、ReplacedElementは行の場合は削除した行の下にあった行、列の場合は削除した列の右にあった列が入ります。

つまりはセル範囲アドレスとしては削除した行や列の範囲が入っていることになります。

参考にしたサイト


python - "ValueError: embedded null character" when using open() - Stack Overflow
ValueError: embedded null characterのQ&Aですがよくわかりませんでした。

Cool Python Tips: Python 3.5の小さな変更点
ValueError: embedded null characterの原因はopen()で開くパスにある '\0' のようです。

次の関連記事:Calc(57)lockControllers()やaddActionLock()でのマクロの速度比較

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ