Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / control / RelationControl.cxx
blobcfb56b67c323fc5815b2f9f305651237311954dd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "RelationControl.hxx"
22 #include <svtools/editbrowsebox.hxx>
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <tools/diagnose_ex.h>
25 #include <vcl/builderfactory.hxx>
26 #include "TableConnectionData.hxx"
27 #include "TableConnection.hxx"
28 #include "TableWindow.hxx"
29 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
30 #include "UITools.hxx"
31 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include "RelControliFace.hxx"
34 #include "dbu_control.hrc"
35 #include "dbaccess_helpid.hrc"
36 #include <osl/diagnose.h>
38 #include <algorithm>
39 #include <list>
40 using std::list;
41 #include <utility>
42 using std::pair;
43 using std::make_pair;
45 #define SOURCE_COLUMN 1
46 #define DEST_COLUMN 2
48 namespace dbaui
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::sdbc;
53 using namespace ::com::sun::star::sdbcx;
54 using namespace ::com::sun::star::container;
55 using namespace svt;
57 typedef ::svt::EditBrowseBox ORelationControl_Base;
58 class ORelationControl : public ORelationControl_Base
60 friend class OTableListBoxControl;
62 VclPtr< ::svt::ListBoxControl> m_pListCell;
63 TTableConnectionData::value_type m_pConnData;
64 OTableListBoxControl* m_pBoxControl;
65 long m_nDataPos;
66 Reference< XPropertySet> m_xSourceDef;
67 Reference< XPropertySet> m_xDestDef;
68 enum opcode { DELETE, INSERT, MODIFY };
69 typedef list< pair < opcode, pair < OConnectionLineDataVec::size_type, OConnectionLineDataVec::size_type> > > ops_type;
70 ops_type m_ops;
72 void fillListBox(const Reference< XPropertySet>& _xDest,long nRow,sal_uInt16 nColumnId);
73 /** returns the column id for the editbrowsebox
74 @param _nColId
75 the column id SOURCE_COLUMN or DEST_COLUMN
77 @return the current column id eihter SOURCE_COLUMN or DEST_COLUMN depends on the connection data
79 sal_uInt16 getColumnIdent( sal_uInt16 _nColId ) const;
80 public:
81 ORelationControl(vcl::Window *pParent);
82 void SetController(OTableListBoxControl* pController)
84 m_pBoxControl = pController;
87 /** searches for a connection between these two tables
88 @param _pSource
89 the left table
90 @param _pDest
91 the right window
93 void setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest);
95 /** allows to access the connection data from outside
97 @return rthe connection data
99 inline TTableConnectionData::value_type getData() const { return m_pConnData; }
101 void lateInit();
103 protected:
104 virtual ~ORelationControl() { disposeOnce(); }
105 virtual void dispose() SAL_OVERRIDE { m_pListCell.disposeAndClear(); ORelationControl_Base::dispose(); }
106 virtual void Resize() SAL_OVERRIDE;
107 virtual Size GetOptimalSize() const SAL_OVERRIDE;
108 virtual bool PreNotify(NotifyEvent& rNEvt ) SAL_OVERRIDE;
110 virtual bool IsTabAllowed(bool bForward) const SAL_OVERRIDE;
112 void Init(const TTableConnectionData::value_type& _pConnData);
113 virtual void Init() SAL_OVERRIDE { ORelationControl_Base::Init(); }
114 virtual void InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol ) SAL_OVERRIDE;
115 virtual ::svt::CellController* GetController( long nRow, sal_uInt16 nCol ) SAL_OVERRIDE;
116 virtual void PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColId ) const SAL_OVERRIDE;
117 virtual bool SeekRow( long nRow ) SAL_OVERRIDE;
118 virtual bool SaveModified() SAL_OVERRIDE;
119 virtual OUString GetCellText( long nRow, sal_uInt16 nColId ) const SAL_OVERRIDE;
121 virtual void CellModified() SAL_OVERRIDE;
123 DECL_LINK( AsynchDeactivate, void* );
124 private:
126 DECL_LINK( AsynchActivate, void* );
130 // class ORelationControl
131 ORelationControl::ORelationControl(vcl::Window *pParent)
132 : EditBrowseBox(pParent,
133 EditBrowseBoxFlags::SMART_TAB_TRAVEL | EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT,
134 WB_TABSTOP | WB_BORDER,
135 BrowserMode::AUTOSIZE_LASTCOL)
136 , m_pBoxControl(NULL)
137 , m_nDataPos(0)
138 , m_xSourceDef(NULL)
139 , m_xDestDef(NULL)
143 VCL_BUILDER_FACTORY(ORelationControl)
145 void ORelationControl::Init(const TTableConnectionData::value_type& _pConnData)
148 m_pConnData = _pConnData;
149 OSL_ENSURE(m_pConnData, "No data supplied!");
151 m_pConnData->normalizeLines();
154 void ORelationControl::lateInit()
156 if ( !m_pConnData.get() )
157 return;
158 m_xSourceDef = m_pConnData->getReferencingTable()->getTable();
159 m_xDestDef = m_pConnData->getReferencedTable()->getTable();
161 if ( ColCount() == 0 )
163 InsertDataColumn( SOURCE_COLUMN, m_pConnData->getReferencingTable()->GetWinName(), 100);
164 InsertDataColumn( DEST_COLUMN, m_pConnData->getReferencedTable()->GetWinName(), 100);
165 // If the Defs do not yet exits, we need to set them with SetSource-/-DestDef
167 m_pListCell.reset( VclPtr<ListBoxControl>::Create( &GetDataWindow() ) );
169 // set browse mode
170 SetMode( BrowserMode::COLUMNSELECTION |
171 BrowserMode::HLINES |
172 BrowserMode::VLINES |
173 BrowserMode::HIDECURSOR |
174 BrowserMode::HIDESELECT |
175 BrowserMode::AUTO_HSCROLL |
176 BrowserMode::AUTO_VSCROLL);
178 else
179 // not the first call
180 RowRemoved(0, GetRowCount());
182 RowInserted(0, m_pConnData->GetConnLineDataList().size() + 1, true); // add one extra row
185 void ORelationControl::Resize()
187 EditBrowseBox::Resize();
188 long nOutputWidth = GetOutputSizePixel().Width() - 1;
189 SetColumnWidth(1, (nOutputWidth / 2));
190 SetColumnWidth(2, (nOutputWidth / 2));
193 bool ORelationControl::PreNotify(NotifyEvent& rNEvt)
195 if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS && !HasChildPathFocus() )
196 PostUserEvent(LINK(this, ORelationControl, AsynchDeactivate), NULL, true);
197 else if (rNEvt.GetType() == MouseNotifyEvent::GETFOCUS)
198 PostUserEvent(LINK(this, ORelationControl, AsynchActivate), NULL, true);
200 return EditBrowseBox::PreNotify(rNEvt);
203 IMPL_LINK_NOARG(ORelationControl, AsynchActivate)
205 ActivateCell();
206 return 0L;
209 IMPL_LINK_NOARG(ORelationControl, AsynchDeactivate)
211 DeactivateCell();
212 return 0L;
215 bool ORelationControl::IsTabAllowed(bool bForward) const
217 long nRow = GetCurRow();
218 sal_uInt16 nCol = GetCurColumnId();
220 bool bRet = !(( ( bForward && (nCol == DEST_COLUMN) && (nRow == GetRowCount() - 1)))
221 || (!bForward && (nCol == SOURCE_COLUMN) && (nRow == 0)));
223 return bRet && EditBrowseBox::IsTabAllowed(bForward);
226 bool ORelationControl::SaveModified()
228 long nRow = GetCurRow();
229 if ( nRow != BROWSER_ENDOFSELECTION )
231 OUString sFieldName(m_pListCell->GetSelectEntry());
232 OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList();
233 if ( rLines.size() <= static_cast<OConnectionLineDataVec::size_type>(nRow) )
235 rLines.push_back(new OConnectionLineData());
236 nRow = rLines.size() - 1;
237 // add new past-rLines row
238 m_ops.push_back(make_pair(INSERT, make_pair(nRow+1, nRow+2)));
241 OConnectionLineDataRef pConnLineData = rLines[nRow];
243 switch( getColumnIdent( GetCurColumnId() ) )
245 case SOURCE_COLUMN:
246 pConnLineData->SetSourceFieldName( sFieldName );
247 break;
248 case DEST_COLUMN:
249 pConnLineData->SetDestFieldName( sFieldName );
250 break;
252 // the modification we just did does *not* need to be registered in m_ops;
253 // it is already taken into account (by the codepath that called us)
254 //m_ops.push_back(make_pair(MODIFY, make_pair(nRow, nRow+1)));
257 const OConnectionLineDataVec::size_type oldSize = m_pConnData->GetConnLineDataList().size();
258 OConnectionLineDataVec::size_type line = m_pConnData->normalizeLines();
259 const OConnectionLineDataVec::size_type newSize = m_pConnData->GetConnLineDataList().size();
260 assert(newSize <= oldSize);
261 m_ops.push_back(make_pair(MODIFY, make_pair(line, newSize)));
262 m_ops.push_back(make_pair(DELETE, make_pair(newSize, oldSize)));
264 return true;
267 sal_uInt16 ORelationControl::getColumnIdent( sal_uInt16 _nColId ) const
269 sal_uInt16 nId = _nColId;
270 if ( m_pConnData->getReferencingTable() != m_pBoxControl->getReferencingTable() )
271 nId = ( _nColId == SOURCE_COLUMN) ? DEST_COLUMN : SOURCE_COLUMN;
272 return nId;
275 OUString ORelationControl::GetCellText( long nRow, sal_uInt16 nColId ) const
277 OUString sText;
278 if ( m_pConnData->GetConnLineDataList().size() > static_cast<size_t>(nRow) )
280 OConnectionLineDataRef pConnLineData = m_pConnData->GetConnLineDataList()[nRow];
281 switch( getColumnIdent( nColId ) )
283 case SOURCE_COLUMN:
284 sText = pConnLineData->GetSourceFieldName();
285 break;
286 case DEST_COLUMN:
287 sText = pConnLineData->GetDestFieldName();
288 break;
291 return sText;
294 void ORelationControl::InitController( CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColumnId )
297 OString sHelpId( HID_RELATIONDIALOG_LEFTFIELDCELL );
299 Reference< XPropertySet> xDef;
300 switch ( getColumnIdent(nColumnId) )
302 case SOURCE_COLUMN:
303 xDef = m_xSourceDef;
304 sHelpId = HID_RELATIONDIALOG_LEFTFIELDCELL;
305 break;
306 case DEST_COLUMN:
307 xDef = m_xDestDef;
308 sHelpId = HID_RELATIONDIALOG_RIGHTFIELDCELL;
309 break;
310 default:
311 // ?????????
312 break;
315 if ( xDef.is() )
317 fillListBox(xDef,nRow,nColumnId);
318 OUString sName = GetCellText( nRow, nColumnId );
319 m_pListCell->SelectEntry( sName );
320 if ( m_pListCell->GetSelectEntry() != sName )
322 m_pListCell->InsertEntry( sName );
323 m_pListCell->SelectEntry( sName );
326 m_pListCell->SetHelpId(sHelpId);
330 CellController* ORelationControl::GetController( long /*nRow*/, sal_uInt16 /*nColumnId*/ )
332 return new ListBoxCellController( m_pListCell.get() );
335 bool ORelationControl::SeekRow( long nRow )
337 m_nDataPos = nRow;
338 return true;
341 void ORelationControl::PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const
343 OUString aText = GetCellText( m_nDataPos, nColumnId );
345 Point aPos( rRect.TopLeft() );
346 Size aTextSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight() );
348 if( aPos.X() < rRect.Left() || aPos.X() + aTextSize.Width() > rRect.Right() ||
349 aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() )
351 rDev.SetClipRegion(vcl::Region(rRect));
354 rDev.DrawText( aPos, aText );
356 if( rDev.IsClipRegion() )
357 rDev.SetClipRegion();
359 void ORelationControl::fillListBox(const Reference< XPropertySet>& _xDest,long /*_nRow*/,sal_uInt16 /*nColumnId*/)
361 m_pListCell->Clear();
364 if ( _xDest.is() )
366 //sal_Int32 nRows = GetRowCount();
367 Reference<XColumnsSupplier> xSup(_xDest,UNO_QUERY);
368 Reference<XNameAccess> xColumns = xSup->getColumns();
369 Sequence< OUString> aNames = xColumns->getElementNames();
370 const OUString* pIter = aNames.getConstArray();
371 const OUString* pEnd = pIter + aNames.getLength();
372 for(;pIter != pEnd;++pIter)
374 m_pListCell->InsertEntry( *pIter );
376 m_pListCell->InsertEntry(OUString(), 0);
379 catch( const Exception& )
381 DBG_UNHANDLED_EXCEPTION();
384 void ORelationControl::setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest)
386 // If I edit here, hide
387 bool bWasEditing = IsEditing();
388 if ( bWasEditing )
389 DeactivateCell();
391 if ( _pSource && _pDest )
393 m_xSourceDef = _pSource->GetTable();
394 SetColumnTitle(1, _pSource->GetName());
396 m_xDestDef = _pDest->GetTable();
397 SetColumnTitle(2, _pDest->GetName());
399 const OJoinTableView* pView = _pSource->getTableView();
400 OTableConnection* pConn = pView->GetTabConn(_pSource,_pDest);
401 if ( pConn && !m_pConnData->GetConnLineDataList().empty() )
403 m_pConnData->CopyFrom(*pConn->GetData());
404 m_pBoxControl->getContainer()->notifyConnectionChange();
406 else
408 // no connection found so we clear our data
409 OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList();
410 ::std::for_each(rLines.begin(),
411 rLines.end(),
412 OUnaryRefFunctor<OConnectionLineData>( ::std::mem_fun(&OConnectionLineData::Reset))
415 m_pConnData->setReferencingTable(_pSource->GetData());
416 m_pConnData->setReferencedTable(_pDest->GetData());
418 m_pConnData->normalizeLines();
421 // Repaint
422 Invalidate();
424 if ( bWasEditing )
426 GoToRow(0);
427 ActivateCell();
431 void ORelationControl::CellModified()
433 EditBrowseBox::CellModified();
434 SaveModified();
435 assert(m_pBoxControl);
436 m_pBoxControl->NotifyCellChange();
439 Size ORelationControl::GetOptimalSize() const
441 return LogicToPixel(Size(140, 80), MAP_APPFONT);
444 // class OTableListBoxControl
445 OTableListBoxControl::OTableListBoxControl(VclBuilderContainer* _pParent,
446 const OJoinTableView::OTableWindowMap* _pTableMap,
447 IRelationControlInterface* _pParentDialog)
448 : m_pTableMap(_pTableMap)
449 , m_pParentDialog(_pParentDialog)
451 _pParent->get(m_pLeftTable, "table1");
452 _pParent->get(m_pRightTable, "table2");
454 _pParent->get(m_pRC_Tables, "relations");
455 m_pRC_Tables->SetController(this);
456 m_pRC_Tables->Init();
458 lateUIInit();
460 Link<> aLink(LINK(this, OTableListBoxControl, OnTableChanged));
461 m_pLeftTable->SetSelectHdl(aLink);
462 m_pRightTable->SetSelectHdl(aLink);
465 OTableListBoxControl::~OTableListBoxControl()
469 void OTableListBoxControl::fillListBoxes()
471 OSL_ENSURE( !m_pTableMap->empty(), "OTableListBoxControl::fillListBoxes: no table window!");
472 OTableWindow* pInitialLeft = NULL;
473 OTableWindow* pInitialRight = NULL;
475 // Collect the names of all TabWins
476 OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
477 OJoinTableView::OTableWindowMap::const_iterator aEnd = m_pTableMap->end();
478 for(;aIter != aEnd;++aIter)
480 m_pLeftTable->InsertEntry(aIter->first);
481 m_pRightTable->InsertEntry(aIter->first);
483 if (!pInitialLeft)
485 pInitialLeft = aIter->second;
486 m_strCurrentLeft = aIter->first;
488 else if (!pInitialRight)
490 pInitialRight = aIter->second;
491 m_strCurrentRight = aIter->first;
495 if ( !pInitialRight )
497 pInitialRight = pInitialLeft;
498 m_strCurrentRight = m_strCurrentLeft;
501 // The corresponding Defs for my Controls
502 m_pRC_Tables->setWindowTables(pInitialLeft,pInitialRight);
504 // The table selected in a ComboBox must not be available in the other
506 if ( m_pTableMap->size() > 2 )
508 m_pLeftTable->RemoveEntry(m_strCurrentRight);
509 m_pRightTable->RemoveEntry(m_strCurrentLeft);
512 // Select the first one on the left side and on the right side,
513 // select the second one
514 m_pLeftTable->SelectEntry(m_strCurrentLeft);
515 m_pRightTable->SelectEntry(m_strCurrentRight);
517 m_pLeftTable->GrabFocus();
520 IMPL_LINK( OTableListBoxControl, OnTableChanged, ListBox*, pListBox )
522 OUString strSelected(pListBox->GetSelectEntry());
523 OTableWindow* pLeft = NULL;
524 OTableWindow* pRight = NULL;
526 // Special treatment: If there are only two tables, we need to switch the other one too when changing in a LB
527 if ( m_pTableMap->size() == 2 )
529 ListBox* pOther;
530 if (pListBox == m_pLeftTable)
531 pOther = m_pRightTable;
532 else
533 pOther = m_pLeftTable;
534 pOther->SelectEntryPos(1 - pOther->GetSelectEntryPos());
536 OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
537 OTableWindow* pFirst = aIter->second;
538 ++aIter;
539 OTableWindow* pSecond = aIter->second;
541 if ( m_pLeftTable->GetSelectEntry() == pFirst->GetName() )
543 pLeft = pFirst;
544 pRight = pSecond;
546 else
548 pLeft = pSecond;
549 pRight = pFirst;
552 else
554 // First we need the TableDef to the Table and with it the TabWin
555 OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(strSelected);
556 OTableWindow* pLoop = NULL;
557 if( aFind != m_pTableMap->end() )
558 pLoop = aFind->second;
559 OSL_ENSURE(pLoop != NULL, "ORelationDialog::OnTableChanged: invalid ListBox entry!");
560 // We need to find strSelect, because we filled the ListBoxes with the table names with which we compare now
561 if (pListBox == m_pLeftTable)
563 // Insert the previously selected Entry on the left side on the right side
564 m_pRightTable->InsertEntry(m_strCurrentLeft);
565 // Remove the currently selected Entry
566 m_pRightTable->RemoveEntry(strSelected);
567 m_strCurrentLeft = strSelected;
569 pLeft = pLoop;
571 OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_pRightTable->GetSelectEntry());
572 OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
573 if ( aIter != m_pTableMap->end() )
574 pRight = aIter->second;
576 m_pLeftTable->GrabFocus();
578 else
580 // Insert the previously selected Entry on the right side on the left side
581 m_pLeftTable->InsertEntry(m_strCurrentRight);
582 // Remove the currently selected Entry
583 m_pLeftTable->RemoveEntry(strSelected);
584 m_strCurrentRight = strSelected;
586 pRight = pLoop;
587 OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_pLeftTable->GetSelectEntry());
588 OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
589 if ( aIter != m_pTableMap->end() )
590 pLeft = aIter->second;
594 pListBox->GrabFocus();
596 m_pRC_Tables->setWindowTables(pLeft,pRight);
598 NotifyCellChange();
599 return 0;
602 void OTableListBoxControl::NotifyCellChange()
604 // Enable/disable the OK button, depending on having a valid situation
605 TTableConnectionData::value_type pConnData = m_pRC_Tables->getData();
606 const OConnectionLineDataVec& rLines = pConnData->GetConnLineDataList();
607 bool bValid = !rLines.empty();
608 if (bValid)
610 OConnectionLineDataVec::const_iterator l(rLines.begin());
611 const OConnectionLineDataVec::const_iterator le(rLines.end());
612 for (; bValid && l!=le; ++l)
614 bValid = ! ((*l)->GetSourceFieldName().isEmpty() || (*l)->GetDestFieldName().isEmpty());
617 m_pParentDialog->setValid(bValid);
619 ORelationControl::ops_type::iterator i (m_pRC_Tables->m_ops.begin());
620 const ORelationControl::ops_type::const_iterator e (m_pRC_Tables->m_ops.end());
621 m_pRC_Tables->DeactivateCell();
622 for(; i != e; ++i)
624 switch(i->first)
626 case ORelationControl::DELETE:
627 m_pRC_Tables->RowRemoved(i->second.first, i->second.second - i->second.first);
628 break;
629 case ORelationControl::INSERT:
630 m_pRC_Tables->RowInserted(i->second.first, i->second.second - i->second.first);
631 break;
632 case ORelationControl::MODIFY:
633 for(OConnectionLineDataVec::size_type j = i->second.first; j < i->second.second; ++j)
634 m_pRC_Tables->RowModified(j);
635 break;
638 m_pRC_Tables->ActivateCell();
639 m_pRC_Tables->m_ops.clear();
642 void fillEntryAndDisable(ListBox& _rListBox,const OUString& _sEntry)
644 _rListBox.InsertEntry(_sEntry);
645 _rListBox.SelectEntryPos(0);
646 _rListBox.Disable();
649 void OTableListBoxControl::fillAndDisable(const TTableConnectionData::value_type& _pConnectionData)
651 fillEntryAndDisable(*m_pLeftTable, _pConnectionData->getReferencingTable()->GetWinName());
652 fillEntryAndDisable(*m_pRightTable, _pConnectionData->getReferencedTable()->GetWinName());
655 void OTableListBoxControl::Init(const TTableConnectionData::value_type& _pConnData)
657 m_pRC_Tables->Init(_pConnData);
660 void OTableListBoxControl::lateUIInit()
662 m_pRC_Tables->Show();
663 lateInit();
666 void OTableListBoxControl::lateInit()
668 m_pRC_Tables->lateInit();
671 void OTableListBoxControl::Disable()
673 m_pLeftTable->Disable();
674 m_pRightTable->Disable();
675 m_pRC_Tables->Disable();
678 void OTableListBoxControl::Invalidate()
680 m_pLeftTable->Invalidate();
681 m_pRightTable->Invalidate();
682 m_pRC_Tables->Invalidate();
685 bool OTableListBoxControl::SaveModified()
687 return m_pRC_Tables->SaveModified();
690 TTableWindowData::value_type OTableListBoxControl::getReferencingTable() const
692 return m_pRC_Tables->getData()->getReferencingTable();
695 void OTableListBoxControl::enableRelation(bool _bEnable)
697 if ( !_bEnable )
698 m_pRC_Tables->PostUserEvent(LINK(m_pRC_Tables, ORelationControl, AsynchDeactivate));
699 m_pRC_Tables->Enable(_bEnable);
704 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */