Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "listcombowizard.hxx"
21 : #include "commonpagesdbp.hxx"
22 : #include <com/sun/star/sdbc/XConnection.hpp>
23 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
24 : #include <com/sun/star/container/XNameAccess.hpp>
25 : #include <com/sun/star/form/ListSourceType.hpp>
26 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
27 : #include <tools/debug.hxx>
28 : #include <vcl/msgbox.hxx>
29 : #include <connectivity/dbtools.hxx>
30 : #include "dbpilots.hrc"
31 : #include <comphelper/extract.hxx>
32 :
33 :
34 : namespace dbp
35 : {
36 :
37 :
38 : using namespace ::com::sun::star::uno;
39 : using namespace ::com::sun::star::lang;
40 : using namespace ::com::sun::star::beans;
41 : using namespace ::com::sun::star::sdbc;
42 : using namespace ::com::sun::star::sdbcx;
43 : using namespace ::com::sun::star::container;
44 : using namespace ::com::sun::star::form;
45 : using namespace ::svt;
46 : using namespace ::dbtools;
47 :
48 0 : OListComboWizard::OListComboWizard( vcl::Window* _pParent,
49 : const Reference< XPropertySet >& _rxObjectModel, const Reference< XComponentContext >& _rxContext )
50 : :OControlWizard(_pParent, _rxObjectModel, _rxContext)
51 : ,m_bListBox(false)
52 0 : ,m_bHadDataSelection(true)
53 : {
54 0 : initControlSettings(&m_aSettings);
55 :
56 0 : m_pPrevPage->SetHelpId(HID_LISTWIZARD_PREVIOUS);
57 0 : m_pNextPage->SetHelpId(HID_LISTWIZARD_NEXT);
58 0 : m_pCancel->SetHelpId(HID_LISTWIZARD_CANCEL);
59 0 : m_pFinish->SetHelpId(HID_LISTWIZARD_FINISH);
60 :
61 : // if we do not need the data source selection page ...
62 0 : if (!needDatasourceSelection())
63 : { // ... skip it!
64 0 : skip(1);
65 0 : m_bHadDataSelection = false;
66 : }
67 0 : }
68 :
69 :
70 0 : bool OListComboWizard::approveControl(sal_Int16 _nClassId)
71 : {
72 0 : switch (_nClassId)
73 : {
74 : case FormComponentType::LISTBOX:
75 0 : m_bListBox = true;
76 0 : setTitleBase(ModuleRes(RID_STR_LISTWIZARD_TITLE).toString());
77 0 : return true;
78 : case FormComponentType::COMBOBOX:
79 0 : m_bListBox = false;
80 0 : setTitleBase(ModuleRes(RID_STR_COMBOWIZARD_TITLE).toString());
81 0 : return true;
82 : }
83 0 : return false;
84 : }
85 :
86 :
87 0 : VclPtr<TabPage> OListComboWizard::createPage(WizardState _nState)
88 : {
89 0 : switch (_nState)
90 : {
91 : case LCW_STATE_DATASOURCE_SELECTION:
92 0 : return VclPtr<OTableSelectionPage>::Create(this);
93 : case LCW_STATE_TABLESELECTION:
94 0 : return VclPtr<OContentTableSelection>::Create(this);
95 : case LCW_STATE_FIELDSELECTION:
96 0 : return VclPtr<OContentFieldSelection>::Create(this);
97 : case LCW_STATE_FIELDLINK:
98 0 : return VclPtr<OLinkFieldsPage>::Create(this);
99 : case LCW_STATE_COMBODBFIELD:
100 0 : return VclPtr<OComboDBFieldPage>::Create(this);
101 : }
102 :
103 0 : return VclPtr<TabPage>();
104 : }
105 :
106 :
107 0 : WizardTypes::WizardState OListComboWizard::determineNextState( WizardState _nCurrentState ) const
108 : {
109 0 : switch (_nCurrentState)
110 : {
111 : case LCW_STATE_DATASOURCE_SELECTION:
112 0 : return LCW_STATE_TABLESELECTION;
113 : case LCW_STATE_TABLESELECTION:
114 0 : return LCW_STATE_FIELDSELECTION;
115 : case LCW_STATE_FIELDSELECTION:
116 0 : return getFinalState();
117 : }
118 :
119 0 : return WZS_INVALID_STATE;
120 : }
121 :
122 :
123 0 : void OListComboWizard::enterState(WizardState _nState)
124 : {
125 0 : OControlWizard::enterState(_nState);
126 :
127 0 : enableButtons(WizardButtonFlags::PREVIOUS, m_bHadDataSelection ? (LCW_STATE_DATASOURCE_SELECTION < _nState) : LCW_STATE_TABLESELECTION < _nState);
128 0 : enableButtons(WizardButtonFlags::NEXT, getFinalState() != _nState);
129 0 : if (_nState < getFinalState())
130 0 : enableButtons(WizardButtonFlags::FINISH, false);
131 :
132 0 : if (getFinalState() == _nState)
133 0 : defaultButton(WizardButtonFlags::FINISH);
134 0 : }
135 :
136 :
137 0 : bool OListComboWizard::leaveState(WizardState _nState)
138 : {
139 0 : if (!OControlWizard::leaveState(_nState))
140 0 : return false;
141 :
142 0 : if (getFinalState() == _nState)
143 0 : defaultButton(WizardButtonFlags::NEXT);
144 :
145 0 : return true;
146 : }
147 :
148 :
149 0 : void OListComboWizard::implApplySettings()
150 : {
151 : try
152 : {
153 : // for quoting identifiers, we need the connection meta data
154 0 : Reference< XConnection > xConn = getFormConnection();
155 : DBG_ASSERT(xConn.is(), "OListComboWizard::implApplySettings: no connection, unable to quote!");
156 0 : Reference< XDatabaseMetaData > xMetaData;
157 0 : if (xConn.is())
158 0 : xMetaData = xConn->getMetaData();
159 :
160 : // do some quotings
161 0 : if (xMetaData.is())
162 : {
163 0 : OUString sQuoteString = xMetaData->getIdentifierQuoteString();
164 0 : if (isListBox()) // only when we have a listbox this should be not empty
165 0 : getSettings().sLinkedListField = quoteName(sQuoteString, getSettings().sLinkedListField);
166 :
167 0 : OUString sCatalog, sSchema, sName;
168 0 : ::dbtools::qualifiedNameComponents( xMetaData, getSettings().sListContentTable, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
169 0 : getSettings().sListContentTable = ::dbtools::composeTableNameForSelect( xConn, sCatalog, sSchema, sName );
170 :
171 0 : getSettings().sListContentField = quoteName(sQuoteString, getSettings().sListContentField);
172 : }
173 :
174 : // ListSourceType: SQL
175 0 : getContext().xObjectModel->setPropertyValue("ListSourceType", makeAny((sal_Int32)ListSourceType_SQL));
176 :
177 0 : if (isListBox())
178 : {
179 : // BoundColumn: 1
180 0 : getContext().xObjectModel->setPropertyValue("BoundColumn", makeAny((sal_Int16)1));
181 :
182 : // build the statement to set as list source
183 0 : OUString sStatement = "SELECT " +
184 0 : OUString( getSettings().sListContentField ) + ", " + OUString( getSettings().sLinkedListField ) +
185 0 : " FROM " + OUString( getSettings().sListContentTable );
186 0 : Sequence< OUString > aListSource(1);
187 0 : aListSource[0] = sStatement;
188 0 : getContext().xObjectModel->setPropertyValue("ListSource", makeAny(aListSource));
189 : }
190 : else
191 : {
192 : // build the statement to set as list source
193 0 : OUString sStatement = "SELECT DISTINCT " +
194 0 : OUString( getSettings().sListContentField ) +
195 0 : " FROM " + OUString( getSettings().sListContentTable );
196 0 : getContext().xObjectModel->setPropertyValue( "ListSource", makeAny(OUString(sStatement)));
197 : }
198 :
199 : // the bound field
200 0 : getContext().xObjectModel->setPropertyValue("DataField", makeAny(OUString(getSettings().sLinkedFormField)));
201 : }
202 0 : catch(const Exception&)
203 : {
204 : OSL_FAIL("OListComboWizard::implApplySettings: could not set the property values for the listbox!");
205 : }
206 0 : }
207 :
208 :
209 0 : bool OListComboWizard::onFinish()
210 : {
211 0 : if ( !OControlWizard::onFinish() )
212 0 : return false;
213 :
214 0 : implApplySettings();
215 0 : return true;
216 : }
217 :
218 0 : Reference< XNameAccess > OLCPage::getTables(bool _bNeedIt)
219 : {
220 0 : Reference< XConnection > xConn = getFormConnection();
221 : DBG_ASSERT(!_bNeedIt || xConn.is(), "OLCPage::getTables: should have an active connection when reaching this page!");
222 : (void)_bNeedIt;
223 :
224 0 : Reference< XTablesSupplier > xSuppTables(xConn, UNO_QUERY);
225 0 : Reference< XNameAccess > xTables;
226 0 : if (xSuppTables.is())
227 0 : xTables = xSuppTables->getTables();
228 :
229 : DBG_ASSERT(!_bNeedIt || xTables.is() || !xConn.is(), "OLCPage::getTables: got no tables from the connection!");
230 :
231 0 : return xTables;
232 : }
233 :
234 :
235 0 : Sequence< OUString > OLCPage::getTableFields(bool _bNeedIt)
236 : {
237 0 : Reference< XNameAccess > xTables = getTables(_bNeedIt);
238 0 : Sequence< OUString > aColumnNames;
239 0 : if (xTables.is())
240 : {
241 : try
242 : {
243 : // the list table as XColumnsSupplier
244 0 : Reference< XColumnsSupplier > xSuppCols;
245 0 : xTables->getByName(getSettings().sListContentTable) >>= xSuppCols;
246 : DBG_ASSERT(!_bNeedIt || xSuppCols.is(), "OLCPage::getTableFields: no columns supplier!");
247 :
248 : // the columns
249 0 : Reference< XNameAccess > xColumns;
250 0 : if (xSuppCols.is())
251 0 : xColumns = xSuppCols->getColumns();
252 :
253 : // the column names
254 0 : if (xColumns.is())
255 0 : aColumnNames = xColumns->getElementNames();
256 : }
257 0 : catch(const Exception&)
258 : {
259 : DBG_ASSERT(!_bNeedIt, "OLinkFieldsPage::initializePage: caught an exception while retrieving the columns!");
260 : }
261 : }
262 0 : return aColumnNames;
263 : }
264 :
265 0 : OContentTableSelection::OContentTableSelection( OListComboWizard* _pParent )
266 0 : :OLCPage(_pParent, "TableSelectionPage", "modules/sabpilot/ui/contenttablepage.ui")
267 : {
268 0 : get(m_pSelectTable, "table");
269 :
270 0 : enableFormDatasourceDisplay();
271 :
272 0 : m_pSelectTable->SetDoubleClickHdl(LINK(this, OContentTableSelection, OnTableDoubleClicked));
273 0 : m_pSelectTable->SetSelectHdl(LINK(this, OContentTableSelection, OnTableSelected));
274 0 : }
275 :
276 0 : OContentTableSelection::~OContentTableSelection()
277 : {
278 0 : disposeOnce();
279 0 : }
280 :
281 0 : void OContentTableSelection::dispose()
282 : {
283 0 : m_pSelectTable.clear();
284 0 : OLCPage::dispose();
285 0 : }
286 :
287 0 : void OContentTableSelection::ActivatePage()
288 : {
289 0 : OLCPage::ActivatePage();
290 0 : m_pSelectTable->GrabFocus();
291 0 : }
292 :
293 :
294 0 : bool OContentTableSelection::canAdvance() const
295 : {
296 0 : if (!OLCPage::canAdvance())
297 0 : return false;
298 :
299 0 : return 0 != m_pSelectTable->GetSelectEntryCount();
300 : }
301 :
302 :
303 0 : IMPL_LINK( OContentTableSelection, OnTableSelected, ListBox*, /*_pListBox*/ )
304 : {
305 0 : updateDialogTravelUI();
306 0 : return 0L;
307 : }
308 :
309 :
310 0 : IMPL_LINK( OContentTableSelection, OnTableDoubleClicked, ListBox*, _pListBox )
311 : {
312 0 : if (_pListBox->GetSelectEntryCount())
313 0 : getDialog()->travelNext();
314 0 : return 0L;
315 : }
316 :
317 :
318 0 : void OContentTableSelection::initializePage()
319 : {
320 0 : OLCPage::initializePage();
321 :
322 : // fill the list with the table name
323 0 : m_pSelectTable->Clear();
324 : try
325 : {
326 0 : Reference< XNameAccess > xTables = getTables(true);
327 0 : Sequence< OUString > aTableNames;
328 0 : if (xTables.is())
329 0 : aTableNames = xTables->getElementNames();
330 0 : fillListBox(*m_pSelectTable, aTableNames);
331 : }
332 0 : catch(const Exception&)
333 : {
334 : OSL_FAIL("OContentTableSelection::initializePage: could not retrieve the table names!");
335 : }
336 :
337 0 : m_pSelectTable->SelectEntry(getSettings().sListContentTable);
338 0 : }
339 :
340 :
341 0 : bool OContentTableSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
342 : {
343 0 : if (!OLCPage::commitPage(_eReason))
344 0 : return false;
345 :
346 0 : OListComboSettings& rSettings = getSettings();
347 0 : rSettings.sListContentTable = m_pSelectTable->GetSelectEntry();
348 0 : if (rSettings.sListContentTable.isEmpty() && (::svt::WizardTypes::eTravelBackward != _eReason))
349 : // need to select a table
350 0 : return false;
351 :
352 0 : return true;
353 : }
354 :
355 0 : OContentFieldSelection::OContentFieldSelection( OListComboWizard* _pParent )
356 0 : :OLCPage(_pParent, "FieldSelectionPage", "modules/sabpilot/ui/contentfieldpage.ui")
357 : {
358 0 : get(m_pSelectTableField, "selectfield");
359 0 : get(m_pDisplayedField, "displayfield");
360 0 : get(m_pInfo, "info");
361 0 : m_pInfo->SetText(ModuleRes( isListBox() ? RID_STR_FIELDINFO_LISTBOX : RID_STR_FIELDINFO_COMBOBOX).toString());
362 0 : m_pSelectTableField->SetSelectHdl(LINK(this, OContentFieldSelection, OnFieldSelected));
363 0 : m_pSelectTableField->SetDoubleClickHdl(LINK(this, OContentFieldSelection, OnTableDoubleClicked));
364 0 : }
365 :
366 0 : OContentFieldSelection::~OContentFieldSelection()
367 : {
368 0 : disposeOnce();
369 0 : }
370 :
371 0 : void OContentFieldSelection::dispose()
372 : {
373 0 : m_pSelectTableField.clear();
374 0 : m_pDisplayedField.clear();
375 0 : m_pInfo.clear();
376 0 : OLCPage::dispose();
377 0 : }
378 :
379 0 : void OContentFieldSelection::ActivatePage()
380 : {
381 0 : OLCPage::ActivatePage();
382 0 : }
383 :
384 :
385 0 : void OContentFieldSelection::initializePage()
386 : {
387 0 : OLCPage::initializePage();
388 :
389 : // fill the list of fields
390 0 : fillListBox(*m_pSelectTableField, getTableFields(true));
391 :
392 0 : m_pSelectTableField->SelectEntry(getSettings().sListContentField);
393 0 : m_pDisplayedField->SetText(getSettings().sListContentField);
394 0 : }
395 :
396 :
397 0 : bool OContentFieldSelection::canAdvance() const
398 : {
399 0 : if (!OLCPage::canAdvance())
400 0 : return false;
401 :
402 0 : return 0 != m_pSelectTableField->GetSelectEntryCount();
403 : }
404 :
405 :
406 0 : IMPL_LINK( OContentFieldSelection, OnTableDoubleClicked, ListBox*, /*NOTINTERESTEDIN*/ )
407 : {
408 0 : if (m_pSelectTableField->GetSelectEntryCount())
409 0 : getDialog()->travelNext();
410 0 : return 0L;
411 : }
412 :
413 :
414 0 : IMPL_LINK( OContentFieldSelection, OnFieldSelected, ListBox*, /*NOTINTERESTEDIN*/ )
415 : {
416 0 : updateDialogTravelUI();
417 0 : m_pDisplayedField->SetText(m_pSelectTableField->GetSelectEntry());
418 0 : return 0L;
419 : }
420 :
421 :
422 0 : bool OContentFieldSelection::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
423 : {
424 0 : if (!OLCPage::commitPage(_eReason))
425 0 : return false;
426 :
427 0 : getSettings().sListContentField = m_pSelectTableField->GetSelectEntry();
428 :
429 0 : return true;
430 : }
431 :
432 0 : OLinkFieldsPage::OLinkFieldsPage( OListComboWizard* _pParent )
433 0 : :OLCPage(_pParent, "FieldLinkPage", "modules/sabpilot/ui/fieldlinkpage.ui")
434 : {
435 0 : get(m_pValueListField, "valuefield");
436 0 : get(m_pTableField, "listtable");
437 :
438 0 : m_pValueListField->SetModifyHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
439 0 : m_pTableField->SetModifyHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
440 0 : m_pValueListField->SetSelectHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
441 0 : m_pTableField->SetSelectHdl(LINK(this, OLinkFieldsPage, OnSelectionModified));
442 0 : }
443 :
444 0 : OLinkFieldsPage::~OLinkFieldsPage()
445 : {
446 0 : disposeOnce();
447 0 : }
448 :
449 0 : void OLinkFieldsPage::dispose()
450 : {
451 0 : m_pValueListField.clear();
452 0 : m_pTableField.clear();
453 0 : OLCPage::dispose();
454 0 : }
455 :
456 0 : void OLinkFieldsPage::ActivatePage()
457 : {
458 0 : OLCPage::ActivatePage();
459 0 : m_pValueListField->GrabFocus();
460 0 : }
461 :
462 :
463 0 : void OLinkFieldsPage::initializePage()
464 : {
465 0 : OLCPage::initializePage();
466 :
467 : // fill the value list
468 0 : fillListBox(*m_pValueListField, getContext().aFieldNames);
469 : // fill the table field list
470 0 : fillListBox(*m_pTableField, getTableFields(true));
471 :
472 : // the initial selections
473 0 : m_pValueListField->SetText(getSettings().sLinkedFormField);
474 0 : m_pTableField->SetText(getSettings().sLinkedListField);
475 :
476 0 : implCheckFinish();
477 0 : }
478 :
479 :
480 0 : bool OLinkFieldsPage::canAdvance() const
481 : {
482 : // we're on the last page here, no travelNext allowed ...
483 0 : return false;
484 : }
485 :
486 :
487 0 : void OLinkFieldsPage::implCheckFinish()
488 : {
489 0 : bool bInvalidSelection = (COMBOBOX_ENTRY_NOTFOUND == m_pValueListField->GetEntryPos(m_pValueListField->GetText()));
490 0 : bInvalidSelection |= (COMBOBOX_ENTRY_NOTFOUND == m_pTableField->GetEntryPos(m_pTableField->GetText()));
491 0 : getDialog()->enableButtons(WizardButtonFlags::FINISH, !bInvalidSelection);
492 0 : }
493 :
494 :
495 0 : IMPL_LINK_NOARG(OLinkFieldsPage, OnSelectionModified)
496 : {
497 0 : implCheckFinish();
498 0 : return 0L;
499 : }
500 :
501 :
502 0 : bool OLinkFieldsPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
503 : {
504 0 : if (!OLCPage::commitPage(_eReason))
505 0 : return false;
506 :
507 0 : getSettings().sLinkedFormField = m_pValueListField->GetText();
508 0 : getSettings().sLinkedListField = m_pTableField->GetText();
509 :
510 0 : return true;
511 : }
512 :
513 0 : OComboDBFieldPage::OComboDBFieldPage( OControlWizard* _pParent )
514 0 : :ODBFieldPage(_pParent)
515 : {
516 0 : setDescriptionText(ModuleRes(RID_STR_COMBOWIZ_DBFIELD).toString());
517 0 : }
518 :
519 :
520 0 : OUString& OComboDBFieldPage::getDBFieldSetting()
521 : {
522 0 : return getSettings().sLinkedFormField;
523 : }
524 :
525 :
526 0 : void OComboDBFieldPage::ActivatePage()
527 : {
528 0 : ODBFieldPage::ActivatePage();
529 0 : getDialog()->enableButtons(WizardButtonFlags::FINISH, true);
530 0 : }
531 :
532 :
533 0 : bool OComboDBFieldPage::canAdvance() const
534 : {
535 : // we're on the last page here, no travelNext allowed ...
536 0 : return false;
537 : }
538 :
539 :
540 0 : } // namespace dbp
541 :
542 :
543 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|