xref: /AOO41X/main/extensions/source/dbpilots/gridwizard.cxx (revision 2a97ec55f1442d65917e8c8b82a55ab76c9ff676)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 #include "gridwizard.hxx"
27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 #include <com/sun/star/sdbc/DataType.hpp>
29 #include <comphelper/stl_types.hxx>
30 #include <tools/string.hxx>
31 #include <com/sun/star/form/XGridColumnFactory.hpp>
32 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
33 #include <com/sun/star/container/XNameContainer.hpp>
34 #include <tools/debug.hxx>
35 #include "dbptools.hxx"
36 #include "dbpilots.hrc"
37 
38 #define GW_STATE_DATASOURCE_SELECTION   0
39 #define GW_STATE_FIELDSELECTION         1
40 
41 //.........................................................................
42 namespace dbp
43 {
44 //.........................................................................
45 
46     using namespace ::com::sun::star::uno;
47     using namespace ::com::sun::star::lang;
48     using namespace ::com::sun::star::beans;
49     using namespace ::com::sun::star::sdbc;
50     using namespace ::com::sun::star::container;
51     using namespace ::com::sun::star::form;
52     using namespace ::com::sun::star::awt;
53     using namespace ::svt;
54 
55     //=====================================================================
56     //= OGridWizard
57     //=====================================================================
58     //---------------------------------------------------------------------
OGridWizard(Window * _pParent,const Reference<XPropertySet> & _rxObjectModel,const Reference<XMultiServiceFactory> & _rxORB)59     OGridWizard::OGridWizard( Window* _pParent,
60             const Reference< XPropertySet >& _rxObjectModel, const Reference< XMultiServiceFactory >& _rxORB )
61         :OControlWizard(_pParent, ModuleRes(RID_DLG_GRIDWIZARD), _rxObjectModel, _rxORB)
62         ,m_bHadDataSelection(sal_True)
63     {
64         initControlSettings(&m_aSettings);
65 
66         m_pPrevPage->SetHelpId(HID_GRIDWIZARD_PREVIOUS);
67         m_pNextPage->SetHelpId(HID_GRIDWIZARD_NEXT);
68         m_pCancel->SetHelpId(HID_GRIDWIZARD_CANCEL);
69         m_pFinish->SetHelpId(HID_GRIDWIZARD_FINISH);
70 
71         // if we do not need the data source selection page ...
72         if (!needDatasourceSelection())
73         {   // ... skip it!
74             skip(1);
75             m_bHadDataSelection = sal_False;
76         }
77     }
78 
79     //---------------------------------------------------------------------
approveControl(sal_Int16 _nClassId)80     sal_Bool OGridWizard::approveControl(sal_Int16 _nClassId)
81     {
82         if (FormComponentType::GRIDCONTROL != _nClassId)
83             return sal_False;
84 
85         Reference< XGridColumnFactory > xColumnFactory(getContext().xObjectModel, UNO_QUERY);
86         if (!xColumnFactory.is())
87             return sal_False;
88 
89         return sal_True;
90     }
91 
92     //---------------------------------------------------------------------
implApplySettings()93     void OGridWizard::implApplySettings()
94     {
95         const OControlWizardContext& rContext = getContext();
96 
97         // the factory for the columns
98         Reference< XGridColumnFactory > xColumnFactory(rContext.xObjectModel, UNO_QUERY);
99         DBG_ASSERT(xColumnFactory.is(), "OGridWizard::implApplySettings: should never have made it 'til here!");
100             // (if we're here, what the hell happened in approveControl??)
101 
102         // the container for the columns
103         Reference< XNameContainer > xColumnContainer(rContext.xObjectModel, UNO_QUERY);
104         DBG_ASSERT(xColumnContainer.is(), "OGridWizard::implApplySettings: no container!");
105 
106         if (!xColumnFactory.is() || !xColumnContainer.is())
107             return;
108 
109         static const ::rtl::OUString s_sDataFieldProperty   = ::rtl::OUString::createFromAscii("DataField");
110         static const ::rtl::OUString s_sLabelProperty       = ::rtl::OUString::createFromAscii("Label");
111         static const ::rtl::OUString s_sWidthProperty       = ::rtl::OUString::createFromAscii("Width");
112         static const ::rtl::OUString s_sMouseWheelBehavior  = ::rtl::OUString::createFromAscii("MouseWheelBehavior");
113         static const ::rtl::OUString s_sEmptyString;
114 
115         // collect "descriptors" for the to-be-created (grid)columns
116         DECLARE_STL_VECTOR( ::rtl::OUString, StringArray );
117         StringArray aColumnServiceNames;    // service names to be used with the XGridColumnFactory
118         StringArray aColumnLabelPostfixes;  // postfixes to append to the column labels
119         StringArray aFormFieldNames;        // data field names
120 
121         aColumnServiceNames.reserve(getSettings().aSelectedFields.getLength());
122         aColumnLabelPostfixes.reserve(getSettings().aSelectedFields.getLength());
123         aFormFieldNames.reserve(getSettings().aSelectedFields.getLength());
124 
125         // loop through the selected field names
126         const ::rtl::OUString* pSelectedFields = getSettings().aSelectedFields.getConstArray();
127         const ::rtl::OUString* pEnd = pSelectedFields + getSettings().aSelectedFields.getLength();
128         for (;pSelectedFields < pEnd; ++pSelectedFields)
129         {
130             // get the information for the selected column
131             sal_Int32 nFieldType = DataType::OTHER;
132             OControlWizardContext::TNameTypeMap::const_iterator aFind = rContext.aTypes.find(*pSelectedFields);
133             if ( aFind != rContext.aTypes.end() )
134                 nFieldType = aFind->second;
135 
136             aFormFieldNames.push_back(*pSelectedFields);
137             switch (nFieldType)
138             {
139                 case DataType::BIT:
140                 case DataType::BOOLEAN:
141                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("CheckBox"));
142                     aColumnLabelPostfixes.push_back(s_sEmptyString);
143                     break;
144 
145                 case DataType::TINYINT:
146                 case DataType::SMALLINT:
147                 case DataType::INTEGER:
148                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("NumericField"));
149                     aColumnLabelPostfixes.push_back(s_sEmptyString);
150                     break;
151 
152                 case DataType::FLOAT:
153                 case DataType::REAL:
154                 case DataType::DOUBLE:
155                 case DataType::NUMERIC:
156                 case DataType::DECIMAL:
157                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("FormattedField"));
158                     aColumnLabelPostfixes.push_back(s_sEmptyString);
159                     break;
160 
161                 case DataType::DATE:
162                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("DateField"));
163                     aColumnLabelPostfixes.push_back(s_sEmptyString);
164                     break;
165 
166                 case DataType::TIME:
167                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("TimeField"));
168                     aColumnLabelPostfixes.push_back(s_sEmptyString);
169                     break;
170 
171                 case DataType::TIMESTAMP:
172                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("DateField"));
173                     aColumnLabelPostfixes.push_back(String(ModuleRes(RID_STR_DATEPOSTFIX)));
174 
175                     aFormFieldNames.push_back(*pSelectedFields);
176                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("TimeField"));
177                     aColumnLabelPostfixes.push_back(String(ModuleRes(RID_STR_TIMEPOSTFIX)));
178                     break;
179 
180                 default:
181                     aColumnServiceNames.push_back(::rtl::OUString::createFromAscii("TextField"));
182                     aColumnLabelPostfixes.push_back(s_sEmptyString);
183             }
184         }
185 
186         DBG_ASSERT( aFormFieldNames.size() == aColumnServiceNames.size()
187                 &&  aColumnServiceNames.size() == aColumnLabelPostfixes.size(),
188                 "OGridWizard::implApplySettings: inconsistent descriptor sequences!");
189 
190         // now loop through the descriptions and create the (grid)columns out of th descriptors
191         {
192             Reference< XNameAccess > xExistenceChecker(xColumnContainer.get());
193 
194             ConstStringArrayIterator pColumnServiceName = aColumnServiceNames.begin();
195             ConstStringArrayIterator pColumnLabelPostfix = aColumnLabelPostfixes.begin();
196             ConstStringArrayIterator pFormFieldName = aFormFieldNames.begin();
197             ConstStringArrayIterator pColumnServiceNameEnd = aColumnServiceNames.end();
198 
199             for (;pColumnServiceName < pColumnServiceNameEnd; ++pColumnServiceName, ++pColumnLabelPostfix, ++pFormFieldName)
200             {
201                 // create a (grid)column for the (resultset)column
202                 try
203                 {
204                     Reference< XPropertySet > xColumn( xColumnFactory->createColumn(*pColumnServiceName), UNO_SET_THROW );
205                     Reference< XPropertySetInfo > xColumnPSI( xColumn->getPropertySetInfo(), UNO_SET_THROW );
206 
207                     ::rtl::OUString sColumnName(*pColumnServiceName);
208                     disambiguateName(xExistenceChecker, sColumnName);
209 
210                     // the data field the column should be bound to
211                     xColumn->setPropertyValue(s_sDataFieldProperty, makeAny(*pFormFieldName));
212                     // the label
213                     xColumn->setPropertyValue(s_sLabelProperty, makeAny(::rtl::OUString(*pFormFieldName) += *pColumnLabelPostfix));
214                     // the width (<void/> => column will be auto-sized)
215                     xColumn->setPropertyValue(s_sWidthProperty, Any());
216 
217                     if ( xColumnPSI->hasPropertyByName( s_sMouseWheelBehavior ) )
218                         xColumn->setPropertyValue( s_sMouseWheelBehavior, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
219 
220                     // insert the column
221                     xColumnContainer->insertByName(sColumnName, makeAny(xColumn));
222                 }
223                 catch(Exception&)
224                 {
225                     DBG_ERROR(  ::rtl::OString("OGridWizard::implApplySettings: unexpected exception while creating the grid column for field ")
226                             +=  ::rtl::OString(pFormFieldName->getStr(), pFormFieldName->getLength(), gsl_getSystemTextEncoding())
227                             +=  ::rtl::OString("!"));
228                 }
229             }
230         }
231     }
232 
233     //---------------------------------------------------------------------
createPage(WizardState _nState)234     OWizardPage* OGridWizard::createPage(WizardState _nState)
235     {
236         switch (_nState)
237         {
238             case GW_STATE_DATASOURCE_SELECTION:
239                 return new OTableSelectionPage(this);
240             case GW_STATE_FIELDSELECTION:
241                 return new OGridFieldsSelection(this);
242         }
243 
244         return NULL;
245     }
246 
247     //---------------------------------------------------------------------
determineNextState(WizardState _nCurrentState) const248     WizardTypes::WizardState OGridWizard::determineNextState( WizardState _nCurrentState ) const
249     {
250         switch (_nCurrentState)
251         {
252             case GW_STATE_DATASOURCE_SELECTION:
253                 return GW_STATE_FIELDSELECTION;
254             case GW_STATE_FIELDSELECTION:
255                 return WZS_INVALID_STATE;
256         }
257 
258         return WZS_INVALID_STATE;
259     }
260 
261     //---------------------------------------------------------------------
enterState(WizardState _nState)262     void OGridWizard::enterState(WizardState _nState)
263     {
264         OControlWizard::enterState(_nState);
265 
266         enableButtons(WZB_PREVIOUS, m_bHadDataSelection ? (GW_STATE_DATASOURCE_SELECTION < _nState) : GW_STATE_FIELDSELECTION < _nState);
267         enableButtons(WZB_NEXT, GW_STATE_FIELDSELECTION != _nState);
268         if (_nState < GW_STATE_FIELDSELECTION)
269             enableButtons(WZB_FINISH, sal_False);
270 
271         if (GW_STATE_FIELDSELECTION == _nState)
272             defaultButton(WZB_FINISH);
273     }
274 
275     //---------------------------------------------------------------------
leaveState(WizardState _nState)276     sal_Bool OGridWizard::leaveState(WizardState _nState)
277     {
278         if (!OControlWizard::leaveState(_nState))
279             return sal_False;
280 
281         if (GW_STATE_FIELDSELECTION == _nState)
282             defaultButton(WZB_NEXT);
283 
284         return sal_True;
285     }
286 
287     //---------------------------------------------------------------------
onFinish()288     sal_Bool OGridWizard::onFinish()
289     {
290         if ( !OControlWizard::onFinish() )
291             return sal_False;
292 
293         implApplySettings();
294 
295         return sal_True;
296     }
297 
298     //=====================================================================
299     //= OGridFieldsSelection
300     //=====================================================================
301     //---------------------------------------------------------------------
OGridFieldsSelection(OGridWizard * _pParent)302     OGridFieldsSelection::OGridFieldsSelection( OGridWizard* _pParent )
303         :OGridPage(_pParent, ModuleRes(RID_PAGE_GW_FIELDSELECTION))
304         ,m_aFrame               (this, ModuleRes(FL_FRAME))
305         ,m_aExistFieldsLabel    (this, ModuleRes(FT_EXISTING_FIELDS))
306         ,m_aExistFields         (this, ModuleRes(LB_EXISTING_FIELDS))
307         ,m_aSelectOne           (this, ModuleRes(PB_FIELDRIGHT))
308         ,m_aSelectAll           (this, ModuleRes(PB_ALLFIELDSRIGHT))
309         ,m_aDeselectOne         (this, ModuleRes(PB_FIELDLEFT))
310         ,m_aDeselectAll         (this, ModuleRes(PB_ALLFIELDSLEFT))
311         ,m_aSelFieldsLabel      (this, ModuleRes(FT_SELECTED_FIELDS))
312         ,m_aSelFields           (this, ModuleRes(LB_SELECTED_FIELDS))
313     {
314         FreeResource();
315 
316         enableFormDatasourceDisplay();
317 
318         m_aSelectOne.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
319         m_aSelectAll.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
320         m_aDeselectOne.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveOneEntry));
321         m_aDeselectAll.SetClickHdl(LINK(this, OGridFieldsSelection, OnMoveAllEntries));
322 
323         m_aExistFields.SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
324         m_aSelFields.SetSelectHdl(LINK(this, OGridFieldsSelection, OnEntrySelected));
325         m_aExistFields.SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
326         m_aSelFields.SetDoubleClickHdl(LINK(this, OGridFieldsSelection, OnEntryDoubleClicked));
327     }
328 
329     //---------------------------------------------------------------------
ActivatePage()330     void OGridFieldsSelection::ActivatePage()
331     {
332         OGridPage::ActivatePage();
333         m_aExistFields.GrabFocus();
334     }
335 
336     //---------------------------------------------------------------------
canAdvance() const337     bool OGridFieldsSelection::canAdvance() const
338     {
339         return false;
340             // we're the last page in our wizard
341     }
342 
343     //---------------------------------------------------------------------
initializePage()344     void OGridFieldsSelection::initializePage()
345     {
346         OGridPage::initializePage();
347 
348         const OControlWizardContext& rContext = getContext();
349         fillListBox(m_aExistFields, rContext.aFieldNames);
350 
351         m_aSelFields.Clear();
352         const OGridSettings& rSettings = getSettings();
353         const ::rtl::OUString* pSelected = rSettings.aSelectedFields.getConstArray();
354         const ::rtl::OUString* pEnd = pSelected + rSettings.aSelectedFields.getLength();
355         for (; pSelected < pEnd; ++pSelected)
356         {
357             m_aSelFields.InsertEntry(*pSelected);
358             m_aExistFields.RemoveEntry(*pSelected);
359         }
360 
361         implCheckButtons();
362     }
363 
364     //---------------------------------------------------------------------
commitPage(::svt::WizardTypes::CommitPageReason _eReason)365     sal_Bool OGridFieldsSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
366     {
367         if (!OGridPage::commitPage(_eReason))
368             return sal_False;
369 
370         OGridSettings& rSettings = getSettings();
371         sal_uInt16 nSelected = m_aSelFields.GetEntryCount();
372 
373         rSettings.aSelectedFields.realloc(nSelected);
374         ::rtl::OUString* pSelected = rSettings.aSelectedFields.getArray();
375 
376         for (sal_uInt16 i=0; i<nSelected; ++i, ++pSelected)
377             *pSelected = m_aSelFields.GetEntry(i);
378 
379         return sal_True;
380     }
381 
382     //---------------------------------------------------------------------
implCheckButtons()383     void OGridFieldsSelection::implCheckButtons()
384     {
385         m_aSelectOne.Enable(m_aExistFields.GetSelectEntryCount() != 0);
386         m_aSelectAll.Enable(m_aExistFields.GetEntryCount() != 0);
387 
388         m_aDeselectOne.Enable(m_aSelFields.GetSelectEntryCount() != 0);
389         m_aDeselectAll.Enable(m_aSelFields.GetEntryCount() != 0);
390 
391         getDialog()->enableButtons(WZB_FINISH, 0 != m_aSelFields.GetEntryCount());
392     }
393 
394     //---------------------------------------------------------------------
IMPL_LINK(OGridFieldsSelection,OnEntryDoubleClicked,ListBox *,_pList)395     IMPL_LINK(OGridFieldsSelection, OnEntryDoubleClicked, ListBox*, _pList)
396     {
397         PushButton* pSimulateButton = &m_aExistFields == _pList ? &m_aSelectOne : &m_aDeselectOne;
398         if (pSimulateButton->IsEnabled())
399             return OnMoveOneEntry( pSimulateButton );
400         else
401             return 1L;
402     }
403 
404     //---------------------------------------------------------------------
405     IMPL_LINK(OGridFieldsSelection, OnEntrySelected, ListBox*, /*NOTINTERESTEDIN*/)
406     {
407         implCheckButtons();
408         return 0L;
409     }
410 
411     //---------------------------------------------------------------------
IMPL_LINK(OGridFieldsSelection,OnMoveOneEntry,PushButton *,_pButton)412     IMPL_LINK(OGridFieldsSelection, OnMoveOneEntry, PushButton*, _pButton)
413     {
414         sal_Bool bMoveRight = (&m_aSelectOne == _pButton);
415         ListBox& rMoveTo = bMoveRight ? m_aSelFields : m_aExistFields;
416 
417         // the index of the selected entry
418         sal_uInt16 nSelected = bMoveRight ? m_aExistFields.GetSelectEntryPos() : m_aSelFields.GetSelectEntryPos();
419         // the (original) relative position of the entry
420         sal_IntPtr nRelativeIndex = reinterpret_cast<sal_IntPtr>(bMoveRight ? m_aExistFields.GetEntryData(nSelected) : m_aSelFields.GetEntryData(nSelected));
421 
422         sal_uInt16 nInsertPos = LISTBOX_APPEND;
423         if (!bMoveRight)
424         {   // need to determine an insert pos which reflects the original
425             nInsertPos = 0;
426             while (nInsertPos < rMoveTo.GetEntryCount())
427             {
428                 if (reinterpret_cast<sal_IntPtr>(rMoveTo.GetEntryData(nInsertPos)) > nRelativeIndex)
429                     break;
430                 ++nInsertPos;
431             }
432         }
433 
434         // the text of the entry to move
435         String sMovingEntry = bMoveRight ? m_aExistFields.GetEntry(nSelected) : m_aSelFields.GetEntry(nSelected);
436 
437         // insert the entry
438         nInsertPos = rMoveTo.InsertEntry(sMovingEntry, nInsertPos);
439         // preserve it's "relative position" entry data
440         rMoveTo.SetEntryData(nInsertPos, reinterpret_cast<void*>(nRelativeIndex));
441 
442         // remove the entry from it's old list
443         if (bMoveRight)
444         {
445             sal_uInt16 nSelectPos = m_aExistFields.GetSelectEntryPos();
446             m_aExistFields.RemoveEntry(nSelected);
447             if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_aExistFields.GetEntryCount()))
448                 m_aExistFields.SelectEntryPos(nSelectPos);
449 
450             m_aExistFields.GrabFocus();
451         }
452         else
453         {
454             sal_uInt16 nSelectPos = m_aSelFields.GetSelectEntryPos();
455             m_aSelFields.RemoveEntry(nSelected);
456             if ((LISTBOX_ENTRY_NOTFOUND != nSelectPos) && (nSelectPos < m_aSelFields.GetEntryCount()))
457                 m_aSelFields.SelectEntryPos(nSelectPos);
458 
459             m_aSelFields.GrabFocus();
460         }
461 
462         implCheckButtons();
463         return 0;
464     }
465 
466     //---------------------------------------------------------------------
IMPL_LINK(OGridFieldsSelection,OnMoveAllEntries,PushButton *,_pButton)467     IMPL_LINK(OGridFieldsSelection, OnMoveAllEntries, PushButton*, _pButton)
468     {
469         sal_Bool bMoveRight = (&m_aSelectAll == _pButton);
470         m_aExistFields.Clear();
471         m_aSelFields.Clear();
472         fillListBox(bMoveRight ? m_aSelFields : m_aExistFields, getContext().aFieldNames);
473 
474         implCheckButtons();
475         return 0;
476     }
477 
478 //.........................................................................
479 }   // namespace dbp
480 //.........................................................................
481 
482