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