00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kompareconnectwidget.h"
00021
00022 #include <QtGui/QApplication>
00023 #include <QtGui/QPainter>
00024 #include <QtGui/QPixmap>
00025 #include <QtGui/QStyle>
00026 #include <QtCore/QTimer>
00027 #include <Q3PointArray>
00028 #include <QtGui/QPaintEvent>
00029 #include <Q3Frame>
00030 #include <QtGui/QMouseEvent>
00031
00032 #include <kdebug.h>
00033
00034 #include "viewsettings.h"
00035 #include "komparelistview.h"
00036 #include "komparesplitter.h"
00037
00038 #define ANTIALIASING_MARGIN 1
00039
00040 using namespace Diff2;
00041
00042 KompareConnectWidgetFrame::KompareConnectWidgetFrame( ViewSettings* settings,
00043 KompareSplitter* parent,
00044 const char* name ) :
00045 QSplitterHandle(Qt::Horizontal, (QSplitter *)parent),
00046 m_wid ( settings, this, name ),
00047 m_label ( " ", this ),
00048 m_layout ( this )
00049 {
00050 setObjectName( name );
00051 setSizePolicy ( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored) );
00052 m_wid.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored) );
00053 m_label.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
00054 m_label.setMargin(3);
00055 Q3Frame* bottomLine = new Q3Frame(this);
00056 bottomLine->setFrameShape(Q3Frame::HLine);
00057 bottomLine->setFrameShadow ( Q3Frame::Plain );
00058 bottomLine->setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
00059 bottomLine->setFixedHeight(1);
00060 m_layout.setSpacing(0);
00061 m_layout.setMargin(0);
00062 m_layout.addWidget(&m_label);
00063 m_layout.addWidget(bottomLine);
00064 m_layout.addWidget(&m_wid);
00065 }
00066
00067 KompareConnectWidgetFrame::~KompareConnectWidgetFrame()
00068 {
00069 }
00070
00071 QSize KompareConnectWidgetFrame::sizeHint() const
00072 {
00073 return QSize(50, style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
00074 }
00075
00076 #if 0
00077 static int kMouseOffset;
00078
00079 void KompareConnectWidgetFrame::mouseMoveEvent( QMouseEvent *e )
00080 {
00081
00082 if ( !(e->state()&Qt::LeftButton) )
00083 return;
00084
00085 QCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
00086 - kMouseOffset;
00087
00088 ((KompareSplitter*)s)->moveSplitter( pos, id() );
00089 }
00090
00091 void KompareConnectWidgetFrame::mousePressEvent( QMouseEvent *e )
00092 {
00093 if ( e->button() == Qt::LeftButton )
00094 kMouseOffset = s->pick( e->pos() );
00095 QSplitterHandle::mousePressEvent(e);
00096 }
00097
00098 void KompareConnectWidgetFrame::mouseReleaseEvent( QMouseEvent *e )
00099 {
00100 if ( !opaque() && e->button() == Qt::LeftButton ) {
00101 QCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
00102 - kMouseOffset;
00103 ((KompareSplitter*)s)->moveSplitter( pos, id() );
00104 }
00105 }
00106 #endif
00107
00108 KompareConnectWidget::KompareConnectWidget( ViewSettings* settings, QWidget* parent, const char* name )
00109 : QWidget(parent, name),
00110 m_settings( settings ),
00111 m_selectedModel( 0 ),
00112 m_selectedDifference( 0 )
00113 {
00114
00115 setBackgroundMode( Qt::NoBackground );
00116 setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
00117 setFocusProxy( parent->parentWidget() );
00118 }
00119
00120 KompareConnectWidget::~KompareConnectWidget()
00121 {
00122 }
00123
00124 void KompareConnectWidget::slotSetSelection( const DiffModel* model, const Difference* diff )
00125 {
00126 if( m_selectedModel == model && m_selectedDifference == diff )
00127 return;
00128
00129 if ( m_selectedModel == model && m_selectedDifference != diff )
00130 {
00131 m_selectedDifference = diff;
00132 slotDelayedRepaint();
00133 return;
00134 }
00135
00136 m_selectedModel = model;
00137 m_selectedDifference = diff;
00138
00139 slotDelayedRepaint();
00140 }
00141
00142 void KompareConnectWidget::slotDelayedRepaint()
00143 {
00144 QTimer::singleShot( 0, this, SLOT( repaint() ) );
00145 }
00146
00147 void KompareConnectWidget::slotSetSelection( const Difference* diff )
00148 {
00149 if ( m_selectedDifference == diff )
00150 return;
00151
00152 m_selectedDifference = diff;
00153
00154 slotDelayedRepaint();
00155 }
00156
00157 void KompareConnectWidget::paintEvent( QPaintEvent* )
00158 {
00159
00160
00161 QPixmap pixbuf(size());
00162 QPainter paint(&pixbuf);
00163 QPainter* p = &paint;
00164
00165 p->setRenderHint(QPainter::Antialiasing);
00166
00167 p->fillRect( 0, 0, pixbuf.width(), pixbuf.height(), QColor(Qt::white).dark(110) );
00168
00169 KompareSplitter* splitter = static_cast<KompareSplitter*>( parent()->parent() );
00170 int count = splitter->count();
00171 KompareListView *leftView = count >= 2 ? static_cast<KompareListViewFrame*>( splitter->widget(0) )->view() : 0;
00172 KompareListView *rightView = count >= 2 ? static_cast<KompareListViewFrame*>( splitter->widget(1) )->view() : 0;
00173
00174 if ( m_selectedModel && leftView && rightView )
00175 {
00176 int firstL = leftView->firstVisibleDifference();
00177 int firstR = rightView->firstVisibleDifference();
00178 int lastL = leftView->lastVisibleDifference();
00179 int lastR = rightView->lastVisibleDifference();
00180
00181 int first = firstL < 0 ? firstR : qMin( firstL, firstR );
00182 int last = lastL < 0 ? lastR : qMax( lastL, lastR );
00183
00184
00185
00186
00187 if ( first >= 0 && last >= 0 && first <= last )
00188 {
00189 const DifferenceList* differences = const_cast<DiffModel*>(m_selectedModel)->differences();
00190 DifferenceListConstIterator diffIt = differences->at( first );
00191 DifferenceListConstIterator dEnd = last + 1 < differences->size() ? differences->at( last + 1 ) : differences->end();
00192
00193 QRect leftRect, rightRect;
00194
00195 for ( int i = first; i <= last; ++diffIt, ++i )
00196 {
00197 Difference* diff = *diffIt;
00198 bool selected = ( diff == m_selectedDifference );
00199
00200 if ( QApplication::reverseLayout() )
00201 {
00202 leftRect = rightView->itemRect( i );
00203 rightRect = leftView->itemRect( i );
00204 }
00205 else
00206 {
00207 leftRect = leftView->itemRect( i );
00208 rightRect = rightView->itemRect( i );
00209 }
00210
00211 int tl = leftRect.top() + ANTIALIASING_MARGIN;
00212 int tr = rightRect.top() + ANTIALIASING_MARGIN;
00213 int bl = leftRect.bottom();
00214 int br = rightRect.bottom();
00215
00216
00217 tl = tl >= -32768 ? tl : -32768;
00218 tr = tr >= -32768 ? tr : -32768;
00219 bl = bl <= 32767 ? bl : 32767;
00220 br = br <= 32767 ? br : 32767;
00221
00222
00223 Q3PointArray topBezier = makeTopBezier( tl, tr );
00224 Q3PointArray bottomBezier = makeBottomBezier( bl, br );
00225
00226 QColor color = m_settings->colorForDifferenceType( diff->type(), selected, diff->applied() ).dark(110);
00227 p->setPen( color );
00228 p->setBrush( color );
00229 p->drawPolygon ( makeConnectPoly( topBezier, bottomBezier ) );
00230
00231 if ( selected )
00232 {
00233 p->setPen( color.dark(135) );
00234 p->drawPolyline( topBezier );
00235 p->drawPolyline( bottomBezier );
00236 }
00237 }
00238 }
00239 }
00240
00241
00242 bitBlt(this, 0, 0, &pixbuf);
00243 }
00244
00245 Q3PointArray KompareConnectWidget::makeTopBezier( int tl, int tr )
00246 {
00247 int l = 0;
00248 int r = width();
00249 int o = (int)((double)r*0.4);
00250 Q3PointArray controlPoints;
00251
00252 if ( tl != tr )
00253 {
00254 controlPoints.setPoints( 4, l,tl, o,tl, r-o,tr, r,tr );
00255 return controlPoints.cubicBezier();
00256 }
00257 else
00258 {
00259 controlPoints.setPoints( 2, l,tl, r,tr );
00260 return controlPoints;
00261 }
00262 }
00263
00264 Q3PointArray KompareConnectWidget::makeBottomBezier( int bl, int br )
00265 {
00266 int l = 0;
00267 int r = width();
00268 int o = (int)((double)r*0.4);
00269 Q3PointArray controlPoints;
00270
00271 if ( bl != br )
00272 {
00273 controlPoints.setPoints( 4, r,br, r-o,br, o,bl, l,bl );
00274 return controlPoints.cubicBezier();
00275 }
00276 else
00277 {
00278 controlPoints.setPoints( 2, r,br, l,bl );
00279 return controlPoints;
00280 }
00281 }
00282
00283 Q3PointArray KompareConnectWidget::makeConnectPoly( const Q3PointArray& topBezier, const Q3PointArray& bottomBezier )
00284 {
00285 Q3PointArray poly( topBezier.size() + bottomBezier.size() );
00286 for( int i = 0; i < topBezier.size(); i++ )
00287 poly.setPoint( i, topBezier.point( i ) );
00288 for( int i = 0; i < bottomBezier.size(); i++ )
00289 poly.setPoint( i + topBezier.size(), bottomBezier.point( i ) );
00290
00291 return poly;
00292 }
00293
00294 #include "kompareconnectwidget.moc"