LibreOffice5(68)画像フィルターリストの作成

2017-08-19

旧ブログ

t f B! P L
FilePickerサービスのappendFilter()メソッドに使える画像フィルター(表示フィルター)一覧が欲しかったのでConfigurationProviderサービスを使って一覧を作成します。取得したのはUINameをキー、Extensionsにワイルドカードを付けた;区切りにしたものを値とした辞書です。

前の関連記事:LibreOffice5(67)オプションページを持つ拡張機能の例を作る: その5


LibreOfficeで扱える画像を定義しているコンポーネントデータノードを見る


share/registry/main.xcdをChromiumで開いて整形された後、bmpとかjpgで検索してみるとoor:package="org.openoffice.TypeDetection" oor:name="Types"というコンポーネントデータノードに画像ファイルの拡張子が定義されているのをみつけました。

このコンポーネントデータノードはmain.xcdの中に同名のものが3つありますが、他の2つが何を定義しているものかよくわかりませんでした。

とりあえず画像ファイルの拡張子を定義しているコンポーネントデータノードはoor:package="org.openoffice.TypeDetection" oor:name="GraphicFilter"コンポーネントデータノードの次に書いてありました。

まず同名のコンポーネントスキーマノードを探して、コンポーネントデータノードの構造を確認しておきます。
<oor:component-schema oor:package="org.openoffice.TypeDetection" oor:name="Types" xml:lang="en-US">
 <templates>
  <group oor:name="Type">
   <prop oor:name="UIOrder" oor:type="xs:int" oor:nillable="false">...</prop>
   <prop oor:name="URLPattern" oor:type="oor:string-list" oor:nillable="false">...</prop>
   <prop oor:name="Extensions" oor:type="oor:string-list" oor:nillable="false">...</prop>
   <prop oor:name="DocumentIconID" oor:type="xs:int" oor:nillable="false">...</prop>
   <prop oor:name="MediaType" oor:type="xs:string" oor:nillable="false">...</prop>
   <prop oor:name="Preferred" oor:type="xs:boolean" oor:nillable="false">...</prop>
   <prop oor:name="PreferredFilter" oor:type="xs:string" oor:nillable="false">...</prop>
   <prop oor:name="UIName" oor:localized="true" oor:type="xs:string"/>
   <prop oor:name="ClipboardFormat" oor:type="xs:string" oor:nillable="false">...</prop>
   <prop oor:name="DetectService" oor:type="xs:string" oor:nillable="false">...</prop>
  </group>
 </templates>
 <component>
  <set oor:name="Types" oor:node-type="Type"/>
 </component>
</oor:component-schema>
画像フィルターはセットノードoor:name="Types"で定義され、ノードタイプはoor:node-type="Type"になっています。

ノードタイプが入れ子になっていないので、Vistorパターンを使わなくても一覧を抽出できそうです。

propノードのExtensionsに拡張子、UINameにファイルタイプの名前が入っているのでこれを抜き出します。

画像ファイルに関するものかどうかはpropノードのMediaTypeで判断することにします。
<prop oor:name="MediaType">
    <value>image/x-MS-bmp</value>
</prop>
こうなっているのでMediaTypeの値がimage/で始まっているものは画像ファイルと判断します。

画像フィルターの辞書を出力するマクロ

import unohelper  # オートメーションには必須(必須なのはuno)。
from com.sun.star.beans import PropertyValue
def macro():
 ctx = XSCRIPTCONTEXT.getComponentContext()  # コンポーネントコンテクストの取得。
 smgr = ctx.getServiceManager()  # サービスマネージャーの取得。
 doc = XSCRIPTCONTEXT.getDocument()
 if not doc.supportsService("com.sun.star.text.TextDocument"):  # Writerドキュメントに結果を出力するのでWriterドキュメントであることを確認する。
  raise RuntimeError("Please execute this macro with a Writer document.")
 configreader = createConfigReader(ctx, smgr)  # 読み込み専用の関数を取得。
 root = configreader("/org.openoffice.TypeDetection.Types/Types")  # org.openoffice.TypeDetectionパンケージのTypesコンポーネントのTypesノードを根ノードにする。
 props = "UIName", "Extensions", "MediaType"  # 取得するプロパティ名のタプル。
 filters = {}  # フィルターの辞書。UINameをキー、拡張子のタプルを値とする。
 for childname in root.getElementNames():  # 子ノードの名前のタプルを取得。ノードオブジェクトの直接取得はできない模様。
  node = root.getByName(childname)  # ノードオブジェクトを取得。
  uiname, extensions, mediatype = node.getPropertyValues(props)  # extentionsはタプルで返ってくる。
  if mediatype.startswith("image/"):  # MediaTypeで画像ファイルフィルタかを判断する。
   filters[uiname] = "*.{}".format(";*.".join(extensions))  # 拡張子のタプルは;を区切って結合する。
 print(filters)  # フィルターの辞書を出力。オートメーションのときのみ。
 doc.getText().setString(str(filters))  # Writerドキュメントに出力。    
 root.dispose()  # ConfigurationAccessサービスのインスタンスを破棄。
def createConfigReader(ctx, smgr):  # ConfigurationProviderサービスのインスタンスを受け取る高階関数。
 configurationprovider = smgr.createInstanceWithContext("com.sun.star.configuration.ConfigurationProvider", ctx)  # ConfigurationProviderの取得。
 def configReader(path):  # ConfigurationAccessサービスのインスタンスを返す関数。
  node = PropertyValue(Name="nodepath", Value=path)
  return configurationprovider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", (node,))
 return configReader
g_exportedScripts = macro, #マクロセレクターに限定表示させる関数をタプルで指定。
19行目でprint()で出力していますが、これはオートメーション用であって、マクロモードでは何も出力されません。

Writerドキュメントでこのマクロを実行するとUINameをキー、拡張子のタプルを値とする辞書を出力します。

GUI/getgraphicfilters.py at 7e536193e0cfab42cf128f9db289e950477fba0e · p--q/GUI

これはオートメーション用コード(if __name__ == "__main__":以降)とデバッグコード(デコレーターenableRemoteDebugging)を付けたものです。

createConfigReader()はコンポーネントコンテクスト、サービスマネージャーを引数にとって、configReader()関数を返す汎用関数です。

configReader()はConfigurationへのパスを渡すとルートノードが取得できます。

マクロから得た画像フィルターの辞書


{'WordPerfect Graphics': '*.wpg', 'SVM - StarView Meta File': '*.svm', 'PSD - Adobe Photoshop': '*.psd', 'EMF - Enhanced Meta File': '*.emf', 'PCD - Photo CD Base16': '*.pcd', 'PCD - Photo CD Base': '*.pcd', 'SGF - StarWriter SGF': '*.sgf', 'PGM - Portable Graymap': '*.pgm', 'SVG - Scalable Vector Graphics': '*.svg;*.svgz', 'PPM - Portable Pixelmap': '*.ppm', 'XBM - X Bitmap': '*.xbm', 'PBM - Portable Bitmap': '*.pbm', 'RAS - Sun Raster Image': '*.ras', 'WMF - Windows Metafile': '*.wmf', 'PCD - Photo CD Base4': '*.pcd', 'TGA - Truevision Targa': '*.tga', 'GIF - Graphics Interchange': '*.gif', 'Corel Presentation Exchange': '*.cmx', 'Adobe/Macromedia Freehand': '*.fh;*.fh1;*.fh2;*.fh3;*.fh4;*.fh5;*.fh6;*.fh7;*.fh8;*.fh9;*.fh10;*.fh11', 'CGM - Computer Graphics Metafile': '*.cgm', 'XPM - X PixMap': '*.xpm', 'MET - OS/2 Metafile': '*.met', 'DXF - AutoCAD Interchange Format': '*.dxf', 'JPEG - Joint Photographic Experts Group': '*.jpg;*.jpeg;*.jfif;*.jif;*.jpe', 'TIFF - Tagged Image File Format': '*.tif;*.tiff', 'PNG - Portable Network Graphic': '*.png', 'PCT - Mac Pict': '*.pct;*.pict', 'EPS - Encapsulated PostScript': '*.eps', 'BMP - Windows Bitmap': '*.bmp', 'PCX - Zsoft Paintbrush': '*.pcx'}

LibreOffice5.2.6.2で出力した結果です。

appendFilter()メソッドの引数にできるように拡張子はセミコロン(;)で区切って、ワイルドカード(*.)を付けています。

次の関連記事:LibreOffice5(69)Javaの例:GUIをPythonにする その2

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ