1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "querydlg.hxx"
21 #include <JoinController.hxx>
22 #include <JoinDesignView.hxx>
23 #include <strings.hrc>
24 #include <comphelper/diagnose_ex.hxx>
25 #include "QTableConnectionData.hxx"
26 #include <core_resource.hxx>
27 #include <QueryTableView.hxx>
28 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
29 #include <com/sun/star/sdbc/SQLException.hpp>
30 #include <RelationControl.hxx>
32 #define ID_INNER_JOIN 1
33 #define ID_LEFT_JOIN 2
34 #define ID_RIGHT_JOIN 3
35 #define ID_FULL_JOIN 4
36 #define ID_CROSS_JOIN 5
38 using namespace dbaui
;
39 using namespace ::com::sun::star::uno
;
40 using namespace ::com::sun::star::container
;
41 using namespace ::com::sun::star::sdbc
;
43 DlgQryJoin::DlgQryJoin(const OQueryTableView
* pParent
,
44 const TTableConnectionData::value_type
& _pData
,
45 const OJoinTableView::OTableWindowMap
* _pTableMap
,
46 const Reference
< XConnection
>& _xConnection
,
47 bool _bAllowTableSelect
)
48 : GenericDialogController(pParent
->GetFrameWeld(), u
"dbaccess/ui/joindialog.ui"_ustr
, u
"JoinDialog"_ustr
)
49 , eJoinType(static_cast<OQueryTableConnectionData
*>(_pData
.get())->GetJoinType())
50 , m_pOrigConnData(_pData
)
51 , m_xConnection(_xConnection
)
52 , m_xML_HelpText(m_xBuilder
->weld_label(u
"helptext"_ustr
))
53 , m_xPB_OK(m_xBuilder
->weld_button(u
"ok"_ustr
))
54 , m_xLB_JoinType(m_xBuilder
->weld_combo_box(u
"type"_ustr
))
55 , m_xCBNatural(m_xBuilder
->weld_check_button(u
"natural"_ustr
))
57 Size
aSize(m_xML_HelpText
->get_approximate_digit_width() * 44,
58 m_xML_HelpText
->get_text_height() * 6);
59 //alternatively loop through the STR_QUERY_* strings with their STR_JOIN_TYPE_HINT
60 //suffix to find the longest entry at runtime
61 m_xML_HelpText
->set_size_request(aSize
.Width(), aSize
.Height());
64 m_pConnData
= _pData
->NewInstance();
65 m_pConnData
->CopyFrom(*_pData
);
67 m_xTableControl
.reset(new OTableListBoxControl(m_xBuilder
.get(), _pTableMap
, this));
69 m_xCBNatural
->set_active(static_cast<OQueryTableConnectionData
*>(m_pConnData
.get())->isNatural());
71 if( _bAllowTableSelect
)
73 m_xTableControl
->Init( m_pConnData
);
74 m_xTableControl
->fillListBoxes();
78 m_xTableControl
->fillAndDisable(m_pConnData
);
79 m_xTableControl
->Init( m_pConnData
);
82 m_xTableControl
->lateUIInit();
84 bool bSupportFullJoin
= false;
85 Reference
<XDatabaseMetaData
> xMeta
;
88 xMeta
= m_xConnection
->getMetaData();
90 bSupportFullJoin
= xMeta
->supportsFullOuterJoins();
95 bool bSupportOuterJoin
= false;
99 bSupportOuterJoin
= xMeta
->supportsOuterJoins();
105 setJoinType(eJoinType
);
107 m_xPB_OK
->connect_clicked(LINK(this, DlgQryJoin
, OKClickHdl
));
109 m_xLB_JoinType
->connect_changed(LINK(this,DlgQryJoin
,LBChangeHdl
));
110 m_xCBNatural
->connect_toggled(LINK(this,DlgQryJoin
,NaturalToggleHdl
));
112 if ( pParent
->getDesignView()->getController().isReadOnly() )
114 m_xLB_JoinType
->set_sensitive(false);
115 m_xCBNatural
->set_sensitive(false);
116 m_xTableControl
->Disable();
120 for (sal_Int32 i
= 0; i
< m_xLB_JoinType
->get_count();)
122 const sal_Int32 nJoinTyp
= m_xLB_JoinType
->get_id(i
).toInt32();
123 if ( !bSupportFullJoin
&& nJoinTyp
== ID_FULL_JOIN
)
124 m_xLB_JoinType
->remove(i
);
125 else if ( !bSupportOuterJoin
&& (nJoinTyp
== ID_LEFT_JOIN
|| nJoinTyp
== ID_RIGHT_JOIN
) )
126 m_xLB_JoinType
->remove(i
);
131 m_xTableControl
->NotifyCellChange();
132 m_xTableControl
->enableRelation(!static_cast<OQueryTableConnectionData
*>(m_pConnData
.get())->isNatural() && eJoinType
!= CROSS_JOIN
);
136 DlgQryJoin::~DlgQryJoin()
140 IMPL_LINK_NOARG( DlgQryJoin
, LBChangeHdl
, weld::ComboBox
&, void )
142 if (!m_xLB_JoinType
->get_value_changed_from_saved())
145 m_xLB_JoinType
->save_value();
146 m_xML_HelpText
->set_label(OUString());
148 m_xTableControl
->enableRelation(true);
150 OUString sFirstWinName
= m_pConnData
->getReferencingTable()->GetWinName();
151 OUString sSecondWinName
= m_pConnData
->getReferencedTable()->GetWinName();
152 const EJoinType eOldJoinType
= eJoinType
;
154 const sal_Int32 nPos
= m_xLB_JoinType
->get_active();
155 const sal_Int32 nJoinType
= m_xLB_JoinType
->get_id(nPos
).toInt32();
156 bool bAddHint
= true;
161 pResId
= STR_QUERY_INNER_JOIN
;
163 eJoinType
= INNER_JOIN
;
166 pResId
= STR_QUERY_LEFTRIGHT_JOIN
;
167 eJoinType
= LEFT_JOIN
;
170 pResId
= STR_QUERY_LEFTRIGHT_JOIN
;
171 eJoinType
= RIGHT_JOIN
;
172 std::swap( sFirstWinName
, sSecondWinName
);
175 pResId
= STR_QUERY_FULL_JOIN
;
176 eJoinType
= FULL_JOIN
;
180 pResId
= STR_QUERY_CROSS_JOIN
;
181 eJoinType
= CROSS_JOIN
;
183 m_pConnData
->ResetConnLines();
184 m_xTableControl
->lateInit();
185 m_xCBNatural
->set_active(false);
186 m_xTableControl
->enableRelation(false);
187 m_pConnData
->AppendConnLine(u
""_ustr
,u
""_ustr
);
188 m_xPB_OK
->set_sensitive(true);
193 m_xCBNatural
->set_sensitive(eJoinType
!= CROSS_JOIN
);
195 if ( eJoinType
!= eOldJoinType
&& eOldJoinType
== CROSS_JOIN
)
197 m_pConnData
->ResetConnLines();
199 if ( eJoinType
!= CROSS_JOIN
)
201 m_xTableControl
->NotifyCellChange();
202 NaturalToggleHdl(*m_xCBNatural
);
205 m_xTableControl
->Invalidate();
207 OUString sHelpText
= DBA_RES(pResId
);
210 sHelpText
= sHelpText
.replaceFirst( "%1", sFirstWinName
);
211 sHelpText
= sHelpText
.replaceFirst( "%2", sSecondWinName
);
215 sHelpText
+= "\n" + DBA_RES( STR_JOIN_TYPE_HINT
);
218 m_xML_HelpText
->set_label( sHelpText
);
221 IMPL_LINK_NOARG(DlgQryJoin
, OKClickHdl
, weld::Button
&, void)
223 m_pConnData
->Update();
224 m_pOrigConnData
->CopyFrom( *m_pConnData
);
226 m_xDialog
->response(RET_OK
);
229 IMPL_LINK_NOARG(DlgQryJoin
, NaturalToggleHdl
, weld::Toggleable
&, void)
231 bool bChecked
= m_xCBNatural
->get_active();
232 static_cast<OQueryTableConnectionData
*>(m_pConnData
.get())->setNatural(bChecked
);
233 m_xTableControl
->enableRelation(!bChecked
);
237 m_pConnData
->ResetConnLines();
240 Reference
<XNameAccess
> xReferencedTableColumns(m_pConnData
->getReferencedTable()->getColumns());
241 for (auto& column
: m_pConnData
->getReferencingTable()->getColumns()->getElementNames())
243 if (xReferencedTableColumns
->hasByName(column
))
244 m_pConnData
->AppendConnLine(column
, column
);
247 catch( const Exception
& )
249 DBG_UNHANDLED_EXCEPTION("dbaccess");
251 m_xTableControl
->NotifyCellChange();
252 m_xTableControl
->Invalidate();
255 void DlgQryJoin::setValid(bool _bValid
)
257 m_xPB_OK
->set_sensitive(_bValid
|| eJoinType
== CROSS_JOIN
);
260 void DlgQryJoin::notifyConnectionChange( )
262 setJoinType( static_cast<OQueryTableConnectionData
*>(m_pConnData
.get())->GetJoinType() );
263 m_xCBNatural
->set_active(static_cast<OQueryTableConnectionData
*>(m_pConnData
.get())->isNatural());
264 NaturalToggleHdl(*m_xCBNatural
);
267 void DlgQryJoin::setJoinType(EJoinType _eNewJoinType
)
269 eJoinType
= _eNewJoinType
;
270 m_xCBNatural
->set_sensitive(eJoinType
!= CROSS_JOIN
);
272 sal_Int32 nJoinType
= 0;
277 nJoinType
= ID_INNER_JOIN
;
280 nJoinType
= ID_LEFT_JOIN
;
283 nJoinType
= ID_RIGHT_JOIN
;
286 nJoinType
= ID_FULL_JOIN
;
289 nJoinType
= ID_CROSS_JOIN
;
293 const sal_Int32 nCount
= m_xLB_JoinType
->get_count();
294 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
296 if (nJoinType
== m_xLB_JoinType
->get_id(i
).toInt32())
298 m_xLB_JoinType
->set_active(i
);
303 LBChangeHdl(*m_xLB_JoinType
);
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */