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