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