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_dbui.hxx"
26 #ifndef DBAUI_QUERYDLG_HXX
27 #include "querydlg.hxx"
28 #endif
29 #ifndef _DBU_QRY_HRC_
30 #include "dbu_qry.hrc"
31 #endif
32 #ifndef DBAUI_QUERYDLG_HRC
33 #include "querydlg.hrc"
34 #endif
35 #ifndef _TOOLS_DEBUG_HXX
36 #include <tools/debug.hxx>
37 #endif
38 #ifndef TOOLS_DIAGNOSE_EX_H
39 #include <tools/diagnose_ex.h>
40 #endif
41 #ifndef DBAUI_QTABLECONNECTIONDATA_HXX
42 #include "QTableConnectionData.hxx"
43 #endif
44 #ifndef DBAUI_QUERYCONTROLLER_HXX
45 #include "querycontroller.hxx"
46 #endif
47 #ifndef DBAUI_QUERYTABLEVIEW_HXX
48 #include "QueryTableView.hxx"
49 #endif
50 #ifndef DBAUI_QUERYDESIGNVIEW_HXX
51 #include "QueryDesignView.hxx"
52 #endif
53 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
54 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
55 #endif
56 #ifndef DBAUI_RELATIONCONTROL_HXX
57 #include "RelationControl.hxx"
58 #endif
59 #ifndef _SV_MSGBOX_HXX
60 #include <vcl/msgbox.hxx>
61 #endif
62 
63 using namespace dbaui;
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::container;
66 using namespace ::com::sun::star::sdbc;
67 
68 namespace dbaui
69 {
70 class OJoinControl 	: public Window
71 {
72 public:
73     FixedLine				aFL_Join;
74 	FixedText				aFT_Title;
75 	ListBox					aLB_JoinType;
76     CheckBox                m_aCBNatural;
77 
78 	OJoinControl(Window* _pParent,const ResId& _rResId);
79 };
OJoinControl(Window * _pParent,const ResId & _rResId)80 OJoinControl::OJoinControl(Window* _pParent,const ResId& _rResId)
81     : Window(_pParent,_rResId)
82     ,aFL_Join( this, ResId( FL_JOIN,*_rResId.GetResMgr() ) )
83     ,aFT_Title( this, ResId(FT_LISTBOXTITLE,*_rResId.GetResMgr()) )
84     ,aLB_JoinType( this, ResId(LB_JOINTYPE,*_rResId.GetResMgr()) )
85     ,m_aCBNatural( this, ResId(CB_NATURAL,*_rResId.GetResMgr()) )
86 {
87     FreeResource();
88 }
89 // -----------------------------------------------------------------------------
90 } // dbaui
91 // -----------------------------------------------------------------------------
DBG_NAME(DlgQryJoin)92 DBG_NAME(DlgQryJoin)
93 DlgQryJoin::DlgQryJoin( OQueryTableView * pParent,
94 					   const TTableConnectionData::value_type& _pData,
95 					   OJoinTableView::OTableWindowMap*	_pTableMap,
96 					   const Reference< XConnection >& _xConnection,
97 					   sal_Bool _bAllowTableSelect)
98     :ModalDialog( pParent, ModuleRes(DLG_QRY_JOIN) )
99     ,aML_HelpText( this, ModuleRes(ML_HELPTEXT) )
100     ,aPB_OK( this, ModuleRes( PB_OK ) )
101     ,aPB_CANCEL( this, ModuleRes( PB_CANCEL ) )
102     ,aPB_HELP( this, ModuleRes( PB_HELP ) )
103     ,m_pJoinControl( NULL )
104     ,m_pTableControl( NULL )
105     ,m_pTableMap(_pTableMap)
106     ,m_pTableView(pParent)
107     ,eJoinType(static_cast<OQueryTableConnectionData*>(_pData.get())->GetJoinType())
108     ,m_pOrigConnData(_pData)
109     ,m_xConnection(_xConnection)
110 {
111 	DBG_CTOR(DlgQryJoin,NULL);
112 
113 	aML_HelpText.SetControlBackground( GetSettings().GetStyleSettings().GetFaceColor() );
114 	//////////////////////////////////////////////////////////////////////
115 	// Connection kopieren
116 	m_pConnData.reset(_pData->NewInstance());
117 	m_pConnData->CopyFrom(*_pData);
118 
119 	m_pTableControl = new OTableListBoxControl(this,ModuleRes(WND_CONTROL),m_pTableMap,this);
120 
121     m_pJoinControl = new OJoinControl(m_pTableControl,ModuleRes(WND_JOIN_CONTROL));
122 
123     m_pJoinControl->Show();
124     m_pJoinControl->m_aCBNatural.Check(static_cast<OQueryTableConnectionData*>(m_pConnData.get())->isNatural());
125     m_pTableControl->Show();
126 
127 	if( _bAllowTableSelect )
128 	{
129 		m_pTableControl->Init( m_pConnData );
130 		m_pTableControl->fillListBoxes();
131 	}
132 	else
133 	{
134 		m_pTableControl->fillAndDisable(m_pConnData);
135 		m_pTableControl->Init( m_pConnData );
136 	}
137 
138 	m_pTableControl->lateUIInit(m_pJoinControl);
139 
140     sal_Bool bSupportFullJoin = sal_False;
141 	Reference<XDatabaseMetaData> xMeta;
142 	try
143 	{
144 		xMeta = m_xConnection->getMetaData();
145 		if ( xMeta.is() )
146 			bSupportFullJoin = xMeta->supportsFullOuterJoins();
147 	}
148 	catch(SQLException&)
149 	{
150 	}
151     sal_Bool bSupportOuterJoin = sal_False;
152 	try
153 	{
154 		if ( xMeta.is() )
155 			bSupportOuterJoin= xMeta->supportsOuterJoins();
156 	}
157 	catch(SQLException&)
158 	{
159 	}
160 
161 	setJoinType(eJoinType);
162 
163 	aPB_OK.SetClickHdl( LINK(this, DlgQryJoin, OKClickHdl) );
164 
165 	m_pJoinControl->aLB_JoinType.SetSelectHdl(LINK(this,DlgQryJoin,LBChangeHdl));
166     m_pJoinControl->m_aCBNatural.SetToggleHdl(LINK(this,DlgQryJoin,NaturalToggleHdl));
167 
168 	if ( static_cast<OQueryTableView*>(pParent)->getDesignView()->getController().isReadOnly() )
169 	{
170 		m_pJoinControl->aLB_JoinType.Disable();
171         m_pJoinControl->m_aCBNatural.Disable();
172 		m_pTableControl->Disable();
173 	}
174 	else
175 	{
176         const sal_uInt16 nCount = m_pJoinControl->aLB_JoinType.GetEntryCount();
177         for (sal_uInt16 i = 0; i < nCount; ++i)
178         {
179             const long nJoinTyp = reinterpret_cast<long>(m_pJoinControl->aLB_JoinType.GetEntryData(i));
180             if ( !bSupportFullJoin && nJoinTyp == ID_FULL_JOIN )
181                 m_pJoinControl->aLB_JoinType.RemoveEntry(i);
182             else if ( !bSupportOuterJoin && (nJoinTyp == ID_LEFT_JOIN || nJoinTyp == ID_RIGHT_JOIN) )
183                 m_pJoinControl->aLB_JoinType.RemoveEntry(i);
184         }
185 
186 		m_pTableControl->NotifyCellChange();
187         m_pTableControl->enableRelation(!static_cast<OQueryTableConnectionData*>(m_pConnData.get())->isNatural() && eJoinType != CROSS_JOIN );
188 	}
189 
190 	FreeResource();
191 }
192 
193 //------------------------------------------------------------------------
~DlgQryJoin()194 DlgQryJoin::~DlgQryJoin()
195 {
196 	DBG_DTOR(DlgQryJoin,NULL);
197     delete m_pJoinControl;
198 	delete m_pTableControl;
199 }
200 // -----------------------------------------------------------------------------
201 IMPL_LINK( DlgQryJoin, LBChangeHdl, ListBox*, /*pListBox*/ )
202 {
203 	DBG_CHKTHIS(DlgQryJoin,NULL);
204     if (m_pJoinControl->aLB_JoinType.GetSelectEntryPos() == m_pJoinControl->aLB_JoinType.GetSavedValue() )
205         return 1;
206 
207     m_pJoinControl->aLB_JoinType.SaveValue();
208 	aML_HelpText.SetText(String());
209 
210     m_pTableControl->enableRelation(true);
211 
212     String sFirstWinName	= m_pConnData->getReferencingTable()->GetWinName();
213     String sSecondWinName	= m_pConnData->getReferencedTable()->GetWinName();
214     const EJoinType eOldJoinType = eJoinType;
215 	sal_uInt16 nResId = 0;
216 	const sal_uInt16 nPos = m_pJoinControl->aLB_JoinType.GetSelectEntryPos();
217     const long nJoinType = reinterpret_cast<long>(m_pJoinControl->aLB_JoinType.GetEntryData(nPos));
218     sal_Bool bAddHint = sal_True;
219 	switch ( nJoinType )
220 	{
221 		default:
222 		case ID_INNER_JOIN:
223 			nResId = STR_QUERY_INNER_JOIN;
224             bAddHint = sal_False;
225             eJoinType = INNER_JOIN;
226 			break;
227 		case ID_LEFT_JOIN:
228             nResId = STR_QUERY_LEFTRIGHT_JOIN;
229             eJoinType = LEFT_JOIN;
230             break;
231         case ID_RIGHT_JOIN:
232             {
233 			    nResId = STR_QUERY_LEFTRIGHT_JOIN;
234                 eJoinType = RIGHT_JOIN;
235                 String sTemp = sFirstWinName;
236                 sFirstWinName = sSecondWinName;
237                 sSecondWinName = sTemp;
238             }
239 			break;
240 		case ID_FULL_JOIN:
241 			nResId = STR_QUERY_FULL_JOIN;
242             eJoinType = FULL_JOIN;
243 			break;
244         case ID_CROSS_JOIN:
245             {
246                 nResId = STR_QUERY_CROSS_JOIN;
247                 eJoinType = CROSS_JOIN;
248 
249                 m_pConnData->ResetConnLines();
250                 m_pTableControl->lateInit();
251                 m_pJoinControl->m_aCBNatural.Check(sal_False);
252                 m_pTableControl->enableRelation(false);
253                 ::rtl::OUString sEmpty;
254                 m_pConnData->AppendConnLine(sEmpty,sEmpty);
255                 aPB_OK.Enable(sal_True);
256             }
257             break;
258 	}
259 
260     m_pJoinControl->m_aCBNatural.Enable(eJoinType != CROSS_JOIN);
261 
262     if ( eJoinType != eOldJoinType && eOldJoinType == CROSS_JOIN )
263     {
264         m_pConnData->ResetConnLines();
265     }
266     if ( eJoinType != CROSS_JOIN )
267     {
268         m_pTableControl->NotifyCellChange();
269         NaturalToggleHdl(&m_pJoinControl->m_aCBNatural);
270     }
271 
272     m_pTableControl->Invalidate();
273 
274 	String sHelpText = String( ModuleRes( nResId ) );
275 	if( nPos )
276 	{
277 		sHelpText.SearchAndReplace( String( RTL_CONSTASCII_STRINGPARAM( "%1" ) ), sFirstWinName );
278 		sHelpText.SearchAndReplace( String( RTL_CONSTASCII_STRINGPARAM( "%2" ) ), sSecondWinName );
279 	}
280     if ( bAddHint )
281     {
282         sHelpText += String( RTL_CONSTASCII_STRINGPARAM( "\n" ) );
283         sHelpText += String( ModuleRes( STR_JOIN_TYPE_HINT ) );
284     }
285 
286     aML_HelpText.SetText( sHelpText );
287 	return 1;
288 }
289 // -----------------------------------------------------------------------------
290 
291 IMPL_LINK( DlgQryJoin, OKClickHdl, Button*, /*pButton*/ )
292 {
293 	DBG_CHKTHIS(DlgQryJoin,NULL);
294 
295 	m_pConnData->Update();
296 	m_pOrigConnData->CopyFrom( *m_pConnData );
297 
298 	EndDialog(RET_OK);
299 	return 1;
300 }
301 // -----------------------------------------------------------------------------
302 
303 IMPL_LINK( DlgQryJoin, NaturalToggleHdl, CheckBox*, /*pButton*/ )
304 {
305 	DBG_CHKTHIS(DlgQryJoin,NULL);
306     sal_Bool bChecked = m_pJoinControl->m_aCBNatural.IsChecked();
307     static_cast<OQueryTableConnectionData*>(m_pConnData.get())->setNatural(bChecked);
308     m_pTableControl->enableRelation(!bChecked);
309     if ( bChecked )
310     {
311         m_pConnData->ResetConnLines();
312         try
313         {
314             Reference<XNameAccess> xReferencedTableColumns(m_pConnData->getReferencedTable()->getColumns());
315             Sequence< ::rtl::OUString> aSeq = m_pConnData->getReferencingTable()->getColumns()->getElementNames();
316             const ::rtl::OUString* pIter = aSeq.getConstArray();
317             const ::rtl::OUString* pEnd	  = pIter + aSeq.getLength();
318             for(;pIter != pEnd;++pIter)
319             {
320                 if ( xReferencedTableColumns->hasByName(*pIter) )
321                     m_pConnData->AppendConnLine(*pIter,*pIter);
322             }
323         }
324         catch( const Exception& )
325         {
326             DBG_UNHANDLED_EXCEPTION();
327         }
328         m_pTableControl->NotifyCellChange();
329         m_pTableControl->Invalidate();
330     }
331 
332 	return 1;
333 }
334 // -----------------------------------------------------------------------------
getConnectionData() const335 TTableConnectionData::value_type DlgQryJoin::getConnectionData() const
336 {
337 	return m_pConnData;
338 }
339 // -----------------------------------------------------------------------------
setValid(sal_Bool _bValid)340 void DlgQryJoin::setValid(sal_Bool _bValid)
341 {
342 	//LBChangeHdl(&aLB_JoinType);
343 
344 	aPB_OK.Enable(_bValid || eJoinType == CROSS_JOIN );
345 }
346 // -----------------------------------------------------------------------------
notifyConnectionChange()347 void DlgQryJoin::notifyConnectionChange( )
348 {
349 	setJoinType( static_cast<OQueryTableConnectionData*>(m_pConnData.get())->GetJoinType() );
350     m_pJoinControl->m_aCBNatural.Check(static_cast<OQueryTableConnectionData*>(m_pConnData.get())->isNatural());
351     NaturalToggleHdl(&m_pJoinControl->m_aCBNatural);
352 }
353 // -----------------------------------------------------------------------------
setJoinType(EJoinType _eNewJoinType)354 void DlgQryJoin::setJoinType(EJoinType _eNewJoinType)
355 {
356 	eJoinType = _eNewJoinType;
357     m_pJoinControl->m_aCBNatural.Enable(eJoinType != CROSS_JOIN);
358 
359     long nJoinType = 0;
360     switch ( eJoinType )
361 	{
362 		default:
363 		case INNER_JOIN:
364 			nJoinType = ID_INNER_JOIN;
365 			break;
366 		case LEFT_JOIN:
367             nJoinType = ID_LEFT_JOIN;
368 			break;
369         case RIGHT_JOIN:
370 			nJoinType = ID_RIGHT_JOIN;
371 			break;
372 		case FULL_JOIN:
373 			nJoinType = ID_FULL_JOIN;
374 			break;
375         case CROSS_JOIN:
376             nJoinType = ID_CROSS_JOIN;
377             break;
378 	}
379 
380     const sal_uInt16 nCount = m_pJoinControl->aLB_JoinType.GetEntryCount();
381     for (sal_uInt16 i = 0; i < nCount; ++i)
382     {
383         if ( nJoinType == reinterpret_cast<long>(m_pJoinControl->aLB_JoinType.GetEntryData(i)) )
384         {
385             m_pJoinControl->aLB_JoinType.SelectEntryPos(i);
386             break;
387         }
388     }
389 
390 	LBChangeHdl(&m_pJoinControl->aLB_JoinType);
391 }
392 // -----------------------------------------------------------------------------
393 
394 
395 
396