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_dbaccess.hxx" 26 27 #ifndef _DBAUI_INDEXDIALOG_HXX_ 28 #include "indexdialog.hxx" 29 #endif 30 #ifndef _DBU_DLG_HRC_ 31 #include "dbu_dlg.hrc" 32 #endif 33 #ifndef _DBA_DBACCESS_HELPID_HRC_ 34 #include "dbaccess_helpid.hrc" 35 #endif 36 #ifndef _DBAUI_INDEXDIALOG_HRC_ 37 #include "indexdialog.hrc" 38 #endif 39 #ifndef _DBAUI_INDEXFIELDSCONTROL_HXX_ 40 #include "indexfieldscontrol.hxx" 41 #endif 42 #ifndef _DBAUI_INDEXCOLLECTION_HXX_ 43 #include "indexcollection.hxx" 44 #endif 45 #ifndef _SV_MSGBOX_HXX 46 #include <vcl/msgbox.hxx> 47 #endif 48 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_ 49 #include <com/sun/star/sdb/SQLContext.hpp> 50 #endif 51 #ifndef DBAUI_TOOLS_HXX 52 #include "UITools.hxx" 53 #endif 54 #ifndef _SVTOOLS_IMGDEF_HXX 55 #include <svtools/imgdef.hxx> 56 #endif 57 #ifndef DBACCESS_UI_BROWSER_ID_HXX 58 #include "browserids.hxx" 59 #endif 60 #ifndef _CONNECTIVITY_DBTOOLS_HXX_ 61 #include <connectivity/dbtools.hxx> 62 #endif 63 //...................................................................... 64 namespace dbaui 65 { 66 //...................................................................... 67 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::container; 70 using namespace ::com::sun::star::sdbc; 71 using namespace ::com::sun::star::sdb; 72 using namespace ::com::sun::star::lang; 73 using namespace ::dbtools; 74 75 //================================================================== 76 //= helper 77 //================================================================== 78 //------------------------------------------------------------------ 79 sal_Bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS) 80 { 81 return (_rLHS.sFieldName == _rRHS.sFieldName) 82 && (_rLHS.bSortAscending == _rRHS.bSortAscending); 83 } 84 85 //------------------------------------------------------------------ 86 sal_Bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS) 87 { 88 return !(_rLHS == _rRHS); 89 } 90 91 //------------------------------------------------------------------ 92 sal_Bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS) 93 { 94 if (_rLHS.size() != _rRHS.size()) 95 return sal_False; 96 97 ConstIndexFieldsIterator aLeft = _rLHS.begin(); 98 ConstIndexFieldsIterator aLeftEnd = _rLHS.end(); 99 ConstIndexFieldsIterator aRight = _rRHS.begin(); 100 for (; aLeft != aLeftEnd; ++aLeft, ++aRight) 101 { 102 if (*aLeft != *aRight) 103 return sal_False; 104 } 105 106 return sal_True; 107 } 108 109 //------------------------------------------------------------------ 110 sal_Bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS) 111 { 112 return !(_rLHS == _rRHS); 113 } 114 115 //================================================================== 116 //= DbaIndexList 117 //================================================================== 118 //------------------------------------------------------------------ 119 DbaIndexList::DbaIndexList(Window* _pParent, const ResId& _rId) 120 :SvTreeListBox(_pParent, _rId) 121 ,m_bSuspendSelectHdl(sal_False) 122 { 123 } 124 125 extern sal_Bool isCharOk(sal_Unicode _cChar,sal_Bool _bFirstChar,sal_Bool _bUpperCase,const ::rtl::OUString& _sAllowedChars); 126 //------------------------------------------------------------------ 127 sal_Bool DbaIndexList::EditedEntry( SvLBoxEntry* _pEntry, const String& _rNewText ) 128 { 129 // first check if this is valid SQL92 name 130 if ( isSQL92CheckEnabled(m_xConnection) ) 131 { 132 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); 133 if ( xMeta.is() ) 134 { 135 ::rtl::OUString sNewName(_rNewText); 136 ::rtl::OUString sAlias = ::dbtools::convertName2SQLName(sNewName,xMeta->getExtraNameCharacters()); 137 if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() ) 138 ? 139 sAlias != sNewName 140 : 141 !sNewName.equalsIgnoreAsciiCase(sAlias)) 142 return sal_False; 143 } 144 } 145 146 if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText)) 147 return sal_False; 148 149 String sOldText = GetEntryText(_pEntry); 150 SvTreeListBox::SetEntryText(_pEntry, _rNewText); 151 152 sal_Bool bValid = sal_True; 153 if (m_aEndEditHdl.IsSet()) 154 bValid = (0 != m_aEndEditHdl.Call(_pEntry)); 155 156 if (bValid) 157 return sal_True; 158 159 SvTreeListBox::SetEntryText(_pEntry, sOldText); 160 161 return sal_False; 162 } 163 164 //------------------------------------------------------------------ 165 void DbaIndexList::enableSelectHandler() 166 { 167 DBG_ASSERT(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!"); 168 m_bSuspendSelectHdl = sal_False; 169 } 170 171 //------------------------------------------------------------------ 172 void DbaIndexList::disableSelectHandler() 173 { 174 DBG_ASSERT(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!"); 175 m_bSuspendSelectHdl = sal_True; 176 } 177 178 //------------------------------------------------------------------ 179 void DbaIndexList::SelectNoHandlerCall( SvLBoxEntry* _pEntry ) 180 { 181 disableSelectHandler(); 182 Select(_pEntry, sal_True); 183 enableSelectHandler(); 184 } 185 186 //------------------------------------------------------------------ 187 sal_Bool DbaIndexList::Select( SvLBoxEntry* pEntry, sal_Bool _bSelect ) 188 { 189 sal_Bool bReturn = SvTreeListBox::Select(pEntry, _bSelect); 190 191 if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect) 192 m_aSelectHdl.Call(this); 193 194 return bReturn; 195 } 196 197 //================================================================== 198 //= DbaIndexDialog 199 //================================================================== 200 DBG_NAME(DbaIndexDialog) 201 //------------------------------------------------------------------ 202 DbaIndexDialog::DbaIndexDialog( Window* _pParent, const Sequence< ::rtl::OUString >& _rFieldNames, 203 const Reference< XNameAccess >& _rxIndexes, 204 const Reference< XConnection >& _rxConnection, 205 const Reference< XMultiServiceFactory >& _rxORB,sal_Int32 _nMaxColumnsInIndex) 206 :ModalDialog( _pParent, ModuleRes(DLG_INDEXDESIGN)) 207 ,m_xConnection(_rxConnection) 208 ,m_aGeometrySettings(E_DIALOG, ::rtl::OUString::createFromAscii("dbaccess.tabledesign.indexdialog")) 209 ,m_aActions (this, ModuleRes(TLB_ACTIONS)) 210 ,m_aIndexes (this, ModuleRes(CTR_INDEXLIST)) 211 ,m_aIndexDetails (this, ModuleRes(FL_INDEXDETAILS)) 212 ,m_aDescriptionLabel (this, ModuleRes(FT_DESC_LABEL)) 213 ,m_aDescription (this, ModuleRes(FT_DESCRIPTION)) 214 ,m_aUnique (this, ModuleRes(CB_UNIQUE)) 215 ,m_aFieldsLabel (this, ModuleRes(FT_FIELDS)) 216 ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex,::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ))) 217 ,m_aClose (this, ModuleRes(PB_CLOSE)) 218 ,m_aHelp (this, ModuleRes(HB_HELP)) 219 ,m_pIndexes(NULL) 220 ,m_pPreviousSelection(NULL) 221 ,m_bEditAgain(sal_False) 222 ,m_xORB(_rxORB) 223 { 224 DBG_CTOR(DbaIndexDialog,NULL); 225 226 FreeResource(); 227 228 m_aActions.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction)); 229 230 m_aIndexes.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected)); 231 m_aIndexes.SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited)); 232 m_aIndexes.SetSelectionMode(SINGLE_SELECTION); 233 m_aIndexes.SetHighlightRange(); 234 m_aIndexes.setConnection(m_xConnection); 235 236 m_pFields->Init(_rFieldNames); 237 238 setToolBox(&m_aActions); 239 240 m_pIndexes = new OIndexCollection(); 241 try 242 { 243 m_pIndexes->attach(_rxIndexes); 244 } 245 catch(SQLException& e) 246 { 247 ::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxORB); 248 } 249 catch(Exception&) 250 { 251 OSL_ENSURE(sal_False, "DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!"); 252 } 253 254 fillIndexList(); 255 256 m_aUnique.SetClickHdl(LINK(this, DbaIndexDialog, OnModified)); 257 m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified)); 258 259 m_aClose.SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog)); 260 261 // get our most recent geometry settings 262 // if (m_aGeometrySettings.Exists()) 263 // { 264 // Point aPos; 265 // m_aGeometrySettings.GetPosition(aPos.X(), aPos.Y()); 266 // SetPosPixel(aPos); 267 // } 268 269 // if all of the indexes have an empty description, we're not interested in displaying it 270 Indexes::const_iterator aCheck; 271 272 for ( aCheck = m_pIndexes->begin(); 273 aCheck != m_pIndexes->end(); 274 ++aCheck 275 ) 276 { 277 if (aCheck->sDescription.getLength()) 278 break; 279 } 280 281 if (aCheck == m_pIndexes->end()) 282 { 283 sal_Int32 nMoveUp = m_aUnique.GetPosPixel().Y() - m_aDescriptionLabel.GetPosPixel().Y(); 284 285 // hide the controls which are necessary for the description 286 m_aDescription.Hide(); 287 m_aDescriptionLabel.Hide(); 288 289 // move other controls up 290 Point aPos = m_aUnique.GetPosPixel(); 291 aPos.Y() -= nMoveUp; 292 m_aUnique.SetPosPixel(aPos); 293 294 aPos = m_aFieldsLabel.GetPosPixel(); 295 aPos.Y() -= nMoveUp; 296 m_aFieldsLabel.SetPosPixel(aPos); 297 298 aPos = m_pFields->GetPosPixel(); 299 aPos.Y() -= nMoveUp; 300 m_pFields->SetPosPixel(aPos); 301 302 // and enlarge the fields list 303 Size aSize = m_pFields->GetSizePixel(); 304 aSize.Height() += nMoveUp; 305 m_pFields->SetSizePixel(aSize); 306 } 307 } 308 309 //------------------------------------------------------------------ 310 void DbaIndexDialog::updateToolbox() 311 { 312 m_aActions.EnableItem(ID_INDEX_NEW, !m_aIndexes.IsEditingActive()); 313 314 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); 315 sal_Bool bSelectedAnything = NULL != pSelected; 316 317 318 if (pSelected) 319 { 320 // is the current entry modified? 321 Indexes::const_iterator aSelectedPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData()); 322 m_aActions.EnableItem(ID_INDEX_SAVE, aSelectedPos->isModified() || aSelectedPos->isNew()); 323 m_aActions.EnableItem(ID_INDEX_RESET, aSelectedPos->isModified() || aSelectedPos->isNew()); 324 bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey; 325 } 326 else 327 { 328 m_aActions.EnableItem(ID_INDEX_SAVE, sal_False); 329 m_aActions.EnableItem(ID_INDEX_RESET, sal_False); 330 } 331 m_aActions.EnableItem(ID_INDEX_DROP, bSelectedAnything); 332 m_aActions.EnableItem(ID_INDEX_RENAME, bSelectedAnything); 333 } 334 335 //------------------------------------------------------------------ 336 void DbaIndexDialog::fillIndexList() 337 { 338 sal_Bool bHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); 339 Image aPKeyIcon(ModuleRes( bHiContrast ? IMG_PKEYICON_SCH : IMG_PKEYICON)); 340 // fill the list with the index names 341 m_aIndexes.Clear(); 342 Indexes::iterator aIndexLoop = m_pIndexes->begin(); 343 Indexes::iterator aEnd = m_pIndexes->end(); 344 for (; aIndexLoop != aEnd; ++aIndexLoop) 345 { 346 SvLBoxEntry* pNewEntry = NULL; 347 if (aIndexLoop->bPrimaryKey) 348 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon); 349 else 350 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName); 351 352 pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin()))); 353 } 354 355 OnIndexSelected(&m_aIndexes); 356 } 357 358 //------------------------------------------------------------------ 359 DbaIndexDialog::~DbaIndexDialog( ) 360 { 361 setToolBox(NULL); 362 delete m_pIndexes; 363 delete m_pFields; 364 365 // save our geometry settings 366 // Point aPos = GetPosPixel(); 367 // m_aGeometrySettings.SetPosition(aPos.X(), aPos.Y()); 368 369 DBG_DTOR(DbaIndexDialog,NULL); 370 } 371 372 //------------------------------------------------------------------ 373 sal_Bool DbaIndexDialog::implCommit(SvLBoxEntry* _pEntry) 374 { 375 DBG_ASSERT(_pEntry, "DbaIndexDialog::implCommit: invalid entry!"); 376 377 Indexes::iterator aCommitPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData()); 378 379 // if it's not a new index, remove it 380 // (we can't modify indexes, only drop'n'insert) 381 if (!aCommitPos->isNew()) 382 if (!implDropIndex(_pEntry, sal_False)) 383 return sal_False; 384 385 // create the new index 386 SQLExceptionInfo aExceptionInfo; 387 try 388 { 389 m_pIndexes->commitNewIndex(aCommitPos); 390 } 391 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); } 392 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); } 393 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); } 394 395 // reflect the new selection in the toolbox 396 updateToolbox(); 397 398 if (aExceptionInfo.isValid()) 399 showError(aExceptionInfo, this, m_xORB); 400 else 401 { 402 m_aUnique.SaveValue(); 403 m_pFields->SaveValue(); 404 } 405 406 return !aExceptionInfo.isValid(); 407 } 408 409 //------------------------------------------------------------------ 410 void DbaIndexDialog::OnNewIndex() 411 { 412 // commit the current entry, if necessary 413 if (!implCommitPreviouslySelected()) 414 return; 415 416 // get a new unique name for the new index 417 String sNewIndexName; 418 const String sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME)); 419 sal_Int32 i; 420 421 for ( i = 1; i < 0x7FFFFFFF; ++i ) 422 { 423 sNewIndexName = sNewIndexNameBase; 424 sNewIndexName += String::CreateFromInt32(i); 425 if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName)) 426 break; 427 } 428 if ((i>0x7FFFFFFF) || (i<0)) 429 { 430 DBG_ERROR("DbaIndexDialog::OnNewIndex: no free index name found!"); 431 // can't do anything ... of course we try another base, but this could end with the same result ... 432 return; 433 } 434 435 SvLBoxEntry* pNewEntry = m_aIndexes.InsertEntry(sNewIndexName); 436 m_pIndexes->insert(sNewIndexName); 437 438 // update the user data on the entries in the list box: 439 // they're iterators of the index collection, and thus they have changed when removing the index 440 for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust)) 441 { 442 Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust)); 443 DBG_ASSERT(aAfterInsertPos != m_pIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with on of the entries!"); 444 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterInsertPos - m_pIndexes->begin()))); 445 } 446 447 // select the entry and start in-place editing 448 m_aIndexes.SelectNoHandlerCall(pNewEntry); 449 OnIndexSelected(&m_aIndexes); 450 m_aIndexes.EditEntry(pNewEntry); 451 updateToolbox(); 452 } 453 454 //------------------------------------------------------------------ 455 void DbaIndexDialog::OnDropIndex(sal_Bool _bConfirm) 456 { 457 // the selected index 458 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); 459 DBG_ASSERT(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!"); 460 if (pSelected) 461 { 462 // let the user confirm the drop 463 if (_bConfirm) 464 { 465 String sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX)); 466 sConfirm.SearchAndReplaceAscii("$name$", m_aIndexes.GetEntryText(pSelected)); 467 QueryBox aConfirm(this, WB_YES_NO, sConfirm); 468 if (RET_YES != aConfirm.Execute()) 469 return; 470 } 471 472 // do the drop 473 implDropIndex(pSelected, sal_True); 474 475 // reflect the new selection in the toolbox 476 updateToolbox(); 477 } 478 } 479 480 //------------------------------------------------------------------ 481 sal_Bool DbaIndexDialog::implDropIndex(SvLBoxEntry* _pEntry, sal_Bool _bRemoveFromCollection) 482 { 483 // do the drop 484 Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData()); 485 DBG_ASSERT(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!"); 486 487 SQLExceptionInfo aExceptionInfo; 488 sal_Bool bSuccess = sal_False; 489 try 490 { 491 if (_bRemoveFromCollection) 492 bSuccess = m_pIndexes->drop(aDropPos); 493 else 494 bSuccess = m_pIndexes->dropNoRemove(aDropPos); 495 } 496 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); } 497 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); } 498 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); } 499 500 if (aExceptionInfo.isValid()) 501 showError(aExceptionInfo, this, m_xORB); 502 else if (bSuccess && _bRemoveFromCollection) 503 { 504 SvLBoxTreeList* pModel = m_aIndexes.GetModel(); 505 506 m_aIndexes.disableSelectHandler(); 507 pModel->Remove(_pEntry); 508 m_aIndexes.enableSelectHandler(); 509 510 // update the user data on the entries in the list box: 511 // they're iterators of the index collection, and thus they have changed when removing the index 512 for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust)) 513 { 514 Indexes::iterator aAfterDropPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust)); 515 DBG_ASSERT(aAfterDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with on of the remaining entries!"); 516 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterDropPos - m_pIndexes->begin()))); 517 } 518 519 // if the remvoved entry was the selected on ... 520 if (m_pPreviousSelection == _pEntry) 521 m_pPreviousSelection = NULL; 522 523 // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler 524 // to prevent that we missed something ... call the handler directly 525 OnIndexSelected(&m_aIndexes); 526 } 527 528 return !aExceptionInfo.isValid(); 529 } 530 531 //------------------------------------------------------------------ 532 void DbaIndexDialog::OnRenameIndex() 533 { 534 // the selected index 535 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); 536 DBG_ASSERT(pSelected, "DbaIndexDialog::OnRenameIndex: invalid call!"); 537 538 // save the changes made 'til here 539 // Upon leaving the edit mode, the control will be re-initialized with the 540 // settings from the current entry 541 implSaveModified(sal_False); 542 543 m_aIndexes.EditEntry(pSelected); 544 updateToolbox(); 545 } 546 547 //------------------------------------------------------------------ 548 void DbaIndexDialog::OnSaveIndex() 549 { 550 // the selected index 551 #if OSL_DEBUG_LEVEL > 0 552 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); 553 OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" ); 554 #endif 555 556 implCommitPreviouslySelected(); 557 updateToolbox(); 558 } 559 560 //------------------------------------------------------------------ 561 void DbaIndexDialog::OnResetIndex() 562 { 563 // the selected index 564 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); 565 DBG_ASSERT(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!"); 566 567 Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData()); 568 569 if (aResetPos->isNew()) 570 { 571 OnDropIndex(sal_False); 572 return; 573 } 574 575 SQLExceptionInfo aExceptionInfo; 576 try 577 { 578 m_pIndexes->resetIndex(aResetPos); 579 } 580 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); } 581 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); } 582 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); } 583 584 if (aExceptionInfo.isValid()) 585 showError(aExceptionInfo, this, m_xORB); 586 else 587 m_aIndexes.SetEntryText(pSelected, aResetPos->sName); 588 589 updateControls(pSelected); 590 updateToolbox(); 591 } 592 593 //------------------------------------------------------------------ 594 IMPL_LINK( DbaIndexDialog, OnIndexAction, ToolBox*, /*NOTINTERESTEDIN*/ ) 595 { 596 sal_uInt16 nClicked = m_aActions.GetCurItemId(); 597 switch (nClicked) 598 { 599 case ID_INDEX_NEW: 600 OnNewIndex(); 601 break; 602 case ID_INDEX_DROP: 603 OnDropIndex(); 604 break; 605 case ID_INDEX_RENAME: 606 OnRenameIndex(); 607 break; 608 case ID_INDEX_SAVE: 609 OnSaveIndex(); 610 break; 611 case ID_INDEX_RESET: 612 OnResetIndex(); 613 break; 614 } 615 return 0L; 616 } 617 618 //------------------------------------------------------------------ 619 IMPL_LINK( DbaIndexDialog, OnCloseDialog, void*, /*NOTINTERESTEDIN*/ ) 620 { 621 if (m_aIndexes.IsEditingActive()) 622 { 623 DBG_ASSERT(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!"); 624 // this means somebody entered a new name, which was invalid, which cause us to posted us an event, 625 // and before the event arrived the user clicked onto "close". VERY fast, this user .... 626 m_aIndexes.EndEditing(sal_False); 627 if (m_bEditAgain) 628 // could not commit the new name (started a new - asynchronous - edit trial) 629 return 1L; 630 } 631 632 // the currently selected entry 633 const SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); 634 DBG_ASSERT(pSelected == m_pPreviousSelection, "DbaIndexDialog::OnCloseDialog: inconsistence!"); 635 636 sal_Int32 nResponse = RET_NO; 637 if (pSelected) 638 { 639 // the descriptor 640 Indexes::const_iterator aSelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData()); 641 642 if (aSelected->isModified() || aSelected->isNew()) 643 { 644 QueryBox aQuestion(this, ModuleRes(QUERY_SAVE_CURRENT_INDEX)); 645 nResponse = aQuestion.Execute(); 646 } 647 } 648 649 switch (nResponse) 650 { 651 case RET_YES: 652 if (!implCommitPreviouslySelected()) 653 return 1L; 654 break; 655 case RET_NO: 656 break; 657 default: 658 return 1L; 659 } 660 661 EndDialog(RET_OK); 662 663 return 0L; 664 } 665 666 //------------------------------------------------------------------ 667 IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvLBoxEntry*, _pEntry ) 668 { 669 m_bEditAgain = sal_False; 670 m_aIndexes.EditEntry(_pEntry); 671 return 0L; 672 } 673 674 //------------------------------------------------------------------ 675 IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvLBoxEntry*, _pEntry ) 676 { 677 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData()); 678 679 DBG_ASSERT(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(), 680 "DbaIndexDialog::OnEntryEdited: invalid entry!"); 681 682 String sNewName = m_aIndexes.GetEntryText(_pEntry); 683 684 Indexes::const_iterator aSameName = m_pIndexes->find(sNewName); 685 if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName)) 686 { 687 String sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED)); 688 sError.SearchAndReplaceAscii("$name$", sNewName); 689 ErrorBox aError(this, WB_OK, sError); 690 aError.Execute(); 691 692 updateToolbox(); 693 m_bEditAgain = sal_True; 694 PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry); 695 return 0L; 696 } 697 698 aPosition->sName = sNewName; 699 700 // rename can be done by a drop/insert combination only 701 if (aPosition->isNew()) 702 { 703 updateToolbox(); 704 // no commitment needed here .... 705 return 1L; 706 } 707 708 if (aPosition->sName != aPosition->getOriginalName()) 709 { 710 aPosition->setModified(sal_True); 711 updateToolbox(); 712 } 713 714 return 1L; 715 } 716 717 //------------------------------------------------------------------ 718 sal_Bool DbaIndexDialog::implSaveModified(sal_Bool _bPlausibility) 719 { 720 if (m_pPreviousSelection) 721 { 722 // try to commit the previously selected index 723 if (m_pFields->IsModified() && !m_pFields->SaveModified()) 724 return sal_False; 725 726 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData()); 727 728 // the unique flag 729 aPreviouslySelected->bUnique = m_aUnique.IsChecked(); 730 if (m_aUnique.GetSavedValue() != m_aUnique.GetState()) 731 aPreviouslySelected->setModified(sal_True); 732 733 // the fields 734 m_pFields->commitTo(aPreviouslySelected->aFields); 735 if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields) 736 aPreviouslySelected->setModified(sal_True); 737 738 // plausibility checks 739 if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected)) 740 return sal_False; 741 } 742 743 return sal_True; 744 } 745 746 //------------------------------------------------------------------ 747 sal_Bool DbaIndexDialog::implCheckPlausibility(const ConstIndexesIterator& _rPos) 748 { 749 // need at least one field 750 if (0 == _rPos->aFields.size()) 751 { 752 ErrorBox aError(this, ModuleRes(ERR_NEED_INDEX_FIELDS)); 753 aError.Execute(); 754 m_pFields->GrabFocus(); 755 return sal_False; 756 } 757 758 // no double fields 759 DECLARE_STL_STDKEY_SET( String, StringBag ); 760 StringBag aExistentFields; 761 for ( ConstIndexFieldsIterator aFieldCheck = _rPos->aFields.begin(); 762 aFieldCheck != _rPos->aFields.end(); 763 ++aFieldCheck 764 ) 765 { 766 if (aExistentFields.end() != aExistentFields.find(aFieldCheck->sFieldName)) 767 { 768 // a column is specified twice ... won't work anyway, so prevent this here and now 769 String sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME)); 770 sMessage.SearchAndReplaceAscii("$name$", aFieldCheck->sFieldName); 771 ErrorBox aError(this, WB_OK, sMessage); 772 aError.Execute(); 773 m_pFields->GrabFocus(); 774 return sal_False; 775 } 776 aExistentFields.insert(aFieldCheck->sFieldName); 777 } 778 779 return sal_True; 780 } 781 782 //------------------------------------------------------------------ 783 sal_Bool DbaIndexDialog::implCommitPreviouslySelected() 784 { 785 if (m_pPreviousSelection) 786 { 787 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData()); 788 789 if (!implSaveModified()) 790 return sal_False; 791 792 // commit the index (if necessary) 793 if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection)) 794 return sal_False; 795 } 796 797 return sal_True; 798 } 799 800 //------------------------------------------------------------------ 801 IMPL_LINK( DbaIndexDialog, OnModified, void*, /*NOTINTERESTEDIN*/ ) 802 { 803 DBG_ASSERT(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!"); 804 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData()); 805 806 aPosition->setModified(sal_True); 807 updateToolbox(); 808 809 return 1L; 810 } 811 812 //------------------------------------------------------------------ 813 void DbaIndexDialog::updateControls(const SvLBoxEntry* _pEntry) 814 { 815 if (_pEntry) 816 { 817 // the descriptor of the selected index 818 Indexes::const_iterator aSelectedIndex = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData()); 819 820 // fill the controls 821 m_aUnique.Check(aSelectedIndex->bUnique); 822 m_aUnique.Enable(!aSelectedIndex->bPrimaryKey); 823 m_aUnique.SaveValue(); 824 825 m_pFields->initializeFrom(aSelectedIndex->aFields); 826 m_pFields->Enable(!aSelectedIndex->bPrimaryKey); 827 m_pFields->SaveValue(); 828 829 m_aDescription.SetText(aSelectedIndex->sDescription); 830 m_aDescription.Enable(!aSelectedIndex->bPrimaryKey); 831 832 m_aDescriptionLabel.Enable(!aSelectedIndex->bPrimaryKey); 833 } 834 else 835 { 836 m_aUnique.Check(sal_False); 837 m_pFields->initializeFrom(IndexFields()); 838 m_aDescription.SetText(String()); 839 } 840 } 841 842 //------------------------------------------------------------------ 843 IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ ) 844 { 845 m_aIndexes.EndSelection(); 846 847 if (m_aIndexes.IsEditingActive()) 848 m_aIndexes.EndEditing(sal_False); 849 850 // commit the old data 851 if (m_aIndexes.FirstSelected() != m_pPreviousSelection) 852 { // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing) 853 if (!implCommitPreviouslySelected()) 854 { 855 m_aIndexes.SelectNoHandlerCall(m_pPreviousSelection); 856 return 1L; 857 } 858 } 859 860 sal_Bool bHaveSelection = (NULL != m_aIndexes.FirstSelected()); 861 862 // disable/enable the detail controls 863 m_aIndexDetails.Enable(bHaveSelection); 864 m_aUnique.Enable(bHaveSelection); 865 m_aDescriptionLabel.Enable(bHaveSelection); 866 m_aFieldsLabel.Enable(bHaveSelection); 867 m_pFields->Enable(bHaveSelection); 868 869 SvLBoxEntry* pNewSelection = m_aIndexes.FirstSelected(); 870 updateControls(pNewSelection); 871 if (bHaveSelection) 872 m_aIndexes.GrabFocus(); 873 874 m_pPreviousSelection = pNewSelection; 875 876 updateToolbox(); 877 return 0L; 878 } 879 // ----------------------------------------------------------------------------- 880 void DbaIndexDialog::StateChanged( StateChangedType nType ) 881 { 882 ModalDialog::StateChanged( nType ); 883 884 if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 885 { 886 // Check if we need to get new images for normal/high contrast mode 887 checkImageList(); 888 } 889 else if ( nType == STATE_CHANGE_TEXT ) 890 { 891 // The physical toolbar changed its outlook and shows another logical toolbar! 892 // We have to set the correct high contrast mode on the new tbx manager. 893 // pMgr->SetHiContrast( IsHiContrastMode() ); 894 checkImageList(); 895 } 896 } 897 // ----------------------------------------------------------------------------- 898 void DbaIndexDialog::DataChanged( const DataChangedEvent& rDCEvt ) 899 { 900 ModalDialog::DataChanged( rDCEvt ); 901 902 if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || 903 ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) && 904 ( rDCEvt.GetFlags() & SETTINGS_STYLE )) 905 { 906 // Check if we need to get new images for normal/high contrast mode 907 checkImageList(); 908 } 909 } 910 //------------------------------------------------------------------ 911 ImageList DbaIndexDialog::getImageList(sal_Int16 _eBitmapSet,sal_Bool _bHiContast) const 912 { 913 sal_Int16 nN = IMG_INDEX_DLG_SC; 914 sal_Int16 nH = IMG_INDEX_DLG_SCH; 915 if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE ) 916 { 917 nN = IMG_INDEX_DLG_LC; 918 nH = IMG_INDEX_DLG_LCH; 919 } // if ( _eBitmapSet == SFX_SYMBOLS_LARGE ) 920 return ImageList(ModuleRes( _bHiContast ? nH : nN )); 921 } 922 //------------------------------------------------------------------ 923 void DbaIndexDialog::resizeControls(const Size& _rDiff) 924 { 925 // we use large images so we must change them 926 Size aTbNewSize = m_aActions.GetSizePixel(); 927 if ( _rDiff.Width() || _rDiff.Height() ) 928 { 929 Size aDlgSize = GetSizePixel(); 930 // adjust size of dlg 931 SetSizePixel(Size(aDlgSize.Width() + _rDiff.Width(), 932 aDlgSize.Height() + _rDiff.Height()) 933 ); 934 Size aIndexSize = m_aIndexes.GetSizePixel(); 935 m_aIndexes.SetPosSizePixel(m_aIndexes.GetPosPixel() + Point(0,_rDiff.Height()), 936 Size(aIndexSize.Width() + _rDiff.Width(), 937 aIndexSize.Height())); 938 939 //now move the rest to the left side 940 Point aMove(_rDiff.Width(),_rDiff.Height()); 941 m_aIndexDetails.SetPosPixel(m_aIndexDetails.GetPosPixel() + aMove); 942 m_aDescriptionLabel.SetPosPixel(m_aDescriptionLabel.GetPosPixel() + aMove); 943 m_aDescription.SetPosPixel(m_aDescription.GetPosPixel() + aMove); 944 m_aUnique.SetPosPixel(m_aUnique.GetPosPixel() + aMove); 945 m_aFieldsLabel.SetPosPixel(m_aFieldsLabel.GetPosPixel() + aMove); 946 OSL_ENSURE(m_pFields,"NO valid fields!"); 947 m_pFields->SetPosPixel(m_pFields->GetPosPixel() + aMove); 948 m_aClose.SetPosPixel(m_aClose.GetPosPixel() + aMove); 949 m_aHelp.SetPosPixel(m_aHelp.GetPosPixel() + aMove); 950 951 Invalidate(); 952 } 953 } 954 955 //...................................................................... 956 } // namespace dbaui 957 //...................................................................... 958 959