#include "sqlcompareview.h" #include "sqlview.h" #include "common/utils.h" #include "diff/diff_match_patch.h" #include "sqlitesyntaxhighlighter.h" #include #include SqlCompareView::SqlCompareView(QWidget *parent) : QTableWidget(parent) { setColumnCount(2); setVerticalScrollMode(ScrollPerPixel); horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); horizontalHeader()->setVisible(false); // verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); diff = new diff_match_patch; } void SqlCompareView::setSides(const QList>& data) { setRowCount(data.size()); int row = 0; SqlView* leftView = nullptr; SqlView* rightView = nullptr; for (const QPair& rowData : data) { leftView = new SqlView(); leftView->setFrameStyle(QFrame::NoFrame); leftView->setPlainText(rowData.first); setCellWidget(row, 0, leftView); rightView = new SqlView(); rightView->setFrameStyle(QFrame::NoFrame); rightView->setPlainText(rowData.second); setCellWidget(row, 1, rightView); setupHighlighting(rowData.first, rowData.second, leftView, rightView); row++; } updateLabels(); updateSizes(); } void SqlCompareView::setLeftLabel(const QString& label) { leftLabel = label; } void SqlCompareView::setRightLabel(const QString& label) { rightLabel = label; } void SqlCompareView::updateSizes() { if (rowCount() == 0 || !isVisible()) return; SqlView* view = dynamic_cast(cellWidget(0, 0)); if (!view) { qCritical() << "Not a SqlView in SqlCompareView::updateSizes():" << cellWidget(0, 0); return; } QFont font = view->font(); QFontMetrics fm(font); int leftWidth = horizontalHeader()->sectionSize(0); int rightWidth = horizontalHeader()->sectionSize(1); SqlView* leftView = nullptr; SqlView* rightView = nullptr; QSize leftSize; QSize rightSize; for (int row = 0, total = rowCount(); row < total; ++row) { leftView = dynamic_cast(cellWidget(row, 0)); leftView->document()->setTextWidth(leftWidth); rightView = dynamic_cast(cellWidget(row, 1)); rightView->document()->setTextWidth(rightWidth); leftSize = QSize(leftWidth, leftView->document()->size().toSize().height()); rightSize = QSize(rightWidth, rightView->document()->size().toSize().height()); if (leftSize.height() > rightSize.height()) rightSize.setHeight(leftSize.height()); else leftSize.setHeight(rightSize.height()); leftView->setFixedSize(leftSize); rightView->setFixedSize(rightSize); } verticalHeader()->resizeSections(QHeaderView::ResizeToContents); } void SqlCompareView::updateLabels() { setHorizontalHeaderLabels({leftLabel, rightLabel}); } void SqlCompareView::setupHighlighting(const QString& left, const QString& right, SqlView* leftView, SqlView* rightView) { QList diffs = diff->diff_main(left, right); int leftPos = 0; int lgt = 0; for (const Diff& d : diffs) { lgt = d.text.length(); switch (d.operation) { case DELETE: leftView->setTextBackgroundColor(leftPos, leftPos + lgt - 1, Qt::red); leftPos += lgt; break; case EQUAL: leftPos += lgt; break; case INSERT: rightView->setTextBackgroundColor(leftPos, leftPos + lgt - 1, Qt::green); break; } } } void SqlCompareView::resizeEvent(QResizeEvent* e) { QTableWidget::resizeEvent(e); updateSizes(); } void SqlCompareView::showEvent(QShowEvent* e) { QTableWidget::showEvent(e); updateSizes(); }