Going further with Dialog and Component
In the previous chapter we use and program only two kinds of control in our dialog (Text edit controls and buttons). We intend in this chapter to go further and use a lot of controls and then see how things work in this area. You cannot read this chapter before reading the previous one, particularly because only code snippets are presented.
We begin again with our counter.
Counter with Numeric Field
When designing the dialog working with our counter, we take two text controls for our numeric data (as input with "setCount" button and as output with "getCount" button). Because text controls are often used our preceding example is important, but it's time now to improve our design and use a numeric field control. Because the dialog aspect is unchanged we don't provide a snapshot of the dialog.
Have a look at com.sun.star.awt.XNumericField interface and see what can be done with this interface : only getvalue
and setValue
will be used in this section, but you can play with other methods.
We provide only the callHandlerMethod
function method in the listing below (see the previous chapter and also the corresponding com.sun.star.awt.XDialogEventHandler interface). The corresponding code is as follows.
// Listing 1
// c++
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("foo1")){//increment
increment();
return sal_True;
}
if (MethodName.equalsAscii("foo2")){//decrement
decrement();
return sal_True;
}
if (MethodName.equalsAscii("foo3")){ //setCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField1"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
setCount((sal_Int32)xNumericField->getValue());
return sal_True;
}
if (MethodName.equalsAscii("foo4")){ //getCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField2"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
xNumericField->setValue(getCount());
return sal_True;
}
return sal_False;
}
There is no need to go into this listing in full detail here. We turn now to another interesting example of control : the radio button.
Using Radio buttons
An option button control com.sun.star.awt.UnoControlRadioButton is a simple switch with two states, that is selected by the user. Usually option buttons are used in groups to display several options, that the user may select. While option buttons and check boxes seem to be similar, selecting one option button deselects all the other option buttons in the same group.
We want use radio button to select the increment or decrement (between 1, 5 and 10). Here is a snapshot of our dialog :
where you see a decrement or increment of value five is selected.
For this problem the com.sun.star.awt.XRadioButton interface is your friend. We intend to provide two solutions for this example. We begin with a solution which use only the four methods of the counter.
A simple solution
This solution keeps the four previous methods managed by callHandlerMethod()
named "foo1", "foo2", .. "foo4" of the com.sun.star.awt.XDialogEventHandler interface. To put it differently no new event is managed by the dialog. We present now the corresponding code, and again with only the callHandlerMethod
. Have a look at the previous chapter if you want to remember you how it works.
// Listing 2
// C++
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("foo1")){//increment
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton1"));
Reference< XRadioButton > xRadioButton(xControl,UNO_QUERY);
if (xRadioButton->getState()) m_nDelta=1;
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton2"));
Reference< XRadioButton > xRadioButton2(xControl,UNO_QUERY);
if (xRadioButton2->getState()) m_nDelta=5;
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton3"));
Reference< XRadioButton > xRadioButton3(xControl,UNO_QUERY);
if (xRadioButton3->getState()) m_nDelta=10;
increment();
return sal_True;
}
if (MethodName.equalsAscii("foo2")){//decrement
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton1"));
Reference< XRadioButton > xRadioButton(xControl,UNO_QUERY);
if (xRadioButton->getState()) m_nDelta=1;
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton2"));
Reference< XRadioButton > xRadioButton2(xControl,UNO_QUERY);
if (xRadioButton2->getState()) m_nDelta=5;
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton3"));
Reference< XRadioButton > xRadioButton3(xControl,UNO_QUERY);
if (xRadioButton3->getState()) m_nDelta=10;
decrement();
return sal_True;
}
if (MethodName.equalsAscii("foo3")){ //setCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField1"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
setCount((sal_Int32)xNumericField->getValue());
return sal_True;
}
if (MethodName.equalsAscii("foo4")){ //getCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField2"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
xNumericField->setValue(getCount());
return sal_True;
}
return sal_False;
}
As you can see only increment()
and decrement()
methods are looking for the radiobutton which is set. The corresponding checking code is completely similar in both method, then it would be better to put it in a function. No event is fired when setting or cleared a radio button in this example. But it is possible to call a method when status is changed : note in this case, you have to provide a method for every buttons. Let's us now examine this second solution.
Managing Radio Buttons Events
Every times a user set or clear a radio button a method is fired : you have to edit the corresponding property of your option button. That means you have to manage an event when clicking with mouse button (see again Developer's Guide). Because there are three radio buttons we have to add three methods. We see this kind of solution could become too complex while the number of button is increasing.
The code is as follows :
// C++
// Listing 3
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("foo1")){//increment
increment();
return sal_True;
}
if (MethodName.equalsAscii("foo2")){//decrement
decrement();
return sal_True;
}
if (MethodName.equalsAscii("foo3")){ //setCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField1"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
setCount((sal_Int32)xNumericField->getValue());
return sal_True;
}
if (MethodName.equalsAscii("foo4")){ //getCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField2"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
xNumericField->setValue(getCount());
return sal_True;
}
if (MethodName.equalsAscii("foo5")){ //incr/decr +/-1
if (m_nDelta!=1) m_nDelta=1;
return sal_True;
}
if (MethodName.equalsAscii("foo6")){ //incr/decr +/-5
if (m_nDelta!=5) m_nDelta=5;
return sal_True;
}
if (MethodName.equalsAscii("foo7")){ //incr/decr +/-10
if (m_nDelta!=10) m_nDelta=10;
return sal_True;
}
return sal_False;
}
Sequence< OUString > SAL_CALL MyCounterImpl::getSupportedMethodNames() throw (RuntimeException){
Sequence< OUString > SeqOUStr(7);
SeqOUStr[0]=OUString::createFromAscii("foo1");
SeqOUStr[1]=OUString::createFromAscii("foo2");
SeqOUStr[2]=OUString::createFromAscii("foo3");
SeqOUStr[3]=OUString::createFromAscii("foo4");
SeqOUStr[4]=OUString::createFromAscii("foo5");
SeqOUStr[5]=OUString::createFromAscii("foo6");
SeqOUStr[6]=OUString::createFromAscii("foo7");
return SeqOUStr;
}
This code is working without reading the state of the radio button but I cannot certify it could be the case in any situation you will encounter. Note that we have already provided a code to access to the state of a radio button in the previous section. Note also m_nDelta
is a new member value set to 1 by the constructor (corresponding to the default selected radio button).
Using a listbox in a dialog
In this section, we replace the radio button control with a list box. Have a look in com.sun.star.awt.XListBox inteface. We only use the getSelectedItemPos()
method in the following code.
// XDialogEventHandler implementation
// C++
// Listing 4
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("foo1")){//increment
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("ListBox1"));
Reference< XListBox > xListBox(xControl,UNO_QUERY);
switch (xListBox->getSelectedItemPos()){
case 0: m_nDelta=1;break;
case 1: m_nDelta=5;break;
case 2: m_nDelta=10;break;
}
increment();
return sal_True;
}
if (MethodName.equalsAscii("foo2")){//decrement
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("ListBox1"));
Reference< XListBox > xListBox(xControl,UNO_QUERY);
switch (xListBox->getSelectedItemPos()){
case 0: m_nDelta=1;break;
case 1: m_nDelta=5;break;
case 2: m_nDelta=10;break;
}
decrement();
return sal_True;
}
if (MethodName.equalsAscii("foo3")){ //setCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField1"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
setCount((sal_Int32)xNumericField->getValue());
return sal_True;
}
if (MethodName.equalsAscii("foo4")){ //getCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField2"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
xNumericField->setValue(getCount());
return sal_True;
}
return sal_False;
}
which yields the dialog below :
Multi-Page Dialog
The multi-page dialog is tackled in OOBasic Document. Our goal is to use a multipage dialog with our counter and see how it works. Our second page will be very similar to the simple dialog we have already encountered, and the first one manage increment step. The great difference is we have to manage more buttons, particularly the "cancel", "<<previous", "next>>" and "OK" buttons. Because I never make multi-page dialog working before writing this section, I begin with the corresponding OOBasic program.
As already explained, I think it's a good practice to solve a problem in OOoBasic before solving it in C++. Before starting this document, OOBasic was already documented in a BASIC Guide (and also in books) but you have only few examples in the SDK to learn the corresponding C++ part. In my knowledge there is no C++/UNO book. The other great reason is the need of OOBasic GUI when constructing the dialog : and then writing a OOBasic program is only a little step. |
OOBasic program
We first give the OOBasic program. The first part after the main is corresponding to the Counter, and the second part is corresponding to the next previous (Step) management. This management is realized with two Sub :
- "cmdPrev_Initiated" sub,
- "cmdNext_Initiated" sub.
When you are in Step=1 the previous button is disabled, while in the Step=2 the next button has to be disabled.
REM ***** BASIC *****
'Listing 5
Dim Dlg As Object
Dim Count As integer
Dim IncrDecr As integer
Sub Main
DialogLibraries.LoadLibrary("Standard")
Dlg = CreateUnoDialog(DialogLibraries.Standard.Dialog2)
'Because of Multi-page don't forget to manage Step :
Dlg.Model.Step=1
Dlg.Execute()
Dlg.dispose()
End Sub
'Our counter begins here <-----------
Sub Increment
Count = Count + IncrDecr
End Sub
Sub Decrement
Count = Count - IncrDecr
End Sub
Sub getCount
Dim oNumericField
oNumericField = Dlg.getControl("NumericField2")
oNumericField.Value = Count
End Sub
Sub setCount
Dim oNumericField
oNumericField = Dlg.getControl("NumericField1")
Count = oNumericField.Value
End Sub
' Our Counter ends here <------------
Sub cmdNext_Initiated
Dim cmdNext As Object
Dim cmdPrev As Object
cmdPrev = Dlg.getControl("cmdPrev")
'inspect(cmdPrev)
cmdNext = Dlg.getControl("cmdNext")
cmdPrev.Model.Enabled = Not cmdPrev.Model.Enabled
cmdNext.Model.Enabled = False
'if Next update IncrDecr
If Dlg.Model.Step = 1 Then
If Dlg.getControl("OptionButton1").State Then
IncrDecr = 1
End If
If Dlg.getControl("OptionButton2").State Then
IncrDecr = 5
End If
If Dlg.getControl("OptionButton3").State Then
IncrDecr = 10
End If
End If
Dlg.Model.Step = Dlg.Model.Step + 1
End Sub
Sub cmdPrev_Initiated
Dim cmdNext As Object
Dim cmdPrev As Object
cmdPrev = Dlg.getControl("cmdPrev")
cmdNext = Dlg.getControl("cmdNext")
cmdPrev.Model.Enabled = False
cmdNext.Model.Enabled = True
Dlg.Model.Step = Dlg.Model.Step - 1
End Sub
Note also that the radio buttons are checked only when clicking on the Next button in Step 1. The dialog then changes its appearance as follows:
where you see "<<Previous" button disabled and
where you see "Next>>" button is disabled.
C++ program
Our goal in this section is to reuse the previous multi-page dialog but with C++. It was easy for me to manage the Next Previous buttons in OOBasic but spend many hours for translating the simple OOBasic line :
REM ***** BASIC *****
Dlg.Model.Step = Dlg.Model.Step + 1
Finally Java Inspector C++ automatic code generation shows me the way. The code is as follows :
// C++
// Listing 6
// XDialogEventHandler implementation
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("increment")){//increment
increment();
return sal_True;
}
if (MethodName.equalsAscii("decrement")){//decrement
decrement();
return sal_True;
}
if (MethodName.equalsAscii("setCount")){ //setCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField1"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
setCount((sal_Int32)xNumericField->getValue());
return sal_True;
}
if (MethodName.equalsAscii("getCount")){ //getCount
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("NumericField2"));
Reference< XNumericField > xNumericField(xControl,UNO_QUERY);
xNumericField->setValue(getCount());
return sal_True;
}
if (MethodName.equalsAscii("cmdPrev_Initiated")){ //<<Previous
// xDialog is a parameter
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("cmdPrev"));
//com.sun.star.awt.XConrolModel
Reference< XControlModel> xControlModel= xControl->getModel();
Any any;
sal_Bool Boolval;
Reference< XPropertySet > xPropertySet( xControlModel,UNO_QUERY);
any=xPropertySet->getPropertyValue(OUString::createFromAscii("Enabled"));
any >>= Boolval;
Boolval = !Boolval;
any <<= Boolval;
xPropertySet->setPropertyValue(OUString::createFromAscii("Enabled"),any);
xControl=xControlContainer->getControl(OUString::createFromAscii("cmdNext"));
xControlModel= xControl->getModel();
Reference< XPropertySet > xPropertySet2( xControlModel,UNO_QUERY);
any=xPropertySet2->getPropertyValue(OUString::createFromAscii("Enabled"));
any >>= Boolval;
Boolval = !Boolval;
any <<= Boolval;
xPropertySet2->setPropertyValue(OUString::createFromAscii("Enabled"),any);
// found with JavaInspector C++ code generation :Step property management
sal_Int32 step;
Reference< XControl > xControl2 (xDialog,UNO_QUERY_THROW);
xControlModel= xControl2->getModel();
Reference< XPropertySet > xPropertySet3( xControlModel,UNO_QUERY);
step = 1;
any <<= step;
xPropertySet3->setPropertyValue(OUString::createFromAscii("Step"),any);
return sal_True;
}
if (MethodName.equalsAscii("cmdNext_Initiated")){ //Next>>
// xDialog is a parameter
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl=xControlContainer->getControl(OUString::createFromAscii("cmdPrev"));
//com.sun.star.awt.XConrolModel
Reference< XControlModel> xControlModel= xControl->getModel();
Any any;
sal_Bool Boolval;
Reference< XPropertySet > xPropertySet( xControlModel,UNO_QUERY);
any <<= sal_True;
xPropertySet->setPropertyValue(OUString::createFromAscii("Enabled"),any);
xControl=xControlContainer->getControl(OUString::createFromAscii("cmdNext"));
xControlModel= xControl->getModel();
Reference< XPropertySet > xPropertySet2( xControlModel,UNO_QUERY);
any <<= sal_False;
xPropertySet2->setPropertyValue(OUString::createFromAscii("Enabled"),any);
// RadioButton management : not great with such if !
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton1"));
Reference< XRadioButton > xRadioButton(xControl,UNO_QUERY);
if (xRadioButton->getState()) m_nDelta=1;
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton2"));
Reference< XRadioButton > xRadioButton2(xControl,UNO_QUERY);
if (xRadioButton2->getState()) m_nDelta=5;
xControl=xControlContainer->getControl(OUString::createFromAscii("OptionButton3"));
Reference< XRadioButton > xRadioButton3(xControl,UNO_QUERY);
if (xRadioButton3->getState()) m_nDelta=10;
// found with JavaInspector C++ code generation
sal_Int32 step;
// the trick is here : not line below
// Reference< XControl >xControl2=xControlContainer->getControl(OUString::createFromAscii("Dialog1"))
Reference< XControl > xControl2 (xDialog,UNO_QUERY_THROW);
xControlModel= xControl2->getModel();
Reference< XPropertySet > xPropertySet3( xControlModel,UNO_QUERY);
step = 2;
any <<= step;
xPropertySet3->setPropertyValue(OUString::createFromAscii("Step"),any);
return sal_True;
}
return sal_False;
}
Sequence< OUString > SAL_CALL MyCounterImpl::getSupportedMethodNames() throw (RuntimeException){
Sequence< OUString > SeqOUStr(6);
SeqOUStr[0]=OUString::createFromAscii("increment");
SeqOUStr[1]=OUString::createFromAscii("decrement");
SeqOUStr[2]=OUString::createFromAscii("setCount");
SeqOUStr[3]=OUString::createFromAscii("getCount");
SeqOUStr[4]=OUString::createFromAscii("cmdNext_Initiated");
SeqOUStr[5]=OUString::createFromAscii("cmdPrev_Initiated");
return SeqOUStr;
}
See com.sun.star.awt.XControl, com.sun.star.awt.XControlContainer, com.sun.star.awt.XControlModel and com.sun.star.beans.XPropertySet, Interfaces.
We turn now to other examples where we leave our Counter only because it's too simple.
The New Tree Control
The New Tree Contol is tackled here but the corresponding article is under construction (since 2006). Frankly speaking I am not completly satisfied with this control at the moment for different reasons :
- the tree expanded listener is useless if your node has no child (not fired). This raises probably problems when wanting to manage a dynamic tree (for instance for an introspection tool)
- The event property in OpenOffice.org dialog editor is too simple and is unable to replace event listener. For instance there is no event to manage a selection change as in Radio Button.
You probably wonder why I take time to write a documentation in such a situation. It's only because I think if the documentation lack nobody will use this control and then nobody will improve the code of this control. And also, I finally achieve to make dynamic trees working with only adding a button (without event listener and without an expanding event). I by-pass then both drawbacks previously evocated.
The most important concept underlying the Tree Control is that of complete separation between data and how that data is displayed on the screen. This is commonly known as Model/View/Controller-design (MVC)
- com.sun.star.awt.tree.XMutableTreeDataModel and com.sun.star.awt.tree.XMutableTreeNode interfaces are related to the model,
- com.sun.star.awt.tree.XTreeControl is related to the control and view.
Our starting OOoBasic program
rvc44 posted in OOOForum (Thu Dec 20, 2007) an example in OOoBasic which serves me as starting point. I have added event listener and obtain the code snippet as follows :
REM ***** BASIC *****
'Listing 7
Option Explicit
'Most of this code belongs to rvc44 http://www.oooforum.org/forum/viewtopic.phtml?t=67005&highlight=
Private oDlg as Object, oLbDescription as Object
Private oTreeCtrl as Object, oTreeModel as Object
Private oMutableTreeDataModel as Object
Private oRootNode as Object, oChildNode as Object, ogNode as Object
Sub mainTree '[Simple example: collapsing and expanding folders]
DialogLibraries.loadLibrary("Standard")
'create the dialog
oDlg = CreateUnoDialog(DialogLibraries.Standard.SimpleTreeDialog)
If IsNull(oDlg) Then Exit Sub
'get a refrence to the control/s and its model/s
oLbDescription = oDlg.getControl("lbDescription")
oLbDescription.setText( "A very simple tree control with listeners." & _
chr(13) & chr(13) &_
"Expanding and collapsing happends automatically" )
oTreeCtrl = oDlg.getControl("TreeControl1")
oTreeModel = oTreeCtrl.Model
'XRay oTreeModel
'instantiate the MutableTreeDataModel service
oMutableTreeDataModel = createUnoService(_
"com.sun.star.awt.tree.MutableTreeDataModel")
'XRay oMutableTreeDataModel
'MutableTreeDataModel implemets XMutableTreeDataModel
'use XMutableTreeNode::createNode(
' [in] any DisplayValue,
' [in] boolean ChildsOnDemand )
'to create the root node
'If you pass to the boolean parameter TRUE as a argument,
'the created node will be treated as a non-leaf (branch) node
'by the XTreeControl , even when it has no child nodes.
'If false, the node will be a leaf.
'The root should obviously be a non-leaf node.
oRootNode = oMutableTreeDataModel.createNode( "Root", true )
'use XMutableTreeNode::setRoot( [in] XMutableTreeNode RootNode )
'to set this node as the root of the model
oMutableTreeDataModel.setRoot(oRootNode)
'now create the children of the root
Dim oChildNode1
oChildNode1 = oMutableTreeDataModel.createNode( "Parent 1", true )
oRootNode.appendChild(oChildNode1)
'Create this child's own children
'In two steps:
Dim oSubChildNode
oSubChildNode = oMutableTreeDataModel.createNode(_
"Child 1", true )
oChildNode1.appendChild(oSubChildNode)
'In only one:
'Go deeper in the hierarchical structure
oSubChildNode.appendChild( _
oMutableTreeDataModel.createNode( _
"Grandson 1", false ) )
oSubChildNode.appendChild( _
oMutableTreeDataModel.createNode( _
"Grandson 2", false ) )
'In only one:
oChildNode1.appendChild( oMutableTreeDataModel.createNode( _
"Child 2", true ) )
'=======================================================================
'As you see, the Data Model always creates the nodes
'(XMutableDataModel::createNode)
'and then you add it to the node you want, taking care that
'the node created and the parent node belong to the same data model
Dim oChildNode2
oChildNode2 = oMutableTreeDataModel.createNode( "Parent 2", true )
oRootNode.appendChild(oChildNode2)
Dim oChildNode3
oChildNode3 = oMutableTreeDataModel.createNode( "Parent 3", FALSE )
'oChildNode3.setCollapsedGraphicURL( ANY_DOC )
'oChildNode3.setExpandedGraphicURL( ANY_DOC )
'oChildNode3.setNodeGraphicURL( BASIC_BRAKE )
oRootNode.appendChild(oChildNode3)
Dim oChildNode4
oChildNode4 = oMutableTreeDataModel.createNode( "Parent 4", true )
oRootNode.appendChild(oChildNode4)
Dim oChildNode5
oChildNode5 = oMutableTreeDataModel.createNode( "Parent 5", true )
oRootNode.appendChild(oChildNode5)
Dim oChildNode6
oChildNode6 = oMutableTreeDataModel.createNode( "Parent 6", FALSE )
oRootNode.appendChild(oChildNode6)
'Although the API refrence states the following:
' "If you want to add child nodes to your tree on demand
' you can .[..] Make sure the parent node returns true
' for XTreeNode::hasChildsOnDemand() either by implementing
' XTreeNode yourself or, if you use the MutableTreeDataModel ,
' use XMutableTreeNode::setHasChildsOnDemand() ."
'https://www.openoffice.org/api/docs/common/ref/com/sun/star/awt/tree/TreeControl.html
Dim bHasChildernOnDemand as Boolean
'in this case hasChildsOnDemand returns FALSE
'bHasChildernOnDemand = oChildNode6.hasChildsOnDemand()
Dim aChild : aChild = oMutableTreeDataModel.createNode( "Grandson", FALSE )
'BUT the node is appended to this node that has no children on demand
oChildNode6.appendChild(aChild)
'Should it throw an exception?
'set the data model at the TreeControlModel::DataModel property.
oTreeModel.DataModel = oMutableTreeDataModel
' oTreeCtrl.DefaultExpandedGraphicURL = FOLDER_OPEN
'oTreeCtrl.DefaultCollapsedGraphicURL = FOLDER_CLOSED
Dim oListener,oListener2
oListener = CreateUnoListener("Tree_","com.sun.star.awt.tree.XTreeExpansionListener")
oListener2 = createUnoListener("Select_","com.sun.star.view.XSelectionChangeListener")
'Xray oListener2
oTreeCtrl.addTreeExpansionListener(oListener)
oTreeCtrl.addSelectionChangeListener(oListener2)
oDlg.execute()
oTreeCtrl.removeSelectionChangeListener(oListener2)
oTreeCtrl.removeTreeExpansionListener(oListener)
oDlg.dispose()
End Sub
Sub Tree_treeExpanding(oEvt)
'oEvt.Node has methods :
'getChildAt Returns the child tree node at Index .
'getChildCount Returns the number of child nodes.
'getParent Returns the parent node of this node.
'getIndex Returns the index of Node in this instances children.
'hasChildsOnDemand Returns true if the children of this node are created on demand.
'getDisplayValue If not empty, the textual representation of this any is used as the text part of this node.
'getNodeGraphicURL The URL for a graphic that is rendered before the text part of this node.
'getExpandedGraphicURL The URL for a graphic that is rendered to visualize expanded non leaf nodes.
'getCollapsedGraphicURL The URL for a graphic that is rendered to visualize collapsed non leaf nodes.
MsgBox("Node : " & oEvt.Node.getDisplayValue &" expanding")
ogNode = oEvt.Node
end sub
Sub Tree_treeExpanded(oEvt)
' MsgBox("Tree expanded")
end sub
Sub Tree_treeCollapsing(oEvt)
'MsgBox("Tree collapsing")
end sub
Sub Tree_treeCollapsed(oEvt)
' MsgBox("Tree collapsed")
end sub
Sub Tree_requestChildNodes(oEvt)
'print oEvt.Node.getIndex(oEvt.Node)
'XRay oEvt.Node
' Msgbox ("Tree_requestChildNodes")
End Sub
Sub Tree_disposing(oEvt)
' Msgbox ("Tree_disposing")
End Sub
Sub Select_selectionChanged(oEvt)
MsgBox("Selection Changed")
end sub
Here is the corresponding snapshot
where you see a "treeExpanding" listener at work, and the second with another listener ("selection change") at work.
If you want to construct such a tree with another programming language, you have to investigate the corresponding interfaces :
- com.sun.star.awt.tree.XMutableTreeDataModel with
createNode
andsetRoot
methods, - com.sun.star.awt.tree.XMutableTreeNode with
appendChild
method, - com.sun.star.awt.tree.XTreeControl -|> com.sun.star.view.XMultiSelectionSupplier -|> com.sun.star.view.XSelectionSupplier with
getSelection
method (-|> is a simplified inheritance notation).
It's time to examine the C++ translation of this example.
C++ Code without Listener
As usual we plan to use the previous OOoBasic dialog but with C++ code. Because we only want a demonstration we will simplify the Tree. Our goal is to retrieve the expanded node but as mentioned in the section title we don't want to use listener that means we want only to manage events of the tree dialog control with our member functions. We will investigate first with OOoBasic.
Managing Events of Tree Control with OOoBasic
Our goal is simple : retrieve the selected node of the tree. We first remove all the event listener of the OOoBasic code :
REM ***** BASIC *****
'Listing 8
...
Sub mainTree '[Simple example: collapsing and expanding folders]
.....
'Dim oListener,oListener2
'oListener = CreateUnoListener("Tree_","com.sun.star.awt.tree.XTreeExpansionListener")
'oListener2 = createUnoListener("Select_","com.sun.star.view.XSelectionChangeListener")
'Xray oListener2
'oTreeCtrl.addTreeExpansionListener(oListener)
'oTreeCtrl.addSelectionChangeListener(oListener2)
oDlg.execute()
'oTreeCtrl.removeSelectionChangeListener(oListener2)
'oTreeCtrl.removeTreeExpansionListener(oListener)
oDlg.dispose()
End Sub
We choose among the events shown below
where you can see the Losing Focus Event ("perte de focus" in French) is used with the sub :
REM ***** BASIC *****
'Listing 9
Sub LosingFocus(Event As Object)
'inspect(oTreeCtrl)
'getSelection is member function of com.sun.star.awt.tree.XTreeControl interface
'getDisplayValue is member function of com.sun.star.awt.tree.XTreeNode interface
MsgBox(oTreeCtrl.getSelection.getDisplayValue())
End Sub
When expanding the tree and selecting a node, you only click in the Text control to see the result
where you see the LosingFocus Sub above is fired.
Managing Events of Tree Control with a C++ member function
We change the preceding OOoBasic example in four ways :
- we simplify the tree to be displayed,
- we display the selection in the already present control text instead of in a message Box,
- because we are dealing with components (and not addon) we have to start from an IDL file. I have keept the counter IDL file even if my new Dialog is unable to make it working.
- the "losing focus" event property is bound to a component method called "LosingFocus" (see Developper's Guide).
The new Constructor
The constructor has to display the tree in the corresponding control. To say it differently we shall find almost of the OOoBasic "mainTree" sub of the previous example in this constructor. The code is then as follows :
// cpp
// Listing 10
inline MyCounterImpl( Reference< XComponentContext > const & xContext) throw ()
: m_xContext( xContext ) {
m_xMCF=m_xContext->getServiceManager();
Reference< XDesktop > xDesktop(
m_xMCF->createInstanceWithContext(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ),
xContext ), UNO_QUERY_THROW );
Reference< XComponent > xcomponent = xDesktop->getCurrentComponent();
Sequence< Any> Args(1);
Args[0] <<= xcomponent;
Reference< XDialogProvider2 > xDialog2(m_xMCF->createInstanceWithArgumentsAndContext(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) ),
Args,
xContext),
UNO_QUERY_THROW );
// Uncomment below and comment above if you want the OOoDesktop as parent of your dialog
// Reference< XDialogProvider2 > xDialog2(m_xMCF->createInstanceWithContext(
// OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) ),
// xContext),
// UNO_QUERY_THROW );
Reference< XDialog > xDialog=xDialog2->createDialogWithHandler(
OUString::createFromAscii( "vnd.sun.star.script:Standard.SimpleTreeDialog?location=application" ),
(XCountable *)this);
// Constructing the Tree (17th Jul 2009)
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl = xControlContainer->getControl(OUString::createFromAscii("TreeControl"));
Reference< XMutableTreeDataModel > xTreeMutDatMod (m_xMCF->createInstanceWithContext(
OUString::createFromAscii("com.sun.star.awt.tree.MutableTreeDataModel"),xContext),UNO_QUERY_THROW);
// Reference< XMutableTreeDataModel > xTreeMutDatMod(xTreeControl,UNO_QUERY); //NO NO NO:hangs the office
Any any;
any <<= OUString::createFromAscii("root");
Reference< XMutableTreeNode > xMTN=xTreeMutDatMod->createNode(any,sal_True);
xTreeMutDatMod->setRoot(xMTN);
any <<= OUString::createFromAscii("Parent 1");
Reference< XMutableTreeNode > xChildNode = xTreeMutDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
any <<= OUString::createFromAscii("Child 1");
Reference< XMutableTreeNode > xChildNode2 = xTreeMutDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
any <<= OUString::createFromAscii("Grandson 1");
Reference< XMutableTreeNode > xChildNode3 = xTreeMutDatMod->createNode(any,sal_False);
xChildNode2->appendChild(xChildNode3);
any <<= OUString::createFromAscii("Grandson 2");
xChildNode3 = xTreeMutDatMod->createNode(any,sal_False);
xChildNode2->appendChild(xChildNode3);
any <<= OUString::createFromAscii("Child 2");
xChildNode2 = xTreeMutDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
any <<= OUString::createFromAscii("Parent 2");
xChildNode=xTreeMutDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
// set the model to see the tree in control (two hours to find the four lines below)
// translation of oTreeModel = oTreeCtrl.Model and oTreeModel.DataModel = oMutableTreeDataModel
Reference< XControlModel > xControlModel=xControl->getModel();
Reference< XPropertySet > xPropertySet( xControlModel,UNO_QUERY);
any <<= xTreeMutDatMod;
xPropertySet->setPropertyValue(OUString::createFromAscii("DataModel"),any);
// execute dialog
xDialog->execute();
}
The "LosingFocus" method
The LosingFocus sub in OOoBasic was very simple. I have translated it with Introspection tools and IDL documentation like com.sun.star.awt.tree.XTreeControl, com.sun.star.awt.tree.XTreeNode and com.sun.star.awt.XTextComponent.
// C++
// Listing 11
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("LosingFocus")){//When Losing Focus in Tree control
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl = xControlContainer->getControl(OUString::createFromAscii("TreeControl"));
// com.sun.star.awt.tree.XTreeControl
Reference< XTreeControl > xTreeControl(xControl,UNO_QUERY);
Any any=xTreeControl->getSelection();
Reference< XTreeNode > xTreeNode;
any >>= xTreeNode;
// put the result of selection in text control
xControl = xControlContainer->getControl(OUString::createFromAscii("lbDescription"));
Reference< XTextComponent > xTextComponent(xControl,UNO_QUERY);
any = xTreeNode->getDisplayValue();
OUString OUStr;
any >>= OUStr;
xTextComponent->setText(OUStr + OUString::createFromAscii(" -- DONE --"));
return sal_True;
}
return sal_False;
}
This method is called when losing focus : click in the text control, for instance.
Here is a snapshot of the corresponding dialog :
Because only a method is used, you have also to change the getSupportedMethodNames()
member function :
// C++
// Listing 12
Sequence< OUString > SAL_CALL MyCounterImpl::getSupportedMethodNames() throw (RuntimeException){
Sequence< OUString > SeqOUStr(1);
SeqOUStr[0]=OUString::createFromAscii("LosingFocus");
// SeqOUStr[1]=OUString::createFromAscii("foo2");
// SeqOUStr[2]=OUString::createFromAscii("foo3");
// SeqOUStr[3]=OUString::createFromAscii("foo4");
return SeqOUStr;
}
I am not sure xml2cmp tools which proceeds the CppComponent.uno.xml file is able to work with a type as follows :
<type>com.sun.star.awt.tree.XTreeControl</type>
In this type, there is four level (com/sun/star/tree) before the module name, instead of usually three. Is the problem here ? Have added it to MakeFile to make it working. If you confirm or infirm that, please contact me.SergeMoutou 16:30, 17 July 2009 (UTC) |
C++ code with listener
Altough I like event listener in OOoBasic I dislike them in C++ : they are easy to use in OOoBasic but hard in C++. Then I don't know when I will write such a documentation.
TO DO
Dynamic Trees
In this section, we want to Investigate how to manage a dynamic tree. A dynamic tree is a tree that is constructed on the demand.
Dynamic Trees in OOoBasic
In fact I begun to write the next section first. Because I encounter some problem I decided to write this section. After many hours I was not able to make dynamic tree working in C++ while it takes me only few minutes to make it working in OOoBasic ! FYI : dynamic Trees in C++ in the next section are working now.
I keep the initial OOoBasic tree and add two buttons : "OK" button and "add Child" button. You select a node and when clicking on "add Child" button a child is added. Its name is the name of the selected node followed with ".n" where n is the number of the child. This is a dynamic tree because its size is not fixed. Its code is as follows:
REM ***** BASIC *****
'Listing 14
Option Explicit
Private oDlg as Object, oLbDescription as Object
Private oTreeCtrl as Object, oTreeModel as Object
Private oMutableTreeDataModel as Object
Private oRootNode as Object, oChildNode as Object, ogNode as Object
Sub mainTree '[Simple example: collapsing and expanding folders]
DialogLibraries.loadLibrary("Standard")
oDlg = CreateUnoDialog(DialogLibraries.Standard.SimpleTreeDialog)
If IsNull(oDlg) Then Exit Sub
oTreeCtrl = oDlg.getControl("TreeControl1")
oTreeModel = oTreeCtrl.Model
oMutableTreeDataModel = createUnoService(_
"com.sun.star.awt.tree.MutableTreeDataModel")
oRootNode = oMutableTreeDataModel.createNode( "Root", true )
oMutableTreeDataModel.setRoot(oRootNode)
Dim oChildNode1
oChildNode1 = oMutableTreeDataModel.createNode( "Parent 1", true )
oRootNode.appendChild(oChildNode1)
'Create this child's own children
'In two steps:
Dim oSubChildNode
oSubChildNode = oMutableTreeDataModel.createNode(_
"Child 1", true )
oChildNode1.appendChild(oSubChildNode)
'In only one:
'Go deeper in the hierarchical structure
oSubChildNode.appendChild( _
oMutableTreeDataModel.createNode( _
"Grandson 1", false ) )
oSubChildNode.appendChild( _
oMutableTreeDataModel.createNode( _
"Grandson 2", false ) )
'In only one:
oChildNode1.appendChild( oMutableTreeDataModel.createNode( _
"Child 2", true ) )
Dim oChildNode2
oChildNode2 = oMutableTreeDataModel.createNode( "Parent 2", true )
oRootNode.appendChild(oChildNode2)
Dim oChildNode3
oChildNode3 = oMutableTreeDataModel.createNode( "Parent 3", FALSE )
oRootNode.appendChild(oChildNode3)
Dim oChildNode4
oChildNode4 = oMutableTreeDataModel.createNode( "Parent 4", true )
oRootNode.appendChild(oChildNode4)
Dim oChildNode5
oChildNode5 = oMutableTreeDataModel.createNode( "Parent 5", true )
oRootNode.appendChild(oChildNode5)
Dim oChildNode6
oChildNode6 = oMutableTreeDataModel.createNode( "Parent 6", FALSE )
oRootNode.appendChild(oChildNode6)
Dim bHasChildernOnDemand as Boolean
Dim aChild : aChild = oMutableTreeDataModel.createNode( "Grandson", FALSE )
oChildNode6.appendChild(aChild)
oTreeModel.DataModel = oMutableTreeDataModel
oDlg.execute()
oDlg.dispose()
End Sub
Sub addChild(Event As Object)
Dim oParentNode, oChildNode
Dim nb as long
Dim oChildName as String
oParentNode = oTreeCtrl.getSelection()
nb = oParentNode.getChildCount()
nb=nb+1 'I want numerotation begins with 1
oChildName = oParentNode.getDisplayValue() + "." + nb
oChildNode = oMutableTreeDataModel.createNode(oChildName , TRUE )
oParentNode.appendChild(oChildNode)
oLbDescription = oDlg.getControl("lbDescription")
oLbDescription.setText(oChildName)
End Sub
The sub "addChild" is bound with the corresponding button. Here is a snapshot of a result:
Question : what is the last created node ? Answer see the Text control : "Root.7.1.2".
Let's turn to the corresponding C++ example.
Dynamic Trees in C++
I start from the previous tree (C++) with the same functioning as in previous section. When a node is selected, "add Child" button creates a child with name nodename.i where i is the number of the child and nodename the name of the node. For debuging intention, I put also the name of the added node in the text control.
Our new constructor
The constructor of previous section is slighty modified. Here is the corresponding code :
// c++
// Listing 15
// added this constructor 06/06/09
inline MyCounterImpl( Reference< XComponentContext > const & xContext) throw ()
: m_xContext( xContext ) {
m_xMCF=m_xContext->getServiceManager();
// Reference< XMutableTreeDataModel > xTreeMutDatMod(xTreeControl,UNO_QUERY); //NO NO NO:hangs the office : see below
Reference< XMutableTreeDataModel > xMutTreeDatMod(m_xMCF->createInstanceWithContext(
OUString::createFromAscii("com.sun.star.awt.tree.MutableTreeDataModel"),m_xContext),UNO_QUERY_THROW);
m_xMutTreeDatMod = xMutTreeDatMod;
// If you want to use java Inspector
Reference< XInstanceInspector > xInspector(m_xMCF->createInstanceWithContext(
OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.InstanceInspector" ) ),
m_xContext),
UNO_QUERY_THROW );
m_xInspector = xInspector;
Reference< XDesktop > xDesktop(
m_xMCF->createInstanceWithContext(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ),
xContext ), UNO_QUERY_THROW );
Reference< XComponent > xcomponent = xDesktop->getCurrentComponent();
Sequence< Any> Args(1);
Args[0] <<= xcomponent;
Reference< XDialogProvider2 > xDialog2(m_xMCF->createInstanceWithArgumentsAndContext(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) ),
Args,
xContext),
UNO_QUERY_THROW );
// Reference< XDialogProvider2 > xDialog2(m_xMCF->createInstanceWithContext(
// OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) ),
// xContext),
// UNO_QUERY_THROW );
Reference< XDialog > xDialog=xDialog2->createDialogWithHandler(
OUString::createFromAscii( "vnd.sun.star.script:Standard.SimpleTreeDialog?location=application" ),
(XCountable *)this);
// Constructing the Tree 21th Jul 2009 (dynamic Tree)
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl = xControlContainer->getControl(OUString::createFromAscii("TreeControl"));
Any any;
any <<= OUString::createFromAscii("root");
Reference< XMutableTreeNode > xMTN=m_xMutTreeDatMod->createNode(any,sal_True);
m_xMutTreeDatMod->setRoot(xMTN);
any <<= OUString::createFromAscii("Parent 1");
Reference< XMutableTreeNode > xChildNode = m_xMutTreeDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
any <<= OUString::createFromAscii("Child 1");
Reference< XMutableTreeNode > xChildNode2 = m_xMutTreeDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
any <<= OUString::createFromAscii("Grandson 1");
Reference< XMutableTreeNode > xChildNode3 = m_xMutTreeDatMod->createNode(any,sal_False);
xChildNode2->appendChild(xChildNode3);
any <<= OUString::createFromAscii("Grandson 2");
xChildNode3 = m_xMutTreeDatMod->createNode(any,sal_False);
xChildNode2->appendChild(xChildNode3);
any <<= OUString::createFromAscii("Child 2");
xChildNode2 = m_xMutTreeDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
any <<= OUString::createFromAscii("Parent 2");
xChildNode=m_xMutTreeDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
// set the model to see the tree in control (two hours to find four lines below)
// translation of oTreeModel = oTreeCtrl.Model and oTreeModel.DataModel = oMutableTreeDataModel
Reference< XControlModel > xControlModel=xControl->getModel();
Reference< XPropertySet > xPropertySet( xControlModel,UNO_QUERY);
any <<= m_xMutTreeDatMod;
xPropertySet->setPropertyValue(OUString::createFromAscii("DataModel"),any);
// execute dialog
xDialog->execute();
}
// end of constructor
The new callHandlerMethod
As you can see in the code below only "addChild" method is used in this example:
// C++
// Listing 16
// XDialogEventHandler implementation
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("LosingFocus")){//When Losing Focus in Tree control
// not used in this example
return sal_True;
}
if (MethodName.equalsAscii("addChild")){//add a child to the selected node
// First retrieve the selection
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl = xControlContainer->getControl(OUString::createFromAscii("TreeControl"));
// com.sun.star.awt.tree.XTreeControl
Reference< XTreeControl > xTreeControl(xControl,UNO_QUERY);
Any any=xTreeControl->getSelection();
// Parent
Reference< XMutableTreeNode > xParentNode;
any >>= xParentNode;
// adding
sal_Int32 nb=xParentNode->getChildCount();
// Child
OUString OUStr;
any=xParentNode->getDisplayValue();
any >>= OUStr;
OUStr = OUStr + OUString::createFromAscii(".") + OUString::valueOf((sal_Int32)++nb);
// put the new node name in text control
xControl = xControlContainer->getControl(OUString::createFromAscii("lbDescription"));
Reference< XTextComponent > xTextComponent(xControl,UNO_QUERY);
xTextComponent->setText(OUStr);
any <<= OUStr;
Reference< XMutableTreeNode > xChildMutTreeNode = m_xMutTreeDatMod->createNode(any ,sal_True);
// Introspection
// any <<= xChildMutTreeNode;
// m_xInspector->inspect(any,OUString::createFromAscii("Inspector"));
xParentNode->appendChild(xChildMutTreeNode);
return sal_True;
}
return sal_False;
}
Sequence< OUString > SAL_CALL MyCounterImpl::getSupportedMethodNames() throw (RuntimeException){
Sequence< OUString > SeqOUStr(2);
SeqOUStr[0]=OUString::createFromAscii("LosingFocus");
SeqOUStr[1]=OUString::createFromAscii("addChild");
return SeqOUStr;
}
Here is a snapshot
where you can see all the nodes added.
See The Cpp Inspector to see an application of a dynamic Tree in a dialog.
General Remark
In this chapter I always use the component constructor to print out the dialog. I am not sure it's a good choice for professional components. I plan to write a chapter on writing professional components but it would be better with a lot of practice that I haven't at the moment. |
Home Page
See also
- French version of this chapter
- Constructing Components
- Component and Dialog
- The New Tree Contol (in construction)
- The corresponding paragraph in Developer's Guide
- Generic UNO Interfaces for complex toolbar controls
- Popup Menu Controller and C++
- Statusbar Controler and C++
- C++ and UNO tutorial
- Service Declaration
- Registering properties
- UNO tutorial
- UNO IDL
- Extensions Packager (BasicAddonBuilder from Paolo Mantovani)
- BASIC UNO Object Browser : You can see the corresponding code as a complex component.
- Minimal Java Component
- Managing Dialogs in OOoBasic.
- OOoBasic Guide