Going further with Dialog and Component
In the previous chapter we use and program only two kinds of control in our dialog. We intend in this chapter to further and use a lot of control and then see how things work in this area. You cannot read this chapter befor reading the previous one.
We begin again with our counter.
Contents
Counter with Numeric Field
When we have designed the dialog working with our counter, we have take two text controls for our numeric data. 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 code is completely similar and it would be beter 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 :
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; }
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.
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 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 with OOoBasic is tackled here. Our goal is to use a multipage dialiog with our counter and see how it works. Our second page will be very similar as 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 OOoBasic program. Template:Documentation/Note
OOoBasic program
We first give the OOoBasic program. The first part after the main is correponding to the Counter, and the seond 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 6 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
C++ program
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){ //... 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= xContol->getModel(); Any any; // possible probleme ici ... parcqu'en fait entre parentheses type any if (xControlModel->getPropertyValue(OUString::createFromAscii("Enabled")){ any <<= sal_False; xControlModel->setPropertyValue(OUString::createFromAscii("Enabled"),any); } else { any <<= sal_True; xControlModel->setPropertyValue(OUString::createFromAscii("Enabled"),any); } xControl=xControlContainer->getControl(OUString::createFromAscii("cmdNext")); xControlModel= xContol->getModel(); if (xControlModel->getPropertyValue(OUString::createFromAscii("Enabled")){ any <<= sal_False; xControlModel->setPropertyValue(OUString::createFromAscii("Enabled"),any); } else { any <<= sal_True; xControlModel->setPropertyValue(OUString::createFromAscii("Enabled"),any); } sal_Int32 step; step <<= xControlModel->getPropertyValue(OUString::createFromAscii("Step")) step--; any <<= step; xControlModel->setPropertyValue(OUString::createFromAscii("Step"),any) return salTrue; }
Home Page
See also
- Constructing Components
- Component and Dialog
- The New Tree Contol
- 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
- OOoBasic Guide
- Managing Dialogs in OOoBasic.
- Contextual Objects in OOoBasic