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