1 #include "sqlcompareview.h"
2 #include "sqlview.h"
3 #include "common/utils.h"
4 #include "diff/diff_match_patch.h"
5 #include "sqlitesyntaxhighlighter.h"
6 #include <QHeaderView>
7 #include <QDebug>
8 
SqlCompareView(QWidget * parent)9 SqlCompareView::SqlCompareView(QWidget *parent) :
10     QTableWidget(parent)
11 {
12     setColumnCount(2);
13     setVerticalScrollMode(ScrollPerPixel);
14     horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
15     horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
16     horizontalHeader()->setVisible(false);
17 //    verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
18     diff = new diff_match_patch;
19 }
20 
setSides(const QList<QPair<QString,QString>> & data)21 void SqlCompareView::setSides(const QList<QPair<QString, QString>>& data)
22 {
23     setRowCount(data.size());
24 
25     int row = 0;
26     SqlView* leftView = nullptr;
27     SqlView* rightView = nullptr;
28     for (const QPair<QString, QString>& rowData : data)
29     {
30         leftView = new SqlView();
31         leftView->setFrameStyle(QFrame::NoFrame);
32         leftView->setPlainText(rowData.first);
33         setCellWidget(row, 0, leftView);
34 
35         rightView = new SqlView();
36         rightView->setFrameStyle(QFrame::NoFrame);
37         rightView->setPlainText(rowData.second);
38         setCellWidget(row, 1, rightView);
39 
40         setupHighlighting(rowData.first, rowData.second, leftView, rightView);
41 
42         row++;
43     }
44     updateLabels();
45     updateSizes();
46 }
47 
setLeftLabel(const QString & label)48 void SqlCompareView::setLeftLabel(const QString& label)
49 {
50     leftLabel = label;
51 }
52 
setRightLabel(const QString & label)53 void SqlCompareView::setRightLabel(const QString& label)
54 {
55     rightLabel = label;
56 }
57 
updateSizes()58 void SqlCompareView::updateSizes()
59 {
60     if (rowCount() == 0 || !isVisible())
61         return;
62 
63     SqlView* view = dynamic_cast<SqlView*>(cellWidget(0, 0));
64     if (!view)
65     {
66         qCritical() << "Not a SqlView in SqlCompareView::updateSizes():" << cellWidget(0, 0);
67         return;
68     }
69 
70     QFont font = view->font();
71     QFontMetrics fm(font);
72 
73     int leftWidth = horizontalHeader()->sectionSize(0);
74     int rightWidth = horizontalHeader()->sectionSize(1);
75 
76     SqlView* leftView = nullptr;
77     SqlView* rightView = nullptr;
78     QSize leftSize;
79     QSize rightSize;
80     for (int row = 0, total = rowCount(); row < total; ++row)
81     {
82         leftView = dynamic_cast<SqlView*>(cellWidget(row, 0));
83         leftView->document()->setTextWidth(leftWidth);
84 
85         rightView = dynamic_cast<SqlView*>(cellWidget(row, 1));
86         rightView->document()->setTextWidth(rightWidth);
87 
88         leftSize = QSize(leftWidth, leftView->document()->size().toSize().height());
89         rightSize = QSize(rightWidth, rightView->document()->size().toSize().height());
90         if (leftSize.height() > rightSize.height())
91             rightSize.setHeight(leftSize.height());
92         else
93             leftSize.setHeight(rightSize.height());
94 
95         leftView->setFixedSize(leftSize);
96         rightView->setFixedSize(rightSize);
97     }
98     verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
99 }
100 
updateLabels()101 void SqlCompareView::updateLabels()
102 {
103     setHorizontalHeaderLabels({leftLabel, rightLabel});
104 }
105 
setupHighlighting(const QString & left,const QString & right,SqlView * leftView,SqlView * rightView)106 void SqlCompareView::setupHighlighting(const QString& left, const QString& right, SqlView* leftView, SqlView* rightView)
107 {
108     QList<Diff> diffs = diff->diff_main(left, right);
109     int leftPos = 0;
110     int lgt = 0;
111     for (const Diff& d : diffs)
112     {
113         lgt = d.text.length();
114         switch (d.operation)
115         {
116             case DELETE:
117                 leftView->setTextBackgroundColor(leftPos, leftPos + lgt - 1, Qt::red);
118                 leftPos += lgt;
119                 break;
120             case EQUAL:
121                 leftPos += lgt;
122                 break;
123             case INSERT:
124                 rightView->setTextBackgroundColor(leftPos, leftPos + lgt - 1, Qt::green);
125                 break;
126         }
127     }
128 }
129 
resizeEvent(QResizeEvent * e)130 void SqlCompareView::resizeEvent(QResizeEvent* e)
131 {
132     QTableWidget::resizeEvent(e);
133     updateSizes();
134 }
135 
showEvent(QShowEvent * e)136 void SqlCompareView::showEvent(QShowEvent* e)
137 {
138     QTableWidget::showEvent(e);
139     updateSizes();
140 }
141