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 <browserids.hxx>
21 #include <com/sun/star/sdbc/XRow.hpp>
22 #include <connectivity/dbexception.hxx>
23 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
24 #include <JoinController.hxx>
25 #include <TableWindowData.hxx>
26 #include <TableWindow.hxx>
27 #include <TableConnectionData.hxx>
28 #include <adtabdlg.hxx>
29 #include <vcl/svapp.hxx>
30 #include <osl/mutex.hxx>
31 #include <osl/diagnose.h>
33 using namespace ::com::sun::star::uno
;
34 using namespace ::com::sun::star::io
;
35 using namespace ::com::sun::star::beans
;
36 using namespace ::com::sun::star::frame
;
37 using namespace ::com::sun::star::util
;
38 using namespace ::com::sun::star::lang
;
39 using namespace ::com::sun::star::container
;
40 using namespace ::com::sun::star::sdbc
;
41 using namespace ::com::sun::star::sdb
;
42 using namespace ::com::sun::star::ui::dialogs
;
43 using namespace ::dbtools
;
44 using namespace ::comphelper
;
49 // AddTableDialogContext
50 class AddTableDialogContext
: public IAddTableDialogContext
52 OJoinController
& m_rController
;
55 explicit AddTableDialogContext( OJoinController
& _rController
)
56 :m_rController( _rController
)
60 virtual ~AddTableDialogContext() {}
62 // IAddTableDialogContext
63 virtual css::uno::Reference
< css::sdbc::XConnection
>
64 getConnection() const override
;
65 virtual bool allowViews() const override
;
66 virtual bool allowQueries() const override
;
67 virtual bool allowAddition() const override
;
68 virtual void addTableWindow( const OUString
& _rQualifiedTableName
, const OUString
& _rAliasName
) override
;
69 virtual void onWindowClosing() override
;
72 OJoinTableView
* getTableView() const;
75 Reference
< XConnection
> AddTableDialogContext::getConnection() const
77 return m_rController
.getConnection();
80 bool AddTableDialogContext::allowViews() const
82 return m_rController
.allowViews();
85 bool AddTableDialogContext::allowQueries() const
87 return m_rController
.allowQueries();
90 bool AddTableDialogContext::allowAddition() const
92 return m_rController
.getJoinView()->getTableView()->IsAddAllowed();
95 void AddTableDialogContext::addTableWindow( const OUString
& _rQualifiedTableName
, const OUString
& _rAliasName
)
97 getTableView()->AddTabWin( _rQualifiedTableName
, _rAliasName
, true );
100 void AddTableDialogContext::onWindowClosing()
102 if (!m_rController
.getView())
104 m_rController
.InvalidateFeature( ID_BROWSER_ADDTABLE
);
105 m_rController
.getView()->GrabFocus();
108 OJoinTableView
* AddTableDialogContext::getTableView() const
110 if ( m_rController
.getJoinView() )
111 return m_rController
.getJoinView()->getTableView();
117 OJoinController::OJoinController(const Reference
< XComponentContext
>& _rM
)
118 : OJoinController_BASE(_rM
)
122 OJoinController::~OJoinController()
126 OJoinDesignView
* OJoinController::getJoinView()
128 return static_cast< OJoinDesignView
* >( getView() );
131 void OJoinController::disposing()
133 if (m_xAddTableDialog
)
135 m_xAddTableDialog
->response(RET_CLOSE
);
136 m_xAddTableDialog
.reset();
139 OJoinController_BASE::disposing();
143 m_vTableConnectionData
.clear();
144 m_vTableData
.clear();
147 void OJoinController::reconnect( bool _bUI
)
149 OJoinController_BASE::reconnect( _bUI
);
150 if ( isConnected() && m_xAddTableDialog
)
151 m_xAddTableDialog
->Update();
154 void OJoinController::impl_onModifyChanged()
156 OJoinController_BASE::impl_onModifyChanged();
157 InvalidateFeature( SID_RELATION_ADD_RELATION
);
160 void OJoinController::SaveTabWinPosSize(OTableWindow
const * pTabWin
, tools::Long nOffsetX
, tools::Long nOffsetY
)
162 // the data for the window
163 const TTableWindowData::value_type
& pData
= pTabWin
->GetData();
164 OSL_ENSURE(pData
!= nullptr, "SaveTabWinPosSize : TabWin has no data !");
166 // set Position & Size of data anew (with current window parameters)
167 Point aPos
= pTabWin
->GetPosPixel();
168 aPos
.AdjustX(nOffsetX
);
169 aPos
.AdjustY(nOffsetY
);
170 pData
->SetPosition(aPos
);
171 pData
->SetSize(pTabWin
->GetSizePixel());
175 FeatureState
OJoinController::GetState(sal_uInt16 _nId
) const
177 FeatureState aReturn
;
178 // (disabled automatically)
179 aReturn
.bEnabled
= true;
183 case ID_BROWSER_EDITDOC
:
184 aReturn
.bChecked
= isEditable();
186 case ID_BROWSER_ADDTABLE
:
187 aReturn
.bEnabled
= ( getView() != nullptr )
188 && const_cast< OJoinController
* >( this )->getJoinView()->getTableView()->IsAddAllowed();
189 aReturn
.bChecked
= aReturn
.bEnabled
&& m_xAddTableDialog
;
190 if ( aReturn
.bEnabled
)
191 aReturn
.sTitle
= OAddTableDlg::getDialogTitleForContext( impl_getDialogContext() );
195 aReturn
= OJoinController_BASE::GetState(_nId
);
200 AddTableDialogContext
& OJoinController::impl_getDialogContext() const
202 if (!m_pDialogContext
)
204 OJoinController
* pNonConstThis
= const_cast< OJoinController
* >( this );
205 pNonConstThis
->m_pDialogContext
.reset( new AddTableDialogContext( *pNonConstThis
) );
207 assert(m_pDialogContext
&& "always exists at this point");
208 return *m_pDialogContext
;
211 void OJoinController::Execute(sal_uInt16 _nId
, const Sequence
< PropertyValue
>& aArgs
)
215 case ID_BROWSER_EDITDOC
:
217 { // the state should be changed to not editable
218 switch (saveModified())
221 // don't change anything here so return
225 setModified(false); // and we are not modified yet
231 setEditable(!isEditable());
232 getJoinView()->setReadOnly(!isEditable());
235 case ID_BROWSER_ADDTABLE
:
236 if (m_xAddTableDialog
)
238 m_xAddTableDialog
->response(RET_CLOSE
);
239 getView()->GrabFocus();
247 OJoinController_BASE::Execute(_nId
,aArgs
);
249 InvalidateFeature(_nId
);
252 void OJoinController::runDialogAsync()
254 assert(!m_xAddTableDialog
);
255 m_xAddTableDialog
= std::make_shared
<OAddTableDlg
>(getFrameWeld(), impl_getDialogContext());
257 weld::WaitObject
aWaitCursor(getFrameWeld());
258 m_xAddTableDialog
->Update();
260 weld::DialogController::runAsync(m_xAddTableDialog
, [this](sal_Int32
/*nResult*/){
261 m_xAddTableDialog
->OnClose();
262 m_xAddTableDialog
.reset();
266 void OJoinController::SaveTabWinsPosSize( OJoinTableView::OTableWindowMap
* pTabWinList
, tools::Long nOffsetX
, tools::Long nOffsetY
)
268 // Deletion and recreation of the old implementation with the current model is not correct anymore:
269 // The TabWins have a pointer to their data, but they are managed by me. When I delete the old ones, the TabWins suddenly have a pointer to objects, which no longer exist.
270 // If the TabWins had a SetData, I could save that effort... but they don't, further I also would still have to set information anew, which actually didn't change.
271 // So I don't delete the TabWinDatas, but only update them.
272 OSL_ENSURE(m_vTableData
.size() == pTabWinList
->size(),
273 "OJoinController::SaveTabWinsPosSize : inconsistent state : should have as many TabWinDatas as TabWins !");
275 for (auto const& tabWin
: *pTabWinList
)
276 SaveTabWinPosSize(tabWin
.second
, nOffsetX
, nOffsetY
);
279 void OJoinController::removeConnectionData(const TTableConnectionData::value_type
& _pData
)
281 m_vTableConnectionData
.erase( std::remove(m_vTableConnectionData
.begin(),m_vTableConnectionData
.end(),_pData
),m_vTableConnectionData
.end());
284 void OJoinController::describeSupportedFeatures()
286 OJoinController_BASE::describeSupportedFeatures();
287 implDescribeSupportedFeature( ".uno:Redo", ID_BROWSER_REDO
, CommandGroup::EDIT
);
288 implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVEDOC
, CommandGroup::DOCUMENT
);
289 implDescribeSupportedFeature( ".uno:Undo", ID_BROWSER_UNDO
, CommandGroup::EDIT
);
290 implDescribeSupportedFeature( ".uno:AddTable", ID_BROWSER_ADDTABLE
,CommandGroup::EDIT
);
291 implDescribeSupportedFeature( ".uno:EditDoc", ID_BROWSER_EDITDOC
, CommandGroup::EDIT
);
292 implDescribeSupportedFeature( ".uno:GetUndoStrings", SID_GETUNDOSTRINGS
);
293 implDescribeSupportedFeature( ".uno:GetRedoStrings", SID_GETREDOSTRINGS
);
296 sal_Bool SAL_CALL
OJoinController::suspend(sal_Bool _bSuspend
)
298 if ( getBroadcastHelper().bInDispose
|| getBroadcastHelper().bDisposed
)
301 SolarMutexGuard aSolarGuard
;
302 ::osl::MutexGuard
aGuard( getMutex() );
303 if ( getView() && getView()->IsInModalMode() )
308 bCheck
= saveModified() != RET_CANCEL
;
310 OSingleDocumentController::suspend(_bSuspend
);
315 void OJoinController::loadTableWindows( const ::comphelper::NamedValueCollection
& i_rViewSettings
)
317 m_vTableData
.clear();
319 m_aMinimumTableViewSize
= Point();
321 Sequence
< PropertyValue
> aWindowData
;
322 aWindowData
= i_rViewSettings
.getOrDefault( "Tables", aWindowData
);
324 const PropertyValue
* pTablesIter
= aWindowData
.getConstArray();
325 const PropertyValue
* pTablesEnd
= pTablesIter
+ aWindowData
.getLength();
326 for ( ; pTablesIter
!= pTablesEnd
; ++pTablesIter
)
328 ::comphelper::NamedValueCollection
aSingleTableData( pTablesIter
->Value
);
329 loadTableWindow( aSingleTableData
);
331 if ( m_aMinimumTableViewSize
!= Point() )
333 getJoinView()->getScrollHelper()->resetRange( m_aMinimumTableViewSize
);
337 void OJoinController::loadTableWindow( const ::comphelper::NamedValueCollection
& i_rTableWindowSettings
)
339 sal_Int32 nX
= -1, nY
= -1, nHeight
= -1, nWidth
= -1;
341 OUString sComposedName
,sTableName
,sWindowName
;
342 bool bShowAll
= false;
344 sComposedName
= i_rTableWindowSettings
.getOrDefault( "ComposedName", sComposedName
);
345 sTableName
= i_rTableWindowSettings
.getOrDefault( "TableName", sTableName
);
346 sWindowName
= i_rTableWindowSettings
.getOrDefault( "WindowName", sWindowName
);
347 nY
= i_rTableWindowSettings
.getOrDefault( "WindowTop", nY
);
348 nX
= i_rTableWindowSettings
.getOrDefault( "WindowLeft", nX
);
349 nWidth
= i_rTableWindowSettings
.getOrDefault( "WindowWidth", nWidth
);
350 nHeight
= i_rTableWindowSettings
.getOrDefault( "WindowHeight", nHeight
);
351 bShowAll
= i_rTableWindowSettings
.getOrDefault( "ShowAll", bShowAll
);
353 TTableWindowData::value_type pData
= createTableWindowData(sComposedName
,sTableName
,sWindowName
);
356 pData
->SetPosition(Point(nX
,nY
));
357 pData
->SetSize( Size( nWidth
, nHeight
) );
358 pData
->ShowAll(bShowAll
);
359 m_vTableData
.push_back(pData
);
360 if ( m_aMinimumTableViewSize
.X() < (nX
+nWidth
) )
361 m_aMinimumTableViewSize
.setX( nX
+nWidth
);
362 if ( m_aMinimumTableViewSize
.Y() < (nY
+nHeight
) )
363 m_aMinimumTableViewSize
.setY( nY
+nHeight
);
367 void OJoinController::saveTableWindows( ::comphelper::NamedValueCollection
& o_rViewSettings
) const
369 if ( m_vTableData
.empty() )
372 ::comphelper::NamedValueCollection aAllTablesData
;
375 for (auto const& elem
: m_vTableData
)
377 ::comphelper::NamedValueCollection aWindowData
;
378 aWindowData
.put( "ComposedName", elem
->GetComposedName() );
379 aWindowData
.put( "TableName", elem
->GetTableName() );
380 aWindowData
.put( "WindowName", elem
->GetWinName() );
381 aWindowData
.put( "WindowTop", static_cast<sal_Int32
>(elem
->GetPosition().Y()) );
382 aWindowData
.put( "WindowLeft", static_cast<sal_Int32
>(elem
->GetPosition().X()) );
383 aWindowData
.put( "WindowWidth", static_cast<sal_Int32
>(elem
->GetSize().Width()) );
384 aWindowData
.put( "WindowHeight", static_cast<sal_Int32
>(elem
->GetSize().Height()) );
385 aWindowData
.put( "ShowAll", elem
->IsShowAll() );
387 const OUString
sTableName( "Table" + OUString::number( i
++ ) );
388 aAllTablesData
.put( sTableName
, aWindowData
.getPropertyValues() );
391 o_rViewSettings
.put( "Tables", aAllTablesData
.getPropertyValues() );
394 TTableWindowData::value_type
OJoinController::createTableWindowData(const OUString
& _sComposedName
,const OUString
& _sTableName
,const OUString
& _sWindowName
)
396 OJoinDesignView
* pView
= getJoinView();
398 return pView
->getTableView()->createTableWindowData(_sComposedName
,_sTableName
,_sWindowName
);
399 OSL_FAIL("We should never ever reach this point!");
401 return TTableWindowData::value_type();
406 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */