Top > OOoBasic > Dialog > Example9

ランタイムダイアログ Edit

事前にダイアログエディタで作成したダイアログを使わずに実行時にコードから作成します。

ダイアログ Edit

まず、コントロールを配置するダイアログを作成します。

Sub Main
  oDialog = CreateUnoService( _
    "com.sun.star.awt.UnoControlDialog")
  oDialogModel = CreateUnoService( _
    "com.sun.star.awt.UnoControlDialogModel")
  oDialogModel.setPropertyValues( _
    Array("Height","PositionX","PositionY","Width"), _
    Array(100,30,30,100) )
  oDialog.setModel(oDialogModel)
  
  oDialog.setVisible(True)
  oDialog.execute()
End Sub

なぜか oDialog.setVisible(True) としておかないとダイアログが表示されません。

Step なども利用できます。

コントロール Edit

ダイアログモデルオブジェクトの createInstance メソッドを利用してコントロールモデルを作成します。

 oCancelButton = oDialogModel.createInstance( _
   "com.sun.star.awt.UnoControlButtonModel")
 oCancelButton.setPropertyValues( _
   Array("Height","Label","PositionX","PositionY","PushButtonType","Width"), _
   Array(14,"~Cancel",55,80,com.sun.star.awt.PushButtonType.CANCEL,32) )
 
 oOKButton = oDialogModel.createInstance( _
   "com.sun.star.awt.UnoControlButtonModel")
 oOKButton.setPropertyValues( _
   Array("Height","Label","PositionX","PositionY","PushButtonType","Width"), _
   Array(14,"~OK",13,80,com.sun.star.awt.PushButtonType.OK,32) )
 
 With oDialogModel
   .insertByName("close",oCancelButton)
   .insertByName("ok",oOKButton)
 End With

コントロールのダイアログへの追加は com.sun.star.container.XNameContainer インターフェースのメソッドを使って行います。コントロールのコントローラを利用したいときには、ダイアログモデルに追加した後でダイアログコントローラオブジェクトから getControl メソッドで取得します。このとき指定するコントロール名はダイアログモデルオブジェクトに追加するときに利用した名前と同じものを指定します。

ランタイムダイアログを作成するコードをつくる Edit

既存の application ダイアログライブラリにあるダイアログからそれと同じようなダイアログをランタイムで作成する OOo Basic のコードを作成します。

Python マクロです。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#!
# -*- coding: utf_8 -*-
 
import unohelper
 
from com.sun.star.beans.PropertyState import DIRECT_VALUE
from com.sun.star.uno.TypeClass import (BOOLEAN as TC_BOOLEAN, 
    ENUM as TC_ENUM, STRING as TC_STRING)
 
from com.sun.star.view.SelectionType import SINGLE as ST_SINGLE
from com.sun.star.awt.tree import XTreeExpansionListener
from com.sun.star.awt.PushButtonType import OK as PBT_OK, CANCEL as PBT_CANCEL
from com.sun.star.view import XSelectionChangeListener
 
VAR_DIALOG = "oDialog"
VAR_DIALOG_MODEL = "oDialogModel"
SUB_NAME = "RuntimeDialog"
INDENT = "  "
 
 
class DialogSelector(unohelper.Base, 
    XTreeExpansionListener, XSelectionChangeListener):
    """ supports only application context now. """
    def __init__(self):
        self.result = ""
        ctx = XSCRIPTCONTEXT.getComponentContext()
        smgr = ctx.getServiceManager()
        d = smgr.createInstanceWithContext(
            "com.sun.star.awt.UnoControlDialog", ctx)
        dm = smgr.createInstanceWithContext(
            "com.sun.star.awt.UnoControlDialogModel", ctx)
        d.setModel(dm)
        dm.setPropertyValues(
            ("Height", "PositionX", "PositionY", "Width"), 
            (200, 50, 50, 150))
        
        btnOkModel = dm.createInstance(
            "com.sun.star.awt.UnoControlButtonModel")
        dm.insertByName("btn_ok", btnOkModel)
        btnOkModel.setPropertyValues(
            ("Height", "PositionX", "PositionY", "PushButtonType", "Width"),
            (15, 120, 2, 1, 30))
        btnCancelModel = dm.createInstance(
            "com.sun.star.awt.UnoControlButtonModel")
        dm.insertByName("btn_cancel", btnCancelModel)
        btnCancelModel.setPropertyValues(
            ("Height", "PositionX", "PositionY", "PushButtonType", "Width"),
            (15, 85, 02, 2, 30))
        
        treeModel = dm.createInstance("com.sun.star.awt.tree.TreeControlModel")
        dm.insertByName("tree", treeModel)
        treeModel.setPropertyValues(
            ("Height", "PositionX", "PositionY", "SelectionType", "Width"), 
            (180, 0, 20, ST_SINGLE, 150))
    
        # create tree data
        self.dataModel = smgr.createInstanceWithContext(
            "com.sun.star.awt.tree.MutableTreeDataModel", ctx)
        root = self.dataModel.createNode("Application", True) #
        self.dataModel.setRoot(root)
        treeModel.DataModel = self.dataModel
    
        self.dialogLibs = smgr.createInstanceWithContext(
            "com.sun.star.script.ApplicationDialogLibraryContainer", ctx)
        
        d.setVisible(True)
        tree = d.getControl("tree")
        tree.addTreeExpansionListener(self)
        tree.addSelectionChangeListener(self)
        self.btn_ok = d.getControl("btn_ok")
        
        n = d.execute()
        
        tree.removeTreeExpansionListener(self)
        tree.removeSelectionChangeListener(self)
        if n == 1:
            node = tree.getSelection()
            if node:
                parent = node.getParent()
                if parent:
                    self.result = "vnd.sun.star.script:%s.%s?location=application" % (
                        parent.getDisplayValue(), node.getDisplayValue())
        
        d.dispose()
    
    def get_resutl(self):
        return self.result
    
    def disposing(self, ev):
        pass
    
    def selectionChanged(self, ev):
        tree = ev.Source
        if not tree: return
        selected = tree.getSelection()
        if isinstance(selected, tuple()): return
        val = False
        parent = selected.getParent()
        if parent:
            parent = parent.getParent()
            if parent:
                val = True
        self.btn_ok.setEnable(val)
    
    def requestChildNodes(self, ev):
        node = ev.Node
        if node:
            root = node.getParent()
            if root:
                parent = root.getParent()
                if not parent:
                    # library
                    libs = self.dialogLibs
                    libName = node.getDisplayValue()
                    if libs.isLibraryPasswordProtected(libName): return
                    lib = libs.getByName(libName)
                    if lib:
                        names = lib.getElementNames()
                        for name in names:
                            c = self.dataModel.createNode(name, False)
                            node.appendChild(c)
            else:
                # root
                if node.getChildCount() > 0: return
                names = self.dialogLibs.getElementNames() # library names
                for name in names:
                    c = self.dataModel.createNode(name, True)
                    node.appendChild(c)
                    
    
    def treeExpanding(self, ev):
        pass
    def treeCollapsing(self, ev):
        pass
    def treeExpanded(self, ev):
        pass
    def treeCollapsed(self, ev):
        pass
 
 
def result_dialog(txt):
    """ shows long text."""
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.getServiceManager()
    d = smgr.createInstanceWithContext(
        "com.sun.star.awt.UnoControlDialog", ctx)
    dm = smgr.createInstanceWithContext(
        "com.sun.star.awt.UnoControlDialogModel", ctx)
    d.setModel(dm)
    dm.setPropertyValues(
        ("Height", "PositionX", "PositionY", "Width"), 
        (200, 50, 50, 200))
    edit = dm.createInstance("com.sun.star.awt.UnoControlEditModel")
    edit.setPropertyValues(
        ("Height", "HScroll", "MultiLine", 
            "PositionX", "PositionY", "VScroll", "Width"), 
        (200, True, True, 0, 0, True, 200))
    dm.insertByName("edit", edit)
    edit.Text = txt
    
    d.setVisible(True)
    d.execute()
    d.dispose()
 
 
def value_to_string(vType, value):
    tc = vType.typeClass
    
    if tc == TC_BOOLEAN:
        return True, "%s" % value
    elif tc == TC_STRING:
        return True, "\"%s\"" % value
    elif tc == TC_ENUM:
        return True, "%s.%s" % (value.typeName, value.value)
    else:
        return True, "%s" % value
    return False, None
 
 
def parse_text(value):
    return value.replace("\n", "\" & chr(10) & \"")
 
 
 
def list_propertyValues(ctrlModel):
    list_names = []
    list_values = []
    list_additional = []
    info = ctrlModel.getPropertySetInfo()
    ps = info.getProperties()
    names = [p.Name for p in ps]
    names.sort()
    states = ctrlModel.getPropertyStates(tuple(names))
    for s, n in zip(states, names):
        if n in ("Name", "PositionX", "PositionY", "Height", "Width", \
                "ResourceResolver", "FontDescriptor", \
                "DialogSourceURL", "Closeable", "Moveable", \
                "Graphic", "FormatsSupplier"):
            continue
        elif s == DIRECT_VALUE:
            
            if info.hasPropertyByName(n):
                p = info.getPropertyByName(n)
                r, v = value_to_string(p.Type, ctrlModel.getPropertyValue(n))
                if not r: continue
                
                if n in ("Label", "Text") and v.find("\n") > 0:
                        list_additional.append("%ss%s = %s" % (INDENT, n, parse_text(v)))
                        list_names.append("\"%s\"" % n)
                        list_values.append("s%s" % n)
                else:
                    list_names.append("\"%s\"" % n)
                    list_values.append(v)
    return ", ".join(list_names), ", ".join(list_values), "\n".join(list_additional)
 
 
def get_pos_size(ctrlModel, alphabetical=False):
    if alphabetical:
        return ", ".join(
        map(str, 
            [ctrlModel.Height, ctrlModel.PositionX, 
            ctrlModel.PositionY, ctrlModel.Width]))
    else:
        return ", ".join(
        map(str, 
            [ctrlModel.PositionX, ctrlModel.PositionY, 
                ctrlModel.Width, ctrlModel.Height]))
 
 
 
def get_control_serviceName(ctrlModel):
    names = ctrlModel.getSupportedServiceNames()
    for n in names:
        if n != "com.sun.star.awt.UnoControlModel":
            return n
    return "" # unknown
 
 
def create_control(ctrlModel):
    ctrlName = ctrlModel.getPropertyValue("Name")
    serviceName = get_control_serviceName(ctrlModel)
    names, values, adds = list_propertyValues(ctrlModel)
    possize = get_pos_size(ctrlModel)
    return """{additional}{i}AddControl({0}, _
{i2}"{1}", "{2}", _
{i2}{possize}, _
{i2}Array({3}), _
{i2}Array({4}))""".format(VAR_DIALOG_MODEL, ctrlName, 
              serviceName, names, values, 
              possize = possize, i = INDENT, i2 = INDENT * 2, 
              additional = adds + "\n" if adds else "")
 
 
def create_dialog(dialogModel):
    names, values, d = list_propertyValues(dialogModel)
    possize = get_pos_size(dialogModel, True)
    return """{indent}{var_dialog} = CreateUnoService("com.sun.star.awt.UnoControlDialog")
{indent}{var_dialog_model} = CreateUnoService("com.sun.star.awt.UnoControlDialogModel")
{indent}{var_dialog}.setModel({var_dialog_model})
{indent}{var_dialog_model}.setPropertyValues( _
{i2}Array("Height", "PositionX", "PositionY", "Width"), _
{i2}Array({possize}))
{indent}{var_dialog_model}.setPropertyValues( _
{i2}Array({0}), _
{i2}Array({1}))
""".format(
    names, values, 
    indent = INDENT, i2 = INDENT * 2, possize = possize, 
    var_dialog = VAR_DIALOG, var_dialog_model = VAR_DIALOG_MODEL)
 
 
def template_add_control():
    return """Function AddControl( _
      oDialogModel As Object, _
      sName As String, sControlType As String, _
      nX As Integer, nY As Integer, nWidth As Integer, nHeight As Integer, _
      sPropertyNames, vPropertyArgs)
  Dim oControlModel As Object
  oControlModel = oDialogModel.createInstance(sControlType)
  oControlModel.setPropertyValues( _
      Array("Height", "PositionX", "PositionY", "Width"), _
      Array(nHeight, nX, nY, nWidth))
  oControlModel.setPropertyValues(sPropertyNames, vPropertyArgs)
  oDialogModel.insertByName(sName, oControlModel)
  AddControl = oControlModel
End Function"""
 
 
def create_basic_runtime_dialog_code():
    ts = DialogSelector()
    dialogUrl = ts.get_resutl()
    del ts
    if not dialogUrl: return
    
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.getServiceManager()
    
    dp = smgr.createInstanceWithContext(
        "com.sun.star.awt.DialogProvider", ctx)
    try:
        dialog = dp.createDialog(dialogUrl)
    except Exception as e:
        return
    
    dialogModel = dialog.getModel()
    controlModels = dialogModel.getControlModels()
    
    # add all controls
    txt_ctrls = map(create_control, controlModels)
    
    # dialog
    txt_ctrls.insert(0, "Sub %s()" % SUB_NAME)
    txt_ctrls.insert(1, create_dialog(dialogModel))
    txt_ctrls.append(
        ("{indent}{var_dialog}.setVisible(True)\n" + \
        "{indent}{var_dialog}.execute()").format(
            indent=INDENT, var_dialog = VAR_DIALOG))
    txt_ctrls.append("End Sub")
    txt_ctrls.append(template_add_control())
    
    result_dialog("\n\n".join(txt_ctrls))
    
    dialog.dispose()
 
 
g_exportedScripts = create_basic_runtime_dialog_code,

xdl ファイルの内容からダイアログを作成 Edit

この方法は一般的ではありません。

ダイアログが xml ファイル形式で保存されている xdl ファイルの内容からダイアログをインスタンス化します。

拡張機能などの場合には同梱しておいたダイアログのファイルを com.sun.star.awt.DialogProvider サービスでインスタンス化するのが一般的なので以下の方法は使い道がありません。

Sub CreateDialogFromInputStream()
 sDialog = "<?xml version=""1.0"" encoding=""UTF-8""?>" & _
"<!DOCTYPE dlg:window PUBLIC ""-//OpenOffice.org//DTD OfficeDocument 1.0//EN"" ""dialog.dtd"">" & _
"<dlg:window xmlns:dlg=""http://openoffice.org/2000/dialog"" xmlns:script=""http://openoffice.org/2000/script"" dlg:id=""Dialog2"" dlg:left=""67"" dlg:top=""76"" dlg:width=""101"" dlg:height=""83"" dlg:closeable=""true"" dlg:moveable=""true"">" & _
" <dlg:bulletinboard>" & _
"  <dlg:button dlg:id=""CommandButton1"" dlg:tab-index=""2"" dlg:left=""5"" dlg:top=""65"" dlg:width=""42"" dlg:height=""14"" dlg:default=""true"" dlg:value=""~OK"" dlg:button-type=""ok""/>" & _
"  <dlg:button dlg:id=""CommandButton2"" dlg:tab-index=""3"" dlg:left=""55"" dlg:top=""65"" dlg:width=""42"" dlg:height=""14"" dlg:value=""~Cancel"" dlg:button-type=""cancel""/>" & _
"  <dlg:text dlg:id=""Label1"" dlg:tab-index=""4"" dlg:left=""4"" dlg:top=""4"" dlg:width=""45"" dlg:height=""14"" dlg:value=""始点"" dlg:align=""right""/>" & _
"  <dlg:text dlg:id=""Label2"" dlg:tab-index=""5"" dlg:left=""4"" dlg:top=""26"" dlg:width=""45"" dlg:height=""14"" dlg:value=""終点"" dlg:align=""right""/>" & _
"  <dlg:numericfield dlg:id=""edit_starting"" dlg:tab-index=""0"" dlg:left=""52"" dlg:top=""5"" dlg:width=""45"" dlg:height=""14"" dlg:decimal-accuracy=""0"" dlg:value-min=""-7200"" dlg:value-max=""7200"" dlg:spin=""true"" dlg:repeat=""50""/>" & _
"  <dlg:numericfield dlg:id=""edit_ending"" dlg:tab-index=""1"" dlg:left=""52"" dlg:top=""25"" dlg:width=""45"" dlg:height=""14"" dlg:decimal-accuracy=""0"" dlg:value-min=""-7200"" dlg:value-max=""7200"" dlg:spin=""true"" dlg:repeat=""50""/>" & _
"  <dlg:checkbox dlg:id=""check_cc"" dlg:tab-index=""6"" dlg:left=""5"" dlg:top=""45"" dlg:width=""90"" dlg:height=""14"" dlg:value=""反時計回り"" dlg:checked=""true""/>" & _
" </dlg:bulletinboard>" & _
"</dlg:window>"

 oTextOutput = CreateUnoService("com.sun.star.io.TextOutputStream")
 oPipe = CreateUnoService("com.sun.star.io.Pipe")
 oTextOutput.setOutputStream(oPipe)
 
 oTextOutput.writeString(sDialog)
 oPipe.closeOutput()
 
 
 oDP = CreateUnoServiceWithArguments("com.sun.star.awt.DialogProvider", _
     Array(None, oPipe, DialogLibraries.Standard, None))
 
 oDialog = oDP.createDialog("")
 oPipe.closeInput()
 
 oDialog.execute()
 oDialog.dispose()
End Sub

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes