joachim99@8
|
1 /***************************************************************************
|
joachim99@8
|
2 difftextwindow.cpp - description
|
joachim99@8
|
3 -------------------
|
joachim99@8
|
4 begin : Mon Apr 8 2002
|
joachim99@58
|
5 copyright : (C) 2002-2004 by Joachim Eibl
|
joachim99@8
|
6 email : joachim.eibl@gmx.de
|
joachim99@8
|
7 ***************************************************************************/
|
joachim99@8
|
8
|
joachim99@8
|
9 /***************************************************************************
|
joachim99@8
|
10 * *
|
joachim99@8
|
11 * This program is free software; you can redistribute it and/or modify *
|
joachim99@8
|
12 * it under the terms of the GNU General Public License as published by *
|
joachim99@8
|
13 * the Free Software Foundation; either version 2 of the License, or *
|
joachim99@8
|
14 * (at your option) any later version. *
|
joachim99@8
|
15 * *
|
joachim99@8
|
16 ***************************************************************************/
|
joachim99@8
|
17
|
joachim99@8
|
18 #include <iostream>
|
joachim99@8
|
19 #include "diff.h"
|
joachim99@8
|
20 #include "merger.h"
|
joachim99@8
|
21 #include <qpainter.h>
|
joachim99@8
|
22 #include <assert.h>
|
joachim99@8
|
23 #include <qpixmap.h>
|
joachim99@8
|
24 #include <qstatusbar.h>
|
joachim99@8
|
25 #include <qapplication.h>
|
joachim99@8
|
26 #include <qtooltip.h>
|
joachim99@8
|
27 #include <qfont.h>
|
joachim99@8
|
28 #include <optiondialog.h>
|
joachim99@8
|
29 #include <math.h>
|
joachim99@8
|
30 #include <qdragobject.h>
|
joachim99@51
|
31 #include <klocale.h>
|
joachim99@8
|
32
|
joachim99@53
|
33 #undef leftInfoWidth
|
joachim99@8
|
34 #define leftInfoWidth (4+m_lineNumberWidth) // Nr of information columns on left side
|
joachim99@8
|
35
|
joachim99@8
|
36
|
joachim99@8
|
37 DiffTextWindow::DiffTextWindow(
|
joachim99@8
|
38 QWidget* pParent,
|
joachim99@8
|
39 QStatusBar* pStatusBar,
|
joachim99@8
|
40 OptionDialog* pOptionDialog
|
joachim99@8
|
41 )
|
joachim99@8
|
42 : QWidget(pParent, 0, WRepaintNoErase)
|
joachim99@8
|
43 {
|
joachim99@8
|
44 setFocusPolicy( QWidget::ClickFocus );
|
joachim99@8
|
45 setAcceptDrops( true );
|
joachim99@8
|
46
|
joachim99@8
|
47 m_pOptionDialog = pOptionDialog;
|
joachim99@8
|
48 init( 0, 0, 0, 0, 0, false );
|
joachim99@8
|
49
|
joachim99@8
|
50 setBackgroundMode( PaletteBase );
|
joachim99@8
|
51 setMinimumSize(QSize(20,20));
|
joachim99@8
|
52
|
joachim99@8
|
53 m_pStatusBar = pStatusBar;
|
joachim99@8
|
54 m_bPaintingAllowed = true;
|
joachim99@27
|
55
|
joachim99@27
|
56 setFont(m_pOptionDialog->m_font);
|
joachim99@8
|
57 }
|
joachim99@8
|
58
|
joachim99@8
|
59
|
joachim99@8
|
60 void DiffTextWindow::init(
|
joachim99@8
|
61 const QString& filename,
|
joachim99@58
|
62 const LineData* pLineData,
|
joachim99@8
|
63 int size,
|
joachim99@8
|
64 const Diff3LineVector* pDiff3LineVector,
|
joachim99@8
|
65 int winIdx,
|
joachim99@8
|
66 bool bTriple
|
joachim99@8
|
67 )
|
joachim99@8
|
68 {
|
joachim99@8
|
69 m_filename = filename;
|
joachim99@8
|
70 m_pLineData = pLineData;
|
joachim99@8
|
71 m_size = size;
|
joachim99@8
|
72 m_pDiff3LineVector = pDiff3LineVector;
|
joachim99@8
|
73 m_winIdx = winIdx;
|
joachim99@8
|
74
|
joachim99@8
|
75 m_firstLine = 0;
|
joachim99@8
|
76 m_oldFirstLine = -1;
|
joachim99@8
|
77 m_firstColumn = 0;
|
joachim99@8
|
78 m_oldFirstColumn = -1;
|
joachim99@8
|
79 m_bTriple = bTriple;
|
joachim99@8
|
80 m_scrollDeltaX=0;
|
joachim99@8
|
81 m_scrollDeltaY=0;
|
joachim99@8
|
82 m_bMyUpdate = false;
|
joachim99@8
|
83 m_fastSelectorLine1 = 0;
|
joachim99@8
|
84 m_fastSelectorNofLines = 0;
|
joachim99@8
|
85 m_lineNumberWidth = 0;
|
joachim99@8
|
86 selection.reset();
|
joachim99@8
|
87 selection.oldFirstLine = -1; // reset is not enough here.
|
joachim99@8
|
88 selection.oldLastLine = -1;
|
joachim99@8
|
89 selection.lastLine = -1;
|
joachim99@8
|
90
|
joachim99@8
|
91 QToolTip::remove(this);
|
joachim99@8
|
92 QToolTip::add( this, QRect( 0,0, 1024, fontMetrics().height() ), m_filename );
|
joachim99@8
|
93 update();
|
joachim99@8
|
94 }
|
joachim99@8
|
95
|
joachim99@8
|
96 void DiffTextWindow::setPaintingAllowed( bool bAllowPainting )
|
joachim99@8
|
97 {
|
joachim99@8
|
98 if (m_bPaintingAllowed != bAllowPainting)
|
joachim99@8
|
99 {
|
joachim99@8
|
100 m_bPaintingAllowed = bAllowPainting;
|
joachim99@8
|
101 if ( m_bPaintingAllowed ) update();
|
joachim99@8
|
102 }
|
joachim99@8
|
103 }
|
joachim99@8
|
104
|
joachim99@8
|
105 void DiffTextWindow::dragEnterEvent( QDragEnterEvent* e )
|
joachim99@8
|
106 {
|
joachim99@8
|
107 e->accept( QUriDrag::canDecode(e) || QTextDrag::canDecode(e) );
|
joachim99@8
|
108 // Note that the corresponding drop is handled in KDiff3App::eventFilter().
|
joachim99@8
|
109 }
|
joachim99@8
|
110
|
joachim99@8
|
111 void DiffTextWindow::setFirstLine(int firstLine)
|
joachim99@8
|
112 {
|
joachim99@8
|
113 m_firstLine = max2(0,firstLine);
|
joachim99@8
|
114 myUpdate(0); // Immediately
|
joachim99@8
|
115 }
|
joachim99@8
|
116
|
joachim99@8
|
117 void DiffTextWindow::setFirstColumn(int firstCol)
|
joachim99@8
|
118 {
|
joachim99@8
|
119 m_firstColumn = max2(0,firstCol);
|
joachim99@8
|
120 myUpdate(0); // Immediately
|
joachim99@8
|
121 }
|
joachim99@8
|
122
|
joachim99@8
|
123 int DiffTextWindow::getNofColumns()
|
joachim99@8
|
124 {
|
joachim99@8
|
125 int nofColumns = 0;
|
joachim99@8
|
126 for( int i = 0; i< m_size; ++i )
|
joachim99@8
|
127 {
|
joachim99@8
|
128 if ( m_pLineData[i].width() > nofColumns )
|
joachim99@8
|
129 nofColumns = m_pLineData[i].width();
|
joachim99@8
|
130 }
|
joachim99@8
|
131 return nofColumns;
|
joachim99@8
|
132 }
|
joachim99@8
|
133
|
joachim99@8
|
134 int DiffTextWindow::getNofLines()
|
joachim99@8
|
135 {
|
joachim99@8
|
136 return m_pDiff3LineVector->size();
|
joachim99@8
|
137 }
|
joachim99@8
|
138
|
joachim99@8
|
139 /** Returns a line number where the linerange [line, line+nofLines] can
|
joachim99@8
|
140 be displayed best. If it fits into the currently visible range then
|
joachim99@8
|
141 the returned value is the current firstLine.
|
joachim99@8
|
142 */
|
joachim99@8
|
143 int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines )
|
joachim99@8
|
144 {
|
joachim99@8
|
145 int newFirstLine = firstLine;
|
joachim99@8
|
146 if ( line < firstLine || line + nofLines + 2 > firstLine + visibleLines )
|
joachim99@8
|
147 {
|
joachim99@8
|
148 if ( nofLines > visibleLines || nofLines <= ( 2*visibleLines / 3 - 1) )
|
joachim99@8
|
149 newFirstLine = line - visibleLines/3;
|
joachim99@8
|
150 else
|
joachim99@8
|
151 newFirstLine = line - (visibleLines - nofLines);
|
joachim99@8
|
152 }
|
joachim99@8
|
153
|
joachim99@8
|
154 return newFirstLine;
|
joachim99@8
|
155 }
|
joachim99@8
|
156
|
joachim99@8
|
157
|
joachim99@8
|
158 void DiffTextWindow::setFastSelectorRange( int line1, int nofLines )
|
joachim99@8
|
159 {
|
joachim99@8
|
160 m_fastSelectorLine1 = line1;
|
joachim99@8
|
161 m_fastSelectorNofLines = nofLines;
|
joachim99@8
|
162
|
joachim99@8
|
163 if ( isVisible() )
|
joachim99@8
|
164 {
|
joachim99@8
|
165 int newFirstLine = getBestFirstLine( line1, nofLines, m_firstLine, getNofVisibleLines() );
|
joachim99@8
|
166 if ( newFirstLine != m_firstLine )
|
joachim99@8
|
167 {
|
joachim99@8
|
168 scroll( 0, newFirstLine - m_firstLine );
|
joachim99@8
|
169 }
|
joachim99@8
|
170
|
joachim99@8
|
171 update();
|
joachim99@8
|
172 }
|
joachim99@8
|
173 }
|
joachim99@8
|
174
|
joachim99@8
|
175
|
joachim99@8
|
176 static void showStatusLine(int line, int winIdx, const QString& filename, const Diff3LineVector& d3lv, QStatusBar* sb)
|
joachim99@8
|
177 {
|
joachim99@8
|
178 int l=0;
|
joachim99@8
|
179 const Diff3Line* pD3l = d3lv[line];
|
joachim99@8
|
180 if(line >= 0 && line<(int)d3lv.size() && pD3l != 0 )
|
joachim99@8
|
181 {
|
joachim99@8
|
182 if ( winIdx==1 ) l = pD3l->lineA;
|
joachim99@8
|
183 else if ( winIdx==2 ) l = pD3l->lineB;
|
joachim99@8
|
184 else if ( winIdx==3 ) l = pD3l->lineC;
|
joachim99@8
|
185 else assert(false);
|
joachim99@8
|
186
|
joachim99@8
|
187 QString s;
|
joachim99@8
|
188 if ( l!=-1 )
|
joachim99@8
|
189 s.sprintf("File %s: Line %d", filename.ascii(), l+1 );
|
joachim99@8
|
190 else
|
joachim99@8
|
191 s.sprintf("File %s: Line not available", filename.ascii() );
|
joachim99@8
|
192 if (sb!=0) sb->message(s);
|
joachim99@8
|
193 }
|
joachim99@8
|
194 }
|
joachim99@8
|
195
|
joachim99@8
|
196
|
joachim99@8
|
197 void DiffTextWindow::mousePressEvent ( QMouseEvent* e )
|
joachim99@8
|
198 {
|
joachim99@8
|
199 if ( e->button() == LeftButton )
|
joachim99@8
|
200 {
|
joachim99@8
|
201 int line;
|
joachim99@8
|
202 int pos;
|
joachim99@8
|
203 convertToLinePos( e->x(), e->y(), line, pos );
|
joachim99@8
|
204 if ( pos < m_firstColumn )
|
joachim99@8
|
205 {
|
joachim99@8
|
206 emit setFastSelectorLine( line );
|
joachim99@8
|
207 selection.firstLine = -1; // Disable current selection
|
joachim99@8
|
208 }
|
joachim99@8
|
209 else
|
joachim99@8
|
210 { // Selection
|
joachim99@8
|
211 resetSelection();
|
joachim99@8
|
212 selection.start( line, pos );
|
joachim99@8
|
213 selection.end( line, pos );
|
joachim99@8
|
214
|
joachim99@8
|
215 showStatusLine( line, m_winIdx, m_filename, *m_pDiff3LineVector, m_pStatusBar );
|
joachim99@8
|
216 }
|
joachim99@8
|
217 }
|
joachim99@8
|
218 }
|
joachim99@8
|
219
|
joachim99@8
|
220 bool isCTokenChar( char c )
|
joachim99@8
|
221 {
|
joachim99@8
|
222 return (c=='_') ||
|
joachim99@8
|
223 ( c>='A' && c<='Z' ) || ( c>='a' && c<='z' ) ||
|
joachim99@8
|
224 (c>='0' && c<='9');
|
joachim99@8
|
225 }
|
joachim99@8
|
226
|
joachim99@8
|
227 /// Calculate where a token starts and ends, given the x-position on screen.
|
joachim99@8
|
228 void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 )
|
joachim99@8
|
229 {
|
joachim99@8
|
230 // Cursor conversions that consider g_tabSize
|
joachim99@8
|
231 int pos = convertToPosInText( p, size, max2( 0, posOnScreen ) );
|
joachim99@8
|
232 if ( pos>=size )
|
joachim99@8
|
233 {
|
joachim99@8
|
234 pos1=size;
|
joachim99@8
|
235 pos2=size;
|
joachim99@8
|
236 return;
|
joachim99@8
|
237 }
|
joachim99@8
|
238
|
joachim99@8
|
239 pos1 = pos;
|
joachim99@8
|
240 pos2 = pos+1;
|
joachim99@8
|
241
|
joachim99@8
|
242 if( isCTokenChar( p[pos1] ) )
|
joachim99@8
|
243 {
|
joachim99@8
|
244 while( pos1>=0 && isCTokenChar( p[pos1] ) )
|
joachim99@8
|
245 --pos1;
|
joachim99@8
|
246 ++pos1;
|
joachim99@8
|
247
|
joachim99@8
|
248 while( pos2<size && isCTokenChar( p[pos2] ) )
|
joachim99@8
|
249 ++pos2;
|
joachim99@8
|
250 }
|
joachim99@8
|
251 }
|
joachim99@8
|
252
|
joachim99@8
|
253 void DiffTextWindow::mouseDoubleClickEvent( QMouseEvent* e )
|
joachim99@8
|
254 {
|
joachim99@8
|
255 if ( e->button() == LeftButton )
|
joachim99@8
|
256 {
|
joachim99@8
|
257 int line;
|
joachim99@8
|
258 int pos;
|
joachim99@8
|
259 convertToLinePos( e->x(), e->y(), line, pos );
|
joachim99@8
|
260
|
joachim99@8
|
261 // Get the string data of the current line
|
joachim99@8
|
262 QCString s = getString( line );
|
joachim99@8
|
263
|
joachim99@8
|
264 if ( ! s.isEmpty() )
|
joachim99@8
|
265 {
|
joachim99@8
|
266 int pos1, pos2;
|
joachim99@8
|
267 calcTokenPos( s, s.length(), pos, pos1, pos2 );
|
joachim99@8
|
268
|
joachim99@8
|
269 resetSelection();
|
joachim99@8
|
270 selection.start( line, convertToPosOnScreen( s, pos1 ) );
|
joachim99@8
|
271 selection.end( line, convertToPosOnScreen( s, pos2 ) );
|
joachim99@8
|
272 update();
|
joachim99@8
|
273 // emit selectionEnd() happens in the mouseReleaseEvent.
|
joachim99@8
|
274 showStatusLine( line, m_winIdx, m_filename, *m_pDiff3LineVector, m_pStatusBar );
|
joachim99@8
|
275 }
|
joachim99@8
|
276 }
|
joachim99@8
|
277 }
|
joachim99@8
|
278
|
joachim99@8
|
279 void DiffTextWindow::mouseReleaseEvent ( QMouseEvent * /*e*/ )
|
joachim99@8
|
280 {
|
joachim99@8
|
281 //if ( e->button() == LeftButton )
|
joachim99@8
|
282 {
|
joachim99@8
|
283 killTimers();
|
joachim99@8
|
284 if (selection.firstLine != -1 )
|
joachim99@8
|
285 {
|
joachim99@8
|
286 emit selectionEnd();
|
joachim99@8
|
287 }
|
joachim99@8
|
288 }
|
joachim99@8
|
289 m_scrollDeltaX=0;
|
joachim99@8
|
290 m_scrollDeltaY=0;
|
joachim99@8
|
291 }
|
joachim99@8
|
292
|
joachim99@8
|
293 void DiffTextWindow::mouseMoveEvent ( QMouseEvent * e )
|
joachim99@8
|
294 {
|
joachim99@8
|
295 int line;
|
joachim99@8
|
296 int pos;
|
joachim99@8
|
297 convertToLinePos( e->x(), e->y(), line, pos );
|
joachim99@8
|
298 if (selection.firstLine != -1 )
|
joachim99@8
|
299 {
|
joachim99@8
|
300 selection.end( line, pos );
|
joachim99@8
|
301 myUpdate(0);
|
joachim99@8
|
302
|
joachim99@8
|
303 showStatusLine( line, m_winIdx, m_filename, *m_pDiff3LineVector, m_pStatusBar );
|
joachim99@8
|
304
|
joachim99@8
|
305 // Scroll because mouse moved out of the window
|
joachim99@8
|
306 const QFontMetrics& fm = fontMetrics();
|
joachim99@8
|
307 int fontHeight = fm.height();
|
joachim99@8
|
308 int fontWidth = fm.width('W');
|
joachim99@8
|
309 int topLineYOffset = fontHeight + 3;
|
joachim99@8
|
310 int deltaX=0;
|
joachim99@8
|
311 int deltaY=0;
|
joachim99@8
|
312 if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1;
|
joachim99@8
|
313 if ( e->x() > width() ) deltaX=+1;
|
joachim99@8
|
314 if ( e->y() < topLineYOffset ) deltaY=-1;
|
joachim99@8
|
315 if ( e->y() > height() ) deltaY=+1;
|
joachim99@8
|
316 m_scrollDeltaX = deltaX;
|
joachim99@8
|
317 m_scrollDeltaY = deltaY;
|
joachim99@8
|
318 if ( deltaX != 0 || deltaY!= 0)
|
joachim99@8
|
319 {
|
joachim99@8
|
320 emit scroll( deltaX, deltaY );
|
joachim99@8
|
321 }
|
joachim99@8
|
322 }
|
joachim99@8
|
323 }
|
joachim99@8
|
324
|
joachim99@8
|
325
|
joachim99@8
|
326 void DiffTextWindow::myUpdate(int afterMilliSecs)
|
joachim99@8
|
327 {
|
joachim99@8
|
328 killTimers();
|
joachim99@8
|
329 m_bMyUpdate = true;
|
joachim99@8
|
330 startTimer( afterMilliSecs );
|
joachim99@8
|
331 }
|
joachim99@8
|
332
|
joachim99@8
|
333 void DiffTextWindow::timerEvent(QTimerEvent*)
|
joachim99@8
|
334 {
|
joachim99@8
|
335 killTimers();
|
joachim99@8
|
336
|
joachim99@8
|
337 if ( m_bMyUpdate )
|
joachim99@8
|
338 {
|
joachim99@8
|
339 paintEvent( 0 );
|
joachim99@8
|
340 m_bMyUpdate = false;
|
joachim99@8
|
341 }
|
joachim99@8
|
342
|
joachim99@8
|
343 if ( m_scrollDeltaX != 0 || m_scrollDeltaY != 0 )
|
joachim99@8
|
344 {
|
joachim99@8
|
345 selection.end( selection.lastLine + m_scrollDeltaY, selection.lastPos + m_scrollDeltaX );
|
joachim99@8
|
346 emit scroll( m_scrollDeltaX, m_scrollDeltaY );
|
joachim99@8
|
347 killTimers();
|
joachim99@8
|
348 startTimer(50);
|
joachim99@8
|
349 }
|
joachim99@8
|
350 }
|
joachim99@8
|
351
|
joachim99@8
|
352 void DiffTextWindow::resetSelection()
|
joachim99@8
|
353 {
|
joachim99@8
|
354 selection.reset();
|
joachim99@8
|
355 update();
|
joachim99@8
|
356 }
|
joachim99@8
|
357
|
joachim99@8
|
358 void DiffTextWindow::convertToLinePos( int x, int y, int& line, int& pos )
|
joachim99@8
|
359 {
|
joachim99@8
|
360 const QFontMetrics& fm = fontMetrics();
|
joachim99@8
|
361 int fontHeight = fm.height();
|
joachim99@8
|
362 int fontWidth = fm.width('W');
|
joachim99@8
|
363 int xOffset = (leftInfoWidth-m_firstColumn)*fontWidth;
|
joachim99@8
|
364
|
joachim99@8
|
365 int topLineYOffset = fontHeight + 3;
|
joachim99@8
|
366
|
joachim99@8
|
367 int yOffset = topLineYOffset - m_firstLine * fontHeight;
|
joachim99@8
|
368
|
joachim99@8
|
369 line = ( y - yOffset ) / fontHeight;
|
joachim99@8
|
370 pos = ( x - xOffset ) / fontWidth;
|
joachim99@8
|
371 }
|
joachim99@8
|
372
|
joachim99@8
|
373 int Selection::firstPosInLine(int l)
|
joachim99@8
|
374 {
|
joachim99@8
|
375 assert( firstLine != -1 );
|
joachim99@8
|
376
|
joachim99@8
|
377 int l1 = firstLine;
|
joachim99@8
|
378 int l2 = lastLine;
|
joachim99@8
|
379 int p1 = firstPos;
|
joachim99@8
|
380 int p2 = lastPos;
|
joachim99@8
|
381 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
|
joachim99@8
|
382 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
|
joachim99@8
|
383
|
joachim99@8
|
384 if ( l==l1 )
|
joachim99@8
|
385 return p1;
|
joachim99@8
|
386 return 0;
|
joachim99@8
|
387 }
|
joachim99@8
|
388
|
joachim99@8
|
389 int Selection::lastPosInLine(int l)
|
joachim99@8
|
390 {
|
joachim99@8
|
391 assert( firstLine != -1 );
|
joachim99@8
|
392
|
joachim99@8
|
393 int l1 = firstLine;
|
joachim99@8
|
394 int l2 = lastLine;
|
joachim99@8
|
395 int p1 = firstPos;
|
joachim99@8
|
396 int p2 = lastPos;
|
joachim99@8
|
397
|
joachim99@8
|
398 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
|
joachim99@8
|
399 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
|
joachim99@8
|
400
|
joachim99@8
|
401 if ( l==l2 )
|
joachim99@8
|
402 return p2;
|
joachim99@8
|
403 return INT_MAX;
|
joachim99@8
|
404 }
|
joachim99@8
|
405
|
joachim99@8
|
406 bool Selection::within( int l, int p )
|
joachim99@8
|
407 {
|
joachim99@8
|
408 if ( firstLine == -1 ) return false;
|
joachim99@8
|
409 int l1 = firstLine;
|
joachim99@8
|
410 int l2 = lastLine;
|
joachim99@8
|
411 int p1 = firstPos;
|
joachim99@8
|
412 int p2 = lastPos;
|
joachim99@8
|
413 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
|
joachim99@8
|
414 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
|
joachim99@8
|
415 if( l1 <= l && l <= l2 )
|
joachim99@8
|
416 {
|
joachim99@8
|
417 if ( l1==l2 )
|
joachim99@8
|
418 return p>=p1 && p<p2;
|
joachim99@8
|
419 if ( l==l1 )
|
joachim99@8
|
420 return p>=p1;
|
joachim99@8
|
421 if ( l==l2 )
|
joachim99@8
|
422 return p<p2;
|
joachim99@8
|
423 return true;
|
joachim99@8
|
424 }
|
joachim99@8
|
425 return false;
|
joachim99@8
|
426 }
|
joachim99@8
|
427
|
joachim99@8
|
428 bool Selection::lineWithin( int l )
|
joachim99@8
|
429 {
|
joachim99@8
|
430 if ( firstLine == -1 ) return false;
|
joachim99@8
|
431 int l1 = firstLine;
|
joachim99@8
|
432 int l2 = lastLine;
|
joachim99@8
|
433
|
joachim99@8
|
434 if ( l1>l2 ){ std::swap(l1,l2); }
|
joachim99@8
|
435
|
joachim99@8
|
436 return ( l1 <= l && l <= l2 );
|
joachim99@8
|
437 }
|
joachim99@8
|
438
|
joachim99@8
|
439 void DiffTextWindow::writeLine(
|
joachim99@8
|
440 QPainter& p,
|
joachim99@8
|
441 const LineData* pld,
|
joachim99@8
|
442 const DiffList* pLineDiff1,
|
joachim99@8
|
443 const DiffList* pLineDiff2,
|
joachim99@8
|
444 int line,
|
joachim99@8
|
445 int whatChanged,
|
joachim99@8
|
446 int whatChanged2,
|
joachim99@8
|
447 int srcLineNr
|
joachim99@8
|
448 )
|
joachim99@8
|
449 {
|
joachim99@8
|
450 QFont normalFont = font();
|
joachim99@8
|
451 QFont diffFont = normalFont;
|
joachim99@8
|
452 diffFont.setItalic( m_pOptionDialog->m_bItalicForDeltas );
|
joachim99@8
|
453 const QFontMetrics& fm = fontMetrics();
|
joachim99@8
|
454 int fontHeight = fm.height();
|
joachim99@8
|
455 int fontAscent = fm.ascent();
|
joachim99@8
|
456 int fontDescent = fm.descent();
|
joachim99@8
|
457 int fontWidth = fm.width('W');
|
joachim99@8
|
458 int topLineYOffset = fontHeight + 3;
|
joachim99@8
|
459
|
joachim99@8
|
460 int xOffset = (leftInfoWidth - m_firstColumn)*fontWidth;
|
joachim99@8
|
461 int yOffset = (line-m_firstLine) * fontHeight + topLineYOffset;
|
joachim99@8
|
462
|
joachim99@8
|
463 QRect lineRect( 0, yOffset, width(), fontHeight );
|
joachim99@8
|
464 if ( ! m_invalidRect.intersects( lineRect ) )
|
joachim99@8
|
465 return;
|
joachim99@8
|
466
|
joachim99@8
|
467 int fastSelectorLine2 = m_fastSelectorLine1+m_fastSelectorNofLines - 1;
|
joachim99@8
|
468 bool bFastSelectionRange = (line>=m_fastSelectorLine1 && line<= fastSelectorLine2 );
|
joachim99@8
|
469 QColor bgColor = m_pOptionDialog->m_bgColor;
|
joachim99@8
|
470 QColor diffBgColor = m_pOptionDialog->m_diffBgColor;
|
joachim99@8
|
471
|
joachim99@8
|
472 if ( bFastSelectionRange )
|
joachim99@8
|
473 {
|
joachim99@8
|
474 bgColor = m_pOptionDialog->m_currentRangeBgColor;
|
joachim99@8
|
475 diffBgColor = m_pOptionDialog->m_currentRangeDiffBgColor;
|
joachim99@8
|
476 }
|
joachim99@8
|
477
|
joachim99@8
|
478 // QRect winRect = rect(); //p.window();
|
joachim99@8
|
479 if ( yOffset+fontHeight<0 || height() + fontHeight < yOffset )
|
joachim99@8
|
480 return;
|
joachim99@8
|
481
|
joachim99@8
|
482 int changed = whatChanged;
|
joachim99@8
|
483 if ( pLineDiff1 != 0 ) changed |= 1;
|
joachim99@8
|
484 if ( pLineDiff2 != 0 ) changed |= 2;
|
joachim99@8
|
485
|
joachim99@8
|
486 QColor c = m_pOptionDialog->m_fgColor;
|
joachim99@8
|
487 if ( changed == 2 ) {
|
joachim99@8
|
488 c = m_cDiff2;
|
joachim99@8
|
489 } else if ( changed == 1 ) {
|
joachim99@8
|
490 c = m_cDiff1;
|
joachim99@8
|
491 } else if ( changed == 3 ) {
|
joachim99@8
|
492 c = m_cDiffBoth;
|
joachim99@8
|
493 }
|
joachim99@8
|
494
|
joachim99@8
|
495 p.fillRect( leftInfoWidth*fontWidth, yOffset, width(), fontHeight, bgColor );
|
joachim99@51
|
496
|
joachim99@8
|
497 if (pld!=0)
|
joachim99@8
|
498 {
|
joachim99@8
|
499 // First calculate the "changed" information for each character.
|
joachim99@8
|
500 int i=0;
|
joachim99@8
|
501 std::vector<UINT8> charChanged( pld->size );
|
joachim99@8
|
502 if ( pLineDiff1!=0 || pLineDiff2 != 0 )
|
joachim99@8
|
503 {
|
joachim99@8
|
504 Merger merger( pLineDiff1, pLineDiff2 );
|
joachim99@8
|
505 while( ! merger.isEndReached() && i<pld->size )
|
joachim99@8
|
506 {
|
joachim99@8
|
507 if ( i < pld->size )
|
joachim99@8
|
508 {
|
joachim99@8
|
509 charChanged[i] = merger.whatChanged();
|
joachim99@8
|
510 ++i;
|
joachim99@8
|
511 }
|
joachim99@8
|
512 merger.next();
|
joachim99@8
|
513 }
|
joachim99@8
|
514 }
|
joachim99@8
|
515
|
joachim99@8
|
516 QCString s=" ";
|
joachim99@8
|
517 // Convert tabs
|
joachim99@8
|
518 int outPos = 0;
|
joachim99@8
|
519 for( i=0; i<pld->size; ++i )
|
joachim99@8
|
520 {
|
joachim99@8
|
521 int spaces = 1;
|
joachim99@8
|
522
|
joachim99@8
|
523 if ( pld->pLine[i]=='\t' )
|
joachim99@8
|
524 {
|
joachim99@8
|
525 spaces = tabber( outPos, g_tabSize );
|
joachim99@8
|
526 s[0] = ' ';
|
joachim99@8
|
527 }
|
joachim99@8
|
528 else
|
joachim99@8
|
529 {
|
joachim99@8
|
530 s[0] = pld->pLine[i];
|
joachim99@8
|
531 }
|
joachim99@8
|
532
|
joachim99@8
|
533 QColor c = m_pOptionDialog->m_fgColor;
|
joachim99@8
|
534 int cchanged = charChanged[i] | whatChanged;
|
joachim99@8
|
535
|
joachim99@8
|
536 if ( cchanged == 2 ) {
|
joachim99@8
|
537 c = m_cDiff2;
|
joachim99@8
|
538 } else if ( cchanged == 1 ) {
|
joachim99@8
|
539 c = m_cDiff1;
|
joachim99@8
|
540 } else if ( cchanged == 3 ) {
|
joachim99@8
|
541 c = m_cDiffBoth;
|
joachim99@8
|
542 }
|
joachim99@8
|
543
|
joachim99@51
|
544 if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 && !m_pOptionDialog->m_bShowWhiteSpace )
|
joachim99@51
|
545 {
|
joachim99@51
|
546 // The user doesn't want to see highlighted white space.
|
joachim99@51
|
547 c = m_pOptionDialog->m_fgColor;
|
joachim99@51
|
548 }
|
joachim99@51
|
549
|
joachim99@8
|
550 QRect outRect( xOffset + fontWidth*outPos, yOffset, fontWidth*spaces, fontHeight );
|
joachim99@8
|
551 if ( m_invalidRect.intersects( outRect ) )
|
joachim99@8
|
552 {
|
joachim99@8
|
553 if( !selection.within( line, outPos ) )
|
joachim99@8
|
554 {
|
joachim99@51
|
555
|
joachim99@8
|
556 if( c!=m_pOptionDialog->m_fgColor )
|
joachim99@8
|
557 {
|
joachim99@8
|
558 QColor lightc = diffBgColor;
|
joachim99@8
|
559 p.fillRect( xOffset + fontWidth*outPos, yOffset,
|
joachim99@8
|
560 fontWidth*spaces, fontHeight, lightc );
|
joachim99@8
|
561 p.setFont(diffFont);
|
joachim99@8
|
562 }
|
joachim99@8
|
563
|
joachim99@8
|
564 p.setPen( c );
|
joachim99@8
|
565 if ( s[0]==' ' && c!=m_pOptionDialog->m_fgColor && charChanged[i]!=0 )
|
joachim99@8
|
566 {
|
joachim99@51
|
567 if ( m_pOptionDialog->m_bShowWhiteSpaceCharacters && m_pOptionDialog->m_bShowWhiteSpace)
|
joachim99@8
|
568 {
|
joachim99@8
|
569 p.fillRect( xOffset + fontWidth*outPos, yOffset+fontAscent,
|
joachim99@8
|
570 fontWidth*spaces-1, fontDescent+1, c );
|
joachim99@8
|
571 }
|
joachim99@8
|
572 }
|
joachim99@8
|
573 else
|
joachim99@8
|
574 {
|
joachim99@51
|
575 p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) );
|
joachim99@8
|
576 }
|
joachim99@8
|
577 p.setFont(normalFont);
|
joachim99@8
|
578 }
|
joachim99@8
|
579 else
|
joachim99@8
|
580 {
|
joachim99@8
|
581
|
joachim99@8
|
582 p.fillRect( xOffset + fontWidth*outPos, yOffset,
|
joachim99@8
|
583 fontWidth*(spaces), fontHeight, colorGroup().highlight() );
|
joachim99@8
|
584
|
joachim99@8
|
585 p.setPen( colorGroup().highlightedText() );
|
joachim99@51
|
586 p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) );
|
joachim99@8
|
587
|
joachim99@8
|
588 selection.bSelectionContainsData = true;
|
joachim99@8
|
589 }
|
joachim99@8
|
590 }
|
joachim99@8
|
591
|
joachim99@8
|
592 outPos += spaces;
|
joachim99@8
|
593 }
|
joachim99@8
|
594
|
joachim99@8
|
595 if( selection.lineWithin( line ) && selection.lineWithin( line+1 ) )
|
joachim99@8
|
596 {
|
joachim99@8
|
597 p.fillRect( xOffset + fontWidth*outPos, yOffset,
|
joachim99@8
|
598 width(), fontHeight, colorGroup().highlight() );
|
joachim99@8
|
599 }
|
joachim99@8
|
600 }
|
joachim99@8
|
601
|
joachim99@8
|
602 p.fillRect( 0, yOffset, leftInfoWidth*fontWidth, fontHeight, m_pOptionDialog->m_bgColor );
|
joachim99@8
|
603
|
joachim99@8
|
604 xOffset = (m_lineNumberWidth+2)*fontWidth;
|
joachim99@8
|
605 int xLeft = m_lineNumberWidth*fontWidth;
|
joachim99@8
|
606 p.setPen( m_pOptionDialog->m_fgColor );
|
joachim99@8
|
607 if ( pld!=0 )
|
joachim99@8
|
608 {
|
joachim99@8
|
609 if ( m_pOptionDialog->m_bShowLineNumbers )
|
joachim99@8
|
610 {
|
joachim99@8
|
611 QString num;
|
joachim99@8
|
612 num.sprintf( "%0*d", m_lineNumberWidth, srcLineNr);
|
joachim99@8
|
613 p.drawText( 0, yOffset + fontAscent, num );
|
joachim99@8
|
614 //p.drawLine( xLeft -1, yOffset, xLeft -1, yOffset+fontHeight-1 );
|
joachim99@8
|
615 }
|
joachim99@8
|
616 p.drawLine( xOffset +1, yOffset, xOffset +1, yOffset+fontHeight-1 );
|
joachim99@8
|
617 }
|
joachim99@8
|
618 if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 )//&& whatChanged==0 )
|
joachim99@8
|
619 {
|
joachim99@51
|
620 if ( m_pOptionDialog->m_bShowWhiteSpace )
|
joachim99@51
|
621 {
|
joachim99@51
|
622 p.setBrushOrigin(0,0);
|
joachim99@51
|
623 p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, QBrush(c,Dense5Pattern) );
|
joachim99@51
|
624 }
|
joachim99@8
|
625 }
|
joachim99@8
|
626 else
|
joachim99@8
|
627 {
|
joachim99@8
|
628 p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, c==m_pOptionDialog->m_fgColor ? bgColor : c );
|
joachim99@8
|
629 }
|
joachim99@8
|
630
|
joachim99@8
|
631 if ( bFastSelectionRange )
|
joachim99@8
|
632 {
|
joachim99@8
|
633 p.fillRect( xOffset + fontWidth-1, yOffset, 3, fontHeight, m_pOptionDialog->m_fgColor );
|
joachim99@8
|
634 /* p.drawLine( xOffset + fontWidth-1, yOffset, xOffset + fontWidth-1, yOffset+fontHeight-1 );
|
joachim99@8
|
635 if ( line == m_fastSelectorLine1 )
|
joachim99@8
|
636 {
|
joachim99@8
|
637 p.drawLine( xOffset + fontWidth-1, yOffset, xOffset + fontWidth+2, yOffset );
|
joachim99@8
|
638 }
|
joachim99@8
|
639 if ( line == fastSelectorLine2 )
|
joachim99@8
|
640 {
|
joachim99@8
|
641 p.drawLine( xOffset + fontWidth-1, yOffset+fontHeight-1, xOffset + fontWidth+2, yOffset+fontHeight-1 );
|
joachim99@8
|
642 }*/
|
joachim99@8
|
643 }
|
joachim99@8
|
644 }
|
joachim99@8
|
645
|
joachim99@8
|
646 void DiffTextWindow::paintEvent( QPaintEvent* e )
|
joachim99@8
|
647 {
|
joachim99@8
|
648 if ( m_pDiff3LineVector==0 || ! m_bPaintingAllowed ) return;
|
joachim99@8
|
649
|
joachim99@8
|
650 m_lineNumberWidth = m_pOptionDialog->m_bShowLineNumbers ? (int)log10((double)m_size)+1 : 0;
|
joachim99@8
|
651
|
joachim99@8
|
652 if (e!=0)
|
joachim99@8
|
653 {
|
joachim99@8
|
654 m_invalidRect |= e->rect();
|
joachim99@8
|
655 }
|
joachim99@8
|
656
|
joachim99@8
|
657 if ( m_winIdx==1 )
|
joachim99@8
|
658 {
|
joachim99@8
|
659 m_cThis = m_pOptionDialog->m_colorA;
|
joachim99@8
|
660 m_cDiff1 = m_pOptionDialog->m_colorB;
|
joachim99@8
|
661 m_cDiff2 = m_pOptionDialog->m_colorC;
|
joachim99@8
|
662 }
|
joachim99@8
|
663 if ( m_winIdx==2 )
|
joachim99@8
|
664 {
|
joachim99@8
|
665 m_cThis = m_pOptionDialog->m_colorB;
|
joachim99@8
|
666 m_cDiff1 = m_pOptionDialog->m_colorC;
|
joachim99@8
|
667 m_cDiff2 = m_pOptionDialog->m_colorA;
|
joachim99@8
|
668 }
|
joachim99@8
|
669 if ( m_winIdx==3 )
|
joachim99@8
|
670 {
|
joachim99@8
|
671 m_cThis = m_pOptionDialog->m_colorC;
|
joachim99@8
|
672 m_cDiff1 = m_pOptionDialog->m_colorA;
|
joachim99@8
|
673 m_cDiff2 = m_pOptionDialog->m_colorB;
|
joachim99@8
|
674 }
|
joachim99@8
|
675 m_cDiffBoth = m_pOptionDialog->m_colorForConflict; // Conflict color
|
joachim99@8
|
676
|
joachim99@8
|
677 bool bOldSelectionContainsData = selection.bSelectionContainsData;
|
joachim99@8
|
678 selection.bSelectionContainsData = false;
|
joachim99@8
|
679
|
joachim99@8
|
680 int fontHeight = fontMetrics().height();
|
joachim99@8
|
681 int fontAscent = fontMetrics().ascent();
|
joachim99@8
|
682 // int fontDescent = fontMetrics().descent();
|
joachim99@8
|
683 int fontWidth = fontMetrics().width('W');
|
joachim99@8
|
684
|
joachim99@8
|
685 int topLineYOffset = fontHeight + 3;
|
joachim99@8
|
686 int xOffset = leftInfoWidth * fontWidth;
|
joachim99@8
|
687
|
joachim99@8
|
688 int firstLineToDraw = 0;
|
joachim99@8
|
689 int lastLineToDraw = (height() - topLineYOffset ) / fontHeight;
|
joachim99@8
|
690 if ( abs(m_oldFirstLine - m_firstLine)>=lastLineToDraw )
|
joachim99@8
|
691 {
|
joachim99@8
|
692 m_oldFirstLine = -1;
|
joachim99@8
|
693 m_invalidRect |= QRect( 0, topLineYOffset, width(), height() );
|
joachim99@8
|
694 }
|
joachim99@8
|
695
|
joachim99@8
|
696 if ( m_oldFirstLine != -1 && m_oldFirstLine != m_firstLine )
|
joachim99@8
|
697 {
|
joachim99@8
|
698 int deltaY = fontHeight * ( m_oldFirstLine - m_firstLine );
|
joachim99@8
|
699 if ( deltaY > 0 )
|
joachim99@8
|
700 { // Move down
|
joachim99@8
|
701 bitBlt( this, 0, deltaY + topLineYOffset /*dy*/, this, 0, topLineYOffset /*sy*/, width(), height()- (deltaY + topLineYOffset), CopyROP, true);
|
joachim99@8
|
702 lastLineToDraw = firstLineToDraw + ( m_oldFirstLine - m_firstLine);
|
joachim99@8
|
703 m_invalidRect |= QRect( 0, topLineYOffset, width(), deltaY );
|
joachim99@8
|
704 }
|
joachim99@8
|
705 else
|
joachim99@8
|
706 { // Move up
|
joachim99@8
|
707 bitBlt( this, 0, topLineYOffset /*dy*/, this, 0, -deltaY+topLineYOffset /*sy*/, width(), height()-(-deltaY+topLineYOffset), CopyROP, true);
|
joachim99@8
|
708 firstLineToDraw = lastLineToDraw + ( m_oldFirstLine - m_firstLine);
|
joachim99@8
|
709 m_invalidRect |= QRect( 0, height()+deltaY, width(), -deltaY );
|
joachim99@8
|
710 }
|
joachim99@8
|
711 }
|
joachim99@8
|
712
|
joachim99@8
|
713 if ( m_oldFirstColumn != -1 && m_oldFirstColumn != m_firstColumn )
|
joachim99@8
|
714 {
|
joachim99@8
|
715 int deltaX = fontWidth * ( m_oldFirstColumn - m_firstColumn );
|
joachim99@8
|
716 if ( deltaX > 0 )
|
joachim99@8
|
717 { // Move right, scroll left
|
joachim99@8
|
718 bitBlt( this, deltaX+xOffset, topLineYOffset, this, xOffset, topLineYOffset, width(), height(), CopyROP, true);
|
joachim99@8
|
719 m_invalidRect |=
|
joachim99@8
|
720 QRect( xOffset, topLineYOffset, deltaX, height() - topLineYOffset );
|
joachim99@8
|
721 }
|
joachim99@8
|
722 else
|
joachim99@8
|
723 { // Move left, scroll right
|
joachim99@8
|
724 bitBlt( this, xOffset, topLineYOffset, this, xOffset-deltaX, topLineYOffset, width()-(xOffset-deltaX), height()-topLineYOffset, CopyROP, true);
|
joachim99@8
|
725 m_invalidRect |=
|
joachim99@8
|
726 QRect( width() + deltaX, topLineYOffset, -deltaX, height() - topLineYOffset );
|
joachim99@8
|
727 }
|
joachim99@8
|
728 }
|
joachim99@8
|
729
|
joachim99@8
|
730 if ( selection.oldLastLine != -1 )
|
joachim99@8
|
731 {
|
joachim99@8
|
732 int lastLine;
|
joachim99@8
|
733 int firstLine;
|
joachim99@8
|
734 if ( selection.oldFirstLine != -1 )
|
joachim99@8
|
735 {
|
joachim99@8
|
736 firstLine = min3( selection.oldFirstLine, selection.lastLine, selection.oldLastLine );
|
joachim99@8
|
737 lastLine = max3( selection.oldFirstLine, selection.lastLine, selection.oldLastLine );
|
joachim99@8
|
738 }
|
joachim99@8
|
739 else
|
joachim99@8
|
740 {
|
joachim99@8
|
741 firstLine = min2( selection.lastLine, selection.oldLastLine );
|
joachim99@8
|
742 lastLine = max2( selection.lastLine, selection.oldLastLine );
|
joachim99@8
|
743 }
|
joachim99@8
|
744 int y1 = topLineYOffset + ( firstLine - m_firstLine ) * fontHeight;
|
joachim99@8
|
745 int y2 = min2( height(),
|
joachim99@8
|
746 topLineYOffset + ( lastLine - m_firstLine +1 ) * fontHeight );
|
joachim99@8
|
747
|
joachim99@8
|
748 if ( y1<height() && y2>topLineYOffset )
|
joachim99@8
|
749 {
|
joachim99@8
|
750 m_invalidRect |= QRect( 0, y1, width(), y2-y1 );
|
joachim99@8
|
751 }
|
joachim99@8
|
752 }
|
joachim99@8
|
753
|
joachim99@8
|
754 if ( m_invalidRect.isEmpty() )
|
joachim99@8
|
755 return;
|
joachim99@8
|
756
|
joachim99@8
|
757 QPainter painter(this);
|
joachim99@8
|
758 //QPainter& p=painter;
|
joachim99@8
|
759 QPixmap pixmap( m_invalidRect.size() );
|
joachim99@8
|
760 QPainter p( &pixmap );
|
joachim99@8
|
761 p.translate( -m_invalidRect.x(), -m_invalidRect.y() );
|
joachim99@8
|
762
|
joachim99@8
|
763 p.fillRect( m_invalidRect, m_pOptionDialog->m_bgColor );
|
joachim99@8
|
764
|
joachim99@8
|
765 firstLineToDraw += m_firstLine;
|
joachim99@8
|
766 lastLineToDraw += m_firstLine;
|
joachim99@8
|
767
|
joachim99@8
|
768 p.setFont( font() );
|
joachim99@8
|
769
|
joachim99@8
|
770 p.setPen( m_cThis );
|
joachim99@8
|
771 if( m_invalidRect.intersects( QRect(0,0,width(), topLineYOffset ) )
|
joachim99@8
|
772 || m_firstLine != m_oldFirstLine )
|
joachim99@8
|
773 {
|
joachim99@8
|
774 int l=-1;
|
joachim99@8
|
775 for ( int i = m_firstLine; i<(int)m_pDiff3LineVector->size(); ++i )
|
joachim99@8
|
776 {
|
joachim99@8
|
777 const Diff3Line* d3l = (*m_pDiff3LineVector)[i];
|
joachim99@8
|
778 if ( m_winIdx==1 ) l=d3l->lineA;
|
joachim99@8
|
779 else if ( m_winIdx==2 ) l=d3l->lineB;
|
joachim99@8
|
780 else if ( m_winIdx==3 ) l=d3l->lineC;
|
joachim99@8
|
781 else assert(false);
|
joachim99@8
|
782 if (l!=-1) break;
|
joachim99@8
|
783 }
|
joachim99@8
|
784
|
joachim99@8
|
785 const char* winId = ( m_winIdx==1 ? (m_bTriple?"A (Base)":"A") :
|
joachim99@8
|
786 ( m_winIdx==2 ? "B" : "C" ) );
|
joachim99@8
|
787
|
joachim99@51
|
788 QString s = QString(" ")+ winId + " : " + m_filename + " : ";
|
joachim99@8
|
789 if ( l!=-1 )
|
joachim99@51
|
790 s += i18n("Topline %1").arg( l+1 );
|
joachim99@8
|
791 else
|
joachim99@51
|
792 s += i18n("End");
|
joachim99@8
|
793
|
joachim99@8
|
794 if (hasFocus())
|
joachim99@8
|
795 {
|
joachim99@8
|
796 painter.fillRect( 0, 0, width(), topLineYOffset, m_cThis );
|
joachim99@8
|
797 painter.setPen( m_pOptionDialog->m_bgColor );
|
joachim99@8
|
798 painter.drawText( 0, fontAscent+1, s );
|
joachim99@8
|
799 }
|
joachim99@8
|
800 else
|
joachim99@8
|
801 {
|
joachim99@8
|
802 painter.fillRect( 0, 0, width(), topLineYOffset, m_pOptionDialog->m_bgColor );
|
joachim99@8
|
803 painter.setPen( m_cThis );
|
joachim99@8
|
804 painter.drawLine( 0, fontHeight + 2, width(), fontHeight + 2 );
|
joachim99@8
|
805 painter.drawText( 0, fontAscent+1, s );
|
joachim99@8
|
806 }
|
joachim99@8
|
807 }
|
joachim99@8
|
808
|
joachim99@8
|
809 int lastVisibleLine = min2( m_firstLine + getNofVisibleLines()+2, (int)m_pDiff3LineVector->size() );
|
joachim99@8
|
810
|
joachim99@8
|
811 for ( int line = m_firstLine; line<lastVisibleLine; ++line )
|
joachim99@8
|
812 {
|
joachim99@8
|
813 const Diff3Line* d3l = (*m_pDiff3LineVector)[line];
|
joachim99@8
|
814 DiffList* pFineDiff1;
|
joachim99@8
|
815 DiffList* pFineDiff2;
|
joachim99@8
|
816 int changed=0;
|
joachim99@8
|
817 int changed2=0;
|
joachim99@8
|
818 int lineIdx;
|
joachim99@8
|
819
|
joachim99@8
|
820 getLineInfo( *d3l, lineIdx, pFineDiff1, pFineDiff2, changed, changed2 );
|
joachim99@8
|
821
|
joachim99@8
|
822 writeLine(
|
joachim99@8
|
823 p, // QPainter
|
joachim99@8
|
824 lineIdx == -1 ? 0 : &m_pLineData[lineIdx], // Text in this line
|
joachim99@8
|
825 pFineDiff1,
|
joachim99@8
|
826 pFineDiff2,
|
joachim99@8
|
827 line, // Line on the screen
|
joachim99@8
|
828 changed,
|
joachim99@8
|
829 changed2,
|
joachim99@8
|
830 lineIdx+1
|
joachim99@8
|
831 );
|
joachim99@8
|
832 }
|
joachim99@8
|
833
|
joachim99@8
|
834 // p.drawLine( m_invalidRect.x(), m_invalidRect.y(), m_invalidRect.right(), m_invalidRect.bottom() );
|
joachim99@8
|
835 p.end();
|
joachim99@8
|
836
|
joachim99@8
|
837 painter.setClipRect ( 0, topLineYOffset, width(), height()-topLineYOffset );
|
joachim99@8
|
838
|
joachim99@8
|
839 painter.drawPixmap( m_invalidRect.x(), m_invalidRect.y(), pixmap );
|
joachim99@8
|
840
|
joachim99@8
|
841 m_oldFirstLine = m_firstLine;
|
joachim99@8
|
842 m_oldFirstColumn = m_firstColumn;
|
joachim99@8
|
843 m_invalidRect = QRect(0,0,0,0);
|
joachim99@8
|
844 selection.oldLastLine = -1;
|
joachim99@8
|
845 if ( selection.oldFirstLine !=-1 )
|
joachim99@8
|
846 selection.oldFirstLine = -1;
|
joachim99@8
|
847 if( !bOldSelectionContainsData && selection.bSelectionContainsData )
|
joachim99@8
|
848 emit newSelection();
|
joachim99@8
|
849
|
joachim99@8
|
850 }
|
joachim99@8
|
851
|
joachim99@8
|
852 QCString DiffTextWindow::getString( int line )
|
joachim99@8
|
853 {
|
joachim99@8
|
854 const Diff3Line* d3l = (*m_pDiff3LineVector)[line];
|
joachim99@8
|
855 DiffList* pFineDiff1;
|
joachim99@8
|
856 DiffList* pFineDiff2;
|
joachim99@8
|
857 int changed=0;
|
joachim99@8
|
858 int changed2=0;
|
joachim99@8
|
859 int lineIdx;
|
joachim99@8
|
860 getLineInfo( *d3l, lineIdx, pFineDiff1, pFineDiff2, changed, changed2 );
|
joachim99@8
|
861
|
joachim99@8
|
862 if (lineIdx==-1) return QCString();
|
joachim99@8
|
863 else
|
joachim99@8
|
864 {
|
joachim99@58
|
865 const LineData* ld = &m_pLineData[lineIdx];
|
joachim99@8
|
866 return QCString( ld->pLine, ld->size + 1 );
|
joachim99@8
|
867 }
|
joachim99@8
|
868 return QCString();
|
joachim99@8
|
869 }
|
joachim99@8
|
870
|
joachim99@8
|
871
|
joachim99@8
|
872 void DiffTextWindow::getLineInfo(
|
joachim99@8
|
873 const Diff3Line& d,
|
joachim99@8
|
874 int& lineIdx,
|
joachim99@8
|
875 DiffList*& pFineDiff1, DiffList*& pFineDiff2, // return values
|
joachim99@8
|
876 int& changed, int& changed2
|
joachim99@8
|
877 )
|
joachim99@8
|
878 {
|
joachim99@8
|
879 changed=0;
|
joachim99@8
|
880 changed2=0;
|
joachim99@8
|
881 bool bAEqB = d.bAEqB || ( d.bWhiteLineA && d.bWhiteLineB );
|
joachim99@8
|
882 bool bAEqC = d.bAEqC || ( d.bWhiteLineA && d.bWhiteLineC );
|
joachim99@8
|
883 bool bBEqC = d.bBEqC || ( d.bWhiteLineB && d.bWhiteLineC );
|
joachim99@8
|
884 if ( m_winIdx == 1 ) {
|
joachim99@8
|
885 lineIdx=d.lineA;
|
joachim99@8
|
886 pFineDiff1=d.pFineAB;
|
joachim99@8
|
887 pFineDiff2=d.pFineCA;
|
joachim99@8
|
888 changed |= ((d.lineB==-1)!=(lineIdx==-1) ? 1 : 0) +
|
joachim99@8
|
889 ((d.lineC==-1)!=(lineIdx==-1) && m_bTriple ? 2 : 0);
|
joachim99@8
|
890 changed2 |= ( bAEqB ? 0 : 1 ) + (bAEqC || !m_bTriple ? 0 : 2);
|
joachim99@8
|
891 }
|
joachim99@8
|
892 else if ( m_winIdx == 2 ) {
|
joachim99@8
|
893 lineIdx=d.lineB;
|
joachim99@8
|
894 pFineDiff1=d.pFineBC;
|
joachim99@8
|
895 pFineDiff2=d.pFineAB;
|
joachim99@8
|
896 changed |= ((d.lineC==-1)!=(lineIdx==-1) && m_bTriple ? 1 : 0) +
|
joachim99@8
|
897 ((d.lineA==-1)!=(lineIdx==-1) ? 2 : 0);
|
joachim99@8
|
898 changed2 |= ( bBEqC || !m_bTriple ? 0 : 1 ) + (bAEqB ? 0 : 2);
|
joachim99@8
|
899 }
|
joachim99@8
|
900 else if ( m_winIdx == 3 ) {
|
joachim99@8
|
901 lineIdx=d.lineC;
|
joachim99@8
|
902 pFineDiff1=d.pFineCA;
|
joachim99@8
|
903 pFineDiff2=d.pFineBC;
|
joachim99@8
|
904 changed |= ((d.lineA==-1)!=(lineIdx==-1) ? 1 : 0) +
|
joachim99@8
|
905 ((d.lineB==-1)!=(lineIdx==-1) ? 2 : 0);
|
joachim99@8
|
906 changed2 |= ( bAEqC ? 0 : 1 ) + (bBEqC ? 0 : 2);
|
joachim99@8
|
907 }
|
joachim99@8
|
908 else assert(false);
|
joachim99@8
|
909 }
|
joachim99@8
|
910
|
joachim99@8
|
911
|
joachim99@8
|
912
|
joachim99@8
|
913 void DiffTextWindow::resizeEvent( QResizeEvent* e )
|
joachim99@8
|
914 {
|
joachim99@8
|
915 QSize s = e->size();
|
joachim99@8
|
916 QFontMetrics fm = fontMetrics();
|
joachim99@8
|
917 int visibleLines = s.height()/fm.height()-2;
|
joachim99@8
|
918 int visibleColumns = s.width()/fm.width('W')-leftInfoWidth;
|
joachim99@8
|
919 emit resizeSignal( visibleColumns, visibleLines );
|
joachim99@8
|
920 QWidget::resizeEvent(e);
|
joachim99@8
|
921 }
|
joachim99@8
|
922
|
joachim99@8
|
923 int DiffTextWindow::getNofVisibleLines()
|
joachim99@8
|
924 {
|
joachim99@8
|
925 QFontMetrics fm = fontMetrics();
|
joachim99@8
|
926 int fmh = fm.height();
|
joachim99@8
|
927 int h = height();
|
joachim99@8
|
928 return h/fmh -2;//height()/fm.height()-2;
|
joachim99@8
|
929 }
|
joachim99@8
|
930
|
joachim99@8
|
931 int DiffTextWindow::getNofVisibleColumns()
|
joachim99@8
|
932 {
|
joachim99@8
|
933 QFontMetrics fm = fontMetrics();
|
joachim99@8
|
934 return width()/fm.width('W')-leftInfoWidth;
|
joachim99@8
|
935 }
|
joachim99@8
|
936
|
joachim99@8
|
937 QString DiffTextWindow::getSelection()
|
joachim99@8
|
938 {
|
joachim99@8
|
939 QString selectionString;
|
joachim99@8
|
940
|
joachim99@8
|
941 int line=0;
|
joachim99@8
|
942 int lineIdx=0;
|
joachim99@8
|
943
|
joachim99@8
|
944 int it;
|
joachim99@8
|
945 for( it=0; it<(int)m_pDiff3LineVector->size(); ++it )
|
joachim99@8
|
946 {
|
joachim99@8
|
947 const Diff3Line* d = (*m_pDiff3LineVector)[it];
|
joachim99@8
|
948 if ( m_winIdx == 1 ) { lineIdx=d->lineA; }
|
joachim99@8
|
949 else if ( m_winIdx == 2 ) { lineIdx=d->lineB; }
|
joachim99@8
|
950 else if ( m_winIdx == 3 ) { lineIdx=d->lineC; }
|
joachim99@8
|
951 else assert(false);
|
joachim99@8
|
952
|
joachim99@8
|
953 if( lineIdx != -1 )
|
joachim99@8
|
954 {
|
joachim99@8
|
955 const char* pLine = m_pLineData[lineIdx].pLine;
|
joachim99@8
|
956 int size = m_pLineData[lineIdx].size;
|
joachim99@8
|
957
|
joachim99@8
|
958 // Consider tabs
|
joachim99@8
|
959 int outPos = 0;
|
joachim99@8
|
960 for( int i=0; i<size; ++i )
|
joachim99@8
|
961 {
|
joachim99@8
|
962 int spaces = 1;
|
joachim99@8
|
963 if ( pLine[i]=='\t' )
|
joachim99@8
|
964 {
|
joachim99@8
|
965 spaces = tabber( outPos, g_tabSize );
|
joachim99@8
|
966 }
|
joachim99@8
|
967
|
joachim99@8
|
968 if( selection.within( line, outPos ) )
|
joachim99@8
|
969 {
|
joachim99@58
|
970 char buf[2];
|
joachim99@58
|
971 buf[0] = pLine[i];
|
joachim99@58
|
972 buf[1] = '\0';
|
joachim99@58
|
973 selectionString += decodeString( buf, m_pOptionDialog );
|
joachim99@8
|
974 }
|
joachim99@8
|
975
|
joachim99@8
|
976 outPos += spaces;
|
joachim99@8
|
977 }
|
joachim99@8
|
978
|
joachim99@8
|
979 if( selection.within( line, outPos ) )
|
joachim99@8
|
980 {
|
joachim99@8
|
981 #ifdef _WIN32
|
joachim99@8
|
982 selectionString += '\r';
|
joachim99@8
|
983 #endif
|
joachim99@8
|
984 selectionString += '\n';
|
joachim99@8
|
985 }
|
joachim99@8
|
986 }
|
joachim99@8
|
987
|
joachim99@8
|
988 ++line;
|
joachim99@8
|
989 }
|
joachim99@8
|
990
|
joachim99@8
|
991 return selectionString;
|
joachim99@8
|
992 }
|
joachim99@8
|
993
|
joachim99@8
|
994 bool DiffTextWindow::findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive )
|
joachim99@8
|
995 {
|
joachim99@8
|
996 int it = d3vLine;
|
joachim99@8
|
997 int endIt = bDirDown ? (int)m_pDiff3LineVector->size() : -1;
|
joachim99@8
|
998 int step = bDirDown ? 1 : -1;
|
joachim99@8
|
999 int startPos = posInLine;
|
joachim99@8
|
1000
|
joachim99@8
|
1001 for( ; it!=endIt; it+=step )
|
joachim99@8
|
1002 {
|
joachim99@8
|
1003 QCString line = getString( it );
|
joachim99@8
|
1004 if ( !line.isEmpty() )
|
joachim99@8
|
1005 {
|
joachim99@8
|
1006 int pos = line.find( s, startPos, bCaseSensitive );
|
joachim99@8
|
1007 if ( pos != -1 )
|
joachim99@8
|
1008 {
|
joachim99@8
|
1009 d3vLine = it;
|
joachim99@8
|
1010 posInLine = pos;
|
joachim99@8
|
1011 return true;
|
joachim99@8
|
1012 }
|
joachim99@8
|
1013
|
joachim99@8
|
1014 startPos = 0;
|
joachim99@8
|
1015 }
|
joachim99@8
|
1016 }
|
joachim99@8
|
1017 return false;
|
joachim99@8
|
1018 }
|
joachim99@8
|
1019
|
joachim99@8
|
1020 void DiffTextWindow::setSelection( int firstLine, int startPos, int lastLine, int endPos )
|
joachim99@8
|
1021 {
|
joachim99@8
|
1022 selection.reset();
|
joachim99@8
|
1023 selection.start( firstLine, convertToPosOnScreen( getString(firstLine), startPos ) );
|
joachim99@8
|
1024 selection.end( lastLine, convertToPosOnScreen( getString(lastLine), endPos ) );
|
joachim99@8
|
1025 update();
|
joachim99@8
|
1026 }
|
joachim99@51
|
1027
|
joachim99@51
|
1028
|
joachim99@51
|
1029 #include <qtextcodec.h>
|
joachim99@51
|
1030
|
joachim99@51
|
1031 QString decodeString( const char*s , OptionDialog* pOptions )
|
joachim99@51
|
1032 {
|
joachim99@51
|
1033 if ( pOptions->m_bStringEncoding )
|
joachim99@51
|
1034 {
|
joachim99@51
|
1035 QTextCodec* c = QTextCodec::codecForLocale();
|
joachim99@51
|
1036 if (c!=0)
|
joachim99@51
|
1037 return c->toUnicode( s );
|
joachim99@51
|
1038 else
|
joachim99@51
|
1039 return QString(s);
|
joachim99@51
|
1040 }
|
joachim99@51
|
1041 else
|
joachim99@51
|
1042 return QString(s);
|
joachim99@51
|
1043 }
|
joachim99@58
|
1044
|
joachim99@58
|
1045 QCString encodeString( const QString& s , OptionDialog* pOptions )
|
joachim99@58
|
1046 {
|
joachim99@58
|
1047 if ( pOptions->m_bStringEncoding )
|
joachim99@58
|
1048 {
|
joachim99@58
|
1049 QTextCodec* c = QTextCodec::codecForLocale();
|
joachim99@58
|
1050 if (c!=0)
|
joachim99@58
|
1051 return c->fromUnicode( s );
|
joachim99@58
|
1052 else
|
joachim99@58
|
1053 return QCString( s.ascii() );
|
joachim99@58
|
1054 }
|
joachim99@58
|
1055 else
|
joachim99@58
|
1056 return QCString( s.ascii() );
|
joachim99@58
|
1057 }
|