Top > OOoBasic > Dialog > GridControl33

グリッドコントロール (3.3) Edit

OpenOffice.org 3.3 の頃のグリッドコントロール。Apache OpenOffice 3.4 以降ではメソッドなどが変更されていますので、グリッドコントロールを参照してください。

モデルプロパティ Edit

プロパティ説明
GridDataModel.awt.grid.XGridDataModelデータ
ColumnModel.awt.grid.XGridColumnModelカラムデータ
RowBackgroundColorlong背景色
EvenRowBackgroundColorlong偶数行の背景色
ShowColumnHeaderboolean列ヘッダの表示
HeaderBackgroundColorlongヘッダの背景色
SelectionModel.view.SelectionType選択形式
HScrollboolean水平スクロールバーの表示
VScrollboolean垂直スクロールバーの表示
LineColorlong線の色
TextColorlongテキストの色

いまのところ表示するフォントと文字のサイズを変更できません。

3.3 の IDL では DataModel となっていますが、3.4 で GridDataModel に修正予定。プロパティ名の定義なので特にコードを書くときには問題ありません。

コントローラ Edit

コントローラからからは選択範囲の操作などが行えます。選択モードの設定はモデルのプロパティで行います。モードによっては各メソッドから取得できる選択範囲のインデックスに注意が必要です。

css.awt.grid.XGridControl インターフェース

3.3

  • long getItemIndexAtPoint( [in] long x, [in] long y )
    • 指定した x および y の位置に表示されている行のインデックスを取得します。
  • void setToolTip( [in] string[] text, [in] long[] column_index )
    • 行のツールチップを設定します。
      • 引数を両方とも空にすると各セルごとに表示されている値がツールチップとして表示されます。それ以外のときには行ごとにツールチップが設定されます。このとき、各セルの値は改行してツールチップに表示されます。
      • 4 列あるときに ["", "", "", ""]、[0, 1, 2, 3] を指定するとツールチップにはセルの内容が順に表示されます。
      • ["1: ", "2: ", "3: ", "4: "]、[0, 1, 2, 3] とすると各セルの値の前にテキストが表示されます。
      • ["hoge", "", "", ""]、[-1, 1, 2, 3] とすると最初のセルの部分にはセルの値が表示されません。

css.awt.grid.XGridSelection ベースインターフェース

  • void selectAllRows()
    • 全ての行を選択します。
  • void selectRows( [in] long[] rows )
    • 指定した行を選択します。
  • void deselectAllRows()
    • 全てのセルの選択を解除します。
  • void deselectRows( [in] long[] rows )
    • 指定した行の選択を解除します。
  • long[] getSelection()
    • 選択されている行のインデックスを取得します。
  • boolean isSelectionEmpty()
    • 行が選択されているかどうか調べます。
  • boolean isSelectedIndex( [in] long index )
    • 指定した行が選択されているかどうか調べます。
  • void selectRow( [in] long index )
    • 指定した行を選択します。
  • void addSelectionListener( [in] css.awt.grid.XGridSelectionListener listener )
    • 選択変更リスナーを追加します。
  • void removeSelectionListener( [in] css.awt.grid.XGridSelectionListener listener )
    • 選択変更リスナーを削除します。
  • long getMinSelectionIndex()
    • 選択されている行の最小のインデックスを返します。
  • long getMaxSelectionIndex()
    • 選択されている行の最大のインデックスを返します。

作成 Edit

一般的なダイアログコントロールを動的に作成する時と同じように com.sun.star.awt.grid.UnoControlGridModel サービスをダイアログモデルからインスタンス化します。

 DialogLibraries.loadLibrary("Standard")
 oDialog = CreateUnoDialog( _
   DialogLibraries.getByName("Standard").getByName("Dialog1"))
 oDialogModel = oDialog.getModel()

 oGridModel = oDialogModel.createInstance( _
     "com.sun.star.awt.grid.UnoControlGridModel")

  with oGridModel
   .PositionX = 10
   .PositionY = 10
   .Width = 190
   .Height = 100
   .Name = "Grid"
   ' adds ColumnModel and GridDataModel
 end with

 oDialogModel.insertByName("Grid1", oGridModel)
 oDialog.execute()

ColumnModel および GridDataModel プロパティを正しく設定する前にダイアログにコントロールを追加しようとするとクラッシュします。列および行については下記参照。

Edit

3.3では、グリッドコントロールの列を指定するにはコントロールモデルの ColumnModel プロパティに com.sun.star.awt.grid.DefaultGridColumnModel サービスで指定します。また、各列は com.sun.star.awt.grid.GridColumn サービスで指定します。

 oGridCol1 = CreateUnoService("com.sun.star.awt.grid.GridColumn")
 'oGridCol1.setTitle("Col 1")
 oGridCol1.Title = "Col 1"
 
 oGridCol2 = CreateUnoService("com.sun.star.awt.grid.GridColumn")
 'oGridCol2.setTitle("Col 2")
 oGridCol2.Title = "Col 2"
 
 oColModel = CreateUnoService("com.sun.star.awt.grid.DefaultGridColumnModel")
 oColModel.addColumn(oGridCol1)
 oColModel.addColumn(oGridCol2)

 oGridModel.ColumnModel = oColModel

列のプロパティ

プロパティ説明
Titlestring列タイトル
ColumnWidthlong列幅
Identifierany列識別子
PreferredWidthlong推奨幅
MinWidthlong最小幅
MaxWidthlong最大幅
Resizeableboolean列幅手動調整可能
HorizontalAlign.style.HorizontalAlignment水平方向配置

css.awt.grid.XGridColumnModel

  • long getColumnCount()
    • 列数を取得します
  • long addColumn( [in] css.awt.grid.XGridColumn column )
    • 列を追加します
  • []css.awt.grid.XGridColumn getColumns()
    • すべての列を取得します
  • css.awt.grid.XGridColumn getColumn( [in] long index )
    • 指定したインデックスの列を取得します。
  • void setDefaultColumns( [in] long elements )
    • デフォルトの列数を設定します
  • css.awt.grid.XGridColumn copyColumn( [in] css.awt.grid.XGridColumn column )
    • 列をコピーします
  • long ColumnHeaderHeight
    • attribute. カラムヘッダ高さ

行データ Edit

oDataModel = oGridModel.GridDataModel

3.3 では行データは com.sun.star.awt.grid.DefaultGridDataModel サービスに各行をラベル、[]string で追加して各行を表示します。

 oDataModel = CreateUnoService("com.sun.star.awt.grid.DefaultGridDataModel")
 oDataModel.addRow("1", Array("1_1", "1_2"))
 oDataModel.addRow("2", Array("2_1", "2_2"))

 oGridModel.GridDataModel = oDataModel
プロパティ説明
Data[][]any表示データ
RowHeaderWidthlong行ヘッダ幅
RowHeaders[]string行ヘッダデータ
RowHeightlong行高さ

3.3 css.awt.grid.XGridDataModel インターフェース

  • long getRowCount
    • データ行数を取得します。
  • void addRow([in] string header, [in] seq<any> data)
    • 行を最後に追加します。
  • void removeRow([in] long index)
    • 指定行を削除します。
  • void removeAll()
    • 全てのデータ行を削除します。
  • void updateCell( [in] long row, [in] long column, [in] any value)
    • 指定したセルのデータを更新します。
  • void updateRow([in] long row, [in] seq<long> columns, [in] seq<any> values )
    • 行中の指定した列のデータを更新します。
  • void addDataListener([in] css.grid.XGridDataListener listener)
    • リスナーを追加します。
  • void removeDataListener([in] css.grid.XGridDataListener listener)
    • リスナーを削除します。

GridDataModel (3.3) Edit

3.3 用です。3.4 では修正されていますし、インターフェースのメソッドが変更されているので利用できません。

独自のデータモデルを利用すると表示するデータとは別にデータ用の値を管理できます。データモデルを作成するには UNO コンポーネントを作成する必要があります。OOo Basic のみではできません。

たとえば、ウォッチウィンドウ のグリッドデータモデルは独自のもので、内部では行データとしてセルを保持したクラスのインスタンスを管理しています。

以下は PyUNO で基本的なデータモデルを実装したものです。二点ほど問題を回避してあります。

グリッドをダイアログなどに作成するとき、グリッドコントロールのモデルにデータモデルを設定しておき、そこにデータを追加しておきます。その後にグリッドコントロールをダイアログに追加します。そうすると、追加されたときに Data attribute からグリッドに表示するデータを一度に取得されます。API の呼び出し回数が少なくて済みます。

ダイアログにグリッドコントロールが追加されたときに addDataListener メソッドからリスナーが渡されます。その後のグリッドのデータの更新はこのリスナーに broadcast しなければ表示が更新されません。

PyUNO からこのリスナーのメソッドを呼び出そうとすると、メソッドが見えません。下記のコードでは CoreReflection を介して呼び出しています。Java で実装するのであれば問題なく行えます。 また、RowUpdate のときに列インデックスを []long 型を指定して渡さないと []byte などになりうまく動作しません。

  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
# -*- coding: utf-8 -*-
import uno, unohelper
 
from com.sun.star.awt.grid import XGridDataModel, GridDataEvent
 
 
class GridDataModelBase(unohelper.Base, XGridDataModel, object):
    """ base class for custom data model for grid control."""
    
    RowAdded = 0x1
    RowRemoved = 0x10
    DataChanged = 0x100
    
    def __init__(self, ctx):
        """ corereflection is used to call method of the listeners."""
        self.ctx = ctx
        self.listeners = []
        self._reflection = self.ctx.getServiceManager().createInstanceWithContext(
            'com.sun.star.reflection.CoreReflection', self.ctx)
    
    def _broadcast_added(self, index, header, data):
        """ broadcast about addition. """
        ev = GridDataEvent(self, '', None, None, index, header, data)
        self._broadcast(self.RowAdded, ev)
    
    def _broadcast_removed(self, index):
        """ broadcast removement. """
        ev = GridDataEvent()
        ev.index = index
        self._broadcast(self.RowRemoved, ev)
    
    def _broadcast_changed(self, name, index, old_value, new_value):
        """ broadcast some changes. """
        if name == 'RowUpdated':
            old_value = uno.Any('[]long', old_value)
        ev = GridDataEvent(self, name, old_value, new_value, index, '', ())
        self._broadcast(self.DataChanged, ev)
    
    def _broadcast(self, update_type, ev):
        """ broadcasting """
        method_name = ''
        if update_type == self.RowAdded:
            method_name = 'rowAdded'
        elif update_type == self.RowRemoved:
            method_name = 'rowRemoved'
        elif update_type == self.DataChanged:
            method_name = 'dataChanged'
        else:
            return
        for listener in self.listeners:
            idl_method = self._reflection.getType(listener).getMethod(method_name)
            if idl_method:
                try:
                    idl_method.invoke(listener, (ev,))
                except Exception as e:
                    print(e)
    
    def removeDataListener(self, listener):
        for k, v in enumerate(self.listeners):
            if listener == v:
                del self.listener[k]
    
    def addDataListener(self, listener):
        self.listeners.append(listener)
 
 
 
class CustomGridDataModel(GridDataModelBase):
    """ Customizable data mode. """
    
    def __init__(self, ctx):
        GridDataModelBase.__init__(self, ctx)
        self.RowHeight = 10
        self.RowHeaderWidth = 20
        self._headers = []
        self._rows = []
    
    @property
    def Data(self):
        """ ondemand created data. """
        return tuple([tuple(row) for row in self._rows])
    
    @property
    def RowHeaders(self):
        """ headers """
        return tuple(self._headers)
    
    @RowHeaders.setter
    def RowHeaders(self, value):
        pass
    
    # XGridDataModel
    def getRowCount(self):
        """ number of rows. """
        return len(self._rows)
    
    def addRow(self, header, row):
        """ new row. """
        if isinstance(header, basestring) and isinstance(row, tuple):
            self._headers.append(header)
            self._rows.append(row)
            self._broadcast_added(len(self._rows) - 1, header, row)
    
    def removeRow(self, index):
        """ remove specified row."""
        if 0 <= index < len(self._rows):
            del self._headers[index]
            del self._rows[index]
            self._broadcast_removed(index)
    
    def removeAll(self):
        """ all rows are removed. """
        self._headers = []
        self._rows = []
        self._broadcast_removed(-1)
    
    def updateCell(self, index, column_index, value):
        """ specific individual cell is updated."""
        if 0 <= index < len(self._rows):
            row = list(self._rows[index])
            if 0 <= column_index < len(row):
                row[column_index] = value
                self._rows[index] = row
                self._broadcast_changed('CellUpdated', index, column_index, value)
    
    def updateRow(self, index, columns, values):
        """ a few cells are update in the same row. """
        if isinstance(columns, tuple) and isinstance(values, tuple) and \
            len(columns) == len(values):
            if 0 <= index < len(self._rows):
                row = list(self._rows[index])
                for i, v in zip(columns, values):
                    row[i] = v
                self._rows[index] = tuple(row)
                self._broadcast_changed('RowUpdated', index, columns, values)
 
 
 
def grid_custom_data_model_test(*args):
    """ test case for custom grid data model."""
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.getServiceManager()
    dp = smgr.createInstanceWithContext(
        'com.sun.star.awt.DialogProvider', ctx)
    
    dlg = dp.createDialog('vnd.sun.star.script:Standard.Dialog1?location=application')
    dlg_model = dlg.getModel()
    
    grid_model = dlg_model.createInstance(
        'com.sun.star.awt.grid.UnoControlGridModel')
    grid_model.setPropertyValues(
        ('Height', 'PositionX', 'PositionY', 'Width'), 
        (100, 3, 3, 100))
    grid_model.ShowColumnHeader = True
    
    # add columns
    oGridCol1 = smgr.createInstanceWithContext(
        "com.sun.star.awt.grid.GridColumn", ctx)
    oGridCol1.Title = "Col 1"
    oGridCol2 = smgr.createInstanceWithContext(
        "com.sun.star.awt.grid.GridColumn", ctx)
    oGridCol2.Title = "Col 2"
    
    oColModel = smgr.createInstanceWithContext(
        "com.sun.star.awt.grid.DefaultGridColumnModel", ctx)
    oColModel.addColumn(oGridCol1)
    oColModel.addColumn(oGridCol2)
    grid_model.ColumnModel = oColModel
    
    
    # create grid data model
    use_default = False
    if use_default:
        # with default grid data model
        dataModel = smgr.createInstanceWithContext(
            "com.sun.star.awt.grid.DefaultGridDataModel", ctx)
    else:
        # using custom one
        #print("CustomGridDataModel is used.")
        dataModel = CustomGridDataModel(ctx)
    
    grid_model.GridDataModel = dataModel
    
    dataModel.addRow("1", ("getByName", "1_2"))
    dataModel.addRow("2", ("2_1", "2_2"))
    
    dlg_model.insertByName('Grid1', grid_model)
    
    # if broadcasting about row addition is correctly sended, 3rd row is shown
    dataModel.addRow("3", ("...", "1_2"))
    
    #dataModel.updateCell(0, 0, 'get?')
    dataModel.updateRow(1, (0, ), ("updated>", ))
    
    dlg.execute()

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