xref: /AOO41X/main/dbaccess/source/ui/control/RelationControl.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 #ifndef DBAUI_RELATIONCONTROL_HXX
27 #include "RelationControl.hxx"
28 #endif
29 #ifndef DBACCESS_SOURCE_UI_INC_RELATIONCONTROL_HRC
30 #include "RelationControl.hrc"
31 #endif
32 
33 #ifndef _SVTOOLS_EDITBROWSEBOX_HXX_
34 #include <svtools/editbrowsebox.hxx>
35 #endif
36 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #endif
39 #ifndef _TOOLS_DEBUG_HXX
40 #include <tools/debug.hxx>
41 #endif
42 #ifndef TOOLS_DIAGNOSE_EX_H
43 #include <tools/diagnose_ex.h>
44 #endif
45 #ifndef DBAUI_TABLECONNECTIONDATA_HXX
46 #include "TableConnectionData.hxx"
47 #endif
48 #ifndef DBAUI_TABLECONNECTION_HXX
49 #include "TableConnection.hxx"
50 #endif
51 #ifndef DBAUI_TABLEWINDOW_HXX
52 #include "TableWindow.hxx"
53 #endif
54 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
55 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
56 #endif
57 #ifndef DBAUI_TOOLS_HXX
58 #include "UITools.hxx"
59 #endif
60 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
61 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
62 #endif
63 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
64 #include <com/sun/star/container/XNameAccess.hpp>
65 #endif
66 #ifndef DBAUI_RELCONTROLIFACE_HXX
67 #include "RelControliFace.hxx"
68 #endif
69 #ifndef _DBU_CONTROL_HRC_
70 #include "dbu_control.hrc"
71 #endif
72 #ifndef _DBA_DBACCESS_HELPID_HRC_
73 #include "dbaccess_helpid.hrc"
74 #endif
75 #ifndef _TOOLS_DEBUG_HXX
76 #include <tools/debug.hxx>
77 #endif
78 
79 #include <algorithm>
80 
81 #define SOURCE_COLUMN   1
82 #define DEST_COLUMN     2
83 
84 namespace dbaui
85 {
86     using namespace ::com::sun::star::uno;
87     using namespace ::com::sun::star::beans;
88     using namespace ::com::sun::star::sdbc;
89     using namespace ::com::sun::star::sdbcx;
90     using namespace ::com::sun::star::container;
91     using namespace svt;
92 
93     typedef ::svt::EditBrowseBox ORelationControl_Base;
94     class ORelationControl : public ORelationControl_Base
95     {
96         friend class OTableListBoxControl;
97 
98         ::std::auto_ptr< ::svt::ListBoxControl> m_pListCell;
99         TTableConnectionData::value_type        m_pConnData;
100         const OJoinTableView::OTableWindowMap*  m_pTableMap;
101         OTableListBoxControl*                   m_pBoxControl;
102         long                                    m_nDataPos;
103         Reference< XPropertySet>                m_xSourceDef;
104         Reference< XPropertySet>                m_xDestDef;
105 
106 
107         void fillListBox(const Reference< XPropertySet>& _xDest,long nRow,sal_uInt16 nColumnId);
108         /** returns the column id for the editbrowsebox
109             @param  _nColId
110                     the column id SOURCE_COLUMN or DEST_COLUMN
111 
112             @return the current column id eihter SOURCE_COLUMN or DEST_COLUMN depends on the connection data
113         */
114         sal_uInt16 getColumnIdent( sal_uInt16 _nColId ) const;
115     public:
116         ORelationControl( OTableListBoxControl* pParent,const OJoinTableView::OTableWindowMap* _pTableMap );
117         virtual ~ORelationControl();
118 
119         /** searches for a connection between these two tables
120             @param  _pSource
121                     the left table
122             @param  _pDest
123                     the right window
124         */
125         void setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest);
126 
127         /** allows to access the connection data from outside
128 
129             @return rthe connection data
130         */
getData() const131         inline TTableConnectionData::value_type getData() const { return m_pConnData; }
132 
133         void lateInit();
134 
135     protected:
136         virtual void Resize();
137 
138         virtual long PreNotify(NotifyEvent& rNEvt );
139 
140         virtual sal_Bool IsTabAllowed(sal_Bool bForward) const;
141 
142         virtual void Init(const TTableConnectionData::value_type& _pConnData);
Init()143         virtual void Init() { ORelationControl_Base::Init(); }
144         virtual void InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol );
145         virtual ::svt::CellController* GetController( long nRow, sal_uInt16 nCol );
146         virtual void PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColId ) const;
147         virtual sal_Bool SeekRow( long nRow );
148         virtual sal_Bool SaveModified();
149         virtual String GetCellText( long nRow, sal_uInt16 nColId ) const;
150 
151         virtual void CellModified();
152 
153         DECL_LINK( AsynchDeactivate, void* );
154     private:
155 
156         DECL_LINK( AsynchActivate, void* );
157 
158     };
159 
160     //========================================================================
161     // class ORelationControl
162     //========================================================================
DBG_NAME(ORelationControl)163     DBG_NAME(ORelationControl)
164     //------------------------------------------------------------------------
165     ORelationControl::ORelationControl( OTableListBoxControl* pParent ,const OJoinTableView::OTableWindowMap* _pTableMap)
166         :EditBrowseBox( pParent, EBBF_SMART_TAB_TRAVEL | EBBF_NOROWPICTURE, WB_TABSTOP | /*WB_3DLOOK | */WB_BORDER | BROWSER_AUTOSIZE_LASTCOL)
167         ,m_pTableMap(_pTableMap)
168         ,m_pBoxControl(pParent)
169         ,m_xSourceDef( NULL )
170         ,m_xDestDef( NULL )
171     {
172         DBG_CTOR(ORelationControl,NULL);
173     }
174 
175     //------------------------------------------------------------------------
~ORelationControl()176     ORelationControl::~ORelationControl()
177     {
178         DBG_DTOR(ORelationControl,NULL);
179     }
180 
181     //------------------------------------------------------------------------
Init(const TTableConnectionData::value_type & _pConnData)182     void ORelationControl::Init(const TTableConnectionData::value_type& _pConnData)
183     {
184         DBG_CHKTHIS(ORelationControl,NULL);
185 
186         m_pConnData = _pConnData;
187         OSL_ENSURE(m_pConnData, "No data supplied!");
188 
189         m_pConnData->normalizeLines();
190     }
191     //------------------------------------------------------------------------------
lateInit()192     void ORelationControl::lateInit()
193     {
194         if ( !m_pConnData.get() )
195             return;
196         m_xSourceDef = m_pConnData->getReferencingTable()->getTable();
197         m_xDestDef = m_pConnData->getReferencedTable()->getTable();
198 
199         if ( ColCount() == 0 )
200         {
201             InsertDataColumn( SOURCE_COLUMN, m_pConnData->getReferencingTable()->GetWinName(), 100);
202             InsertDataColumn( DEST_COLUMN, m_pConnData->getReferencedTable()->GetWinName(), 100);
203                 // wenn es die Defs noch nicht gibt, dann muessen sie noch mit SetSource-/-DestDef gesetzt werden !
204 
205             m_pListCell.reset( new ListBoxControl( &GetDataWindow() ) );
206 
207             //////////////////////////////////////////////////////////////////////
208             // set browse mode
209             SetMode(    BROWSER_COLUMNSELECTION |
210                         BROWSER_HLINESFULL      |
211                         BROWSER_VLINESFULL      |
212                         BROWSER_HIDECURSOR      |
213                         BROWSER_HIDESELECT      |
214                         BROWSER_AUTO_HSCROLL    |
215                         BROWSER_AUTO_VSCROLL);
216         }
217         else
218             // not the first call
219             RowRemoved(0, GetRowCount());
220 
221         RowInserted(0, m_pConnData->GetConnLineDataList()->size() + 1, sal_True); // add one extra row
222     }
223     //------------------------------------------------------------------------------
Resize()224     void ORelationControl::Resize()
225     {
226         DBG_CHKTHIS(ORelationControl,NULL);
227         EditBrowseBox::Resize();
228         long nOutputWidth = GetOutputSizePixel().Width();
229         SetColumnWidth(1, (nOutputWidth / 2));
230         SetColumnWidth(2, (nOutputWidth / 2));
231     }
232 
233     //------------------------------------------------------------------------------
PreNotify(NotifyEvent & rNEvt)234     long ORelationControl::PreNotify(NotifyEvent& rNEvt)
235     {
236         DBG_CHKTHIS(ORelationControl,NULL);
237         if (rNEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
238             PostUserEvent(LINK(this, ORelationControl, AsynchDeactivate));
239         else if (rNEvt.GetType() == EVENT_GETFOCUS)
240             PostUserEvent(LINK(this, ORelationControl, AsynchActivate));
241 
242         return EditBrowseBox::PreNotify(rNEvt);
243     }
244 
245     //------------------------------------------------------------------------------
IMPL_LINK(ORelationControl,AsynchActivate,void *,EMPTYARG)246     IMPL_LINK(ORelationControl, AsynchActivate, void*, EMPTYARG)
247     {
248         ActivateCell();
249         return 0L;
250     }
251 
252     //------------------------------------------------------------------------------
IMPL_LINK(ORelationControl,AsynchDeactivate,void *,EMPTYARG)253     IMPL_LINK(ORelationControl, AsynchDeactivate, void*, EMPTYARG)
254     {
255         DeactivateCell();
256         return 0L;
257     }
258 
259     //------------------------------------------------------------------------------
IsTabAllowed(sal_Bool bForward) const260     sal_Bool ORelationControl::IsTabAllowed(sal_Bool bForward) const
261     {
262         DBG_CHKTHIS(ORelationControl,NULL);
263         long nRow = GetCurRow();
264         sal_uInt16 nCol = GetCurColumnId();
265 
266         sal_Bool bRet = !((     ( bForward && (nCol == DEST_COLUMN)     && (nRow == GetRowCount() - 1)))
267                         ||  (!bForward && (nCol == SOURCE_COLUMN)   && (nRow == 0)));
268 
269         return bRet && EditBrowseBox::IsTabAllowed(bForward);
270     }
271 
272     //------------------------------------------------------------------------------
SaveModified()273     sal_Bool ORelationControl::SaveModified()
274     {
275         DBG_CHKTHIS(ORelationControl,NULL);
276         sal_Int32 nRow = GetCurRow();
277         if ( nRow != BROWSER_ENDOFSELECTION )
278         {
279             String sFieldName(m_pListCell->GetSelectEntry());
280             OConnectionLineDataVec* pLines = m_pConnData->GetConnLineDataList();
281             if ( pLines->size() <= static_cast<sal_uInt32>(nRow) )
282             {
283                 pLines->push_back(new OConnectionLineData());
284                 nRow = pLines->size() - 1;
285             }
286 
287             OConnectionLineDataRef pConnLineData = (*pLines)[nRow];
288 
289             switch( getColumnIdent( GetCurColumnId() ) )
290             {
291             case SOURCE_COLUMN:
292                 pConnLineData->SetSourceFieldName( sFieldName );
293                 break;
294             case DEST_COLUMN:
295                 pConnLineData->SetDestFieldName( sFieldName );
296                 break;
297             }
298         }
299 
300         return sal_True;
301     }
302     //------------------------------------------------------------------------------
getColumnIdent(sal_uInt16 _nColId) const303     sal_uInt16 ORelationControl::getColumnIdent( sal_uInt16 _nColId ) const
304     {
305         sal_uInt16 nId = _nColId;
306         if ( m_pConnData->getReferencingTable() != m_pBoxControl->getReferencingTable() )
307             nId = ( _nColId == SOURCE_COLUMN) ? DEST_COLUMN : SOURCE_COLUMN;
308         return nId;
309     }
310 
311     //------------------------------------------------------------------------------
GetCellText(long nRow,sal_uInt16 nColId) const312     String ORelationControl::GetCellText( long nRow, sal_uInt16 nColId ) const
313     {
314         DBG_CHKTHIS(ORelationControl,NULL);
315         String sText;
316         if ( m_pConnData->GetConnLineDataList()->size() > static_cast<size_t>(nRow) )
317         {
318             OConnectionLineDataRef pConnLineData = (*m_pConnData->GetConnLineDataList())[nRow];
319             switch( getColumnIdent( nColId ) )
320             {
321             case SOURCE_COLUMN:
322                 sText  = pConnLineData->GetSourceFieldName();
323                 break;
324             case DEST_COLUMN:
325                 sText  = pConnLineData->GetDestFieldName();
326                 break;
327             }
328         }
329         return sText;
330     }
331 
332     //------------------------------------------------------------------------------
InitController(CellControllerRef &,long nRow,sal_uInt16 nColumnId)333     void ORelationControl::InitController( CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColumnId )
334     {
335         DBG_CHKTHIS(ORelationControl,NULL);
336 
337         rtl::OString sHelpId( HID_RELATIONDIALOG_LEFTFIELDCELL );
338 
339         Reference< XPropertySet> xDef;
340         switch ( getColumnIdent(nColumnId) )
341         {
342             case SOURCE_COLUMN:
343                 xDef    = m_xSourceDef;
344                 sHelpId = HID_RELATIONDIALOG_LEFTFIELDCELL;
345                 break;
346             case DEST_COLUMN:
347                 xDef    = m_xDestDef;
348                 sHelpId = HID_RELATIONDIALOG_RIGHTFIELDCELL;
349                 break;
350             default:
351                 //  ?????????
352                 break;
353         }
354 
355         if ( xDef.is() )
356         {
357             fillListBox(xDef,nRow,nColumnId);
358             String sName = GetCellText( nRow, nColumnId );
359             m_pListCell->SelectEntry( sName );
360             if ( m_pListCell->GetSelectEntry() != sName )
361             {
362                 m_pListCell->InsertEntry( sName );
363                 m_pListCell->SelectEntry( sName );
364             }
365 
366             m_pListCell->SetHelpId(sHelpId);
367         }
368     }
369 
370     //------------------------------------------------------------------------------
GetController(long,sal_uInt16)371     CellController* ORelationControl::GetController( long /*nRow*/, sal_uInt16 /*nColumnId*/ )
372     {
373         DBG_CHKTHIS(ORelationControl,NULL);
374         return new ListBoxCellController( m_pListCell.get() );
375     }
376 
377     //------------------------------------------------------------------------------
SeekRow(long nRow)378     sal_Bool ORelationControl::SeekRow( long nRow )
379     {
380         DBG_CHKTHIS(ORelationControl,NULL);
381         m_nDataPos = nRow;
382         return sal_True;
383     }
384 
385     //------------------------------------------------------------------------------
PaintCell(OutputDevice & rDev,const Rectangle & rRect,sal_uInt16 nColumnId) const386     void ORelationControl::PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const
387     {
388         DBG_CHKTHIS(ORelationControl,NULL);
389         String aText  =const_cast< ORelationControl*>(this)->GetCellText( m_nDataPos, nColumnId );
390 
391         Point aPos( rRect.TopLeft() );
392         Size aTextSize( GetDataWindow().GetTextHeight(),GetDataWindow().GetTextWidth( aText ));
393 
394         if( aPos.X() < rRect.Right() || aPos.X() + aTextSize.Width() > rRect.Right() ||
395             aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() )
396             rDev.SetClipRegion( rRect );
397 
398         rDev.DrawText( aPos, aText );
399 
400         if( rDev.IsClipRegion() )
401             rDev.SetClipRegion();
402     }
403     // -----------------------------------------------------------------------------
fillListBox(const Reference<XPropertySet> & _xDest,long,sal_uInt16)404     void ORelationControl::fillListBox(const Reference< XPropertySet>& _xDest,long /*_nRow*/,sal_uInt16 /*nColumnId*/)
405     {
406         m_pListCell->Clear();
407         try
408         {
409             if ( _xDest.is() )
410             {
411                 //sal_Int32 nRows = GetRowCount();
412                 Reference<XColumnsSupplier> xSup(_xDest,UNO_QUERY);
413                 Reference<XNameAccess> xColumns = xSup->getColumns();
414                 Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
415                 const ::rtl::OUString* pIter = aNames.getConstArray();
416                 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
417                 for(;pIter != pEnd;++pIter)
418                 {
419                     m_pListCell->InsertEntry( *pIter );
420                 }
421                 m_pListCell->InsertEntry(String(), 0);
422             }
423         }
424         catch( const Exception& )
425         {
426             DBG_UNHANDLED_EXCEPTION();
427         }
428     }
429     // -----------------------------------------------------------------------------
setWindowTables(const OTableWindow * _pSource,const OTableWindow * _pDest)430     void ORelationControl::setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest)
431     {
432         // wenn ich hier gerade editiere, ausblenden
433         sal_Bool bWasEditing = IsEditing();
434         if ( bWasEditing )
435             DeactivateCell();
436 
437         if ( _pSource && _pDest )
438         {
439             m_xSourceDef = _pSource->GetTable();
440             SetColumnTitle(1, _pSource->GetName());
441 
442 
443             m_xDestDef = _pDest->GetTable();
444             SetColumnTitle(2, _pDest->GetName());
445 
446             const OJoinTableView* pView = _pSource->getTableView();
447             OTableConnection* pConn = pView->GetTabConn(_pSource,_pDest);
448             if ( pConn && !m_pConnData->GetConnLineDataList()->empty() )
449             {
450                 m_pConnData->CopyFrom(*pConn->GetData());
451                 m_pBoxControl->getContainer()->notifyConnectionChange();
452             }
453             else
454             {
455                 // no connection found so we clear our data
456                 OConnectionLineDataVec* pLines = m_pConnData->GetConnLineDataList();
457                 ::std::for_each(pLines->begin(),
458                                 pLines->end(),
459                                 OUnaryRefFunctor<OConnectionLineData>( ::std::mem_fun(&OConnectionLineData::Reset))
460                                 );
461 
462                 m_pConnData->setReferencingTable(_pSource->GetData());
463                 m_pConnData->setReferencedTable(_pDest->GetData());
464             }
465             m_pConnData->normalizeLines();
466 
467         }
468         // neu zeichnen
469         Invalidate();
470 
471         if ( bWasEditing )
472         {
473             GoToRow(0);
474             ActivateCell();
475         }
476     }
477     //------------------------------------------------------------------------
CellModified()478     void ORelationControl::CellModified()
479     {
480         DBG_CHKTHIS(ORelationControl,NULL);
481         EditBrowseBox::CellModified();
482         SaveModified();
483         static_cast<OTableListBoxControl*>(GetParent())->NotifyCellChange();
484     }
485     //========================================================================
486     // class OTableListBoxControl
DBG_NAME(OTableListBoxControl)487 DBG_NAME(OTableListBoxControl)
488 
489 //========================================================================
490 
491 OTableListBoxControl::OTableListBoxControl(  Window* _pParent
492                                             ,const ResId& _rResId
493                                             ,const OJoinTableView::OTableWindowMap* _pTableMap
494                                             ,IRelationControlInterface* _pParentDialog)
495      : Window(_pParent,_rResId)
496      , m_aFL_InvolvedTables(    this, ResId(FL_INVOLVED_TABLES,*_rResId.GetResMgr()))
497      , m_lmbLeftTable(          this, ResId(LB_LEFT_TABLE,*_rResId.GetResMgr()))
498      , m_lmbRightTable(         this, ResId(LB_RIGHT_TABLE,*_rResId.GetResMgr()))
499      , m_aFL_InvolvedFields(    this, ResId(FL_INVOLVED_FIELDS,*_rResId.GetResMgr()))
500      , m_pTableMap(_pTableMap)
501      , m_pParentDialog(_pParentDialog)
502     {
503         m_pRC_Tables = new ORelationControl( this,m_pTableMap );
504         m_pRC_Tables->SetHelpId(HID_RELDLG_KEYFIELDS);
505         m_pRC_Tables->Init( );
506         m_pRC_Tables->SetZOrder(&m_lmbRightTable, WINDOW_ZORDER_BEHIND);
507 
508         lateUIInit();
509 
510         Link aLink(LINK(this, OTableListBoxControl, OnTableChanged));
511         m_lmbLeftTable.SetSelectHdl(aLink);
512         m_lmbRightTable.SetSelectHdl(aLink);
513 
514         FreeResource();
515         DBG_CTOR(OTableListBoxControl,NULL);
516     }
517     // -----------------------------------------------------------------------------
~OTableListBoxControl()518     OTableListBoxControl::~OTableListBoxControl()
519     {
520         ORelationControl* pTemp = m_pRC_Tables;
521         m_pRC_Tables = NULL;
522         delete pTemp;
523         DBG_DTOR(OTableListBoxControl,NULL);
524     }
525     // -----------------------------------------------------------------------------
fillListBoxes()526     void OTableListBoxControl::fillListBoxes()
527     {
528         DBG_ASSERT( !m_pTableMap->empty(), "OTableListBoxControl::fillListBoxes: no table window!");
529         OTableWindow* pInitialLeft = NULL;
530         OTableWindow* pInitialRight = NULL;
531 
532         // die Namen aller TabWins einsammeln
533         OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
534         OJoinTableView::OTableWindowMap::const_iterator aEnd = m_pTableMap->end();
535         for(;aIter != aEnd;++aIter)
536         {
537             m_lmbLeftTable.InsertEntry(aIter->first);
538             m_lmbRightTable.InsertEntry(aIter->first);
539 
540             if (!pInitialLeft)
541             {
542                 pInitialLeft = aIter->second;
543                 m_strCurrentLeft = aIter->first;
544             }
545             else if (!pInitialRight)
546             {
547                 pInitialRight = aIter->second;
548                 m_strCurrentRight = aIter->first;
549             }
550         } // for(;aIter != m_pTableMap->end();++aIter)
551 
552         if ( !pInitialRight )
553         {
554             pInitialRight = pInitialLeft;
555             m_strCurrentRight = m_strCurrentLeft;
556         }
557 
558         // die entsprechenden Defs an mein Controls
559         m_pRC_Tables->setWindowTables(pInitialLeft,pInitialRight);
560 
561         // die in einer ComboBox ausgewaehlte Tabelle darf nicht in der anderen zur Verfuegung stehen
562 
563         if ( m_pTableMap->size() > 2 )
564         {
565             m_lmbLeftTable.RemoveEntry(m_strCurrentRight);
566             m_lmbRightTable.RemoveEntry(m_strCurrentLeft);
567         }
568 
569         // links das erste, rechts das zweite selektieren
570         m_lmbLeftTable.SelectEntry(m_strCurrentLeft);
571         m_lmbRightTable.SelectEntry(m_strCurrentRight);
572 
573         m_lmbLeftTable.GrabFocus();
574     }
575     // -----------------------------------------------------------------------------
IMPL_LINK(OTableListBoxControl,OnTableChanged,ListBox *,pListBox)576     IMPL_LINK( OTableListBoxControl, OnTableChanged, ListBox*, pListBox )
577     {
578         String strSelected(pListBox->GetSelectEntry());
579         OTableWindow* pLeft     = NULL;
580         OTableWindow* pRight    = NULL;
581 
582         // eine Sonderbehandlung : wenn es nur zwei Tabellen gibt, muss ich bei Wechsel in einer LB auch in der anderen umschalten
583         if ( m_pTableMap->size() == 2 )
584         {
585             ListBox* pOther;
586             if ( pListBox == &m_lmbLeftTable )
587                 pOther = &m_lmbRightTable;
588             else
589                 pOther = &m_lmbLeftTable;
590             pOther->SelectEntryPos(1 - pOther->GetSelectEntryPos());
591 
592             OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
593             OTableWindow* pFirst = aIter->second;
594             ++aIter;
595             OTableWindow* pSecond = aIter->second;
596 
597             if ( m_lmbLeftTable.GetSelectEntry() == String(pFirst->GetName()) )
598             {
599                 pLeft   = pFirst;
600                 pRight  = pSecond;
601             }
602             else
603             {
604                 pLeft   = pSecond;
605                 pRight  = pFirst;
606             }
607         }
608         else
609         {
610             // zuerst brauche ich die TableDef zur Tabelle, dazu das TabWin
611             OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(strSelected);
612             OTableWindow* pLoop = NULL;
613             if( aFind != m_pTableMap->end() )
614                 pLoop = aFind->second;
615             DBG_ASSERT(pLoop != NULL, "ORelationDialog::OnTableChanged : ungueltiger Eintrag in ListBox !");
616                 // da ich die ListBoxen selber mit eben diesen Tabellennamen, mit denen ich sie jetzt vergleiche, gefuellt habe,
617                 // MUSS ich strSelected finden
618             if (pListBox == &m_lmbLeftTable)
619             {
620                 // den vorher links selektierten Eintrag wieder rein rechts
621                 m_lmbRightTable.InsertEntry(m_strCurrentLeft);
622                 // und den jetzt selektierten raus
623                 m_lmbRightTable.RemoveEntry(strSelected);
624                 m_strCurrentLeft    = strSelected;
625 
626                 pLeft = pLoop;
627 
628                 OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_lmbRightTable.GetSelectEntry());
629                 OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
630                 if ( aIter != m_pTableMap->end() )
631                     pRight = aIter->second;
632 
633                 m_lmbLeftTable.GrabFocus();
634             }
635             else
636             {
637                 // den vorher rechts selektierten Eintrag wieder rein links
638                 m_lmbLeftTable.InsertEntry(m_strCurrentRight);
639                 // und den jetzt selektierten raus
640                 m_lmbLeftTable.RemoveEntry(strSelected);
641                 m_strCurrentRight = strSelected;
642 
643                 pRight = pLoop;
644                 OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_lmbLeftTable.GetSelectEntry());
645                 OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
646                 if ( aIter != m_pTableMap->end() )
647                     pLeft = aIter->second;
648             }
649         }
650 
651         pListBox->GrabFocus();
652 
653         m_pRC_Tables->setWindowTables(pLeft,pRight);
654 
655         NotifyCellChange();
656         return 0;
657     }
658     // -----------------------------------------------------------------------------
NotifyCellChange()659     void OTableListBoxControl::NotifyCellChange()
660     {
661         // den Ok-Button en- oder disablen, je nachdem, ob ich eine gueltige Situation habe
662         TTableConnectionData::value_type pConnData = m_pRC_Tables->getData();
663         const OConnectionLineDataVec* pLines = pConnData->GetConnLineDataList();
664         m_pParentDialog->setValid(!pLines->empty());
665 
666         if ( pLines->size() >= static_cast<sal_uInt32>(m_pRC_Tables->GetRowCount()) )
667         {
668             m_pRC_Tables->DeactivateCell();
669             m_pRC_Tables->RowInserted(m_pRC_Tables->GetRowCount(), pLines->size() - static_cast<sal_uInt32>(m_pRC_Tables->GetRowCount()) + 1, sal_True);
670             m_pRC_Tables->ActivateCell();
671         }
672     }
673     // -----------------------------------------------------------------------------
fillEntryAndDisable(ListBox & _rListBox,const String & _sEntry)674     void fillEntryAndDisable(ListBox& _rListBox,const String& _sEntry)
675     {
676         _rListBox.InsertEntry(_sEntry);
677         _rListBox.SelectEntryPos(0);
678         _rListBox.Disable();
679     }
680     // -----------------------------------------------------------------------------
fillAndDisable(const TTableConnectionData::value_type & _pConnectionData)681     void OTableListBoxControl::fillAndDisable(const TTableConnectionData::value_type& _pConnectionData)
682     {
683         fillEntryAndDisable(m_lmbLeftTable,_pConnectionData->getReferencingTable()->GetWinName());
684         fillEntryAndDisable(m_lmbRightTable,_pConnectionData->getReferencedTable()->GetWinName());
685     }
686     // -----------------------------------------------------------------------------
Init(const TTableConnectionData::value_type & _pConnData)687     void OTableListBoxControl::Init(const TTableConnectionData::value_type& _pConnData)
688     {
689         m_pRC_Tables->Init(_pConnData);
690     }
691     // -----------------------------------------------------------------------------
lateUIInit(Window * _pTableSeparator)692     void OTableListBoxControl::lateUIInit(Window* _pTableSeparator)
693     {
694         const sal_Int32 nDiff = LogicToPixel( Point(0,6), MAP_APPFONT ).Y();
695         Point aDlgPoint = LogicToPixel( Point(12,43), MAP_APPFONT );
696         if ( _pTableSeparator )
697         {
698             _pTableSeparator->SetZOrder(&m_lmbRightTable, WINDOW_ZORDER_BEHIND);
699             m_pRC_Tables->SetZOrder(_pTableSeparator, WINDOW_ZORDER_BEHIND);
700             //aDlgPoint = m_pTableSeparator->GetPosPixel() + Point(0,aSize.Height()) + LogicToPixel( Point(0,6), MAP_APPFONT );
701             _pTableSeparator->SetPosPixel(Point(0,m_aFL_InvolvedFields.GetPosPixel().Y()));
702             const Size aSize = _pTableSeparator->GetSizePixel();
703             aDlgPoint.Y() = _pTableSeparator->GetPosPixel().Y() + aSize.Height();
704             m_aFL_InvolvedFields.SetPosPixel(Point(m_aFL_InvolvedFields.GetPosPixel().X(),aDlgPoint.Y()));
705             aDlgPoint.Y() += nDiff + m_aFL_InvolvedFields.GetSizePixel().Height();
706         }
707         //////////////////////////////////////////////////////////////////////
708         // positing BrowseBox control
709         const Size aCurrentSize = GetSizePixel();
710         Size aDlgSize = LogicToPixel( Size(24,0), MAP_APPFONT );
711         aDlgSize.Width() = aCurrentSize.Width() - aDlgSize.Width();
712         aDlgSize.Height() = aCurrentSize.Height() - aDlgPoint.Y() - nDiff;
713 
714         m_pRC_Tables->SetPosSizePixel( aDlgPoint, aDlgSize );
715         m_pRC_Tables->Show();
716 
717         lateInit();
718     }
719     // -----------------------------------------------------------------------------
lateInit()720     void OTableListBoxControl::lateInit()
721     {
722         m_pRC_Tables->lateInit();
723     }
724     // -----------------------------------------------------------------------------
SaveModified()725     sal_Bool OTableListBoxControl::SaveModified()
726     {
727         sal_Bool bRet = m_pRC_Tables->SaveModified();
728         m_pRC_Tables->getData()->normalizeLines();
729         return bRet;
730     }
731     // -----------------------------------------------------------------------------
getReferencingTable() const732     TTableWindowData::value_type OTableListBoxControl::getReferencingTable()    const
733     {
734         return m_pRC_Tables->getData()->getReferencingTable();
735     }
736     // -----------------------------------------------------------------------------
enableRelation(bool _bEnable)737     void OTableListBoxControl::enableRelation(bool _bEnable)
738     {
739         if ( !_bEnable )
740             PostUserEvent(LINK(m_pRC_Tables, ORelationControl, AsynchDeactivate));
741         m_pRC_Tables->Enable(_bEnable);
742 
743     }
744     // -----------------------------------------------------------------------------
745 }
746 // -----------------------------------------------------------------------------
747 
748