xref: /trunk/main/extensions/source/dbpilots/listcombowizard.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include "listcombowizard.hxx"
31 #include "commonpagesdbp.hxx"
32 #include <com/sun/star/sdbc/XConnection.hpp>
33 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/form/ListSourceType.hpp>
36 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
37 #include <tools/debug.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <connectivity/dbtools.hxx>
40 #include "dbpilots.hrc"
41 #include <comphelper/extract.hxx>
42 
43 //.........................................................................
44 namespace dbp
45 {
46 //.........................................................................
47 
48     using namespace ::com::sun::star::uno;
49     using namespace ::com::sun::star::lang;
50     using namespace ::com::sun::star::beans;
51     using namespace ::com::sun::star::sdbc;
52     using namespace ::com::sun::star::sdbcx;
53     using namespace ::com::sun::star::container;
54     using namespace ::com::sun::star::form;
55     using namespace ::svt;
56     using namespace ::dbtools;
57 
58     //=====================================================================
59     //= OListComboWizard
60     //=====================================================================
61     //---------------------------------------------------------------------
62     OListComboWizard::OListComboWizard( Window* _pParent,
63             const Reference< XPropertySet >& _rxObjectModel, const Reference< XMultiServiceFactory >& _rxORB )
64         :OControlWizard(_pParent, ModuleRes(RID_DLG_LISTCOMBOWIZARD), _rxObjectModel, _rxORB)
65         ,m_bListBox(sal_False)
66         ,m_bHadDataSelection(sal_True)
67     {
68         initControlSettings(&m_aSettings);
69 
70         m_pPrevPage->SetHelpId(HID_LISTWIZARD_PREVIOUS);
71         m_pNextPage->SetHelpId(HID_LISTWIZARD_NEXT);
72         m_pCancel->SetHelpId(HID_LISTWIZARD_CANCEL);
73         m_pFinish->SetHelpId(HID_LISTWIZARD_FINISH);
74 
75         // if we do not need the data source selection page ...
76         if (!needDatasourceSelection())
77         {   // ... skip it!
78             skip(1);
79             m_bHadDataSelection = sal_False;
80         }
81     }
82 
83     //---------------------------------------------------------------------
84     sal_Bool OListComboWizard::approveControl(sal_Int16 _nClassId)
85     {
86         switch (_nClassId)
87         {
88             case FormComponentType::LISTBOX:
89                 m_bListBox = sal_True;
90                 setTitleBase(String(ModuleRes(RID_STR_LISTWIZARD_TITLE)));
91                 return sal_True;
92             case FormComponentType::COMBOBOX:
93                 m_bListBox = sal_False;
94                 setTitleBase(String(ModuleRes(RID_STR_COMBOWIZARD_TITLE)));
95                 return sal_True;
96         }
97         return sal_False;
98     }
99 
100     //---------------------------------------------------------------------
101     OWizardPage* OListComboWizard::createPage(WizardState _nState)
102     {
103         switch (_nState)
104         {
105             case LCW_STATE_DATASOURCE_SELECTION:
106                 return new OTableSelectionPage(this);
107             case LCW_STATE_TABLESELECTION:
108                 return new OContentTableSelection(this);
109             case LCW_STATE_FIELDSELECTION:
110                 return new OContentFieldSelection(this);
111             case LCW_STATE_FIELDLINK:
112                 return new OLinkFieldsPage(this);
113             case LCW_STATE_COMBODBFIELD:
114                 return new OComboDBFieldPage(this);
115         }
116 
117         return NULL;
118     }
119 
120     //---------------------------------------------------------------------
121     WizardTypes::WizardState OListComboWizard::determineNextState( WizardState _nCurrentState ) const
122     {
123         switch (_nCurrentState)
124         {
125             case LCW_STATE_DATASOURCE_SELECTION:
126                 return LCW_STATE_TABLESELECTION;
127             case LCW_STATE_TABLESELECTION:
128                 return LCW_STATE_FIELDSELECTION;
129             case LCW_STATE_FIELDSELECTION:
130                 return getFinalState();
131         }
132 
133         return WZS_INVALID_STATE;
134     }
135 
136     //---------------------------------------------------------------------
137     void OListComboWizard::enterState(WizardState _nState)
138     {
139         OControlWizard::enterState(_nState);
140 
141         enableButtons(WZB_PREVIOUS, m_bHadDataSelection ? (LCW_STATE_DATASOURCE_SELECTION < _nState) : LCW_STATE_TABLESELECTION < _nState);
142         enableButtons(WZB_NEXT, getFinalState() != _nState);
143         if (_nState < getFinalState())
144             enableButtons(WZB_FINISH, sal_False);
145 
146         if (getFinalState() == _nState)
147             defaultButton(WZB_FINISH);
148     }
149 
150     //---------------------------------------------------------------------
151     sal_Bool OListComboWizard::leaveState(WizardState _nState)
152     {
153         if (!OControlWizard::leaveState(_nState))
154             return sal_False;
155 
156         if (getFinalState() == _nState)
157             defaultButton(WZB_NEXT);
158 
159         return sal_True;
160     }
161 
162     //---------------------------------------------------------------------
163     void OListComboWizard::implApplySettings()
164     {
165         try
166         {
167             // for quoting identifiers, we need the connection meta data
168             Reference< XConnection > xConn = getFormConnection();
169             DBG_ASSERT(xConn.is(), "OListComboWizard::implApplySettings: no connection, unable to quote!");
170             Reference< XDatabaseMetaData > xMetaData;
171             if (xConn.is())
172                 xMetaData = xConn->getMetaData();
173 
174             // do some quotings
175             if (xMetaData.is())
176             {
177                 ::rtl::OUString sQuoteString = xMetaData->getIdentifierQuoteString();
178                 if (isListBox()) // only when we have a listbox this should be not empty
179                     getSettings().sLinkedListField = quoteName(sQuoteString, getSettings().sLinkedListField);
180 
181                 ::rtl::OUString sCatalog, sSchema, sName;
182                 ::dbtools::qualifiedNameComponents( xMetaData, getSettings().sListContentTable, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
183                 getSettings().sListContentTable = ::dbtools::composeTableNameForSelect( xConn, sCatalog, sSchema, sName );
184 
185                 getSettings().sListContentField = quoteName(sQuoteString, getSettings().sListContentField);
186             }
187 
188             // ListSourceType: SQL
189             getContext().xObjectModel->setPropertyValue(::rtl::OUString::createFromAscii("ListSourceType"), makeAny((sal_Int32)ListSourceType_SQL));
190 
191             if (isListBox())
192             {
193                 // BoundColumn: 1
194                 getContext().xObjectModel->setPropertyValue(::rtl::OUString::createFromAscii("BoundColumn"), makeAny((sal_Int16)1));
195 
196                 // build the statement to set as list source
197                 String sStatement;
198                 sStatement.AppendAscii("SELECT ");
199                 sStatement += getSettings().sListContentField;
200                 sStatement.AppendAscii(", ");
201                 sStatement += getSettings().sLinkedListField;
202                 sStatement.AppendAscii(" FROM ");
203                 sStatement += getSettings().sListContentTable;
204                 Sequence< ::rtl::OUString > aListSource(1);
205                 aListSource[0] = sStatement;
206                 getContext().xObjectModel->setPropertyValue(::rtl::OUString::createFromAscii("ListSource"), makeAny(aListSource));
207             }
208             else
209             {
210                 // build the statement to set as list source
211                 String sStatement;
212                 sStatement.AppendAscii("SELECT DISTINCT ");
213                 sStatement += getSettings().sListContentField;
214                 sStatement.AppendAscii(" FROM ");
215                 sStatement += getSettings().sListContentTable;
216                 getContext().xObjectModel->setPropertyValue(::rtl::OUString::createFromAscii("ListSource"), makeAny(::rtl::OUString(sStatement)));
217             }
218 
219             // the bound field
220             getContext().xObjectModel->setPropertyValue(::rtl::OUString::createFromAscii("DataField"), makeAny(::rtl::OUString(getSettings().sLinkedFormField)));
221         }
222         catch(Exception&)
223         {
224             DBG_ERROR("OListComboWizard::implApplySettings: could not set the property values for the listbox!");
225         }
226     }
227 
228     //---------------------------------------------------------------------
229     sal_Bool OListComboWizard::onFinish()
230     {
231         if ( !OControlWizard::onFinish() )
232             return sal_False;
233 
234         implApplySettings();
235         return sal_True;
236     }
237 
238     //=====================================================================
239     //= OLCPage
240     //=====================================================================
241     //---------------------------------------------------------------------
242     Reference< XNameAccess > OLCPage::getTables(sal_Bool _bNeedIt)
243     {
244         Reference< XConnection > xConn = getFormConnection();
245         DBG_ASSERT(!_bNeedIt || xConn.is(), "OLCPage::getTables: should have an active connection when reaching this page!");
246         (void)_bNeedIt;
247 
248         Reference< XTablesSupplier > xSuppTables(xConn, UNO_QUERY);
249         Reference< XNameAccess > xTables;
250         if (xSuppTables.is())
251             xTables = xSuppTables->getTables();
252 
253         DBG_ASSERT(!_bNeedIt || xTables.is() || !xConn.is(), "OLCPage::getTables: got no tables from the connection!");
254 
255         return xTables;
256     }
257 
258     //---------------------------------------------------------------------
259     Sequence< ::rtl::OUString > OLCPage::getTableFields(sal_Bool _bNeedIt)
260     {
261         Reference< XNameAccess > xTables = getTables(_bNeedIt);
262         Sequence< ::rtl::OUString > aColumnNames;
263         if (xTables.is())
264         {
265             try
266             {
267                 // the list table as XColumnsSupplier
268                 Reference< XColumnsSupplier > xSuppCols;
269                 xTables->getByName(getSettings().sListContentTable) >>= xSuppCols;
270                 DBG_ASSERT(!_bNeedIt || xSuppCols.is(), "OLCPage::getTableFields: no columns supplier!");
271 
272                 // the columns
273                 Reference< XNameAccess > xColumns;
274                 if (xSuppCols.is())
275                     xColumns = xSuppCols->getColumns();
276 
277                 // the column names
278                 if (xColumns.is())
279                     aColumnNames = xColumns->getElementNames();
280             }
281             catch(Exception&)
282             {
283                 DBG_ASSERT(!_bNeedIt, "OLinkFieldsPage::initializePage: caught an exception while retrieving the columns!");
284             }
285         }
286         return aColumnNames;
287     }
288 
289     //=====================================================================
290     //= OContentTableSelection
291     //=====================================================================
292     //---------------------------------------------------------------------
293     OContentTableSelection::OContentTableSelection( OListComboWizard* _pParent )
294         :OLCPage(_pParent, ModuleRes(RID_PAGE_LCW_CONTENTSELECTION_TABLE))
295         ,m_aFrame               (this, ModuleRes(FL_FRAME))
296         ,m_aSelectTableLabel    (this, ModuleRes(FT_SELECTTABLE_LABEL))
297         ,m_aSelectTable         (this, ModuleRes(LB_SELECTTABLE))
298     {
299         FreeResource();
300 
301         enableFormDatasourceDisplay();
302 
303         m_aSelectTable.SetDoubleClickHdl(LINK(this, OContentTableSelection, OnTableDoubleClicked));
304         m_aSelectTable.SetSelectHdl(LINK(this, OContentTableSelection, OnTableSelected));
305     }
306 
307     //---------------------------------------------------------------------
308     void OContentTableSelection::ActivatePage()
309     {
310         OLCPage::ActivatePage();
311         m_aSelectTable.GrabFocus();
312     }
313 
314     //---------------------------------------------------------------------
315     bool OContentTableSelection::canAdvance() const
316     {
317         if (!OLCPage::canAdvance())
318             return false;
319 
320         return 0 != m_aSelectTable.GetSelectEntryCount();
321     }
322 
323     //---------------------------------------------------------------------
324     IMPL_LINK( OContentTableSelection, OnTableSelected, ListBox*, /*_pListBox*/ )
325     {
326         updateDialogTravelUI();
327         return 0L;
328     }
329 
330     //---------------------------------------------------------------------
331     IMPL_LINK( OContentTableSelection, OnTableDoubleClicked, ListBox*, _pListBox )
332     {
333         if (_pListBox->GetSelectEntryCount())
334             getDialog()->travelNext();
335         return 0L;
336     }
337 
338     //---------------------------------------------------------------------
339     void OContentTableSelection::initializePage()
340     {
341         OLCPage::initializePage();
342 
343         // fill the list with the table name
344         m_aSelectTable.Clear();
345         try
346         {
347             Reference< XNameAccess > xTables = getTables(sal_True);
348             Sequence< ::rtl::OUString > aTableNames;
349             if (xTables.is())
350                 aTableNames = xTables->getElementNames();
351             fillListBox(m_aSelectTable, aTableNames);
352         }
353         catch(Exception&)
354         {
355             DBG_ERROR("OContentTableSelection::initializePage: could not retrieve the table names!");
356         }
357 
358         m_aSelectTable.SelectEntry(getSettings().sListContentTable);
359     }
360 
361     //---------------------------------------------------------------------
362     sal_Bool OContentTableSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
363     {
364         if (!OLCPage::commitPage(_eReason))
365             return sal_False;
366 
367         OListComboSettings& rSettings = getSettings();
368         rSettings.sListContentTable = m_aSelectTable.GetSelectEntry();
369         if (!rSettings.sListContentTable.Len() && (::svt::WizardTypes::eTravelBackward != _eReason))
370             // need to select a table
371             return sal_False;
372 
373         return sal_True;
374     }
375 
376     //=====================================================================
377     //= OContentFieldSelection
378     //=====================================================================
379     //---------------------------------------------------------------------
380     OContentFieldSelection::OContentFieldSelection( OListComboWizard* _pParent )
381         :OLCPage(_pParent, ModuleRes(RID_PAGE_LCW_CONTENTSELECTION_FIELD))
382         ,m_aFrame               (this, ModuleRes(FL_FRAME))
383         ,m_aTableFields         (this, ModuleRes(FT_TABLEFIELDS))
384         ,m_aSelectTableField    (this, ModuleRes(LB_SELECTFIELD))
385         ,m_aDisplayedFieldLabel (this, ModuleRes(FT_DISPLAYEDFIELD))
386         ,m_aDisplayedField      (this, ModuleRes(ET_DISPLAYEDFIELD))
387         ,m_aInfo                (this, ModuleRes(FT_CONTENTFIELD_INFO))
388     {
389         m_aInfo.SetText(String(ModuleRes( isListBox() ? STR_FIELDINFO_LISTBOX : STR_FIELDINFO_COMBOBOX)));
390         FreeResource();
391         m_aSelectTableField.SetSelectHdl(LINK(this, OContentFieldSelection, OnFieldSelected));
392         m_aSelectTableField.SetDoubleClickHdl(LINK(this, OContentFieldSelection, OnTableDoubleClicked));
393     }
394 
395     //---------------------------------------------------------------------
396     void OContentFieldSelection::ActivatePage()
397     {
398         OLCPage::ActivatePage();
399         m_aTableFields.GrabFocus();
400     }
401 
402     //---------------------------------------------------------------------
403     void OContentFieldSelection::initializePage()
404     {
405         OLCPage::initializePage();
406 
407         // fill the list of fields
408         fillListBox(m_aSelectTableField, getTableFields(sal_True));
409 
410         m_aSelectTableField.SelectEntry(getSettings().sListContentField);
411         m_aDisplayedField.SetText(getSettings().sListContentField);
412     }
413 
414     //---------------------------------------------------------------------
415     bool OContentFieldSelection::canAdvance() const
416     {
417         if (!OLCPage::canAdvance())
418             return false;
419 
420         return 0 != m_aSelectTableField.GetSelectEntryCount();
421     }
422 
423     //---------------------------------------------------------------------
424     IMPL_LINK( OContentFieldSelection, OnTableDoubleClicked, ListBox*, /*NOTINTERESTEDIN*/ )
425     {
426         if (m_aSelectTableField.GetSelectEntryCount())
427             getDialog()->travelNext();
428         return 0L;
429     }
430 
431     //---------------------------------------------------------------------
432     IMPL_LINK( OContentFieldSelection, OnFieldSelected, ListBox*, /*NOTINTERESTEDIN*/ )
433     {
434         updateDialogTravelUI();
435         m_aDisplayedField.SetText(m_aSelectTableField.GetSelectEntry());
436         return 0L;
437     }
438 
439     //---------------------------------------------------------------------
440     sal_Bool OContentFieldSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
441     {
442         if (!OLCPage::commitPage(_eReason))
443             return sal_False;
444 
445         getSettings().sListContentField = m_aSelectTableField.GetSelectEntry();
446 
447         return sal_True;
448     }
449 
450     //=====================================================================
451     //= OLinkFieldsPage
452     //=====================================================================
453     //---------------------------------------------------------------------
454     OLinkFieldsPage::OLinkFieldsPage( OListComboWizard* _pParent )
455         :OLCPage(_pParent, ModuleRes(RID_PAGE_LCW_FIELDLINK))
456         ,m_aDescription         (this, ModuleRes(FT_FIELDLINK_DESC))
457         ,m_aFrame               (this, ModuleRes(FL_FRAME))
458         ,m_aValueListFieldLabel (this, ModuleRes(FT_VALUELISTFIELD))
459         ,m_aValueListField      (this, ModuleRes(CMB_VALUELISTFIELD))
460         ,m_aTableFieldLabel     (this, ModuleRes(FT_TABLEFIELD))
461         ,m_aTableField          (this, ModuleRes(CMB_TABLEFIELD))
462     {
463         FreeResource();
464 
465         m_aValueListField.SetModifyHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
466         m_aTableField.SetModifyHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
467         m_aValueListField.SetSelectHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
468         m_aTableField.SetSelectHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
469     }
470 
471     //---------------------------------------------------------------------
472     void OLinkFieldsPage::ActivatePage()
473     {
474         OLCPage::ActivatePage();
475         m_aValueListField.GrabFocus();
476     }
477 
478     //---------------------------------------------------------------------
479     void OLinkFieldsPage::initializePage()
480     {
481         OLCPage::initializePage();
482 
483         // fill the value list
484         fillListBox(m_aValueListField, getContext().aFieldNames);
485         // fill the table field list
486         fillListBox(m_aTableField, getTableFields(sal_True));
487 
488         // the initial selections
489         m_aValueListField.SetText(getSettings().sLinkedFormField);
490         m_aTableField.SetText(getSettings().sLinkedListField);
491 
492         implCheckFinish();
493     }
494 
495     //---------------------------------------------------------------------
496     bool OLinkFieldsPage::canAdvance() const
497     {
498         // we're on the last page here, no travelNext allowed ...
499         return false;
500     }
501 
502     //---------------------------------------------------------------------
503     void OLinkFieldsPage::implCheckFinish()
504     {
505         sal_Bool bInvalidSelection = (COMBOBOX_ENTRY_NOTFOUND == m_aValueListField.GetEntryPos(m_aValueListField.GetText()));
506         bInvalidSelection |= (COMBOBOX_ENTRY_NOTFOUND == m_aTableField.GetEntryPos(m_aTableField.GetText()));
507         getDialog()->enableButtons(WZB_FINISH, !bInvalidSelection);
508     }
509 
510     //---------------------------------------------------------------------
511     IMPL_LINK(OLinkFieldsPage, OnSelectionModified, void*, EMPTYARG)
512     {
513         implCheckFinish();
514         return 0L;
515     }
516 
517     //---------------------------------------------------------------------
518     sal_Bool OLinkFieldsPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
519     {
520         if (!OLCPage::commitPage(_eReason))
521             return sal_False;
522 
523         getSettings().sLinkedFormField = m_aValueListField.GetText();
524         getSettings().sLinkedListField = m_aTableField.GetText();
525 
526         return sal_True;
527     }
528 
529     //=====================================================================
530     //= OComboDBFieldPage
531     //=====================================================================
532     //---------------------------------------------------------------------
533     OComboDBFieldPage::OComboDBFieldPage( OControlWizard* _pParent )
534         :ODBFieldPage(_pParent)
535     {
536         setDescriptionText(String(ModuleRes(RID_STR_COMBOWIZ_DBFIELD)));
537     }
538 
539     //---------------------------------------------------------------------
540     String& OComboDBFieldPage::getDBFieldSetting()
541     {
542         return getSettings().sLinkedFormField;
543     }
544 
545     //---------------------------------------------------------------------
546     void OComboDBFieldPage::ActivatePage()
547     {
548         ODBFieldPage::ActivatePage();
549         getDialog()->enableButtons(WZB_FINISH, sal_True);
550     }
551 
552     //---------------------------------------------------------------------
553     bool OComboDBFieldPage::canAdvance() const
554     {
555         // we're on the last page here, no travelNext allowed ...
556         return false;
557     }
558 
559 //.........................................................................
560 }   // namespace dbp
561 //.........................................................................
562 
563