Skip to content

Commit 39a49e3

Browse files
committed
Allow clicking cells with foreign key in order to jump to referenced cell
Add a tooltip to the database browser when you hover a cell with a foreign key set in order to show the referenced table and column. When clicking on such a cell while holding the Ctrl and Shift key (only one of them won't work because they are for multiselection and Alt doesn't do the trick on my system because it's just for grabbing and moving the window) try to jump to the table and row which is referenced in the clicked cell. See issue #192.
1 parent 9dc5908 commit 39a49e3

File tree

9 files changed

+92
-3
lines changed

9 files changed

+92
-3
lines changed

src/ExtendedTableWidget.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "ExtendedTableWidget.h"
22
#include "sqlitetablemodel.h"
33
#include "FilterTableHeader.h"
4+
#include "sqlitetypes.h"
45

56
#include <QApplication>
67
#include <QClipboard>
@@ -15,6 +16,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
1516
setHorizontalScrollMode(ExtendedTableWidget::ScrollPerPixel);
1617

1718
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(vscrollbarChanged(int)));
19+
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(cellClicked(QModelIndex)));
1820

1921
// Set up filter row
2022
m_tableHeader = new FilterTableHeader(this);
@@ -125,3 +127,16 @@ QSet<int> ExtendedTableWidget::selectedCols()
125127
selectedCols.insert(idx.column());
126128
return selectedCols;
127129
}
130+
131+
void ExtendedTableWidget::cellClicked(const QModelIndex& index)
132+
{
133+
// If Alt key is pressed try to jump to the row referenced by the foreign key of the clicked cell
134+
if(qApp->keyboardModifiers().testFlag(Qt::ControlModifier) && qApp->keyboardModifiers().testFlag(Qt::ShiftModifier) && model())
135+
{
136+
SqliteTableModel* m = qobject_cast<SqliteTableModel*>(model());
137+
sqlb::ForeignKeyClause fk = m->getForeignKeyClause(index.column()-1);
138+
139+
if(fk.isSet())
140+
emit foreignKeyClicked(fk.table(), fk.columns().size() ? fk.columns().at(0) : "", m->data(index, Qt::EditRole).toByteArray());
141+
}
142+
}

src/ExtendedTableWidget.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ class ExtendedTableWidget : public QTableView
1717
public:
1818
QSet<int> selectedCols();
1919

20+
signals:
21+
void foreignKeyClicked(const QString& table, const QString& column, const QByteArray& value);
22+
2023
private:
2124
void copy();
2225
int numVisibleRows();
2326

2427
private slots:
2528
void vscrollbarChanged(int value);
29+
void cellClicked(const QModelIndex& index);
2630

2731
protected:
2832
virtual void keyPressEvent(QKeyEvent* event);

src/FilterTableHeader.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,9 @@ void FilterTableHeader::clearFilters()
129129
foreach (FilterLineEdit* filterLineEdit, filterWidgets)
130130
filterLineEdit->clear();
131131
}
132+
133+
void FilterTableHeader::setFilter(int column, const QString& value)
134+
{
135+
if(column < filterWidgets.size())
136+
filterWidgets.at(column)->setText(value);
137+
}

src/FilterTableHeader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public slots:
2020
void generateFilters(int number, bool bKeepValues = false);
2121
void adjustPositions();
2222
void clearFilters();
23+
void setFilter(int column, const QString& value);
2324

2425
signals:
2526
void filterChanged(int column, QString value);

src/MainWindow.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,3 +2151,27 @@ void MainWindow::on_comboPointShape_currentIndexChanged(int index)
21512151
}
21522152
ui->plotWidget->replot();
21532153
}
2154+
2155+
void MainWindow::jumpToRow(const QString& table, QString column, const QByteArray& value)
2156+
{
2157+
// First check if table exists
2158+
DBBrowserObject obj = db.getObjectByName(table);
2159+
if(obj.getname().size() == 0)
2160+
return;
2161+
2162+
// If no column name is set, assume the primary key is meant
2163+
if(!column.size())
2164+
column = obj.table.fields().at(obj.table.findPk())->name();
2165+
2166+
// If column doesn't exist don't do anything
2167+
int column_index = obj.table.findField(column);
2168+
if(column_index == -1)
2169+
return;
2170+
2171+
// Jump to table
2172+
ui->comboBrowseTable->setCurrentIndex(ui->comboBrowseTable->findText(table));
2173+
populateTable(table);
2174+
2175+
// Set filter
2176+
ui->dataTable->filterHeader()->setFilter(column_index+1, value);
2177+
}

src/MainWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public slots:
110110
void logSql(const QString &sql, int msgtype);
111111
void dbState(bool dirty);
112112
void browseRefresh();
113+
void jumpToRow(const QString& table, QString column, const QByteArray& value);
113114

114115
private slots:
115116
void createTreeContextMenu(const QPoint & qPoint);

src/MainWindow.ui

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@
324324
<rect>
325325
<x>0</x>
326326
<y>0</y>
327-
<width>311</width>
328-
<height>531</height>
327+
<width>509</width>
328+
<height>458</height>
329329
</rect>
330330
</property>
331331
<layout class="QFormLayout" name="formLayout">
@@ -810,7 +810,7 @@
810810
<x>0</x>
811811
<y>0</y>
812812
<width>1037</width>
813-
<height>25</height>
813+
<height>19</height>
814814
</rect>
815815
</property>
816816
<widget class="QMenu" name="fileMenu">
@@ -1766,6 +1766,9 @@
17661766
<class>ExtendedTableWidget</class>
17671767
<extends>QTableWidget</extends>
17681768
<header>ExtendedTableWidget.h</header>
1769+
<slots>
1770+
<signal>foreignKeyClicked(QString,QString,QByteArray)</signal>
1771+
</slots>
17691772
</customwidget>
17701773
<customwidget>
17711774
<class>SqlTextEdit</class>
@@ -2664,6 +2667,22 @@
26642667
</hint>
26652668
</hints>
26662669
</connection>
2670+
<connection>
2671+
<sender>dataTable</sender>
2672+
<signal>foreignKeyClicked(QString,QString,QByteArray)</signal>
2673+
<receiver>MainWindow</receiver>
2674+
<slot>jumpToRow(QString,QString,QByteArray)</slot>
2675+
<hints>
2676+
<hint type="sourcelabel">
2677+
<x>60</x>
2678+
<y>105</y>
2679+
</hint>
2680+
<hint type="destinationlabel">
2681+
<x>518</x>
2682+
<y>314</y>
2683+
</hint>
2684+
</hints>
2685+
</connection>
26672686
</connections>
26682687
<slots>
26692688
<slot>fileOpen()</slot>
@@ -2719,5 +2738,6 @@
27192738
<slot>saveSqlFileAs()</slot>
27202739
<slot>switchToBrowseDataTab()</slot>
27212740
<slot>copyCurrentCreateStatement()</slot>
2741+
<slot>jumpToRow(QString,QString,QByteArray)</slot>
27222742
</slots>
27232743
</ui>

src/sqlitetablemodel.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,26 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
265265
if(m_data.at(index.row()).at(index.column()).isNull())
266266
return QColor(PreferencesDialog::getSettingsValue("databrowser", "null_bg_colour").toString());
267267
return QVariant();
268+
} else if(role == Qt::ToolTipRole) {
269+
sqlb::ForeignKeyClause fk = getForeignKeyClause(index.column()-1);
270+
if(fk.isSet())
271+
return tr("References %1(%2)\nHold Ctrl+Shift and click to jump there").arg(fk.table()).arg(fk.columns().join(','));
272+
else
273+
return QString();
268274
} else {
269275
return QVariant();
270276
}
271277
}
272278

279+
sqlb::ForeignKeyClause SqliteTableModel::getForeignKeyClause(int column) const
280+
{
281+
DBBrowserObject obj = m_db->getObjectByName(m_sTable);
282+
if(obj.getname().size())
283+
return obj.table.fields().at(column)->foreignKey();
284+
else
285+
return sqlb::ForeignKeyClause();
286+
}
287+
273288
bool SqliteTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
274289
{
275290
if(index.isValid() && role == Qt::EditRole)

src/sqlitetablemodel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QVector>
77

88
class DBBrowserDB;
9+
namespace sqlb { class ForeignKeyClause; }
910

1011
class SqliteTableModel : public QAbstractTableModel
1112
{
@@ -41,6 +42,8 @@ class SqliteTableModel : public QAbstractTableModel
4142

4243
typedef QList<QByteArray> QByteArrayList;
4344

45+
sqlb::ForeignKeyClause getForeignKeyClause(int column) const;
46+
4447
signals:
4548

4649
public slots:

0 commit comments

Comments
 (0)