Top > OOoBasic > Dialog > Example10

モードレスダイアログ Edit

ダイアログエディタで作成して利用するダイアログはモダルなダイアログになってしまいます。モダルなダイアログではユーザーが閉じるまで下に表示されているドキュメントなどが利用できません。ダイアログと開いた元のウィンドウを両方同時に使用できません。

モードレスダイアログでは両方同時に利用できます。しかし、ダイアログエディタで作成したダイアログをモードレスダイアログにする方法はありません。その代わり、コードを書くことでモードレスダイアログを作成できます。

結構大変です。また、普通のダイアログと違いいくつか制約があります。

  • Step が使えない
  • ステータスバーのような部分が表示されるが利用できない

1.単純なモードレスダイアログ Edit

コントロールを配置していないダイアログです。ここではドキュメントのサブフレームとして表示されるように作成します。

modelessdialog-1.png

filemodelessdialog-1.odt

コードの最後で setVisible(True) としているところを execute とするとモダルダイアログになります。

  oWindow.setVisible(True)
  'oWindow.execute()
End Sub

また、ウィンドウの作成は以下のようになります。"dialog" を "window" に変えるとウィンドウになります。

Function CreateNewWindow( _
  oToolkit,oParent,nX,nY,nWidth,nHeight) As Object
  aRect = CreateUnoStruct("com.sun.star.awt.Rectangle")
  With aRect
    .X = nX
    .Y = nY
    .Width = nWidth
    .Height = nHeight
  End With
  aWinDesc = CreateUnoStruct("com.sun.star.awt.WindowDescriptor")
  With aWinDesc
    .Type = com.sun.star.awt.WindowClass.TOP
    .WindowServiceName = "dialog"
    .ParentIndex = -1
    .Bounds = aRect
    .Parent = oParent
    .WindowAttributes = _
      com.sun.star.awt.WindowAttribute.MOVEABLE + _
      com.sun.star.awt.WindowAttribute.CLOSEABLE
  End With
  CreateNewWindow = oToolkit.createWindow(aWinDesc)
End Function

2.コントロールを配置する Edit

1で作成したダイアログは普通のダイアログとは違うため普通にコントロールを配置できません。コントロールを配置するためにコントロールコンテナを利用します。

modelessdialog-2.png

filemodelessdialog-2.odt

ラベル、テキストボックス、ボタンを配置しました。ボタンに動作を割り当てるにはアクションリスナーを利用します。また、ボタンが複数あるときには ActionCommand でボタンを区別すればアクションリスナーは一つしか作成する必要ありません。

コントロールの作成には次の関数を利用しました。

Function CreateControl(sType,nX,nY,nWidth,nHeight,sNames,vValues) As Object
  oCtrl = CreateUnoService("com.sun.star.awt.UnoControl" & sType)
  oCtrlModel = CreateUnoService("com.sun.star.awt.UnoControl" & sType & "Model")
  oCtrlModel.setPropertyValues(sNames,vValues)
  oCtrl.setModel(oCtrlModel)
  oCtrl.setPosSize(nX,nY,nWidth,nHeight,com.sun.star.awt.PosSize.POSSIZE)
  CreateControl = oCtrl
End Function

ボタンのためのリスナーではコントロールコンテナ oCont 変数からテキストエディットを取得していますが、この変数は Global 変数にしておく必要があります。

Sub ButtonListener_actionPerformed( oEv )
  sCmd = oEv.ActionCommand
  If sCmd = "btn" Then
    msgbox oCont.getControl("edit").getText()
  End If
End Sub
Sub ButtonListener_disposing( oEv )
End Sub

3.XSelectionChangeListener Edit

せっかくのモードレスダイアログなのでドキュメントとダイアログを同時に利用します。今回はドキュメントの選択範囲の変更を調べられるように XSelectionChangeListener を利用します。

filemodelessdialog-3.odt

安定したものにするためにいくつか注意する点があります。

  1. サブフレームを閉じるときにリスナーを削除する
  2. ドキュメントファイルを閉じる前にリスナーを削除する
  3. 選択範囲オブジェクトがサポートしているサービスを調べる
  4. selectionChanged が実行中のときには実行されないようにする

1、2 を怠るとドキュメントを閉じるときに OOo がクラッシュします。ドキュメントまたはサブフレームを閉じるときにリスナーを削除する必要があるので XCloseListener を利用します。

Sub RemoveListeners()
  oFrame.removeCloseListener(oListeners(1))
  oParentFrame.removeCloseListener(oListeners(1))
  oParentFrame.Controller.removeSelectionChangeListener(oListeners(2))
End Sub

Sub DocClose_queryClosing( oEv, oOwnership )
End Sub
Sub DocClose_notifyClosing( oEv )
  RemoveListeners()
End Sub
Sub DocClose_disposing( oEv )
End Sub

3、4 は以下のようにします。実行中のときに bUpdated で実行を規制します。また、オブジェクトがサポートしているサービスを supportsService で調べています。選択範囲はテキスト範囲コンテナ、図形描写コンテナなどさまざまなのでチェックする必要があります。

Sub DocSelection_selectionChanged( oEv )
  If NOT bUpdated Then Exit Sub
  bUpdated = False
  oSelection = oEv.Source.getSelection()
  If oSelection.supportsService("com.sun.star.text.TextRanges") Then
    If oSelection.getCount() > 0 Then
      oRange = oSelection.getByIndex(0)
      sTxt = oRange.getString()
      oCont.getControl("edit").setText(sTxt)
    End If
  End If
  bUpdated = True
End Sub
Sub DocSelection_disposing( oEv )
End Sub

oEv.Source で取得できるのはドキュメントのコントローラです。ThisComponent.getCurrentController() としたときと同じインターフェースになります。


Attach file: filemodelessdialog-1.png 809 download [Information] filemodelessdialog-3.odt 1394 download [Information] filemodelessdialog-2.odt 1513 download [Information] filemodelessdialog-2.png 895 download [Information] filemodelessdialog-1.odt 1636 download [Information]

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