File: | home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx |
Warning: | line 690, column 13 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
22 | #include <svtools/editbrowsebox.hxx> | |||
23 | #include <com/sun/star/beans/XPropertySet.hpp> | |||
24 | #include <tools/diagnose_ex.h> | |||
25 | #include <toolkit/helper/vclunohelper.hxx> | |||
26 | #include <TableConnectionData.hxx> | |||
27 | #include <TableConnection.hxx> | |||
28 | #include <TableWindow.hxx> | |||
29 | #include <com/sun/star/awt/XWindow.hpp> | |||
30 | #include <com/sun/star/container/XNameAccess.hpp> | |||
31 | #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> | |||
32 | #include <RelControliFace.hxx> | |||
33 | #include <helpids.h> | |||
34 | #include <o3tl/safeint.hxx> | |||
35 | #include <osl/diagnose.h> | |||
36 | ||||
37 | #include <vector> | |||
38 | #include <utility> | |||
39 | using std::pair; | |||
40 | using std::make_pair; | |||
41 | ||||
42 | #define SOURCE_COLUMN1 1 | |||
43 | #define DEST_COLUMN2 2 | |||
44 | ||||
45 | namespace dbaui | |||
46 | { | |||
47 | using namespace ::com::sun::star::uno; | |||
48 | using namespace ::com::sun::star::beans; | |||
49 | using namespace ::com::sun::star::sdbc; | |||
50 | using namespace ::com::sun::star::sdbcx; | |||
51 | using namespace ::com::sun::star::container; | |||
52 | using namespace svt; | |||
53 | ||||
54 | typedef ::svt::EditBrowseBox ORelationControl_Base; | |||
55 | class ORelationControl : public ORelationControl_Base | |||
56 | { | |||
57 | friend class OTableListBoxControl; | |||
58 | ||||
59 | VclPtr< ::svt::ListBoxControl> m_pListCell; | |||
60 | TTableConnectionData::value_type m_pConnData; | |||
61 | OTableListBoxControl* m_pBoxControl; | |||
62 | long m_nDataPos; | |||
63 | Reference< XPropertySet> m_xSourceDef; | |||
64 | Reference< XPropertySet> m_xDestDef; | |||
65 | enum opcode { DELETE, INSERT, MODIFY }; | |||
66 | typedef std::vector< pair < opcode, pair < OConnectionLineDataVec::size_type, OConnectionLineDataVec::size_type> > > ops_type; | |||
67 | ops_type m_ops; | |||
68 | ||||
69 | void fillListBox(const Reference< XPropertySet>& _xDest); | |||
70 | /** returns the column id for the editbrowsebox | |||
71 | @param _nColId | |||
72 | the column id SOURCE_COLUMN or DEST_COLUMN | |||
73 | ||||
74 | @return the current column id either SOURCE_COLUMN or DEST_COLUMN depends on the connection data | |||
75 | */ | |||
76 | sal_uInt16 getColumnIdent( sal_uInt16 _nColId ) const; | |||
77 | public: | |||
78 | explicit ORelationControl(const css::uno::Reference<css::awt::XWindow>& rParent); | |||
79 | void SetController(OTableListBoxControl* pController) | |||
80 | { | |||
81 | m_pBoxControl = pController; | |||
82 | } | |||
83 | ||||
84 | /** searches for a connection between these two tables | |||
85 | @param _pSource | |||
86 | the left table | |||
87 | @param _pDest | |||
88 | the right window | |||
89 | */ | |||
90 | void setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest); | |||
91 | ||||
92 | /** allows to access the connection data from outside | |||
93 | ||||
94 | @return the connection data | |||
95 | */ | |||
96 | const TTableConnectionData::value_type& getData() const { return m_pConnData; } | |||
97 | ||||
98 | void lateInit(); | |||
99 | ||||
100 | protected: | |||
101 | virtual ~ORelationControl() override { disposeOnce(); } | |||
102 | virtual void dispose() override { m_pListCell.disposeAndClear(); ORelationControl_Base::dispose(); } | |||
103 | virtual void Resize() override; | |||
104 | virtual Size GetOptimalSize() const override; | |||
105 | virtual bool PreNotify(NotifyEvent& rNEvt ) override; | |||
106 | ||||
107 | virtual bool IsTabAllowed(bool bForward) const override; | |||
108 | ||||
109 | void Init(const TTableConnectionData::value_type& _pConnData); | |||
110 | using ORelationControl_Base::Init; | |||
111 | virtual void InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol ) override; | |||
112 | virtual ::svt::CellController* GetController( long nRow, sal_uInt16 nCol ) override; | |||
113 | virtual void PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId ) const override; | |||
114 | virtual bool SeekRow( long nRow ) override; | |||
115 | virtual bool SaveModified() override; | |||
116 | virtual OUString GetCellText( long nRow, sal_uInt16 nColId ) const override; | |||
117 | ||||
118 | virtual void CellModified() override; | |||
119 | ||||
120 | DECL_LINK( AsynchDeactivate, void*, void )static void LinkStubAsynchDeactivate(void *, void*); void AsynchDeactivate (void*); | |||
121 | private: | |||
122 | ||||
123 | DECL_LINK( AsynchActivate, void*, void )static void LinkStubAsynchActivate(void *, void*); void AsynchActivate (void*); | |||
124 | ||||
125 | }; | |||
126 | ||||
127 | ORelationControl::ORelationControl(const css::uno::Reference<css::awt::XWindow>& rParent) | |||
128 | : EditBrowseBox(VCLUnoHelper::GetWindow(rParent), | |||
129 | EditBrowseBoxFlags::SMART_TAB_TRAVEL | EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT, | |||
130 | WB_TABSTOP | WB_BORDER, | |||
131 | BrowserMode::AUTOSIZE_LASTCOL) | |||
132 | , m_pBoxControl(nullptr) | |||
133 | , m_nDataPos(0) | |||
134 | { | |||
135 | } | |||
136 | ||||
137 | void ORelationControl::Init(const TTableConnectionData::value_type& _pConnData) | |||
138 | { | |||
139 | ||||
140 | m_pConnData = _pConnData; | |||
141 | OSL_ENSURE(m_pConnData, "No data supplied!")do { if (true && (!(m_pConnData))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" ":" "141" ": "), "%s", "No data supplied!"); } } while (false ); | |||
142 | ||||
143 | m_pConnData->normalizeLines(); | |||
144 | } | |||
145 | ||||
146 | void ORelationControl::lateInit() | |||
147 | { | |||
148 | if ( !m_pConnData ) | |||
149 | return; | |||
150 | m_xSourceDef = m_pConnData->getReferencingTable()->getTable(); | |||
151 | m_xDestDef = m_pConnData->getReferencedTable()->getTable(); | |||
152 | ||||
153 | if ( ColCount() == 0 ) | |||
154 | { | |||
155 | InsertDataColumn( SOURCE_COLUMN1, m_pConnData->getReferencingTable()->GetWinName(), 100); | |||
156 | InsertDataColumn( DEST_COLUMN2, m_pConnData->getReferencedTable()->GetWinName(), 100); | |||
157 | // If the Defs do not yet exits, we need to set them with SetSource-/-DestDef | |||
158 | ||||
159 | m_pListCell.reset( VclPtr<ListBoxControl>::Create( &GetDataWindow() ) ); | |||
160 | ||||
161 | // set browse mode | |||
162 | SetMode( BrowserMode::COLUMNSELECTION | | |||
163 | BrowserMode::HLINES | | |||
164 | BrowserMode::VLINES | | |||
165 | BrowserMode::HIDECURSOR | | |||
166 | BrowserMode::HIDESELECT | | |||
167 | BrowserMode::AUTO_HSCROLL | | |||
168 | BrowserMode::AUTO_VSCROLL); | |||
169 | } | |||
170 | else | |||
171 | // not the first call | |||
172 | RowRemoved(0, GetRowCount()); | |||
173 | ||||
174 | RowInserted(0, m_pConnData->GetConnLineDataList().size() + 1); // add one extra row | |||
175 | } | |||
176 | ||||
177 | void ORelationControl::Resize() | |||
178 | { | |||
179 | EditBrowseBox::Resize(); | |||
180 | long nOutputWidth = GetOutputSizePixel().Width() - 1; | |||
181 | SetColumnWidth(1, (nOutputWidth / 2)); | |||
182 | SetColumnWidth(2, (nOutputWidth / 2)); | |||
183 | } | |||
184 | ||||
185 | bool ORelationControl::PreNotify(NotifyEvent& rNEvt) | |||
186 | { | |||
187 | if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS && !HasChildPathFocus() && !ControlHasFocus()) | |||
188 | PostUserEvent(LINK(this, ORelationControl, AsynchDeactivate)::tools::detail::makeLink( ::tools::detail::castTo<ORelationControl *>(this), &ORelationControl::LinkStubAsynchDeactivate ), nullptr, true); | |||
189 | else if (rNEvt.GetType() == MouseNotifyEvent::GETFOCUS) | |||
190 | PostUserEvent(LINK(this, ORelationControl, AsynchActivate)::tools::detail::makeLink( ::tools::detail::castTo<ORelationControl *>(this), &ORelationControl::LinkStubAsynchActivate), nullptr, true); | |||
191 | ||||
192 | return EditBrowseBox::PreNotify(rNEvt); | |||
193 | } | |||
194 | ||||
195 | IMPL_LINK_NOARG(ORelationControl, AsynchActivate, void*, void)void ORelationControl::LinkStubAsynchActivate(void * instance , void* data) { return static_cast<ORelationControl *>( instance)->AsynchActivate(data); } void ORelationControl:: AsynchActivate(__attribute__ ((unused)) void*) | |||
196 | { | |||
197 | ActivateCell(); | |||
198 | } | |||
199 | ||||
200 | IMPL_LINK_NOARG(ORelationControl, AsynchDeactivate, void*, void)void ORelationControl::LinkStubAsynchDeactivate(void * instance , void* data) { return static_cast<ORelationControl *>( instance)->AsynchDeactivate(data); } void ORelationControl ::AsynchDeactivate(__attribute__ ((unused)) void*) | |||
201 | { | |||
202 | DeactivateCell(); | |||
203 | } | |||
204 | ||||
205 | bool ORelationControl::IsTabAllowed(bool bForward) const | |||
206 | { | |||
207 | long nRow = GetCurRow(); | |||
208 | sal_uInt16 nCol = GetCurColumnId(); | |||
209 | ||||
210 | bool bRet = !( ( bForward && (nCol == DEST_COLUMN2) && (nRow == GetRowCount() - 1)) | |||
211 | || (!bForward && (nCol == SOURCE_COLUMN1) && (nRow == 0))); | |||
212 | ||||
213 | return bRet && EditBrowseBox::IsTabAllowed(bForward); | |||
214 | } | |||
215 | ||||
216 | bool ORelationControl::SaveModified() | |||
217 | { | |||
218 | long nRow = GetCurRow(); | |||
219 | if ( nRow != BROWSER_ENDOFSELECTION(static_cast<long>((-1))) ) | |||
220 | { | |||
221 | weld::ComboBox& rListBox = m_pListCell->get_widget(); | |||
222 | OUString sFieldName(rListBox.get_active_text()); | |||
223 | OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList(); | |||
224 | if ( rLines.size() <= o3tl::make_unsigned(nRow) ) | |||
225 | { | |||
226 | rLines.push_back(new OConnectionLineData()); | |||
227 | nRow = rLines.size() - 1; | |||
228 | // add new past-rLines row | |||
229 | m_ops.emplace_back(INSERT, make_pair(nRow+1, nRow+2)); | |||
230 | } | |||
231 | ||||
232 | OConnectionLineDataRef pConnLineData = rLines[nRow]; | |||
233 | ||||
234 | switch( getColumnIdent( GetCurColumnId() ) ) | |||
235 | { | |||
236 | case SOURCE_COLUMN1: | |||
237 | pConnLineData->SetSourceFieldName( sFieldName ); | |||
238 | break; | |||
239 | case DEST_COLUMN2: | |||
240 | pConnLineData->SetDestFieldName( sFieldName ); | |||
241 | break; | |||
242 | } | |||
243 | // the modification we just did does *not* need to be registered in m_ops; | |||
244 | // it is already taken into account (by the codepath that called us) | |||
245 | //m_ops.push_back(make_pair(MODIFY, make_pair(nRow, nRow+1))); | |||
246 | } | |||
247 | ||||
248 | const OConnectionLineDataVec::size_type oldSize = m_pConnData->GetConnLineDataList().size(); | |||
249 | OConnectionLineDataVec::size_type line = m_pConnData->normalizeLines(); | |||
250 | const OConnectionLineDataVec::size_type newSize = m_pConnData->GetConnLineDataList().size(); | |||
251 | assert(newSize <= oldSize)(static_cast <bool> (newSize <= oldSize) ? void (0) : __assert_fail ("newSize <= oldSize", "/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" , 251, __extension__ __PRETTY_FUNCTION__)); | |||
252 | m_ops.emplace_back(MODIFY, make_pair(line, newSize)); | |||
253 | m_ops.emplace_back(DELETE, make_pair(newSize, oldSize)); | |||
254 | ||||
255 | return true; | |||
256 | } | |||
257 | ||||
258 | sal_uInt16 ORelationControl::getColumnIdent( sal_uInt16 _nColId ) const | |||
259 | { | |||
260 | sal_uInt16 nId = _nColId; | |||
261 | if ( m_pConnData->getReferencingTable() != m_pBoxControl->getReferencingTable() ) | |||
262 | nId = ( _nColId == SOURCE_COLUMN1) ? DEST_COLUMN2 : SOURCE_COLUMN1; | |||
263 | return nId; | |||
264 | } | |||
265 | ||||
266 | OUString ORelationControl::GetCellText( long nRow, sal_uInt16 nColId ) const | |||
267 | { | |||
268 | OUString sText; | |||
269 | if ( m_pConnData->GetConnLineDataList().size() > o3tl::make_unsigned(nRow) ) | |||
270 | { | |||
271 | OConnectionLineDataRef pConnLineData = m_pConnData->GetConnLineDataList()[nRow]; | |||
272 | switch( getColumnIdent( nColId ) ) | |||
273 | { | |||
274 | case SOURCE_COLUMN1: | |||
275 | sText = pConnLineData->GetSourceFieldName(); | |||
276 | break; | |||
277 | case DEST_COLUMN2: | |||
278 | sText = pConnLineData->GetDestFieldName(); | |||
279 | break; | |||
280 | } | |||
281 | } | |||
282 | return sText; | |||
283 | } | |||
284 | ||||
285 | void ORelationControl::InitController( CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColumnId ) | |||
286 | { | |||
287 | ||||
288 | OString sHelpId( HID_RELATIONDIALOG_LEFTFIELDCELL"DBACCESS_HID_RELATIONDIALOG_LEFTFIELDCELL" ); | |||
289 | ||||
290 | Reference< XPropertySet> xDef; | |||
291 | switch ( getColumnIdent(nColumnId) ) | |||
292 | { | |||
293 | case SOURCE_COLUMN1: | |||
294 | xDef = m_xSourceDef; | |||
295 | sHelpId = HID_RELATIONDIALOG_LEFTFIELDCELL"DBACCESS_HID_RELATIONDIALOG_LEFTFIELDCELL"; | |||
296 | break; | |||
297 | case DEST_COLUMN2: | |||
298 | xDef = m_xDestDef; | |||
299 | sHelpId = HID_RELATIONDIALOG_RIGHTFIELDCELL"DBACCESS_HID_RELATIONDIALOG_RIGHTFIELDCELL"; | |||
300 | break; | |||
301 | default: | |||
302 | // ????????? | |||
303 | break; | |||
304 | } | |||
305 | ||||
306 | if ( !xDef.is() ) | |||
307 | return; | |||
308 | ||||
309 | fillListBox(xDef); | |||
310 | OUString sName = GetCellText( nRow, nColumnId ); | |||
311 | weld::ComboBox& rList = m_pListCell->get_widget(); | |||
312 | rList.set_active_text(sName); | |||
313 | if (rList.get_active_text() != sName) | |||
314 | { | |||
315 | rList.append_text(sName); | |||
316 | rList.set_active_text(sName); | |||
317 | } | |||
318 | ||||
319 | rList.set_help_id(sHelpId); | |||
320 | } | |||
321 | ||||
322 | CellController* ORelationControl::GetController( long /*nRow*/, sal_uInt16 /*nColumnId*/ ) | |||
323 | { | |||
324 | return new ListBoxCellController( m_pListCell.get() ); | |||
325 | } | |||
326 | ||||
327 | bool ORelationControl::SeekRow( long nRow ) | |||
328 | { | |||
329 | m_nDataPos = nRow; | |||
330 | return true; | |||
331 | } | |||
332 | ||||
333 | void ORelationControl::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const | |||
334 | { | |||
335 | OUString aText = GetCellText( m_nDataPos, nColumnId ); | |||
336 | ||||
337 | Point aPos( rRect.TopLeft() ); | |||
338 | Size aTextSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight() ); | |||
339 | ||||
340 | if( aPos.X() < rRect.Left() || aPos.X() + aTextSize.Width() > rRect.Right() || | |||
341 | aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() ) | |||
342 | { | |||
343 | rDev.SetClipRegion(vcl::Region(rRect)); | |||
344 | } | |||
345 | ||||
346 | rDev.DrawText( aPos, aText ); | |||
347 | ||||
348 | if( rDev.IsClipRegion() ) | |||
349 | rDev.SetClipRegion(); | |||
350 | } | |||
351 | void ORelationControl::fillListBox(const Reference< XPropertySet>& _xDest) | |||
352 | { | |||
353 | weld::ComboBox& rList = m_pListCell->get_widget(); | |||
354 | rList.clear(); | |||
355 | try | |||
356 | { | |||
357 | if ( _xDest.is() ) | |||
358 | { | |||
359 | //sal_Int32 nRows = GetRowCount(); | |||
360 | Reference<XColumnsSupplier> xSup(_xDest,UNO_QUERY); | |||
361 | Reference<XNameAccess> xColumns = xSup->getColumns(); | |||
362 | Sequence< OUString> aNames = xColumns->getElementNames(); | |||
363 | const OUString* pIter = aNames.getConstArray(); | |||
364 | const OUString* pEnd = pIter + aNames.getLength(); | |||
365 | for(;pIter != pEnd;++pIter) | |||
366 | { | |||
367 | rList.append_text(*pIter); | |||
368 | } | |||
369 | rList.insert_text(0, OUString()); | |||
370 | } | |||
371 | } | |||
372 | catch( const Exception& ) | |||
373 | { | |||
374 | DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" ":" "374" ": ", "dbaccess" );; | |||
375 | } | |||
376 | } | |||
377 | void ORelationControl::setWindowTables(const OTableWindow* _pSource,const OTableWindow* _pDest) | |||
378 | { | |||
379 | // If I edit here, hide | |||
380 | bool bWasEditing = IsEditing(); | |||
381 | if ( bWasEditing ) | |||
382 | DeactivateCell(); | |||
383 | ||||
384 | if ( _pSource && _pDest ) | |||
385 | { | |||
386 | m_xSourceDef = _pSource->GetTable(); | |||
387 | SetColumnTitle(1, _pSource->GetName()); | |||
388 | ||||
389 | m_xDestDef = _pDest->GetTable(); | |||
390 | SetColumnTitle(2, _pDest->GetName()); | |||
391 | ||||
392 | const OJoinTableView* pView = _pSource->getTableView(); | |||
393 | OTableConnection* pConn = pView->GetTabConn(_pSource,_pDest); | |||
394 | if ( pConn && !m_pConnData->GetConnLineDataList().empty() ) | |||
395 | { | |||
396 | m_pConnData->CopyFrom(*pConn->GetData()); | |||
397 | m_pBoxControl->getContainer()->notifyConnectionChange(); | |||
398 | } | |||
399 | else | |||
400 | { | |||
401 | // no connection found so we clear our data | |||
402 | OConnectionLineDataVec& rLines = m_pConnData->GetConnLineDataList(); | |||
403 | for( const auto& rLine : rLines ) | |||
404 | { | |||
405 | rLine->Reset(); | |||
406 | } | |||
407 | ||||
408 | m_pConnData->setReferencingTable(_pSource->GetData()); | |||
409 | m_pConnData->setReferencedTable(_pDest->GetData()); | |||
410 | } | |||
411 | m_pConnData->normalizeLines(); | |||
412 | ||||
413 | } | |||
414 | // Repaint | |||
415 | Invalidate(); | |||
416 | ||||
417 | if ( bWasEditing ) | |||
418 | { | |||
419 | GoToRow(0); | |||
420 | ActivateCell(); | |||
421 | } | |||
422 | } | |||
423 | ||||
424 | void ORelationControl::CellModified() | |||
425 | { | |||
426 | EditBrowseBox::CellModified(); | |||
427 | SaveModified(); | |||
428 | assert(m_pBoxControl)(static_cast <bool> (m_pBoxControl) ? void (0) : __assert_fail ("m_pBoxControl", "/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" , 428, __extension__ __PRETTY_FUNCTION__)); | |||
429 | m_pBoxControl->NotifyCellChange(); | |||
430 | } | |||
431 | ||||
432 | Size ORelationControl::GetOptimalSize() const | |||
433 | { | |||
434 | return LogicToPixel(Size(140, 80), MapMode(MapUnit::MapAppFont)); | |||
435 | } | |||
436 | ||||
437 | OTableListBoxControl::OTableListBoxControl(weld::Builder* _pParent, | |||
438 | const OJoinTableView::OTableWindowMap* _pTableMap, | |||
439 | IRelationControlInterface* _pParentDialog) | |||
440 | : m_xLeftTable(_pParent->weld_combo_box("table1")) | |||
441 | , m_xRightTable(_pParent->weld_combo_box("table2")) | |||
442 | , m_xTable(_pParent->weld_container("relations")) | |||
443 | , m_xTableCtrlParent(m_xTable->CreateChildFrame()) | |||
444 | , m_xRC_Tables(VclPtr<ORelationControl>::Create(m_xTableCtrlParent)) | |||
445 | , m_pTableMap(_pTableMap) | |||
446 | , m_pParentDialog(_pParentDialog) | |||
447 | { | |||
448 | Size aPrefSize = m_xRC_Tables->GetOptimalSize(); | |||
449 | m_xTable->set_size_request(aPrefSize.Width(), aPrefSize.Height()); | |||
450 | ||||
451 | m_xRC_Tables->SetController(this); | |||
452 | m_xRC_Tables->Init(); | |||
453 | ||||
454 | lateUIInit(); | |||
455 | ||||
456 | Link<weld::ComboBox&,void> aLink(LINK(this, OTableListBoxControl, OnTableChanged)::tools::detail::makeLink( ::tools::detail::castTo<OTableListBoxControl *>(this), &OTableListBoxControl::LinkStubOnTableChanged )); | |||
457 | m_xLeftTable->connect_changed(aLink); | |||
458 | m_xRightTable->connect_changed(aLink); | |||
459 | } | |||
460 | ||||
461 | OTableListBoxControl::~OTableListBoxControl() | |||
462 | { | |||
463 | m_xRC_Tables.disposeAndClear(); | |||
464 | m_xTableCtrlParent->dispose(); | |||
465 | m_xTableCtrlParent.clear(); | |||
466 | } | |||
467 | ||||
468 | void OTableListBoxControl::fillListBoxes() | |||
469 | { | |||
470 | OSL_ENSURE( !m_pTableMap->empty(), "OTableListBoxControl::fillListBoxes: no table window!")do { if (true && (!(!m_pTableMap->empty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" ":" "470" ": "), "%s", "OTableListBoxControl::fillListBoxes: no table window!" ); } } while (false); | |||
471 | OTableWindow* pInitialLeft = nullptr; | |||
472 | OTableWindow* pInitialRight = nullptr; | |||
473 | ||||
474 | // Collect the names of all TabWins | |||
475 | for (auto const& elem : *m_pTableMap) | |||
476 | { | |||
477 | m_xLeftTable->append_text(elem.first); | |||
478 | m_xRightTable->append_text(elem.first); | |||
479 | ||||
480 | if (!pInitialLeft) | |||
481 | { | |||
482 | pInitialLeft = elem.second; | |||
483 | m_strCurrentLeft = elem.first; | |||
484 | } | |||
485 | else if (!pInitialRight) | |||
486 | { | |||
487 | pInitialRight = elem.second; | |||
488 | m_strCurrentRight = elem.first; | |||
489 | } | |||
490 | } | |||
491 | ||||
492 | if ( !pInitialRight ) | |||
493 | { | |||
494 | pInitialRight = pInitialLeft; | |||
495 | m_strCurrentRight = m_strCurrentLeft; | |||
496 | } | |||
497 | ||||
498 | // The corresponding Defs for my Controls | |||
499 | m_xRC_Tables->setWindowTables(pInitialLeft,pInitialRight); | |||
500 | ||||
501 | // The table selected in a ComboBox must not be available in the other | |||
502 | ||||
503 | if ( m_pTableMap->size() > 2 ) | |||
504 | { | |||
505 | m_xLeftTable->remove_text(m_strCurrentRight); | |||
506 | m_xRightTable->remove_text(m_strCurrentLeft); | |||
507 | } | |||
508 | ||||
509 | // Select the first one on the left side and on the right side, | |||
510 | // select the second one | |||
511 | m_xLeftTable->set_active_text(m_strCurrentLeft); | |||
512 | m_xRightTable->set_active_text(m_strCurrentRight); | |||
513 | ||||
514 | m_xLeftTable->grab_focus(); | |||
515 | } | |||
516 | ||||
517 | IMPL_LINK(OTableListBoxControl, OnTableChanged, weld::ComboBox&, rListBox, void)void OTableListBoxControl::LinkStubOnTableChanged(void * instance , weld::ComboBox& data) { return static_cast<OTableListBoxControl *>(instance)->OnTableChanged(data); } void OTableListBoxControl ::OnTableChanged(weld::ComboBox& rListBox) | |||
518 | { | |||
519 | OUString strSelected(rListBox.get_active_text()); | |||
520 | OTableWindow* pLeft = nullptr; | |||
521 | OTableWindow* pRight = nullptr; | |||
522 | ||||
523 | // Special treatment: If there are only two tables, we need to switch the other one too when changing in a LB | |||
524 | if ( m_pTableMap->size() == 2 ) | |||
525 | { | |||
526 | weld::ComboBox* pOther; | |||
527 | if (&rListBox == m_xLeftTable.get()) | |||
528 | pOther = m_xRightTable.get(); | |||
529 | else | |||
530 | pOther = m_xLeftTable.get(); | |||
531 | pOther->set_active(1 - pOther->get_active()); | |||
532 | ||||
533 | OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin(); | |||
534 | OTableWindow* pFirst = aIter->second; | |||
535 | ++aIter; | |||
536 | OTableWindow* pSecond = aIter->second; | |||
537 | ||||
538 | if (m_xLeftTable->get_active_text() == pFirst->GetName()) | |||
539 | { | |||
540 | pLeft = pFirst; | |||
541 | pRight = pSecond; | |||
542 | } | |||
543 | else | |||
544 | { | |||
545 | pLeft = pSecond; | |||
546 | pRight = pFirst; | |||
547 | } | |||
548 | } | |||
549 | else | |||
550 | { | |||
551 | // First we need the TableDef to the Table and with it the TabWin | |||
552 | OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(strSelected); | |||
553 | OTableWindow* pLoop = nullptr; | |||
554 | if( aFind != m_pTableMap->end() ) | |||
555 | pLoop = aFind->second; | |||
556 | OSL_ENSURE(pLoop != nullptr, "ORelationDialog::OnTableChanged: invalid ListBox entry!")do { if (true && (!(pLoop != nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" ":" "556" ": "), "%s", "ORelationDialog::OnTableChanged: invalid ListBox entry!" ); } } while (false); | |||
557 | // We need to find strSelect, because we filled the ListBoxes with the table names with which we compare now | |||
558 | if (&rListBox == m_xLeftTable.get()) | |||
559 | { | |||
560 | // Insert the previously selected Entry on the left side on the right side | |||
561 | m_xRightTable->append_text(m_strCurrentLeft); | |||
562 | // Remove the currently selected Entry | |||
563 | m_xRightTable->remove_text(strSelected); | |||
564 | m_strCurrentLeft = strSelected; | |||
565 | ||||
566 | pLeft = pLoop; | |||
567 | ||||
568 | OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_xRightTable->get_active_text()); | |||
569 | OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name")do { if (true && (!(aIter != m_pTableMap->end()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" ":" "569" ": "), "%s", "Invalid name"); } } while (false); | |||
570 | if ( aIter != m_pTableMap->end() ) | |||
571 | pRight = aIter->second; | |||
572 | ||||
573 | m_xLeftTable->grab_focus(); | |||
574 | } | |||
575 | else | |||
576 | { | |||
577 | // Insert the previously selected Entry on the right side on the left side | |||
578 | m_xLeftTable->append_text(m_strCurrentRight); | |||
579 | // Remove the currently selected Entry | |||
580 | m_xLeftTable->remove_text(strSelected); | |||
581 | m_strCurrentRight = strSelected; | |||
582 | ||||
583 | pRight = pLoop; | |||
584 | OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_xLeftTable->get_active_text()); | |||
585 | OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name")do { if (true && (!(aIter != m_pTableMap->end()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/dbaccess/source/ui/control/RelationControl.cxx" ":" "585" ": "), "%s", "Invalid name"); } } while (false); | |||
586 | if ( aIter != m_pTableMap->end() ) | |||
587 | pLeft = aIter->second; | |||
588 | } | |||
589 | } | |||
590 | ||||
591 | rListBox.grab_focus(); | |||
592 | ||||
593 | m_xRC_Tables->setWindowTables(pLeft,pRight); | |||
594 | ||||
595 | NotifyCellChange(); | |||
596 | } | |||
597 | ||||
598 | void OTableListBoxControl::NotifyCellChange() | |||
599 | { | |||
600 | // Enable/disable the OK button, depending on having a valid situation | |||
601 | TTableConnectionData::value_type pConnData = m_xRC_Tables->getData(); | |||
602 | const OConnectionLineDataVec& rLines = pConnData->GetConnLineDataList(); | |||
603 | bool bValid = !rLines.empty(); | |||
604 | if (bValid) | |||
605 | { | |||
606 | for (auto const& line : rLines) | |||
607 | { | |||
608 | bValid = ! (line->GetSourceFieldName().isEmpty() || line->GetDestFieldName().isEmpty()); | |||
609 | if (!bValid) | |||
610 | break; | |||
611 | } | |||
612 | } | |||
613 | m_pParentDialog->setValid(bValid); | |||
614 | ||||
615 | m_xRC_Tables->DeactivateCell(); | |||
616 | for (auto const& elem : m_xRC_Tables->m_ops) | |||
617 | { | |||
618 | switch(elem.first) | |||
619 | { | |||
620 | case ORelationControl::DELETE: | |||
621 | m_xRC_Tables->RowRemoved(elem.second.first, elem.second.second - elem.second.first); | |||
622 | break; | |||
623 | case ORelationControl::INSERT: | |||
624 | m_xRC_Tables->RowInserted(elem.second.first, elem.second.second - elem.second.first); | |||
625 | break; | |||
626 | case ORelationControl::MODIFY: | |||
627 | for(OConnectionLineDataVec::size_type j = elem.second.first; j < elem.second.second; ++j) | |||
628 | m_xRC_Tables->RowModified(j); | |||
629 | break; | |||
630 | } | |||
631 | } | |||
632 | m_xRC_Tables->ActivateCell(); | |||
633 | m_xRC_Tables->m_ops.clear(); | |||
634 | } | |||
635 | ||||
636 | static void fillEntryAndDisable(weld::ComboBox& _rListBox,const OUString& _sEntry) | |||
637 | { | |||
638 | _rListBox.append_text(_sEntry); | |||
639 | _rListBox.set_active(0); | |||
640 | _rListBox.set_sensitive(false); | |||
641 | } | |||
642 | ||||
643 | void OTableListBoxControl::fillAndDisable(const TTableConnectionData::value_type& _pConnectionData) | |||
644 | { | |||
645 | fillEntryAndDisable(*m_xLeftTable, _pConnectionData->getReferencingTable()->GetWinName()); | |||
646 | fillEntryAndDisable(*m_xRightTable, _pConnectionData->getReferencedTable()->GetWinName()); | |||
647 | } | |||
648 | ||||
649 | void OTableListBoxControl::Init(const TTableConnectionData::value_type& _pConnData) | |||
650 | { | |||
651 | m_xRC_Tables->Init(_pConnData); | |||
652 | } | |||
653 | ||||
654 | void OTableListBoxControl::lateUIInit() | |||
655 | { | |||
656 | m_xRC_Tables->Show(); | |||
657 | lateInit(); | |||
658 | } | |||
659 | ||||
660 | void OTableListBoxControl::lateInit() | |||
661 | { | |||
662 | m_xRC_Tables->lateInit(); | |||
663 | } | |||
664 | ||||
665 | void OTableListBoxControl::Disable() | |||
666 | { | |||
667 | m_xLeftTable->set_sensitive(false); | |||
668 | m_xRightTable->set_sensitive(false); | |||
669 | m_xRC_Tables->Disable(); | |||
670 | } | |||
671 | ||||
672 | void OTableListBoxControl::Invalidate() | |||
673 | { | |||
674 | m_xRC_Tables->Invalidate(); | |||
675 | } | |||
676 | ||||
677 | void OTableListBoxControl::SaveModified() | |||
678 | { | |||
679 | m_xRC_Tables->SaveModified(); | |||
680 | } | |||
681 | ||||
682 | TTableWindowData::value_type const & OTableListBoxControl::getReferencingTable() const | |||
683 | { | |||
684 | return m_xRC_Tables->getData()->getReferencingTable(); | |||
685 | } | |||
686 | ||||
687 | void OTableListBoxControl::enableRelation(bool _bEnable) | |||
688 | { | |||
689 | if ( !_bEnable ) | |||
| ||||
690 | m_xRC_Tables->PostUserEvent(LINK(m_xRC_Tables, ORelationControl, AsynchDeactivate)::tools::detail::makeLink( ::tools::detail::castTo<ORelationControl *>(m_xRC_Tables), &ORelationControl::LinkStubAsynchDeactivate )); | |||
| ||||
691 | m_xRC_Tables->Enable(_bEnable); | |||
692 | } | |||
693 | } | |||
694 | ||||
695 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |