File indexing completed on 2024-05-05 05:45:46
0001 /* 0002 SPDX-FileCopyrightText: 2001-2003 John Firebaugh <jfirebaugh@kde.org> 0003 SPDX-FileCopyrightText: 2001-2009 Otto Bruggeman <bruggie@gmail.com> 0004 SPDX-FileCopyrightText: 2004 Jeff Snyder <jeff@caffeinated.me.uk> 0005 SPDX-FileCopyrightText: 2007-2011 Kevin Kofler <kevin.kofler@chello.at> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "kompareconnectwidget.h" 0011 0012 #include <QApplication> 0013 #include <QPainter> 0014 #include <QPainterPath> 0015 #include <QPixmap> 0016 #include <QStyle> 0017 #include <QTimer> 0018 #include <QPaintEvent> 0019 #include <QFrame> 0020 #include <QMouseEvent> 0021 #include <QDebug> 0022 0023 #include "viewsettings.h" 0024 #include "komparelistview.h" 0025 #include "komparesplitter.h" 0026 0027 using namespace KompareDiff2; 0028 0029 KompareConnectWidgetFrame::KompareConnectWidgetFrame(ViewSettings* settings, 0030 KompareSplitter* parent, 0031 const char* name) : 0032 QSplitterHandle(Qt::Horizontal, (QSplitter*)parent), 0033 m_wid(settings, this, name), 0034 m_label(QStringLiteral(" "), this), // putting a space here because Qt 4 computes different size hints for empty labels 0035 m_layout(this) 0036 { 0037 setObjectName(QLatin1String(name)); 0038 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored)); 0039 m_wid.setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); 0040 m_label.setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed)); 0041 m_label.setMargin(3); 0042 QFrame* bottomLine = new QFrame(this); 0043 bottomLine->setFrameShape(QFrame::HLine); 0044 bottomLine->setFrameShadow(QFrame::Plain); 0045 bottomLine->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed)); 0046 bottomLine->setFixedHeight(1); 0047 m_layout.setSpacing(0); 0048 m_layout.setContentsMargins(0, 0, 0, 0); 0049 m_layout.addWidget(&m_label); 0050 m_layout.addWidget(bottomLine); 0051 m_layout.addWidget(&m_wid); 0052 } 0053 0054 KompareConnectWidgetFrame::~KompareConnectWidgetFrame() 0055 { 0056 } 0057 0058 QSize KompareConnectWidgetFrame::sizeHint() const 0059 { 0060 return QSize(50, style()->pixelMetric(QStyle::PM_ScrollBarExtent)); 0061 } 0062 0063 #if 0 0064 static int kMouseOffset; 0065 0066 void KompareConnectWidgetFrame::mouseMoveEvent(QMouseEvent* e) 0067 { 0068 0069 if (!(e->state()&Qt::LeftButton)) 0070 return; 0071 0072 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos())) 0073 - kMouseOffset; 0074 0075 ((KompareSplitter*)s)->moveSplitter(pos, id()); 0076 } 0077 0078 void KompareConnectWidgetFrame::mousePressEvent(QMouseEvent* e) 0079 { 0080 if (e->button() == Qt::LeftButton) 0081 kMouseOffset = s->pick(e->pos()); 0082 QSplitterHandle::mousePressEvent(e); 0083 } 0084 0085 void KompareConnectWidgetFrame::mouseReleaseEvent(QMouseEvent* e) 0086 { 0087 if (!opaque() && e->button() == Qt::LeftButton) { 0088 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos())) 0089 - kMouseOffset; 0090 ((KompareSplitter*)s)->moveSplitter(pos, id()); 0091 } 0092 } 0093 #endif 0094 0095 KompareConnectWidget::KompareConnectWidget(ViewSettings* settings, QWidget* parent, const char* name) 0096 : QWidget(parent), 0097 m_settings(settings), 0098 m_selectedModel(nullptr), 0099 m_selectedDifference(nullptr) 0100 { 0101 setObjectName(QLatin1String(name)); 0102 // connect( m_settings, SIGNAL( settingsChanged() ), this, SLOT( slotDelayedRepaint() ) ); 0103 setAttribute(Qt::WA_NoSystemBackground, true); 0104 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum)); 0105 setFocusProxy(parent->parentWidget()); 0106 } 0107 0108 KompareConnectWidget::~KompareConnectWidget() 0109 { 0110 m_settings = nullptr; 0111 m_selectedModel = nullptr; 0112 m_selectedDifference = nullptr; 0113 } 0114 0115 void KompareConnectWidget::slotSetSelection(const DiffModel* model, const Difference* diff) 0116 { 0117 if (m_selectedModel == model && m_selectedDifference == diff) 0118 return; 0119 0120 if (m_selectedModel == model && m_selectedDifference != diff) 0121 { 0122 m_selectedDifference = diff; 0123 slotDelayedRepaint(); 0124 return; 0125 } 0126 0127 m_selectedModel = model; 0128 m_selectedDifference = diff; 0129 0130 slotDelayedRepaint(); 0131 } 0132 0133 void KompareConnectWidget::slotDelayedRepaint() 0134 { 0135 QTimer::singleShot(0, this, static_cast<void(KompareConnectWidget::*)()>(&KompareConnectWidget::repaint)); 0136 } 0137 0138 void KompareConnectWidget::slotSetSelection(const Difference* diff) 0139 { 0140 if (m_selectedDifference == diff) 0141 return; 0142 0143 m_selectedDifference = diff; 0144 0145 slotDelayedRepaint(); 0146 } 0147 0148 void KompareConnectWidget::paintEvent(QPaintEvent* /* e */) 0149 { 0150 QPixmap pixbuf(size()); 0151 QPainter paint(&pixbuf); 0152 QPainter* p = &paint; 0153 0154 p->setRenderHint(QPainter::Antialiasing); 0155 p->fillRect(0, 0, pixbuf.width(), pixbuf.height(), palette().color(QPalette::Window)); 0156 p->translate(QPointF(0, 0.5)); 0157 0158 KompareSplitter* splitter = static_cast<KompareSplitter*>(parent()->parent()); 0159 int count = splitter->count(); 0160 KompareListView* leftView = count >= 2 ? static_cast<KompareListViewFrame*>(splitter->widget(0))->view() : nullptr; 0161 KompareListView* rightView = count >= 2 ? static_cast<KompareListViewFrame*>(splitter->widget(1))->view() : nullptr; 0162 0163 if (m_selectedModel && leftView && rightView) 0164 { 0165 int firstL = leftView->firstVisibleDifference(); 0166 int firstR = rightView->firstVisibleDifference(); 0167 int lastL = leftView->lastVisibleDifference(); 0168 int lastR = rightView->lastVisibleDifference(); 0169 0170 int first = firstL < 0 ? firstR : qMin(firstL, firstR); 0171 int last = lastL < 0 ? lastR : qMax(lastL, lastR); 0172 // qCDebug(KOMPAREPART) << " left: " << firstL << " - " << lastL ; 0173 // qCDebug(KOMPAREPART) << " right: " << firstR << " - " << lastR ; 0174 // qCDebug(KOMPAREPART) << " drawing: " << first << " - " << last ; 0175 if (first >= 0 && last >= 0 && first <= last) 0176 { 0177 const DifferenceList* differences = const_cast<DiffModel*>(m_selectedModel)->differences(); 0178 QRect leftRect, rightRect; 0179 for (int i = first; i <= last; ++i) 0180 { 0181 Difference* diff = differences->at(i); 0182 bool selected = (diff == m_selectedDifference); 0183 0184 if (QApplication::isRightToLeft()) 0185 { 0186 leftRect = rightView->itemRect(i); 0187 rightRect = leftView->itemRect(i); 0188 } 0189 else 0190 { 0191 leftRect = leftView->itemRect(i); 0192 rightRect = rightView->itemRect(i); 0193 } 0194 0195 int tl = leftRect.top(); 0196 int tr = rightRect.top(); 0197 int bl = leftRect.bottom(); 0198 int br = rightRect.bottom(); 0199 0200 // Bah, stupid 16-bit signed shorts in that crappy X stuff... 0201 tl = tl >= -32768 ? tl : -32768; 0202 tr = tr >= -32768 ? tr : -32768; 0203 bl = bl <= 32767 ? bl : 32767; 0204 br = br <= 32767 ? br : 32767; 0205 0206 QPainterPath topBezier = makeBezier(tl, tr); 0207 QPainterPath bottomBezier = makeBezier(bl, br); 0208 0209 QPainterPath poly(topBezier); 0210 poly.connectPath(bottomBezier.toReversed()); 0211 poly.closeSubpath(); 0212 0213 QColor bg = m_settings->colorForDifferenceType(diff->type(), selected, diff->applied()); 0214 p->setPen(bg); 0215 p->setBrush(bg); 0216 p->drawPath(poly); 0217 0218 if (selected) 0219 { 0220 p->setPen(bg.darker(135)); 0221 p->setBrush(Qt::NoBrush); 0222 p->drawPath(topBezier); 0223 p->drawPath(bottomBezier.toReversed()); 0224 } 0225 } 0226 } 0227 } 0228 0229 // p->flush(); 0230 QPainter widgetPainter(this); 0231 widgetPainter.drawImage(0, 0, pixbuf.toImage()); 0232 } 0233 0234 QPainterPath KompareConnectWidget::makeBezier(int leftHeight, int rightHeight) const 0235 { 0236 int r = width(); 0237 int o = (int)((double)r * 0.4); // 40% of width 0238 0239 QPainterPath p(QPointF(0, leftHeight)); 0240 if (leftHeight == rightHeight) { 0241 p.lineTo(QPointF(r, rightHeight)); 0242 } else { 0243 p.cubicTo(QPointF(o, leftHeight), QPointF(r - o, rightHeight), QPointF(r, rightHeight)); 0244 } 0245 return p; 0246 } 0247 0248 #include "moc_kompareconnectwidget.cpp"