Don’t remove entries in table selection for Insert Relation dialog

Previously the dialog for inserting a relation behaved differently
depending on whether the query has two or more than two tables. If there
are only two, then you can select either table as the left table and the
right table will automatically flip to select the other table. If there
are more than two tables then instead it will remove the second table
from the list of options for the left table and remove the first table
for the list of options for the right table. As you change the values of
a combobox it would add and remove options in the other one so that you
can never select the same table in both boxes.

This behaviour is quite annoying if you happen to want to choose the
second table as the left part of the join. In that case you have to
first set the right table to something else so that it will appear in
the left combobox and let you select it. After that you can select the
table you actually wanted in the right box.

Instead of that behaviour, this patch makes it always have all the
tables available in each combobox. If you select the same one that is
already in the other combobox, it will now just shove the selection
along by one place including wrapping around back to zero if the last
one is already selected. I think this is easier to work with. It also
means we don’t have to have a special case to handle when there are only
two tables because the general case will have the same behaviour as
before the patch.

Change-Id: Ib02e4d169d7e2756ebfccd9d20a1ab244fa5688e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194039
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Jenkins
This commit is contained in:
Neil Roberts
2025-11-14 20:02:59 +01:00
committed by Noel Grandin
parent a00e45f393
commit a2f091a1e6
2 changed files with 20 additions and 85 deletions
+20 -83
View File
@@ -474,115 +474,52 @@ namespace dbaui
m_xRightTable->append_text(elem.first);
if (!pInitialLeft)
{
pInitialLeft = elem.second;
m_strCurrentLeft = elem.first;
}
else if (!pInitialRight)
{
pInitialRight = elem.second;
m_strCurrentRight = elem.first;
}
}
if ( !pInitialRight )
{
pInitialRight = pInitialLeft;
m_strCurrentRight = m_strCurrentLeft;
}
// The corresponding Defs for my Controls
m_xRC_Tables->setWindowTables(pInitialLeft,pInitialRight);
// The table selected in a ComboBox must not be available in the other
if ( m_pTableMap->size() > 2 )
{
m_xLeftTable->remove_text(m_strCurrentRight);
m_xRightTable->remove_text(m_strCurrentLeft);
}
// Select the first one on the left side and on the right side,
// select the second one
m_xLeftTable->set_active_text(m_strCurrentLeft);
m_xRightTable->set_active_text(m_strCurrentRight);
m_xLeftTable->set_active(0);
m_xRightTable->set_active(pInitialRight ? 1 : 0);
m_xLeftTable->grab_focus();
}
IMPL_LINK(OTableListBoxControl, OnTableChanged, weld::ComboBox&, rListBox, void)
{
OUString strSelected(rListBox.get_active_text());
OTableWindow* pLeft = nullptr;
OTableWindow* pRight = nullptr;
// Special treatment: If there are only two tables, we need to switch the other one too when changing in a LB
if ( m_pTableMap->size() == 2 )
{
weld::ComboBox* pOther;
if (&rListBox == m_xLeftTable.get())
pOther = m_xRightTable.get();
else
pOther = m_xLeftTable.get();
pOther->set_active(1 - rListBox.get_active());
OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->begin();
OTableWindow* pFirst = aIter->second;
++aIter;
OTableWindow* pSecond = aIter->second;
if (m_xLeftTable->get_active_text() == pFirst->GetName())
{
pLeft = pFirst;
pRight = pSecond;
}
else
{
pLeft = pSecond;
pRight = pFirst;
}
}
weld::ComboBox* pOther;
if (&rListBox == m_xLeftTable.get())
pOther = m_xRightTable.get();
else
{
// First we need the TableDef to the Table and with it the TabWin
OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(strSelected);
OTableWindow* pLoop = nullptr;
if( aFind != m_pTableMap->end() )
pLoop = aFind->second;
OSL_ENSURE(pLoop != nullptr, "ORelationDialog::OnTableChanged: invalid ListBox entry!");
// We need to find strSelect, because we filled the ListBoxes with the table names with which we compare now
if (&rListBox == m_xLeftTable.get())
{
// Insert the previously selected Entry on the left side on the right side
m_xRightTable->append_text(m_strCurrentLeft);
// Remove the currently selected Entry
m_xRightTable->remove_text(strSelected);
m_strCurrentLeft = strSelected;
pOther = m_xLeftTable.get();
pLeft = pLoop;
// If the same table is selected in the other combobox then make it switch to another table
if (rListBox.get_active() == pOther->get_active())
pOther->set_active((pOther->get_active() + 1) % m_pTableMap->size());
OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_xRightTable->get_active_text());
OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
if ( aIter != m_pTableMap->end() )
pRight = aIter->second;
// Find the TableWindow for each selected table name
OUString sLeftSelected(m_xLeftTable->get_active_text());
OJoinTableView::OTableWindowMap::const_iterator aFind = m_pTableMap->find(sLeftSelected);
if( aFind != m_pTableMap->end() )
pLeft = aFind->second;
OSL_ENSURE(pLeft != nullptr, "ORelationDialog::OnTableChanged: invalid ListBox entry!");
m_xLeftTable->grab_focus();
}
else
{
// Insert the previously selected Entry on the right side on the left side
m_xLeftTable->append_text(m_strCurrentRight);
// Remove the currently selected Entry
m_xLeftTable->remove_text(strSelected);
m_strCurrentRight = strSelected;
pRight = pLoop;
OJoinTableView::OTableWindowMap::const_iterator aIter = m_pTableMap->find(m_xLeftTable->get_active_text());
OSL_ENSURE( aIter != m_pTableMap->end(), "Invalid name");
if ( aIter != m_pTableMap->end() )
pLeft = aIter->second;
}
}
OUString sRightSelected(m_xRightTable->get_active_text());
aFind = m_pTableMap->find(sRightSelected);
if( aFind != m_pTableMap->end() )
pRight = aFind->second;
OSL_ENSURE(pRight != nullptr, "ORelationDialog::OnTableChanged: invalid ListBox entry!");
rListBox.grab_focus();
@@ -36,8 +36,6 @@ namespace dbaui
const OJoinTableView::OTableWindowMap* m_pTableMap;
IRelationControlInterface* m_pParentDialog;
OUString m_strCurrentLeft;
OUString m_strCurrentRight;
DECL_LINK( OnTableChanged, weld::ComboBox&, void );
public:
OTableListBoxControl(weld::Builder* _pParent,