23#include <osl/diagnose.h>
32#include <com/sun/star/sdbc/XConnection.hpp>
33#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
34#include <com/sun/star/accessibility/AccessibleEventId.hpp>
36#include <com/sun/star/sdbcx/KeyType.hpp>
37#include <com/sun/star/container/XIndexAccess.hpp>
38#include <com/sun/star/beans/XPropertySet.hpp>
42#include <core_resource.hxx>
63 std::unique_ptr<OQueryTabConnUndoAction> _pUndoAction,
67 _pUndoAction->SetOwnership(_bOwner);
68 _pUndoAction->SetConnection(_pConnection);
77 bool openJoinDialog(
OQueryTableView* _pView,
const TTableConnectionData::value_type& _pConnectionData,
bool _bSelectableTables)
82 bool bOk = aDlg.run() ==
RET_OK;
85 pData->SetJoinType(aDlg.GetJoinType());
100 OSL_ENSURE(_pConnection,
"Invalid connection!");
105 addUndoAction( _pView,
106 std::make_unique<OQueryAddTabConnUndoAction>(_pView),
113 _pView->
Invalidate(InvalidateFlags::NoChildren);
120 if ( _rSource.
GetData()->isQuery() || _rDest.
GetData()->isQuery() )
127 auto xNewConnData = std::make_shared<OQueryTableConnectionData>( _rSource.
GetData(), _rDest.
GetData() );
129 OUString sRelatedColumn;
133 for(
const OUString& rElement : aKeyCols)
136 if ( !( _rxSourceForeignKeyColumns->getByName(rElement) >>= xColumn ) )
138 OSL_FAIL(
"addConnections: invalid foreign key column!" );
145 sal_Int32 nFindIndex = ::comphelper::findValue(_rSource.
GetOriginalColumns()->getElementNames(),rElement);
147 xNewConnData->SetFieldIndex(
JTCS_FROM,nFindIndex+1);
149 OSL_FAIL(
"Column not found!");
155 sal_Int32 nFindIndex = ::comphelper::findValue(xRefColumns->getElementNames(),sRelatedColumn);
157 xNewConnData->SetFieldIndex(
JTCS_TO,nFindIndex+1);
159 OSL_FAIL(
"Column not found!");
161 xNewConnData->AppendConnLine(rElement,sRelatedColumn);
187 OTableWindowMap::const_iterator aIter =
GetTabWinMap().find(rName);
190 OUString aNewName = rName +
"_" + OUString::number(++nRet);
203 "before calling OQueryTableView::ReSync() please call ClearAll !");
206 std::vector<OUString> arrInvalidTables;
208 TTableWindowData::const_reverse_iterator aIter = rTabWinDataList.rbegin();
211 for(;aIter != rTabWinDataList.rend();++aIter)
219 if (!pTabWin->Init())
223 pTabWin->clearListBox();
225 arrInvalidTables.push_back(
pData->GetAliasName());
227 rTabWinDataList.erase( std::remove(rTabWinDataList.begin(), rTabWinDataList.end(), *aIter), rTabWinDataList.end());
233 if (!
pData->HasPosition() && !
pData->HasSize())
241 TTableConnectionData::const_reverse_iterator aConIter = rTabConnDataList.rbegin();
243 for(;aConIter != rTabConnDataList.rend();++aConIter)
249 bool bInvalid = std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
251 bInvalid = bInvalid && std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
256 rTabConnDataList.erase( std::remove(rTabConnDataList.begin(), rTabConnDataList.end(), *aConIter), rTabConnDataList.end());
270 m_pView->getController().setModified(
true);
283 auto aEnd = rConnections.end();
284 auto aIter = std::find( rConnections.begin(),
290 for (
auto const& connection : rConnections)
303 if (pTabConn ==
nullptr)
306 auto pNewData = std::static_pointer_cast<OQueryTableConnectionData>(rNewConn.
GetData()->NewInstance());
307 pNewData->CopyFrom(*rNewConn.
GetData());
311 connectionModified(
this,pNewConn,_bCreateUndoAction);
316 ,
const OUString& _sTableName
317 ,
const OUString& _rWinName)
319 return std::make_shared<OQueryTableWindowData>( _rComposedName, _sTableName,_rWinName );
330 if(!xConnection.is())
336 ::dbtools::qualifiedNameComponents(xMetaData,
341 ::dbtools::EComposeRule::InDataManipulation);
343 if (!sRealName.isEmpty())
347 AddTabWin(_rTableName, sRealName, _rAliasName, bNewTable);
351 OSL_FAIL(
"qualifiedNameComponents");
362 const sal_Int32
nCount = _rxKeys->getCount();
368 sal_Int32 nKeyType = 0;
370 if(KeyType::FOREIGN == nKeyType)
372 OUString sReferencedTable;
375 if(sReferencedTable == _rReferencedTable)
385 OSL_ENSURE(!_rTableName.isEmpty() || !strAlias.isEmpty(),
"OQueryTableView::AddTabWin : no tables or aliases !");
390 bool bAppend = bNewTable;
391 TTableWindowData::value_type pNewTabWinData;
393 bool bFoundElem =
false;
394 for (
auto const& elem : rWindowData)
396 pNewTabWinData = elem;
397 if (pNewTabWinData && pNewTabWinData->GetWinName() == strAlias && pNewTabWinData->GetComposedName() == _rComposedName && pNewTabWinData->GetTableName() == _rTableName)
404 bAppend = !bFoundElem;
415 pUndoAction->SetTabWin(pNewTabWin);
416 bool bSuccess =
ShowTabWin(pNewTabWin, pUndoAction.
get(), bAppend);
420 pUndoAction->SetTabWin(
nullptr);
421 pUndoAction->SetOwnership(
false);
427 if(bNewTable && !rTabWins.empty() && !_rTableName.isEmpty())
431 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
433 Any(pNewTabWin->GetAccessible())
438 if ( pNewTabWin->GetData()->isQuery() )
445 if ( !xKeyIndex.is() )
449 OUString aReferencedTable;
452 const sal_Int32 nKeyCount = xKeyIndex->getCount();
453 for ( sal_Int32
i=0;
i<nKeyCount ; ++
i )
456 xColumnsSupplier.set( xProp, UNO_QUERY_THROW );
457 xFKeyColumns.set( xColumnsSupplier->getColumns(), UNO_SET_THROW );
459 sal_Int32 nKeyType = 0;
464 case KeyType::FOREIGN:
468 OSL_ENSURE(!aReferencedTable.isEmpty(),
"Foreign key without referencedTableName");
470 OTableWindowMap::const_iterator aIter = rTabWins.find(aReferencedTable);
471 OTableWindowMap::const_iterator aEnd = rTabWins.end();
474 for(aIter = rTabWins.begin();aIter != aEnd;++aIter)
477 OSL_ENSURE( pTabWinTmp,
"TableWindow is null!" );
478 if ( pTabWinTmp != pNewTabWin && pTabWinTmp->
GetComposedName() == aReferencedTable )
482 if ( aIter != aEnd && pNewTabWin.
get() != aIter->second.get() )
483 addConnections(
this, *pNewTabWin, *
static_cast<OQueryTableWindow*
>(aIter->second.get()), xFKeyColumns );
487 case KeyType::PRIMARY:
490 for (
auto const& tabWin : rTabWins)
493 if ( pTabWinTmp == pNewTabWin )
496 if ( pTabWinTmp->
GetData()->isQuery() )
499 OSL_ENSURE(pTabWinTmp,
"TableWindow is null!");
506 addConnections(
this, *pTabWinTmp, *pNewTabWin, xTColumns );
522 m_pView->getController().addUndoActionAndInvalidate( std::move(pUndoAction) );
530 OUString aSourceFieldName, aDestFieldName;
540 auto xNewConnectionData = std::make_shared<OQueryTableConnectionData>(pSourceWin->
GetData(), pDestWin->
GetData());
542 sal_uInt32 nSourceFieldIndex, nDestFieldIndex;
546 nSourceFieldIndex = jxdSource.
nEntry;
548 nDestFieldIndex = jxdDest.
nEntry;
551 xNewConnectionData->SetFieldIndex(
JTCS_FROM, nSourceFieldIndex);
552 xNewConnectionData->SetFieldIndex(
JTCS_TO, nDestFieldIndex);
554 xNewConnectionData->AppendConnLine( aSourceFieldName,aDestFieldName );
565 OUString aTmp(aSourceFieldName);
566 aSourceFieldName = aDestFieldName;
567 aDestFieldName = aTmp;
570 pConn->
GetData()->AppendConnLine( aSourceFieldName,aDestFieldName );
572 connectionModified(
this,pConn,
false);
578 if (openJoinDialog(
this, rConnection->GetData(),
false))
580 connectionModified(
this, rConnection,
false);
587 TTableConnectionData::value_type
pData = std::make_shared<OQueryTableConnectionData>();
588 if( !openJoinDialog(
this,
pData,
true) )
609 connectionModified(
this,pConn,bNew);
623 std::make_unique<OQueryDelTabConnUndoAction>(
this),
632 OSL_ENSURE(!rAliasName.isEmpty(),
"OQueryTableView::FindTable : the AliasName should not be empty !");
634 OTableWindowMap::const_iterator aIter =
GetTabWinMap().find(rAliasName);
658 if ( tabWin.second == &rTabWin )
669 OSL_ENSURE(pTabWin !=
nullptr,
"OQueryTableView::RemoveTabWin : Window should not be NULL !");
690 m_pView->getController().addUndoActionAndInvalidate( std::move(pUndoAction) );
695 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
732 OTableWindowMap::const_iterator aIter = std::find_if(rTabWins.begin(), rTabWins.end(),
733 [&pTabWin](
const OTableWindowMap::value_type& rEntry) { return rEntry.second == pTabWin; });
734 if (aIter != rTabWins.end())
735 rTabWins.erase( aIter );
741 rTabWinDataList.erase( std::remove(rTabWinDataList.begin(), rTabWinDataList.end(), pTabWin->
GetData()), rTabWinDataList.end());
753 auto aIter2 = rTabConList.begin();
754 for(;aIter2 != rTabConList.end();)
758 OSL_ENSURE(pTmpEntry,
"OQueryTableConnection is null!");
768 aIter2 = rTabConList.begin();
784 m_pView->getController().setModified(
true );
785 m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
791 bool bSuccess =
false;
797 TTableWindowData::value_type
pData = pTabWin->
GetData();
798 OSL_ENSURE(
pData !=
nullptr,
"OQueryTableView::ShowTabWin : TabWin has no data !");
824 for(
const auto& conn : rTableCon)
831 m_pView->getController().getTableWindowData().push_back(pTabWin->
GetData());
850 if(!
m_pView->getController().isReadOnly())
851 m_pView->getController().setModified(
true );
853 m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
860 OSL_ENSURE(
getDesignView() !=
nullptr,
"OQueryTableView::InsertField : has no Parent !");
879 OUString sError(
DBA_RES(STR_STATEMENT_WITHOUT_RESULT_SET));
880 ::dbtools::throwSQLException( sError, ::dbtools::StandardSQLState::GENERAL_ERROR,
nullptr );
static Reference< XPropertySet > getKeyReferencedTo(const Reference< XIndexAccess > &_rxKeys, std::u16string_view _rReferencedTable)
#define ID_BROWSER_ADDTABLE
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
reference_type * get() const
static VclPtr< reference_type > Create(Arg &&... arg)
TTableWindowData & getTableWindowData()
void SaveTabWinUIConfig(OTableWindow const *pWin)
OJoinController & getController() const
void InvalidateConnections()
rtl::Reference< OJoinDesignViewAccess > m_pAccessible
const std::vector< VclPtr< OTableConnection > > & getTableConnections() const
gives a read only access to the connection vector
virtual bool RemoveConnection(VclPtr< OTableConnection > &rConnection, bool bDelete)
RemoveConnection allows to remove connections from join table view.
VclPtr< OTableWindow > m_pLastFocusTabWin
TTableWindowData::value_type createTableWindowData(const OUString &_rComposedName, const OUString &_sTableName, const OUString &_rWinName)
virtual void EnsureVisible(const OTableWindow *_pWin)
std::map< OUString, VclPtr< OTableWindow > > OTableWindowMap
virtual void ClearAll()
Hard deletion.
void SelectConn(OTableConnection *pConn)
OJoinDesignView * getDesignView() const
VclPtr< OJoinDesignView > m_pView
VclPtr< OTableConnection > & GetSelectedConn()
void SetDefaultTabWinPosSize(OTableWindow *pTabWin)
OTableConnection * GetTabConn(const OTableWindow *pLhs, const OTableWindow *pRhs, bool _bSuppressCrossOrNaturalJoin=false) const
void addConnection(OTableConnection *_pConnection, bool _bAddData=true)
allows to add new connections to join table view
OTableWindowMap & GetTabWinMap()
void TableDeleted(const OUString &rAliasName)
void InsertConnection(OTableConnection *pConnection)
std::vector< VclPtr< OTableConnection > > & GetTabConnList()
void SetOwnership(bool bTakeIt)
EJoinType GetJoinType() const
OUString const & GetAliasName(EConnectionSide nWhich) const
virtual void onNoColumns_throw() override
called when init fails at the tablewindowdata because the m_xTable object could not provide columns,...
virtual void ReSync() override
rebuild everything (TabWins, Connections) (PRECONDITION: ClearAll was called previously)
virtual bool RemoveConnection(VclPtr< OTableConnection > &rConn, bool bDelete) override
RemoveConnection allows to remove connections from join table view.
bool FindTableFromField(const OUString &rFieldName, OTableFieldDescRef const &rInfo, sal_uInt16 &rCnt)
void GetConnection(OQueryTableConnection *pConn)
Inserting a Connection the structure.
bool ShowTabWin(OQueryTableWindow *pTabWin, OQueryTabWinUndoAct *pUndoAction, bool _bAppend)
void NotifyTabConnection(const OQueryTableConnection &rNewConn, bool _bCreateUndoAction=true)
announce new Connection and insert it, if not existing yet
bool ExistsAVisitedConn(const OQueryTableWindow *pFrom) const
virtual std::shared_ptr< OTableWindowData > CreateImpl(const OUString &_rComposedName, const OUString &_sTableName, const OUString &_rWinName) override
virtual bool suppressCrossNaturalJoin(const TTableConnectionData::value_type &_pData) const override
OQueryTableWindow * FindTable(const OUString &rAliasName)
search TabWin
virtual void EnsureVisible(const OTableWindow *_pWin) override
ensure visibility of TabWins (+ and invalidate connections)
virtual void ConnDoubleClicked(VclPtr< OTableConnection > &rConnection) override
bool ContainsTabWin(const OTableWindow &rTabWin)
base class overwritten: create and delete windows (not really delete, as it becomes an UndoAction)
void HideTabWin(OQueryTableWindow *pTabWin, OQueryTabWinUndoAct *pUndoAction)
virtual VclPtr< OTableWindow > createWindow(const TTableWindowData::value_type &_pData) override
factory method to create table windows
void createNewConnection()
opens the join dialog and allows to create a new join connection
void InsertField(const OTableFieldDescRef &rInfo)
insert field (simply passed to parents)
virtual void AddTabWin(const OUString &_rTableName, const OUString &_rAliasName, bool bNewTable=false) override
virtual void RemoveTabWin(OTableWindow *pTabWin) override
virtual void ClearAll() override
delete everything hard (TabWins, Connections), without any notifications
sal_Int32 CountTableAlias(const OUString &rName, sal_Int32 &rMax)
how many tables with a certain alias do I already have?
virtual void AddConnection(const OJoinExchangeData &jxdSource, const OJoinExchangeData &jxdDest) override
base class overwritten: create and delete Connections
void DropConnection(VclPtr< OQueryTableConnection > const &rConn)
Removing a Connection from the structure.
OUString const & GetAliasName() const
virtual bool Init() override
bool ExistsField(const OUString &strFieldName, OTableFieldDescRef const &rInfo)
OUString const & GetAliasName() const
void addUndoActionAndInvalidate(std::unique_ptr< SfxUndoAction > pAction)
addUndoActionAndInvalidate adds an undo action to the undoManager, additionally invalidates the UNDO ...
const TTableWindowData::value_type & getReferencingTable() const
const TTableWindowData::value_type & getReferencedTable() const
const TTableConnectionData::value_type & GetData() const
void InvalidateConnection()
OTableWindow * GetDestWin() const
OTableWindow * GetSourceWin() const
css::uno::Reference< css::container::XNameAccess > GetOriginalColumns() const
const TTableWindowData::value_type & GetData() const
void clearListBox()
clears the listbox inside.
void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize) override
OUString const & GetComposedName() const
void SetUpdateMode(bool bUpdate)
tools::Long CalcZoom(tools::Long n) const
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
css::uno::Reference< css::accessibility::XAccessible > GetAccessible(bool bCreate=true)
void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void SetHelpId(const OUString &)
virtual OUString get_text(int row, int col=-1) const=0
#define DBG_UNHANDLED_EXCEPTION(...)
constexpr OUStringLiteral HID_CTL_QRYDGNTAB
std::unique_ptr< sal_Int32[]> pData
OSQLColumns::const_iterator find(const OSQLColumns::const_iterator &first, const OSQLColumns::const_iterator &last, std::u16string_view _rVal, const ::comphelper::UStringMixEqual &_rCase)
std::vector< std::shared_ptr< OTableConnectionData > > TTableConnectionData
std::vector< std::shared_ptr< OTableWindowData > > TTableWindowData
constexpr OUStringLiteral PROPERTY_RELATEDCOLUMN(u"RelatedColumn")
constexpr OUStringLiteral PROPERTY_TYPE(u"Type")
constexpr OUStringLiteral PROPERTY_REFERENCEDTABLE(u"ReferencedTable")
VclPtr< OTableWindowListBox > pListBox