Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "RelationControl.hxx"
21 :
22 : #include <svtools/editbrowsebox.hxx>
23 : #include <com/sun/star/beans/XPropertySet.hpp>
24 : #include <tools/diagnose_ex.h>
25 : #include <vcl/builder.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>
37 :
38 : #include <algorithm>
39 : #include <list>
40 : using std::list;
41 : #include <utility>
42 : using std::pair;
43 : using std::make_pair;
44 :
45 : #define SOURCE_COLUMN 1
46 : #define DEST_COLUMN 2
47 :
48 : namespace dbaui
49 : {
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;
56 :
57 : typedef ::svt::EditBrowseBox ORelationControl_Base;
58 : class ORelationControl : public ORelationControl_Base
59 : {
60 : friend class OTableListBoxControl;
61 :
62 : ::std::unique_ptr< ::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;
71 :
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
76 :
77 : @return the current column id eihter SOURCE_COLUMN or DEST_COLUMN depends on the connection data
78 : */
79 : sal_uInt16 getColumnIdent( sal_uInt16 _nColId ) const;
80 : public:
81 : ORelationControl(vcl::Window *pParent);
82 0 : void SetController(OTableListBoxControl* pController)
83 : {
84 0 : m_pBoxControl = pController;
85 0 : }
86 : virtual ~ORelationControl();
87 :
88 : /** searches for a connection between these two tables
89 : @param _pSource
90 : the left table
91 : @param _pDest
92 : the right window
93 : */
94 : void setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest);
95 :
96 : /** allows to access the connection data from outside
97 :
98 : @return rthe connection data
99 : */
100 0 : inline TTableConnectionData::value_type getData() const { return m_pConnData; }
101 :
102 : void lateInit();
103 :
104 : protected:
105 : virtual void Resize() SAL_OVERRIDE;
106 : virtual Size GetOptimalSize() const SAL_OVERRIDE;
107 : virtual bool PreNotify(NotifyEvent& rNEvt ) SAL_OVERRIDE;
108 :
109 : virtual bool IsTabAllowed(bool bForward) const SAL_OVERRIDE;
110 :
111 : virtual void Init(const TTableConnectionData::value_type& _pConnData);
112 0 : virtual void Init() SAL_OVERRIDE { ORelationControl_Base::Init(); }
113 : virtual void InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol ) SAL_OVERRIDE;
114 : virtual ::svt::CellController* GetController( long nRow, sal_uInt16 nCol ) SAL_OVERRIDE;
115 : virtual void PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColId ) const SAL_OVERRIDE;
116 : virtual bool SeekRow( long nRow ) SAL_OVERRIDE;
117 : virtual bool SaveModified() SAL_OVERRIDE;
118 : virtual OUString GetCellText( long nRow, sal_uInt16 nColId ) const SAL_OVERRIDE;
119 :
120 : virtual void CellModified() SAL_OVERRIDE;
121 :
122 : DECL_LINK( AsynchDeactivate, void* );
123 : private:
124 :
125 : DECL_LINK( AsynchActivate, void* );
126 :
127 : };
128 :
129 : // class ORelationControl
130 0 : ORelationControl::ORelationControl(vcl::Window *pParent)
131 : : EditBrowseBox(pParent,
132 : EBBF_SMART_TAB_TRAVEL | EBBF_NOROWPICTURE,
133 : WB_TABSTOP | WB_BORDER | BROWSER_AUTOSIZE_LASTCOL)
134 : , m_pBoxControl(NULL)
135 : , m_nDataPos(0)
136 : , m_xSourceDef(NULL)
137 0 : , m_xDestDef(NULL)
138 : {
139 0 : }
140 :
141 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeORelationControl(vcl::Window *pParent, VclBuilder::stringmap &)
142 : {
143 0 : return new ORelationControl(pParent);
144 : }
145 :
146 0 : ORelationControl::~ORelationControl()
147 : {
148 0 : }
149 :
150 0 : void ORelationControl::Init(const TTableConnectionData::value_type& _pConnData)
151 : {
152 :
153 0 : m_pConnData = _pConnData;
154 : OSL_ENSURE(m_pConnData, "No data supplied!");
155 :
156 0 : m_pConnData->normalizeLines();
157 0 : }
158 :
159 0 : void ORelationControl::lateInit()
160 : {
161 0 : if ( !m_pConnData.get() )
162 0 : return;
163 0 : m_xSourceDef = m_pConnData->getReferencingTable()->getTable();
164 0 : m_xDestDef = m_pConnData->getReferencedTable()->getTable();
165 :
166 0 : if ( ColCount() == 0 )
167 : {
168 0 : InsertDataColumn( SOURCE_COLUMN, m_pConnData->getReferencingTable()->GetWinName(), 100);
169 0 : InsertDataColumn( DEST_COLUMN, m_pConnData->getReferencedTable()->GetWinName(), 100);
170 : // If the Defs do not yet exits, we need to set them with SetSource-/-DestDef
171 :
172 0 : m_pListCell.reset( new ListBoxControl( &GetDataWindow() ) );
173 :
174 : // set browse mode
175 : SetMode( BROWSER_COLUMNSELECTION |
176 : BROWSER_HLINESFULL |
177 : BROWSER_VLINESFULL |
178 : BROWSER_HIDECURSOR |
179 : BROWSER_HIDESELECT |
180 : BROWSER_AUTO_HSCROLL |
181 0 : BROWSER_AUTO_VSCROLL);
182 : }
183 : else
184 : // not the first call
185 0 : RowRemoved(0, GetRowCount());
186 :
187 0 : RowInserted(0, m_pConnData->GetConnLineDataList().size() + 1, true); // add one extra row
188 : }
189 :
190 0 : void ORelationControl::Resize()
191 : {
192 0 : EditBrowseBox::Resize();
193 0 : long nOutputWidth = GetOutputSizePixel().Width() - 1;
194 0 : SetColumnWidth(1, (nOutputWidth / 2));
195 0 : SetColumnWidth(2, (nOutputWidth / 2));
196 0 : }
197 :
198 0 : bool ORelationControl::PreNotify(NotifyEvent& rNEvt)
199 : {
200 0 : if (rNEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
201 0 : PostUserEvent(LINK(this, ORelationControl, AsynchDeactivate));
202 0 : else if (rNEvt.GetType() == EVENT_GETFOCUS)
203 0 : PostUserEvent(LINK(this, ORelationControl, AsynchActivate));
204 :
205 0 : return EditBrowseBox::PreNotify(rNEvt);
206 : }
207 :
208 0 : IMPL_LINK_NOARG(ORelationControl, AsynchActivate)
209 : {
210 0 : ActivateCell();
211 0 : return 0L;
212 : }
213 :
214 0 : IMPL_LINK_NOARG(ORelationControl, AsynchDeactivate)
215 : {
216 0 : DeactivateCell();
217 0 : return 0L;
218 : }
219 :
220 0 : bool ORelationControl::IsTabAllowed(bool bForward) const
221 : {
222 0 : long nRow = GetCurRow();
223 0 : sal_uInt16 nCol = GetCurColumnId();
224 :
225 0 : bool bRet = !(( ( bForward && (nCol == DEST_COLUMN) && (nRow == GetRowCount() - 1)))
226 0 : || (!bForward && (nCol == SOURCE_COLUMN) && (nRow == 0)));
227 :
228 0 : return bRet && EditBrowseBox::IsTabAllowed(bForward);
229 : }
230 :
231 0 : bool ORelationControl::SaveModified()
232 : {
233 0 : long nRow = GetCurRow();
234 0 : if ( nRow != BROWSER_ENDOFSELECTION )
235 : {
236 0 : OUString sFieldName(m_pListCell->GetSelectEntry());
237 0 : OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList();
238 0 : if ( rLines.size() <= static_cast<OConnectionLineDataVec::size_type>(nRow) )
239 : {
240 0 : rLines.push_back(new OConnectionLineData());
241 0 : nRow = rLines.size() - 1;
242 : // add new past-rLines row
243 0 : m_ops.push_back(make_pair(INSERT, make_pair(nRow+1, nRow+2)));
244 : }
245 :
246 0 : OConnectionLineDataRef pConnLineData = rLines[nRow];
247 :
248 0 : switch( getColumnIdent( GetCurColumnId() ) )
249 : {
250 : case SOURCE_COLUMN:
251 0 : pConnLineData->SetSourceFieldName( sFieldName );
252 0 : break;
253 : case DEST_COLUMN:
254 0 : pConnLineData->SetDestFieldName( sFieldName );
255 0 : break;
256 0 : }
257 : // the modification we just did does *not* need to be registered in m_ops;
258 : // it is already taken into account (by the codepath that called us)
259 : //m_ops.push_back(make_pair(MODIFY, make_pair(nRow, nRow+1)));
260 : }
261 :
262 0 : const OConnectionLineDataVec::size_type oldSize = m_pConnData->GetConnLineDataList().size();
263 0 : OConnectionLineDataVec::size_type line = m_pConnData->normalizeLines();
264 0 : const OConnectionLineDataVec::size_type newSize = m_pConnData->GetConnLineDataList().size();
265 : assert(newSize <= oldSize);
266 0 : m_ops.push_back(make_pair(MODIFY, make_pair(line, newSize)));
267 0 : m_ops.push_back(make_pair(DELETE, make_pair(newSize, oldSize)));
268 :
269 0 : return true;
270 : }
271 :
272 0 : sal_uInt16 ORelationControl::getColumnIdent( sal_uInt16 _nColId ) const
273 : {
274 0 : sal_uInt16 nId = _nColId;
275 0 : if ( m_pConnData->getReferencingTable() != m_pBoxControl->getReferencingTable() )
276 0 : nId = ( _nColId == SOURCE_COLUMN) ? DEST_COLUMN : SOURCE_COLUMN;
277 0 : return nId;
278 : }
279 :
280 0 : OUString ORelationControl::GetCellText( long nRow, sal_uInt16 nColId ) const
281 : {
282 0 : OUString sText;
283 0 : if ( m_pConnData->GetConnLineDataList().size() > static_cast<size_t>(nRow) )
284 : {
285 0 : OConnectionLineDataRef pConnLineData = m_pConnData->GetConnLineDataList()[nRow];
286 0 : switch( getColumnIdent( nColId ) )
287 : {
288 : case SOURCE_COLUMN:
289 0 : sText = pConnLineData->GetSourceFieldName();
290 0 : break;
291 : case DEST_COLUMN:
292 0 : sText = pConnLineData->GetDestFieldName();
293 0 : break;
294 0 : }
295 : }
296 0 : return sText;
297 : }
298 :
299 0 : void ORelationControl::InitController( CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColumnId )
300 : {
301 :
302 0 : OString sHelpId( HID_RELATIONDIALOG_LEFTFIELDCELL );
303 :
304 0 : Reference< XPropertySet> xDef;
305 0 : switch ( getColumnIdent(nColumnId) )
306 : {
307 : case SOURCE_COLUMN:
308 0 : xDef = m_xSourceDef;
309 0 : sHelpId = HID_RELATIONDIALOG_LEFTFIELDCELL;
310 0 : break;
311 : case DEST_COLUMN:
312 0 : xDef = m_xDestDef;
313 0 : sHelpId = HID_RELATIONDIALOG_RIGHTFIELDCELL;
314 0 : break;
315 : default:
316 : // ?????????
317 0 : break;
318 : }
319 :
320 0 : if ( xDef.is() )
321 : {
322 0 : fillListBox(xDef,nRow,nColumnId);
323 0 : OUString sName = GetCellText( nRow, nColumnId );
324 0 : m_pListCell->SelectEntry( sName );
325 0 : if ( m_pListCell->GetSelectEntry() != sName )
326 : {
327 0 : m_pListCell->InsertEntry( sName );
328 0 : m_pListCell->SelectEntry( sName );
329 : }
330 :
331 0 : m_pListCell->SetHelpId(sHelpId);
332 0 : }
333 0 : }
334 :
335 0 : CellController* ORelationControl::GetController( long /*nRow*/, sal_uInt16 /*nColumnId*/ )
336 : {
337 0 : return new ListBoxCellController( m_pListCell.get() );
338 : }
339 :
340 0 : bool ORelationControl::SeekRow( long nRow )
341 : {
342 0 : m_nDataPos = nRow;
343 0 : return true;
344 : }
345 :
346 0 : void ORelationControl::PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const
347 : {
348 0 : OUString aText = const_cast< ORelationControl*>(this)->GetCellText( m_nDataPos, nColumnId );
349 :
350 0 : Point aPos( rRect.TopLeft() );
351 0 : Size aTextSize( GetDataWindow().GetTextHeight(),GetDataWindow().GetTextWidth( aText ));
352 :
353 0 : if( aPos.X() < rRect.Right() || aPos.X() + aTextSize.Width() > rRect.Right() ||
354 0 : aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() )
355 : {
356 0 : rDev.SetClipRegion(vcl::Region(rRect));
357 : }
358 :
359 0 : rDev.DrawText( aPos, aText );
360 :
361 0 : if( rDev.IsClipRegion() )
362 0 : rDev.SetClipRegion();
363 0 : }
364 0 : void ORelationControl::fillListBox(const Reference< XPropertySet>& _xDest,long /*_nRow*/,sal_uInt16 /*nColumnId*/)
365 : {
366 0 : m_pListCell->Clear();
367 : try
368 : {
369 0 : if ( _xDest.is() )
370 : {
371 : //sal_Int32 nRows = GetRowCount();
372 0 : Reference<XColumnsSupplier> xSup(_xDest,UNO_QUERY);
373 0 : Reference<XNameAccess> xColumns = xSup->getColumns();
374 0 : Sequence< OUString> aNames = xColumns->getElementNames();
375 0 : const OUString* pIter = aNames.getConstArray();
376 0 : const OUString* pEnd = pIter + aNames.getLength();
377 0 : for(;pIter != pEnd;++pIter)
378 : {
379 0 : m_pListCell->InsertEntry( *pIter );
380 : }
381 0 : m_pListCell->InsertEntry(OUString(), 0);
382 : }
383 : }
384 0 : catch( const Exception& )
385 : {
386 : DBG_UNHANDLED_EXCEPTION();
387 : }
388 0 : }
389 0 : void ORelationControl::setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest)
390 : {
391 : // If I edit here, hide
392 0 : bool bWasEditing = IsEditing();
393 0 : if ( bWasEditing )
394 0 : DeactivateCell();
395 :
396 0 : if ( _pSource && _pDest )
397 : {
398 0 : m_xSourceDef = _pSource->GetTable();
399 0 : SetColumnTitle(1, _pSource->GetName());
400 :
401 0 : m_xDestDef = _pDest->GetTable();
402 0 : SetColumnTitle(2, _pDest->GetName());
403 :
404 0 : const OJoinTableView* pView = _pSource->getTableView();
405 0 : OTableConnection* pConn = pView->GetTabConn(_pSource,_pDest);
406 0 : if ( pConn && !m_pConnData->GetConnLineDataList().empty() )
407 : {
408 0 : m_pConnData->CopyFrom(*pConn->GetData());
409 0 : m_pBoxControl->getContainer()->notifyConnectionChange();
410 : }
411 : else
412 : {
413 : // no connection found so we clear our data
414 0 : OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList();
415 : ::std::for_each(rLines.begin(),
416 : rLines.end(),
417 0 : OUnaryRefFunctor<OConnectionLineData>( ::std::mem_fun(&OConnectionLineData::Reset))
418 0 : );
419 :
420 0 : m_pConnData->setReferencingTable(_pSource->GetData());
421 0 : m_pConnData->setReferencedTable(_pDest->GetData());
422 : }
423 0 : m_pConnData->normalizeLines();
424 :
425 : }
426 : // Repaint
427 0 : Invalidate();
428 :
429 0 : if ( bWasEditing )
430 : {
431 0 : GoToRow(0);
432 0 : ActivateCell();
433 : }
434 0 : }
435 :
436 0 : void ORelationControl::CellModified()
437 : {
438 0 : EditBrowseBox::CellModified();
439 0 : SaveModified();
440 : assert(m_pBoxControl);
441 0 : m_pBoxControl->NotifyCellChange();
442 0 : }
443 :
444 0 : Size ORelationControl::GetOptimalSize() const
445 : {
446 0 : return LogicToPixel(Size(140, 80), MAP_APPFONT);
447 : }
448 :
449 : // class OTableListBoxControl
450 0 : OTableListBoxControl::OTableListBoxControl(VclBuilderContainer* _pParent,
451 : const OJoinTableView::OTableWindowMap* _pTableMap,
452 : IRelationControlInterface* _pParentDialog)
453 : : m_pTableMap(_pTableMap)
454 0 : , m_pParentDialog(_pParentDialog)
455 : {
456 0 : _pParent->get(m_pLeftTable, "table1");
457 0 : _pParent->get(m_pRightTable, "table2");
458 :
459 0 : _pParent->get(m_pRC_Tables, "relations");
460 0 : m_pRC_Tables->SetController(this);
461 0 : m_pRC_Tables->Init();
462 :
463 0 : lateUIInit();
464 :
465 0 : Link aLink(LINK(this, OTableListBoxControl, OnTableChanged));
466 0 : m_pLeftTable->SetSelectHdl(aLink);
467 0 : m_pRightTable->SetSelectHdl(aLink);
468 0 : }
469 :
470 0 : OTableListBoxControl::~OTableListBoxControl()
471 : {
472 0 : }
473 :
474 0 : void OTableListBoxControl::fillListBoxes()
475 : {
476 : OSL_ENSURE( !m_pTableMap->empty(), "OTableListBoxControl::fillListBoxes: no table window!");
477 0 : OTableWindow* pInitialLeft = NULL;
478 0 : OTableWindow* pInitialRight = NULL;
479 :
480 : // Collect the names of all TabWins
481 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
482 0 : OJoinTableView::OTableWindowMap::const_iterator aEnd = m_pTableMap->end();
483 0 : for(;aIter != aEnd;++aIter)
484 : {
485 0 : m_pLeftTable->InsertEntry(aIter->first);
486 0 : m_pRightTable->InsertEntry(aIter->first);
487 :
488 0 : if (!pInitialLeft)
489 : {
490 0 : pInitialLeft = aIter->second;
491 0 : m_strCurrentLeft = aIter->first;
492 : }
493 0 : else if (!pInitialRight)
494 : {
495 0 : pInitialRight = aIter->second;
496 0 : m_strCurrentRight = aIter->first;
497 : }
498 : }
499 :
500 0 : if ( !pInitialRight )
501 : {
502 0 : pInitialRight = pInitialLeft;
503 0 : m_strCurrentRight = m_strCurrentLeft;
504 : }
505 :
506 : // The corresponding Defs for my Controls
507 0 : m_pRC_Tables->setWindowTables(pInitialLeft,pInitialRight);
508 :
509 : // The table selected in a ComboBox must not be available in the other
510 :
511 0 : if ( m_pTableMap->size() > 2 )
512 : {
513 0 : m_pLeftTable->RemoveEntry(m_strCurrentRight);
514 0 : m_pRightTable->RemoveEntry(m_strCurrentLeft);
515 : }
516 :
517 : // Select the first one on the left side and on the right side,
518 : // select the second one
519 0 : m_pLeftTable->SelectEntry(m_strCurrentLeft);
520 0 : m_pRightTable->SelectEntry(m_strCurrentRight);
521 :
522 0 : m_pLeftTable->GrabFocus();
523 0 : }
524 :
525 0 : IMPL_LINK( OTableListBoxControl, OnTableChanged, ListBox*, pListBox )
526 : {
527 0 : OUString strSelected(pListBox->GetSelectEntry());
528 0 : OTableWindow* pLeft = NULL;
529 0 : OTableWindow* pRight = NULL;
530 :
531 : // Special treatment: If there are only two tables, we need to switch the other one too when changing in a LB
532 0 : if ( m_pTableMap->size() == 2 )
533 : {
534 : ListBox* pOther;
535 0 : if (pListBox == m_pLeftTable)
536 0 : pOther = m_pRightTable;
537 : else
538 0 : pOther = m_pLeftTable;
539 0 : pOther->SelectEntryPos(1 - pOther->GetSelectEntryPos());
540 :
541 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
542 0 : OTableWindow* pFirst = aIter->second;
543 0 : ++aIter;
544 0 : OTableWindow* pSecond = aIter->second;
545 :
546 0 : if ( m_pLeftTable->GetSelectEntry() == pFirst->GetName() )
547 : {
548 0 : pLeft = pFirst;
549 0 : pRight = pSecond;
550 : }
551 : else
552 : {
553 0 : pLeft = pSecond;
554 0 : pRight = pFirst;
555 : }
556 : }
557 : else
558 : {
559 : // First we need the TableDef to the Table and with it the TabWin
560 0 : OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(strSelected);
561 0 : OTableWindow* pLoop = NULL;
562 0 : if( aFind != m_pTableMap->end() )
563 0 : pLoop = aFind->second;
564 : OSL_ENSURE(pLoop != NULL, "ORelationDialog::OnTableChanged: invalid ListBox entry!");
565 : // We need to find strSelect, because we filled the ListBoxes with the table names with which we compare now
566 0 : if (pListBox == m_pLeftTable)
567 : {
568 : // Insert the previously selected Entry on the left side on the right side
569 0 : m_pRightTable->InsertEntry(m_strCurrentLeft);
570 : // Remove the currently selected Entry
571 0 : m_pRightTable->RemoveEntry(strSelected);
572 0 : m_strCurrentLeft = strSelected;
573 :
574 0 : pLeft = pLoop;
575 :
576 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_pRightTable->GetSelectEntry());
577 : OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
578 0 : if ( aIter != m_pTableMap->end() )
579 0 : pRight = aIter->second;
580 :
581 0 : m_pLeftTable->GrabFocus();
582 : }
583 : else
584 : {
585 : // Insert the previously selected Entry on the right side on the left side
586 0 : m_pLeftTable->InsertEntry(m_strCurrentRight);
587 : // Remove the currently selected Entry
588 0 : m_pLeftTable->RemoveEntry(strSelected);
589 0 : m_strCurrentRight = strSelected;
590 :
591 0 : pRight = pLoop;
592 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_pLeftTable->GetSelectEntry());
593 : OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
594 0 : if ( aIter != m_pTableMap->end() )
595 0 : pLeft = aIter->second;
596 : }
597 : }
598 :
599 0 : pListBox->GrabFocus();
600 :
601 0 : m_pRC_Tables->setWindowTables(pLeft,pRight);
602 :
603 0 : NotifyCellChange();
604 0 : return 0;
605 : }
606 :
607 0 : void OTableListBoxControl::NotifyCellChange()
608 : {
609 : // Enable/disable the OK button, depending on having a valid situation
610 0 : TTableConnectionData::value_type pConnData = m_pRC_Tables->getData();
611 0 : const OConnectionLineDataVec& rLines = pConnData->GetConnLineDataList();
612 0 : bool bValid = !rLines.empty();
613 0 : if (bValid)
614 : {
615 0 : OConnectionLineDataVec::const_iterator l(rLines.begin());
616 0 : const OConnectionLineDataVec::const_iterator le(rLines.end());
617 0 : for (; bValid && l!=le; ++l)
618 : {
619 0 : bValid = ! ((*l)->GetSourceFieldName().isEmpty() || (*l)->GetDestFieldName().isEmpty());
620 : }
621 : }
622 0 : m_pParentDialog->setValid(bValid);
623 :
624 0 : ORelationControl::ops_type::iterator i (m_pRC_Tables->m_ops.begin());
625 0 : const ORelationControl::ops_type::const_iterator e (m_pRC_Tables->m_ops.end());
626 0 : m_pRC_Tables->DeactivateCell();
627 0 : for(; i != e; ++i)
628 : {
629 0 : switch(i->first)
630 : {
631 : case ORelationControl::DELETE:
632 0 : m_pRC_Tables->RowRemoved(i->second.first, i->second.second - i->second.first);
633 0 : break;
634 : case ORelationControl::INSERT:
635 0 : m_pRC_Tables->RowInserted(i->second.first, i->second.second - i->second.first);
636 0 : break;
637 : case ORelationControl::MODIFY:
638 0 : for(OConnectionLineDataVec::size_type j = i->second.first; j < i->second.second; ++j)
639 0 : m_pRC_Tables->RowModified(j);
640 0 : break;
641 : }
642 : }
643 0 : m_pRC_Tables->ActivateCell();
644 0 : m_pRC_Tables->m_ops.clear();
645 0 : }
646 :
647 0 : void fillEntryAndDisable(ListBox& _rListBox,const OUString& _sEntry)
648 : {
649 0 : _rListBox.InsertEntry(_sEntry);
650 0 : _rListBox.SelectEntryPos(0);
651 0 : _rListBox.Disable();
652 0 : }
653 :
654 0 : void OTableListBoxControl::fillAndDisable(const TTableConnectionData::value_type& _pConnectionData)
655 : {
656 0 : fillEntryAndDisable(*m_pLeftTable, _pConnectionData->getReferencingTable()->GetWinName());
657 0 : fillEntryAndDisable(*m_pRightTable, _pConnectionData->getReferencedTable()->GetWinName());
658 0 : }
659 :
660 0 : void OTableListBoxControl::Init(const TTableConnectionData::value_type& _pConnData)
661 : {
662 0 : m_pRC_Tables->Init(_pConnData);
663 0 : }
664 :
665 0 : void OTableListBoxControl::lateUIInit()
666 : {
667 0 : m_pRC_Tables->Show();
668 0 : lateInit();
669 0 : }
670 :
671 0 : void OTableListBoxControl::lateInit()
672 : {
673 0 : m_pRC_Tables->lateInit();
674 0 : }
675 :
676 0 : void OTableListBoxControl::Disable()
677 : {
678 0 : m_pLeftTable->Disable();
679 0 : m_pRightTable->Disable();
680 0 : m_pRC_Tables->Disable();
681 0 : }
682 :
683 0 : void OTableListBoxControl::Invalidate()
684 : {
685 0 : m_pLeftTable->Invalidate();
686 0 : m_pRightTable->Invalidate();
687 0 : m_pRC_Tables->Invalidate();
688 0 : }
689 :
690 0 : bool OTableListBoxControl::SaveModified()
691 : {
692 0 : return m_pRC_Tables->SaveModified();
693 : }
694 :
695 0 : TTableWindowData::value_type OTableListBoxControl::getReferencingTable() const
696 : {
697 0 : return m_pRC_Tables->getData()->getReferencingTable();
698 : }
699 :
700 0 : void OTableListBoxControl::enableRelation(bool _bEnable)
701 : {
702 0 : if ( !_bEnable )
703 0 : m_pRC_Tables->PostUserEvent(LINK(m_pRC_Tables, ORelationControl, AsynchDeactivate));
704 0 : m_pRC_Tables->Enable(_bEnable);
705 :
706 0 : }
707 72 : }
708 :
709 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|