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_dbui.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 //------------------------------------------------------------------
operator ==(const OIndexField & _rLHS,const OIndexField & _rRHS)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 //------------------------------------------------------------------
operator !=(const OIndexField & _rLHS,const OIndexField & _rRHS)86 sal_Bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS)
87 {
88 return !(_rLHS == _rRHS);
89 }
90
91 //------------------------------------------------------------------
operator ==(const IndexFields & _rLHS,const IndexFields & _rRHS)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 //------------------------------------------------------------------
operator !=(const IndexFields & _rLHS,const IndexFields & _rRHS)110 sal_Bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
111 {
112 return !(_rLHS == _rRHS);
113 }
114
115 //==================================================================
116 //= DbaIndexList
117 //==================================================================
118 //------------------------------------------------------------------
DbaIndexList(Window * _pParent,const ResId & _rId)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 //------------------------------------------------------------------
EditedEntry(SvLBoxEntry * _pEntry,const String & _rNewText)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 //------------------------------------------------------------------
enableSelectHandler()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 //------------------------------------------------------------------
disableSelectHandler()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 //------------------------------------------------------------------
SelectNoHandlerCall(SvLBoxEntry * _pEntry)179 void DbaIndexList::SelectNoHandlerCall( SvLBoxEntry* _pEntry )
180 {
181 disableSelectHandler();
182 Select(_pEntry, sal_True);
183 enableSelectHandler();
184 }
185
186 //------------------------------------------------------------------
Select(SvLBoxEntry * pEntry,sal_Bool _bSelect)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 //==================================================================
DBG_NAME(DbaIndexDialog)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 //------------------------------------------------------------------
updateToolbox()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 //------------------------------------------------------------------
fillIndexList()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 //------------------------------------------------------------------
~DbaIndexDialog()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 //------------------------------------------------------------------
implCommit(SvLBoxEntry * _pEntry)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 //------------------------------------------------------------------
OnNewIndex()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 //------------------------------------------------------------------
OnDropIndex(sal_Bool _bConfirm)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 //------------------------------------------------------------------
implDropIndex(SvLBoxEntry * _pEntry,sal_Bool _bRemoveFromCollection)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 //------------------------------------------------------------------
OnRenameIndex()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 //------------------------------------------------------------------
OnSaveIndex()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 //------------------------------------------------------------------
OnResetIndex()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 //------------------------------------------------------------------
IMPL_LINK(DbaIndexDialog,OnEditIndexAgain,SvLBoxEntry *,_pEntry)667 IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvLBoxEntry*, _pEntry )
668 {
669 m_bEditAgain = sal_False;
670 m_aIndexes.EditEntry(_pEntry);
671 return 0L;
672 }
673
674 //------------------------------------------------------------------
IMPL_LINK(DbaIndexDialog,OnEntryEdited,SvLBoxEntry *,_pEntry)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 //------------------------------------------------------------------
implSaveModified(sal_Bool _bPlausibility)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 //------------------------------------------------------------------
implCheckPlausibility(const ConstIndexesIterator & _rPos)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 //------------------------------------------------------------------
implCommitPreviouslySelected()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 //------------------------------------------------------------------
updateControls(const SvLBoxEntry * _pEntry)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 // -----------------------------------------------------------------------------
StateChanged(StateChangedType nType)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 // -----------------------------------------------------------------------------
DataChanged(const DataChangedEvent & rDCEvt)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 //------------------------------------------------------------------
getImageList(sal_Int16 _eBitmapSet,sal_Bool _bHiContast) const911 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 //------------------------------------------------------------------
resizeControls(const Size & _rDiff)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 /* vim: set noet sw=4 ts=4: */
959