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 : 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 : {
374 0 : rDev.SetClipRegion(Region(rRect));
375 : }
376 :
377 0 : rDev.DrawText( aPos, aText );
378 :
379 0 : if( rDev.IsClipRegion() )
380 0 : rDev.SetClipRegion();
381 0 : }
382 : // -----------------------------------------------------------------------------
383 0 : void ORelationControl::fillListBox(const Reference< XPropertySet>& _xDest,long /*_nRow*/,sal_uInt16 /*nColumnId*/)
384 : {
385 0 : m_pListCell->Clear();
386 : try
387 : {
388 0 : if ( _xDest.is() )
389 : {
390 : //sal_Int32 nRows = GetRowCount();
391 0 : Reference<XColumnsSupplier> xSup(_xDest,UNO_QUERY);
392 0 : Reference<XNameAccess> xColumns = xSup->getColumns();
393 0 : Sequence< OUString> aNames = xColumns->getElementNames();
394 0 : const OUString* pIter = aNames.getConstArray();
395 0 : const OUString* pEnd = pIter + aNames.getLength();
396 0 : for(;pIter != pEnd;++pIter)
397 : {
398 0 : m_pListCell->InsertEntry( *pIter );
399 : }
400 0 : m_pListCell->InsertEntry(String(), 0);
401 : }
402 : }
403 0 : catch( const Exception& )
404 : {
405 : DBG_UNHANDLED_EXCEPTION();
406 : }
407 0 : }
408 : // -----------------------------------------------------------------------------
409 0 : void ORelationControl::setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest)
410 : {
411 : // If I edit here, hide
412 0 : sal_Bool bWasEditing = IsEditing();
413 0 : if ( bWasEditing )
414 0 : DeactivateCell();
415 :
416 0 : if ( _pSource && _pDest )
417 : {
418 0 : m_xSourceDef = _pSource->GetTable();
419 0 : SetColumnTitle(1, _pSource->GetName());
420 :
421 :
422 0 : m_xDestDef = _pDest->GetTable();
423 0 : SetColumnTitle(2, _pDest->GetName());
424 :
425 0 : const OJoinTableView* pView = _pSource->getTableView();
426 0 : OTableConnection* pConn = pView->GetTabConn(_pSource,_pDest);
427 0 : if ( pConn && !m_pConnData->GetConnLineDataList()->empty() )
428 : {
429 0 : m_pConnData->CopyFrom(*pConn->GetData());
430 0 : m_pBoxControl->getContainer()->notifyConnectionChange();
431 : }
432 : else
433 : {
434 : // no connection found so we clear our data
435 0 : OConnectionLineDataVec* pLines = m_pConnData->GetConnLineDataList();
436 : ::std::for_each(pLines->begin(),
437 : pLines->end(),
438 0 : OUnaryRefFunctor<OConnectionLineData>( ::std::mem_fun(&OConnectionLineData::Reset))
439 0 : );
440 :
441 0 : m_pConnData->setReferencingTable(_pSource->GetData());
442 0 : m_pConnData->setReferencedTable(_pDest->GetData());
443 : }
444 0 : m_pConnData->normalizeLines();
445 :
446 : }
447 : // Repaint
448 0 : Invalidate();
449 :
450 0 : if ( bWasEditing )
451 : {
452 0 : GoToRow(0);
453 0 : ActivateCell();
454 : }
455 0 : }
456 : //------------------------------------------------------------------------
457 0 : void ORelationControl::CellModified()
458 : {
459 : DBG_CHKTHIS(ORelationControl,NULL);
460 0 : EditBrowseBox::CellModified();
461 0 : SaveModified();
462 : #if OSL_DEBUG_LEVEL > 0
463 : OTableListBoxControl *parent = dynamic_cast<OTableListBoxControl*>(GetParent());
464 : #else
465 0 : OTableListBoxControl *parent = static_cast<OTableListBoxControl*>(GetParent());
466 : #endif
467 : assert(parent);
468 0 : parent->NotifyCellChange();
469 0 : }
470 : //========================================================================
471 : // class OTableListBoxControl
472 : DBG_NAME(OTableListBoxControl)
473 :
474 : //========================================================================
475 :
476 0 : OTableListBoxControl::OTableListBoxControl( Window* _pParent
477 : ,const ResId& _rResId
478 : ,const OJoinTableView::OTableWindowMap* _pTableMap
479 : ,IRelationControlInterface* _pParentDialog)
480 : : Window(_pParent,_rResId)
481 0 : , m_aFL_InvolvedTables( this, ResId(FL_INVOLVED_TABLES,*_rResId.GetResMgr()))
482 0 : , m_lmbLeftTable( this, ResId(LB_LEFT_TABLE,*_rResId.GetResMgr()))
483 0 : , m_lmbRightTable( this, ResId(LB_RIGHT_TABLE,*_rResId.GetResMgr()))
484 0 : , m_aFL_InvolvedFields( this, ResId(FL_INVOLVED_FIELDS,*_rResId.GetResMgr()))
485 : , m_pTableMap(_pTableMap)
486 0 : , m_pParentDialog(_pParentDialog)
487 : {
488 0 : m_pRC_Tables = new ORelationControl( this );
489 0 : m_pRC_Tables->SetHelpId(HID_RELDLG_KEYFIELDS);
490 0 : m_pRC_Tables->Init( );
491 0 : m_pRC_Tables->SetZOrder(&m_lmbRightTable, WINDOW_ZORDER_BEHIND);
492 :
493 0 : lateUIInit();
494 :
495 0 : Link aLink(LINK(this, OTableListBoxControl, OnTableChanged));
496 0 : m_lmbLeftTable.SetSelectHdl(aLink);
497 0 : m_lmbRightTable.SetSelectHdl(aLink);
498 :
499 0 : FreeResource();
500 : DBG_CTOR(OTableListBoxControl,NULL);
501 0 : }
502 : // -----------------------------------------------------------------------------
503 0 : OTableListBoxControl::~OTableListBoxControl()
504 : {
505 0 : ORelationControl* pTemp = m_pRC_Tables;
506 0 : m_pRC_Tables = NULL;
507 0 : delete pTemp;
508 : DBG_DTOR(OTableListBoxControl,NULL);
509 0 : }
510 : // -----------------------------------------------------------------------------
511 0 : void OTableListBoxControl::fillListBoxes()
512 : {
513 : OSL_ENSURE( !m_pTableMap->empty(), "OTableListBoxControl::fillListBoxes: no table window!");
514 0 : OTableWindow* pInitialLeft = NULL;
515 0 : OTableWindow* pInitialRight = NULL;
516 :
517 : // Collect the names of all TabWins
518 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
519 0 : OJoinTableView::OTableWindowMap::const_iterator aEnd = m_pTableMap->end();
520 0 : for(;aIter != aEnd;++aIter)
521 : {
522 0 : m_lmbLeftTable.InsertEntry(aIter->first);
523 0 : m_lmbRightTable.InsertEntry(aIter->first);
524 :
525 0 : if (!pInitialLeft)
526 : {
527 0 : pInitialLeft = aIter->second;
528 0 : m_strCurrentLeft = aIter->first;
529 : }
530 0 : else if (!pInitialRight)
531 : {
532 0 : pInitialRight = aIter->second;
533 0 : m_strCurrentRight = aIter->first;
534 : }
535 : }
536 :
537 0 : if ( !pInitialRight )
538 : {
539 0 : pInitialRight = pInitialLeft;
540 0 : m_strCurrentRight = m_strCurrentLeft;
541 : }
542 :
543 : // The corresponding Defs for my Controls
544 0 : m_pRC_Tables->setWindowTables(pInitialLeft,pInitialRight);
545 :
546 : // The table selected in a ComboBox must not be available in the other
547 :
548 0 : if ( m_pTableMap->size() > 2 )
549 : {
550 0 : m_lmbLeftTable.RemoveEntry(m_strCurrentRight);
551 0 : m_lmbRightTable.RemoveEntry(m_strCurrentLeft);
552 : }
553 :
554 : // Select the first one on the left side and on the right side,
555 : // select the second one
556 0 : m_lmbLeftTable.SelectEntry(m_strCurrentLeft);
557 0 : m_lmbRightTable.SelectEntry(m_strCurrentRight);
558 :
559 0 : m_lmbLeftTable.GrabFocus();
560 0 : }
561 : // -----------------------------------------------------------------------------
562 0 : IMPL_LINK( OTableListBoxControl, OnTableChanged, ListBox*, pListBox )
563 : {
564 0 : String strSelected(pListBox->GetSelectEntry());
565 0 : OTableWindow* pLeft = NULL;
566 0 : OTableWindow* pRight = NULL;
567 :
568 : // Special treatment: If there are only two tables, we need to switch the other one too when changing in a LB
569 0 : if ( m_pTableMap->size() == 2 )
570 : {
571 : ListBox* pOther;
572 0 : if ( pListBox == &m_lmbLeftTable )
573 0 : pOther = &m_lmbRightTable;
574 : else
575 0 : pOther = &m_lmbLeftTable;
576 0 : pOther->SelectEntryPos(1 - pOther->GetSelectEntryPos());
577 :
578 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
579 0 : OTableWindow* pFirst = aIter->second;
580 0 : ++aIter;
581 0 : OTableWindow* pSecond = aIter->second;
582 :
583 0 : if ( m_lmbLeftTable.GetSelectEntry() == String(pFirst->GetName()) )
584 : {
585 0 : pLeft = pFirst;
586 0 : pRight = pSecond;
587 : }
588 : else
589 : {
590 0 : pLeft = pSecond;
591 0 : pRight = pFirst;
592 : }
593 : }
594 : else
595 : {
596 : // First we need the TableDef to the Table and with it the TabWin
597 0 : OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(strSelected);
598 0 : OTableWindow* pLoop = NULL;
599 0 : if( aFind != m_pTableMap->end() )
600 0 : pLoop = aFind->second;
601 : OSL_ENSURE(pLoop != NULL, "ORelationDialog::OnTableChanged: invalid ListBox entry!");
602 : // We need to find strSelect, because we filled the ListBoxes with the table names with which we compare now
603 0 : if (pListBox == &m_lmbLeftTable)
604 : {
605 : // Insert the previously selected Entry on the left side on the right side
606 0 : m_lmbRightTable.InsertEntry(m_strCurrentLeft);
607 : // Remove the currently selected Entry
608 0 : m_lmbRightTable.RemoveEntry(strSelected);
609 0 : m_strCurrentLeft = strSelected;
610 :
611 0 : pLeft = pLoop;
612 :
613 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_lmbRightTable.GetSelectEntry());
614 : OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
615 0 : if ( aIter != m_pTableMap->end() )
616 0 : pRight = aIter->second;
617 :
618 0 : m_lmbLeftTable.GrabFocus();
619 : }
620 : else
621 : {
622 : // Insert the previously selected Entry on the right side on the left side
623 0 : m_lmbLeftTable.InsertEntry(m_strCurrentRight);
624 : // Remove the currently selected Entry
625 0 : m_lmbLeftTable.RemoveEntry(strSelected);
626 0 : m_strCurrentRight = strSelected;
627 :
628 0 : pRight = pLoop;
629 0 : OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_lmbLeftTable.GetSelectEntry());
630 : OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
631 0 : if ( aIter != m_pTableMap->end() )
632 0 : pLeft = aIter->second;
633 : }
634 : }
635 :
636 0 : pListBox->GrabFocus();
637 :
638 0 : m_pRC_Tables->setWindowTables(pLeft,pRight);
639 :
640 0 : NotifyCellChange();
641 0 : return 0;
642 : }
643 : // -----------------------------------------------------------------------------
644 0 : void OTableListBoxControl::NotifyCellChange()
645 : {
646 : // Enable/disable the OK button, depending on having a valid situation
647 0 : TTableConnectionData::value_type pConnData = m_pRC_Tables->getData();
648 0 : const OConnectionLineDataVec* pLines = pConnData->GetConnLineDataList();
649 0 : bool bValid = !pLines->empty();
650 0 : if (bValid)
651 : {
652 0 : OConnectionLineDataVec::const_iterator l(pLines->begin());
653 0 : const OConnectionLineDataVec::const_iterator le(pLines->end());
654 0 : for (; bValid && l!=le; ++l)
655 : {
656 0 : bValid = ! ((*l)->GetSourceFieldName().isEmpty() || (*l)->GetDestFieldName().isEmpty());
657 : }
658 : }
659 0 : m_pParentDialog->setValid(bValid);
660 :
661 0 : ORelationControl::ops_type::iterator i (m_pRC_Tables->m_ops.begin());
662 0 : const ORelationControl::ops_type::const_iterator e (m_pRC_Tables->m_ops.end());
663 0 : m_pRC_Tables->DeactivateCell();
664 0 : for(; i != e; ++i)
665 : {
666 0 : switch(i->first)
667 : {
668 : case ORelationControl::DELETE:
669 0 : m_pRC_Tables->RowRemoved(i->second.first, i->second.second - i->second.first);
670 0 : break;
671 : case ORelationControl::INSERT:
672 0 : m_pRC_Tables->RowInserted(i->second.first, i->second.second - i->second.first);
673 0 : break;
674 : case ORelationControl::MODIFY:
675 0 : for(OConnectionLineDataVec::size_type j = i->second.first; j < i->second.second; ++j)
676 0 : m_pRC_Tables->RowModified(j);
677 0 : break;
678 : }
679 : }
680 0 : m_pRC_Tables->ActivateCell();
681 0 : m_pRC_Tables->m_ops.clear();
682 0 : }
683 : // -----------------------------------------------------------------------------
684 0 : void fillEntryAndDisable(ListBox& _rListBox,const String& _sEntry)
685 : {
686 0 : _rListBox.InsertEntry(_sEntry);
687 0 : _rListBox.SelectEntryPos(0);
688 0 : _rListBox.Disable();
689 0 : }
690 : // -----------------------------------------------------------------------------
691 0 : void OTableListBoxControl::fillAndDisable(const TTableConnectionData::value_type& _pConnectionData)
692 : {
693 0 : fillEntryAndDisable(m_lmbLeftTable,_pConnectionData->getReferencingTable()->GetWinName());
694 0 : fillEntryAndDisable(m_lmbRightTable,_pConnectionData->getReferencedTable()->GetWinName());
695 0 : }
696 : // -----------------------------------------------------------------------------
697 0 : void OTableListBoxControl::Init(const TTableConnectionData::value_type& _pConnData)
698 : {
699 0 : m_pRC_Tables->Init(_pConnData);
700 0 : }
701 : // -----------------------------------------------------------------------------
702 0 : void OTableListBoxControl::lateUIInit(Window* _pTableSeparator)
703 : {
704 0 : const sal_Int32 nDiff = LogicToPixel( Point(0,6), MAP_APPFONT ).Y();
705 0 : Point aDlgPoint = LogicToPixel( Point(12,43), MAP_APPFONT );
706 0 : if ( _pTableSeparator )
707 : {
708 0 : _pTableSeparator->SetZOrder(&m_lmbRightTable, WINDOW_ZORDER_BEHIND);
709 0 : m_pRC_Tables->SetZOrder(_pTableSeparator, WINDOW_ZORDER_BEHIND);
710 0 : _pTableSeparator->SetPosPixel(Point(0,m_aFL_InvolvedFields.GetPosPixel().Y()));
711 0 : const Size aSize = _pTableSeparator->GetSizePixel();
712 0 : aDlgPoint.Y() = _pTableSeparator->GetPosPixel().Y() + aSize.Height();
713 0 : m_aFL_InvolvedFields.SetPosPixel(Point(m_aFL_InvolvedFields.GetPosPixel().X(),aDlgPoint.Y()));
714 0 : aDlgPoint.Y() += nDiff + m_aFL_InvolvedFields.GetSizePixel().Height();
715 : }
716 : //////////////////////////////////////////////////////////////////////
717 : // positing BrowseBox control
718 0 : const Size aCurrentSize = GetSizePixel();
719 0 : Size aDlgSize = LogicToPixel( Size(24,0), MAP_APPFONT );
720 0 : aDlgSize.Width() = aCurrentSize.Width() - aDlgSize.Width();
721 0 : aDlgSize.Height() = aCurrentSize.Height() - aDlgPoint.Y() - nDiff;
722 :
723 0 : m_pRC_Tables->SetPosSizePixel( aDlgPoint, aDlgSize );
724 0 : m_pRC_Tables->Show();
725 :
726 0 : lateInit();
727 0 : }
728 : // -----------------------------------------------------------------------------
729 0 : void OTableListBoxControl::lateInit()
730 : {
731 0 : m_pRC_Tables->lateInit();
732 0 : }
733 : // -----------------------------------------------------------------------------
734 0 : sal_Bool OTableListBoxControl::SaveModified()
735 : {
736 0 : return m_pRC_Tables->SaveModified();
737 : }
738 : // -----------------------------------------------------------------------------
739 0 : TTableWindowData::value_type OTableListBoxControl::getReferencingTable() const
740 : {
741 0 : return m_pRC_Tables->getData()->getReferencingTable();
742 : }
743 : // -----------------------------------------------------------------------------
744 0 : void OTableListBoxControl::enableRelation(bool _bEnable)
745 : {
746 0 : if ( !_bEnable )
747 0 : PostUserEvent(LINK(m_pRC_Tables, ORelationControl, AsynchDeactivate));
748 0 : m_pRC_Tables->Enable(_bEnable);
749 :
750 0 : }
751 : // -----------------------------------------------------------------------------
752 12 : }
753 : // -----------------------------------------------------------------------------
754 :
755 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|