joachim99@8
|
1 /***************************************************************************
|
joachim99@8
|
2 difftextwindow.cpp - description
|
joachim99@8
|
3 -------------------
|
joachim99@8
|
4 begin : Mon Apr 8 2002
|
joachim99@77
|
5 copyright : (C) 2002-2007 by Joachim Eibl
|
joachim99@69
|
6 email : joachim.eibl at 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@69
|
18 #include "difftextwindow.h"
|
joachim99@8
|
19 #include "merger.h"
|
joachim99@75
|
20 #include "optiondialog.h"
|
joachim99@75
|
21
|
joachim99@75
|
22 #include <qnamespace.h>
|
joachim99@70
|
23 #include <QDragEnterEvent>
|
joachim99@75
|
24 #include <QDir>
|
joachim99@75
|
25 #include <QStatusBar>
|
joachim99@75
|
26 #include <QApplication>
|
joachim99@75
|
27 #include <QToolTip>
|
joachim99@75
|
28 #include <QLineEdit>
|
joachim99@75
|
29 #include <QLabel>
|
joachim99@75
|
30 #include <QPushButton>
|
joachim99@75
|
31 #include <QLayout>
|
joachim99@75
|
32 #include <QTextCodec>
|
joachim99@75
|
33 #include <QUrl>
|
Chris@113
|
34 #include <QMimeData>
|
joachim99@75
|
35
|
joachim99@51
|
36 #include <klocale.h>
|
joachim99@69
|
37 #include <kfiledialog.h>
|
joachim99@8
|
38
|
joachim99@77
|
39 #include <cmath>
|
joachim99@77
|
40 #include <cstdlib>
|
joachim99@75
|
41 #include <assert.h>
|
joachim99@75
|
42
|
joachim99@75
|
43
|
joachim99@69
|
44 class DiffTextWindowData
|
joachim99@69
|
45 {
|
joachim99@69
|
46 public:
|
joachim99@69
|
47 DiffTextWindowData( DiffTextWindow* p )
|
joachim99@69
|
48 {
|
joachim99@69
|
49 m_pDiffTextWindow = p;
|
joachim99@69
|
50 m_bPaintingAllowed = false;
|
joachim99@69
|
51 m_pLineData = 0;
|
joachim99@69
|
52 m_size = 0;
|
joachim99@69
|
53 m_bWordWrap = false;
|
joachim99@69
|
54 m_delayedDrawTimer = 0;
|
joachim99@69
|
55 m_pDiff3LineVector = 0;
|
joachim99@69
|
56 m_pManualDiffHelpList = 0;
|
joachim99@69
|
57 m_pOptionDialog = 0;
|
joachim99@69
|
58 m_fastSelectorLine1 = 0;
|
joachim99@69
|
59 m_fastSelectorNofLines = 0;
|
joachim99@69
|
60 m_bTriple = 0;
|
joachim99@69
|
61 m_winIdx = 0;
|
joachim99@69
|
62 m_firstLine = 0;
|
joachim99@69
|
63 m_oldFirstLine = 0;
|
joachim99@69
|
64 m_oldFirstColumn = 0;
|
joachim99@69
|
65 m_firstColumn = 0;
|
joachim99@69
|
66 m_lineNumberWidth = 0;
|
joachim99@69
|
67 m_pStatusBar = 0;
|
joachim99@69
|
68 m_scrollDeltaX = 0;
|
joachim99@69
|
69 m_scrollDeltaY = 0;
|
joachim99@69
|
70 m_bMyUpdate = false;
|
joachim99@69
|
71 m_bSelectionInProgress = false;
|
joachim99@92
|
72 m_pTextCodec = 0;
|
joachim99@95
|
73 #if defined(_WIN32) || defined(Q_OS_OS2)
|
joachim99@92
|
74 m_eLineEndStyle = eLineEndStyleDos;
|
joachim99@92
|
75 #else
|
joachim99@92
|
76 m_eLineEndStyle = eLineEndStyleUnix;
|
joachim99@92
|
77 #endif
|
joachim99@69
|
78 }
|
joachim99@69
|
79 DiffTextWindow* m_pDiffTextWindow;
|
joachim99@69
|
80 DiffTextWindowFrame* m_pDiffTextWindowFrame;
|
joachim99@92
|
81 QTextCodec* m_pTextCodec;
|
joachim99@92
|
82 e_LineEndStyle m_eLineEndStyle;
|
joachim99@8
|
83
|
joachim99@69
|
84 bool m_bPaintingAllowed;
|
joachim99@69
|
85 const LineData* m_pLineData;
|
joachim99@69
|
86 int m_size;
|
joachim99@69
|
87 QString m_filename;
|
joachim99@69
|
88 bool m_bWordWrap;
|
joachim99@69
|
89 int m_delayedDrawTimer;
|
joachim99@69
|
90
|
joachim99@69
|
91 const Diff3LineVector* m_pDiff3LineVector;
|
joachim99@69
|
92 Diff3WrapLineVector m_diff3WrapLineVector;
|
joachim99@69
|
93 const ManualDiffHelpList* m_pManualDiffHelpList;
|
joachim99@69
|
94
|
joachim99@69
|
95 OptionDialog* m_pOptionDialog;
|
joachim99@69
|
96 QColor m_cThis;
|
joachim99@69
|
97 QColor m_cDiff1;
|
joachim99@69
|
98 QColor m_cDiff2;
|
joachim99@69
|
99 QColor m_cDiffBoth;
|
joachim99@69
|
100
|
joachim99@69
|
101 int m_fastSelectorLine1;
|
joachim99@69
|
102 int m_fastSelectorNofLines;
|
joachim99@69
|
103
|
joachim99@69
|
104 bool m_bTriple;
|
joachim99@69
|
105 int m_winIdx;
|
joachim99@69
|
106 int m_firstLine;
|
joachim99@69
|
107 int m_oldFirstLine;
|
joachim99@69
|
108 int m_oldFirstColumn;
|
joachim99@69
|
109 int m_firstColumn;
|
joachim99@69
|
110 int m_lineNumberWidth;
|
joachim99@69
|
111
|
joachim99@69
|
112 void getLineInfo(
|
joachim99@69
|
113 const Diff3Line& d,
|
joachim99@69
|
114 int& lineIdx,
|
joachim99@69
|
115 DiffList*& pFineDiff1, DiffList*& pFineDiff2, // return values
|
joachim99@69
|
116 int& changed, int& changed2 );
|
joachim99@69
|
117
|
joachim99@69
|
118 QString getString( int d3lIdx );
|
joachim99@69
|
119 QString getLineString( int line );
|
joachim99@69
|
120
|
joachim99@69
|
121 void writeLine(
|
joachim99@69
|
122 MyPainter& p, const LineData* pld,
|
joachim99@69
|
123 const DiffList* pLineDiff1, const DiffList* pLineDiff2, int line,
|
joachim99@69
|
124 int whatChanged, int whatChanged2, int srcLineIdx,
|
joachim99@69
|
125 int wrapLineOffset, int wrapLineLength, bool bWrapLine, const QRect& invalidRect, int deviceWidth
|
joachim99@69
|
126 );
|
joachim99@69
|
127
|
joachim99@69
|
128 void draw( MyPainter& p, const QRect& invalidRect, int deviceWidth, int beginLine, int endLine );
|
joachim99@69
|
129
|
joachim99@69
|
130 QStatusBar* m_pStatusBar;
|
joachim99@69
|
131
|
joachim99@69
|
132 Selection m_selection;
|
joachim99@69
|
133
|
joachim99@69
|
134 int m_scrollDeltaX;
|
joachim99@69
|
135 int m_scrollDeltaY;
|
joachim99@69
|
136
|
joachim99@69
|
137 bool m_bMyUpdate;
|
joachim99@69
|
138 void myUpdate(int afterMilliSecs );
|
joachim99@69
|
139
|
joachim99@69
|
140 int leftInfoWidth() { return 4+m_lineNumberWidth; } // Nr of information columns on left side
|
joachim99@69
|
141 int convertLineOnScreenToLineInSource( int lineOnScreen, e_CoordType coordType, bool bFirstLine );
|
joachim99@69
|
142
|
joachim99@69
|
143 bool m_bSelectionInProgress;
|
joachim99@69
|
144 QPoint m_lastKnownMousePos;
|
joachim99@69
|
145 };
|
joachim99@8
|
146
|
joachim99@8
|
147 DiffTextWindow::DiffTextWindow(
|
joachim99@69
|
148 DiffTextWindowFrame* pParent,
|
joachim99@8
|
149 QStatusBar* pStatusBar,
|
joachim99@69
|
150 OptionDialog* pOptionDialog,
|
joachim99@69
|
151 int winIdx
|
joachim99@8
|
152 )
|
joachim99@75
|
153 : QWidget(pParent)
|
joachim99@8
|
154 {
|
joachim99@75
|
155 setObjectName(QString("DiffTextWindow%1").arg(winIdx));
|
joachim99@75
|
156 setAttribute( Qt::WA_OpaquePaintEvent );
|
joachim99@80
|
157 //setAttribute( Qt::WA_PaintOnScreen );
|
joachim99@75
|
158
|
joachim99@69
|
159 d = new DiffTextWindowData(this);
|
joachim99@69
|
160 d->m_pDiffTextWindowFrame = pParent;
|
joachim99@70
|
161 setFocusPolicy( Qt::ClickFocus );
|
joachim99@8
|
162 setAcceptDrops( true );
|
joachim99@8
|
163
|
joachim99@69
|
164 d->m_pOptionDialog = pOptionDialog;
|
joachim99@92
|
165 init( 0, 0, d->m_eLineEndStyle, 0, 0, 0, 0, false );
|
joachim99@8
|
166
|
joachim99@8
|
167 setMinimumSize(QSize(20,20));
|
joachim99@8
|
168
|
joachim99@69
|
169 d->m_pStatusBar = pStatusBar;
|
joachim99@69
|
170 d->m_bPaintingAllowed = true;
|
joachim99@69
|
171 d->m_bWordWrap = false;
|
joachim99@69
|
172 d->m_winIdx = winIdx;
|
joachim99@27
|
173
|
joachim99@69
|
174 setFont(d->m_pOptionDialog->m_font);
|
joachim99@8
|
175 }
|
joachim99@8
|
176
|
joachim99@69
|
177 DiffTextWindow::~DiffTextWindow()
|
joachim99@69
|
178 {
|
joachim99@69
|
179 delete d;
|
joachim99@69
|
180 }
|
joachim99@8
|
181
|
joachim99@8
|
182 void DiffTextWindow::init(
|
joachim99@8
|
183 const QString& filename,
|
joachim99@92
|
184 QTextCodec* pTextCodec,
|
joachim99@92
|
185 e_LineEndStyle eLineEndStyle,
|
joachim99@58
|
186 const LineData* pLineData,
|
joachim99@8
|
187 int size,
|
joachim99@8
|
188 const Diff3LineVector* pDiff3LineVector,
|
joachim99@69
|
189 const ManualDiffHelpList* pManualDiffHelpList,
|
joachim99@8
|
190 bool bTriple
|
joachim99@8
|
191 )
|
joachim99@8
|
192 {
|
joachim99@69
|
193 d->m_filename = filename;
|
joachim99@69
|
194 d->m_pLineData = pLineData;
|
joachim99@69
|
195 d->m_size = size;
|
joachim99@69
|
196 d->m_pDiff3LineVector = pDiff3LineVector;
|
joachim99@69
|
197 d->m_diff3WrapLineVector.clear();
|
joachim99@69
|
198 d->m_pManualDiffHelpList = pManualDiffHelpList;
|
joachim99@8
|
199
|
joachim99@69
|
200 d->m_firstLine = 0;
|
joachim99@69
|
201 d->m_oldFirstLine = -1;
|
joachim99@69
|
202 d->m_firstColumn = 0;
|
joachim99@69
|
203 d->m_oldFirstColumn = -1;
|
joachim99@69
|
204 d->m_bTriple = bTriple;
|
joachim99@69
|
205 d->m_scrollDeltaX=0;
|
joachim99@69
|
206 d->m_scrollDeltaY=0;
|
joachim99@69
|
207 d->m_bMyUpdate = false;
|
joachim99@69
|
208 d->m_fastSelectorLine1 = 0;
|
joachim99@69
|
209 d->m_fastSelectorNofLines = 0;
|
joachim99@69
|
210 d->m_lineNumberWidth = 0;
|
joachim99@69
|
211 d->m_selection.reset();
|
joachim99@69
|
212 d->m_selection.oldFirstLine = -1; // reset is not enough here.
|
joachim99@69
|
213 d->m_selection.oldLastLine = -1;
|
joachim99@69
|
214 d->m_selection.lastLine = -1;
|
joachim99@8
|
215
|
joachim99@92
|
216 d->m_pTextCodec = pTextCodec;
|
joachim99@92
|
217 d->m_eLineEndStyle = eLineEndStyle;
|
joachim99@92
|
218
|
joachim99@8
|
219 update();
|
joachim99@69
|
220 d->m_pDiffTextWindowFrame->init();
|
joachim99@69
|
221 }
|
joachim99@69
|
222
|
joachim99@69
|
223 void DiffTextWindow::reset()
|
joachim99@69
|
224 {
|
joachim99@69
|
225 d->m_pLineData=0;
|
joachim99@69
|
226 d->m_size=0;
|
joachim99@69
|
227 d->m_pDiff3LineVector=0;
|
joachim99@69
|
228 d->m_filename="";
|
joachim99@69
|
229 d->m_diff3WrapLineVector.clear();
|
joachim99@8
|
230 }
|
joachim99@8
|
231
|
joachim99@8
|
232 void DiffTextWindow::setPaintingAllowed( bool bAllowPainting )
|
joachim99@8
|
233 {
|
joachim99@69
|
234 if (d->m_bPaintingAllowed != bAllowPainting)
|
joachim99@8
|
235 {
|
joachim99@69
|
236 d->m_bPaintingAllowed = bAllowPainting;
|
joachim99@69
|
237 if ( d->m_bPaintingAllowed ) update();
|
joachim99@69
|
238 else reset();
|
joachim99@8
|
239 }
|
joachim99@8
|
240 }
|
joachim99@8
|
241
|
joachim99@8
|
242 void DiffTextWindow::dragEnterEvent( QDragEnterEvent* e )
|
joachim99@8
|
243 {
|
joachim99@75
|
244 e->setAccepted( e->mimeData()->hasUrls() || e->mimeData()->hasText() );
|
joachim99@8
|
245 // Note that the corresponding drop is handled in KDiff3App::eventFilter().
|
joachim99@8
|
246 }
|
joachim99@8
|
247
|
joachim99@69
|
248
|
joachim99@8
|
249 void DiffTextWindow::setFirstLine(int firstLine)
|
joachim99@8
|
250 {
|
joachim99@66
|
251 int fontHeight = fontMetrics().height();
|
joachim99@69
|
252
|
joachim99@66
|
253 int newFirstLine = max2(0,firstLine);
|
joachim99@66
|
254
|
joachim99@69
|
255 int deltaY = fontHeight * ( d->m_firstLine - newFirstLine );
|
joachim99@69
|
256
|
joachim99@69
|
257 d->m_firstLine = newFirstLine;
|
joachim99@69
|
258
|
joachim99@69
|
259 if ( d->m_bSelectionInProgress && d->m_selection.firstLine != -1 )
|
joachim99@66
|
260 {
|
joachim99@69
|
261 int line, pos;
|
joachim99@69
|
262 convertToLinePos( d->m_lastKnownMousePos.x(), d->m_lastKnownMousePos.y(), line, pos );
|
joachim99@69
|
263 d->m_selection.end( line, pos );
|
joachim99@69
|
264 update();
|
joachim99@66
|
265 }
|
joachim99@66
|
266 else
|
joachim99@66
|
267 {
|
joachim99@69
|
268 QWidget::scroll( 0, deltaY );
|
joachim99@66
|
269 }
|
joachim99@69
|
270 d->m_pDiffTextWindowFrame->setFirstLine( d->m_firstLine );
|
joachim99@69
|
271 }
|
joachim99@69
|
272
|
joachim99@69
|
273 int DiffTextWindow::getFirstLine()
|
joachim99@69
|
274 {
|
joachim99@69
|
275 return d->m_firstLine;
|
joachim99@8
|
276 }
|
joachim99@8
|
277
|
joachim99@8
|
278 void DiffTextWindow::setFirstColumn(int firstCol)
|
joachim99@8
|
279 {
|
joachim99@66
|
280 int fontWidth = fontMetrics().width('W');
|
joachim99@69
|
281 int xOffset = d->leftInfoWidth() * fontWidth;
|
joachim99@69
|
282
|
joachim99@66
|
283 int newFirstColumn = max2(0,firstCol);
|
joachim99@66
|
284
|
joachim99@69
|
285 int deltaX = fontWidth * ( d->m_firstColumn - newFirstColumn );
|
joachim99@66
|
286
|
joachim99@69
|
287 d->m_firstColumn = newFirstColumn;
|
joachim99@68
|
288
|
joachim99@69
|
289 QRect r( xOffset, 0, width()-xOffset, height() );
|
joachim99@69
|
290
|
joachim99@69
|
291 if ( d->m_pOptionDialog->m_bRightToLeftLanguage )
|
joachim99@68
|
292 {
|
joachim99@68
|
293 deltaX = -deltaX;
|
joachim99@75
|
294 r = QRect( width()-1-xOffset, 0, -(width()-xOffset), height() ).normalized();
|
joachim99@68
|
295 }
|
joachim99@68
|
296
|
joachim99@69
|
297 if ( d->m_bSelectionInProgress && d->m_selection.firstLine != -1 )
|
joachim99@69
|
298 {
|
joachim99@69
|
299 int line, pos;
|
joachim99@69
|
300 convertToLinePos( d->m_lastKnownMousePos.x(), d->m_lastKnownMousePos.y(), line, pos );
|
joachim99@69
|
301 d->m_selection.end( line, pos );
|
joachim99@69
|
302 update();
|
joachim99@69
|
303 }
|
joachim99@69
|
304 else
|
joachim99@69
|
305 {
|
joachim99@69
|
306 QWidget::scroll( deltaX, 0, r );
|
joachim99@69
|
307 }
|
joachim99@8
|
308 }
|
joachim99@8
|
309
|
joachim99@8
|
310 int DiffTextWindow::getNofColumns()
|
joachim99@8
|
311 {
|
joachim99@69
|
312 if (d->m_bWordWrap)
|
joachim99@8
|
313 {
|
joachim99@66
|
314 return getNofVisibleColumns();
|
joachim99@8
|
315 }
|
joachim99@66
|
316 else
|
joachim99@66
|
317 {
|
joachim99@66
|
318 int nofColumns = 0;
|
joachim99@69
|
319 for( int i = 0; i< d->m_size; ++i )
|
joachim99@66
|
320 {
|
joachim99@69
|
321 if ( d->m_pLineData[i].width( d->m_pOptionDialog->m_tabSize ) > nofColumns )
|
joachim99@69
|
322 nofColumns = d->m_pLineData[i].width( d->m_pOptionDialog->m_tabSize );
|
joachim99@66
|
323 }
|
joachim99@66
|
324 return nofColumns;
|
joachim99@66
|
325 }
|
joachim99@8
|
326 }
|
joachim99@8
|
327
|
joachim99@8
|
328 int DiffTextWindow::getNofLines()
|
joachim99@8
|
329 {
|
joachim99@69
|
330 return d->m_bWordWrap ? d->m_diff3WrapLineVector.size() :
|
joachim99@69
|
331 d->m_pDiff3LineVector->size();
|
joachim99@66
|
332 }
|
joachim99@66
|
333
|
joachim99@66
|
334
|
joachim99@66
|
335 int DiffTextWindow::convertLineToDiff3LineIdx( int line )
|
joachim99@66
|
336 {
|
joachim99@69
|
337 if ( d->m_bWordWrap && d->m_diff3WrapLineVector.size()>0 )
|
joachim99@69
|
338 return d->m_diff3WrapLineVector[ min2( line, (int)d->m_diff3WrapLineVector.size()-1 ) ].diff3LineIndex;
|
joachim99@66
|
339 else
|
joachim99@66
|
340 return line;
|
joachim99@66
|
341 }
|
joachim99@66
|
342
|
joachim99@66
|
343 int DiffTextWindow::convertDiff3LineIdxToLine( int d3lIdx )
|
joachim99@66
|
344 {
|
joachim99@69
|
345 if ( d->m_bWordWrap && d->m_pDiff3LineVector!=0 && d->m_pDiff3LineVector->size()>0 )
|
joachim99@69
|
346 return (*d->m_pDiff3LineVector)[ min2( d3lIdx, (int)d->m_pDiff3LineVector->size()-1 ) ]->sumLinesNeededForDisplay;
|
joachim99@66
|
347 else
|
joachim99@66
|
348 return d3lIdx;
|
joachim99@8
|
349 }
|
joachim99@8
|
350
|
joachim99@8
|
351 /** Returns a line number where the linerange [line, line+nofLines] can
|
joachim99@8
|
352 be displayed best. If it fits into the currently visible range then
|
joachim99@8
|
353 the returned value is the current firstLine.
|
joachim99@8
|
354 */
|
joachim99@8
|
355 int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines )
|
joachim99@8
|
356 {
|
joachim99@8
|
357 int newFirstLine = firstLine;
|
joachim99@8
|
358 if ( line < firstLine || line + nofLines + 2 > firstLine + visibleLines )
|
joachim99@8
|
359 {
|
joachim99@8
|
360 if ( nofLines > visibleLines || nofLines <= ( 2*visibleLines / 3 - 1) )
|
joachim99@8
|
361 newFirstLine = line - visibleLines/3;
|
joachim99@8
|
362 else
|
joachim99@8
|
363 newFirstLine = line - (visibleLines - nofLines);
|
joachim99@8
|
364 }
|
joachim99@8
|
365
|
joachim99@8
|
366 return newFirstLine;
|
joachim99@8
|
367 }
|
joachim99@8
|
368
|
joachim99@8
|
369
|
joachim99@8
|
370 void DiffTextWindow::setFastSelectorRange( int line1, int nofLines )
|
joachim99@69
|
371 {
|
joachim99@69
|
372 d->m_fastSelectorLine1 = line1;
|
joachim99@69
|
373 d->m_fastSelectorNofLines = nofLines;
|
joachim99@8
|
374 if ( isVisible() )
|
joachim99@8
|
375 {
|
joachim99@66
|
376 int newFirstLine = getBestFirstLine(
|
joachim99@69
|
377 convertDiff3LineIdxToLine(d->m_fastSelectorLine1),
|
joachim99@69
|
378 convertDiff3LineIdxToLine(d->m_fastSelectorLine1+d->m_fastSelectorNofLines)-convertDiff3LineIdxToLine(d->m_fastSelectorLine1),
|
joachim99@69
|
379 d->m_firstLine,
|
joachim99@66
|
380 getNofVisibleLines()
|
joachim99@66
|
381 );
|
joachim99@69
|
382 if ( newFirstLine != d->m_firstLine )
|
joachim99@8
|
383 {
|
joachim99@69
|
384 scroll( 0, newFirstLine - d->m_firstLine );
|
joachim99@8
|
385 }
|
joachim99@8
|
386
|
joachim99@8
|
387 update();
|
joachim99@8
|
388 }
|
joachim99@8
|
389 }
|
joachim99@8
|
390
|
joachim99@8
|
391
|
joachim99@66
|
392 void DiffTextWindow::showStatusLine(int line )
|
joachim99@8
|
393 {
|
joachim99@66
|
394 int d3lIdx = convertLineToDiff3LineIdx( line );
|
joachim99@98
|
395 if( d->m_pDiff3LineVector!=0 && d3lIdx >= 0 && d3lIdx<(int)d->m_pDiff3LineVector->size() )
|
joachim99@8
|
396 {
|
joachim99@69
|
397 const Diff3Line* pD3l = (*d->m_pDiff3LineVector)[d3lIdx];
|
joachim99@69
|
398 if ( pD3l != 0 )
|
joachim99@69
|
399 {
|
joachim99@69
|
400 int l = pD3l->getLineInFile( d->m_winIdx );
|
joachim99@8
|
401
|
joachim99@75
|
402 QString s = i18n("File") + " " + d->m_filename;
|
joachim99@69
|
403 if ( l!=-1 )
|
joachim99@75
|
404 s += ": " + i18n("Line") + " " + QString::number( l+1 );
|
joachim99@69
|
405 else
|
joachim99@75
|
406 s += ": " + i18n("Line not available");
|
joachim99@75
|
407 if (d->m_pStatusBar!=0) d->m_pStatusBar->showMessage(s);
|
joachim99@69
|
408
|
joachim99@69
|
409 emit lineClicked( d->m_winIdx, l );
|
joachim99@69
|
410 }
|
joachim99@8
|
411 }
|
joachim99@8
|
412 }
|
joachim99@8
|
413
|
joachim99@66
|
414 void DiffTextWindow::focusInEvent(QFocusEvent* e)
|
joachim99@66
|
415 {
|
joachim99@66
|
416 emit gotFocus();
|
joachim99@66
|
417 QWidget::focusInEvent(e);
|
joachim99@66
|
418 }
|
joachim99@8
|
419
|
joachim99@8
|
420 void DiffTextWindow::mousePressEvent ( QMouseEvent* e )
|
joachim99@8
|
421 {
|
joachim99@69
|
422 if ( e->button() == Qt::LeftButton )
|
joachim99@8
|
423 {
|
joachim99@8
|
424 int line;
|
joachim99@8
|
425 int pos;
|
joachim99@8
|
426 convertToLinePos( e->x(), e->y(), line, pos );
|
joachim99@69
|
427 if ( pos < d->m_firstColumn )
|
joachim99@8
|
428 {
|
joachim99@66
|
429 emit setFastSelectorLine( convertLineToDiff3LineIdx(line) );
|
joachim99@69
|
430 d->m_selection.firstLine = -1; // Disable current d->m_selection
|
joachim99@8
|
431 }
|
joachim99@8
|
432 else
|
joachim99@8
|
433 { // Selection
|
joachim99@8
|
434 resetSelection();
|
joachim99@69
|
435 d->m_selection.start( line, pos );
|
joachim99@69
|
436 d->m_selection.end( line, pos );
|
joachim99@69
|
437 d->m_bSelectionInProgress = true;
|
joachim99@69
|
438 d->m_lastKnownMousePos = e->pos();
|
joachim99@8
|
439
|
joachim99@66
|
440 showStatusLine( line );
|
joachim99@8
|
441 }
|
joachim99@8
|
442 }
|
joachim99@8
|
443 }
|
joachim99@8
|
444
|
joachim99@68
|
445 bool isCTokenChar( QChar c )
|
joachim99@8
|
446 {
|
joachim99@8
|
447 return (c=='_') ||
|
joachim99@8
|
448 ( c>='A' && c<='Z' ) || ( c>='a' && c<='z' ) ||
|
joachim99@8
|
449 (c>='0' && c<='9');
|
joachim99@8
|
450 }
|
joachim99@8
|
451
|
joachim99@8
|
452 /// Calculate where a token starts and ends, given the x-position on screen.
|
joachim99@69
|
453 void calcTokenPos( const QString& s, int posOnScreen, int& pos1, int& pos2, int tabSize )
|
joachim99@8
|
454 {
|
joachim99@8
|
455 // Cursor conversions that consider g_tabSize
|
joachim99@69
|
456 int pos = convertToPosInText( s, max2( 0, posOnScreen ), tabSize );
|
joachim99@68
|
457 if ( pos>=(int)s.length() )
|
joachim99@8
|
458 {
|
joachim99@68
|
459 pos1=s.length();
|
joachim99@68
|
460 pos2=s.length();
|
joachim99@8
|
461 return;
|
joachim99@8
|
462 }
|
joachim99@8
|
463
|
joachim99@8
|
464 pos1 = pos;
|
joachim99@8
|
465 pos2 = pos+1;
|
joachim99@8
|
466
|
joachim99@68
|
467 if( isCTokenChar( s[pos1] ) )
|
joachim99@8
|
468 {
|
joachim99@68
|
469 while( pos1>=0 && isCTokenChar( s[pos1] ) )
|
joachim99@8
|
470 --pos1;
|
joachim99@8
|
471 ++pos1;
|
joachim99@8
|
472
|
joachim99@68
|
473 while( pos2<(int)s.length() && isCTokenChar( s[pos2] ) )
|
joachim99@8
|
474 ++pos2;
|
joachim99@8
|
475 }
|
joachim99@8
|
476 }
|
joachim99@8
|
477
|
joachim99@8
|
478 void DiffTextWindow::mouseDoubleClickEvent( QMouseEvent* e )
|
joachim99@8
|
479 {
|
joachim99@69
|
480 d->m_bSelectionInProgress = false;
|
joachim99@69
|
481 d->m_lastKnownMousePos = e->pos();
|
joachim99@69
|
482 if ( e->button() == Qt::LeftButton )
|
joachim99@8
|
483 {
|
joachim99@8
|
484 int line;
|
joachim99@8
|
485 int pos;
|
joachim99@8
|
486 convertToLinePos( e->x(), e->y(), line, pos );
|
joachim99@8
|
487
|
joachim99@8
|
488 // Get the string data of the current line
|
joachim99@68
|
489 QString s;
|
joachim99@69
|
490 if ( d->m_bWordWrap )
|
joachim99@66
|
491 {
|
joachim99@75
|
492 if ( line<0 || line >= (int)d->m_diff3WrapLineVector.size() )
|
joachim99@75
|
493 return;
|
joachim99@69
|
494 const Diff3WrapLine& d3wl = d->m_diff3WrapLineVector[line];
|
joachim99@69
|
495 s = d->getString( d3wl.diff3LineIndex ).mid( d3wl.wrapLineOffset, d3wl.wrapLineLength );
|
joachim99@66
|
496 }
|
joachim99@66
|
497 else
|
joachim99@66
|
498 {
|
joachim99@75
|
499 if ( line<0 || line >= (int)d->m_pDiff3LineVector->size() )
|
joachim99@75
|
500 return;
|
joachim99@69
|
501 s = d->getString( line );
|
joachim99@66
|
502 }
|
joachim99@69
|
503
|
joachim99@8
|
504 if ( ! s.isEmpty() )
|
joachim99@8
|
505 {
|
joachim99@8
|
506 int pos1, pos2;
|
joachim99@69
|
507 calcTokenPos( s, pos, pos1, pos2, d->m_pOptionDialog->m_tabSize );
|
joachim99@8
|
508
|
joachim99@8
|
509 resetSelection();
|
joachim99@69
|
510 d->m_selection.start( line, convertToPosOnScreen( s, pos1, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@69
|
511 d->m_selection.end( line, convertToPosOnScreen( s, pos2, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@8
|
512 update();
|
joachim99@69
|
513 // emit d->m_selectionEnd() happens in the mouseReleaseEvent.
|
joachim99@66
|
514 showStatusLine( line );
|
joachim99@8
|
515 }
|
joachim99@8
|
516 }
|
joachim99@8
|
517 }
|
joachim99@8
|
518
|
joachim99@69
|
519 void DiffTextWindow::mouseReleaseEvent ( QMouseEvent* e )
|
joachim99@8
|
520 {
|
joachim99@69
|
521 d->m_bSelectionInProgress = false;
|
joachim99@69
|
522 d->m_lastKnownMousePos = e->pos();
|
joachim99@8
|
523 //if ( e->button() == LeftButton )
|
joachim99@8
|
524 {
|
joachim99@75
|
525 if (d->m_delayedDrawTimer)
|
joachim99@75
|
526 killTimer(d->m_delayedDrawTimer);
|
joachim99@69
|
527 d->m_delayedDrawTimer = 0;
|
joachim99@69
|
528 if (d->m_selection.firstLine != -1 )
|
joachim99@8
|
529 {
|
joachim99@8
|
530 emit selectionEnd();
|
joachim99@8
|
531 }
|
joachim99@8
|
532 }
|
joachim99@69
|
533 d->m_scrollDeltaX=0;
|
joachim99@69
|
534 d->m_scrollDeltaY=0;
|
joachim99@8
|
535 }
|
joachim99@8
|
536
|
joachim99@69
|
537 inline int sqr(int x){return x*x;}
|
joachim99@69
|
538
|
joachim99@8
|
539 void DiffTextWindow::mouseMoveEvent ( QMouseEvent * e )
|
joachim99@8
|
540 {
|
joachim99@8
|
541 int line;
|
joachim99@8
|
542 int pos;
|
joachim99@8
|
543 convertToLinePos( e->x(), e->y(), line, pos );
|
joachim99@69
|
544 d->m_lastKnownMousePos = e->pos();
|
joachim99@69
|
545
|
joachim99@69
|
546 if (d->m_selection.firstLine != -1 )
|
joachim99@8
|
547 {
|
joachim99@69
|
548 d->m_selection.end( line, pos );
|
joachim99@8
|
549
|
joachim99@66
|
550 showStatusLine( line );
|
joachim99@8
|
551
|
joachim99@8
|
552 // Scroll because mouse moved out of the window
|
joachim99@8
|
553 const QFontMetrics& fm = fontMetrics();
|
joachim99@8
|
554 int fontWidth = fm.width('W');
|
joachim99@8
|
555 int deltaX=0;
|
joachim99@8
|
556 int deltaY=0;
|
joachim99@69
|
557 if ( ! d->m_pOptionDialog->m_bRightToLeftLanguage )
|
joachim99@68
|
558 {
|
joachim99@69
|
559 if ( e->x() < d->leftInfoWidth()*fontWidth ) deltaX = -1 - abs(e->x()-d->leftInfoWidth()*fontWidth)/fontWidth;
|
joachim99@69
|
560 if ( e->x() > width() ) deltaX = +1 + abs(e->x()-width())/fontWidth;
|
joachim99@68
|
561 }
|
joachim99@68
|
562 else
|
joachim99@68
|
563 {
|
joachim99@69
|
564 if ( e->x() > width()-1-d->leftInfoWidth()*fontWidth ) deltaX=+1+ abs(e->x() - (width()-1-d->leftInfoWidth()*fontWidth)) / fontWidth;
|
joachim99@69
|
565 if ( e->x() < fontWidth ) deltaX=-1- abs(e->x()-fontWidth)/fontWidth;
|
joachim99@68
|
566 }
|
joachim99@69
|
567 if ( e->y() < 0 ) deltaY = -1 - sqr( e->y() ) / sqr(fm.height());
|
joachim99@69
|
568 if ( e->y() > height() ) deltaY = +1 + sqr( e->y() - height() ) / sqr(fm.height());
|
joachim99@80
|
569 if ( (deltaX != 0 && d->m_scrollDeltaX!=deltaX) || (deltaY!= 0 && d->m_scrollDeltaY!=deltaY) )
|
joachim99@8
|
570 {
|
joachim99@69
|
571 d->m_scrollDeltaX = deltaX;
|
joachim99@69
|
572 d->m_scrollDeltaY = deltaY;
|
joachim99@8
|
573 emit scroll( deltaX, deltaY );
|
joachim99@80
|
574 if (d->m_delayedDrawTimer)
|
joachim99@80
|
575 killTimer( d->m_delayedDrawTimer );
|
joachim99@69
|
576 d->m_delayedDrawTimer = startTimer(50);
|
joachim99@66
|
577 }
|
joachim99@66
|
578 else
|
joachim99@66
|
579 {
|
joachim99@69
|
580 d->m_scrollDeltaX = deltaX;
|
joachim99@69
|
581 d->m_scrollDeltaY = deltaY;
|
joachim99@69
|
582 d->myUpdate(0);
|
joachim99@8
|
583 }
|
joachim99@8
|
584 }
|
joachim99@8
|
585 }
|
joachim99@8
|
586
|
joachim99@8
|
587
|
joachim99@69
|
588 void DiffTextWindowData::myUpdate(int afterMilliSecs)
|
joachim99@8
|
589 {
|
joachim99@75
|
590 if (m_delayedDrawTimer)
|
joachim99@75
|
591 m_pDiffTextWindow->killTimer( m_delayedDrawTimer );
|
joachim99@8
|
592 m_bMyUpdate = true;
|
joachim99@69
|
593 m_delayedDrawTimer = m_pDiffTextWindow->startTimer( afterMilliSecs );
|
joachim99@8
|
594 }
|
joachim99@8
|
595
|
joachim99@8
|
596 void DiffTextWindow::timerEvent(QTimerEvent*)
|
joachim99@8
|
597 {
|
joachim99@69
|
598 killTimer(d->m_delayedDrawTimer);
|
joachim99@69
|
599 d->m_delayedDrawTimer = 0;
|
joachim99@8
|
600
|
joachim99@69
|
601 if ( d->m_bMyUpdate )
|
joachim99@8
|
602 {
|
joachim99@69
|
603 int fontHeight = fontMetrics().height();
|
joachim99@69
|
604
|
joachim99@69
|
605 if ( d->m_selection.oldLastLine != -1 )
|
joachim99@69
|
606 {
|
joachim99@69
|
607 int lastLine;
|
joachim99@69
|
608 int firstLine;
|
joachim99@69
|
609 if ( d->m_selection.oldFirstLine != -1 )
|
joachim99@69
|
610 {
|
joachim99@69
|
611 firstLine = min3( d->m_selection.oldFirstLine, d->m_selection.lastLine, d->m_selection.oldLastLine );
|
joachim99@69
|
612 lastLine = max3( d->m_selection.oldFirstLine, d->m_selection.lastLine, d->m_selection.oldLastLine );
|
joachim99@69
|
613 }
|
joachim99@69
|
614 else
|
joachim99@69
|
615 {
|
joachim99@69
|
616 firstLine = min2( d->m_selection.lastLine, d->m_selection.oldLastLine );
|
joachim99@69
|
617 lastLine = max2( d->m_selection.lastLine, d->m_selection.oldLastLine );
|
joachim99@69
|
618 }
|
joachim99@69
|
619 int y1 = ( firstLine - d->m_firstLine ) * fontHeight;
|
joachim99@69
|
620 int y2 = min2( height(), ( lastLine - d->m_firstLine + 1 ) * fontHeight );
|
joachim99@69
|
621
|
joachim99@69
|
622 if ( y1<height() && y2>0 )
|
joachim99@69
|
623 {
|
joachim99@69
|
624 QRect invalidRect = QRect( 0, y1, width(), y2-y1 );
|
joachim99@69
|
625 update( invalidRect );
|
joachim99@69
|
626 }
|
joachim99@69
|
627 }
|
joachim99@69
|
628
|
joachim99@69
|
629 d->m_bMyUpdate = false;
|
joachim99@8
|
630 }
|
joachim99@8
|
631
|
joachim99@69
|
632 if ( d->m_scrollDeltaX != 0 || d->m_scrollDeltaY != 0 )
|
joachim99@8
|
633 {
|
joachim99@69
|
634 d->m_selection.end( d->m_selection.lastLine + d->m_scrollDeltaY, d->m_selection.lastPos + d->m_scrollDeltaX );
|
joachim99@69
|
635 emit scroll( d->m_scrollDeltaX, d->m_scrollDeltaY );
|
joachim99@69
|
636 killTimer(d->m_delayedDrawTimer);
|
joachim99@69
|
637 d->m_delayedDrawTimer = startTimer(50);
|
joachim99@8
|
638 }
|
joachim99@8
|
639 }
|
joachim99@8
|
640
|
joachim99@8
|
641 void DiffTextWindow::resetSelection()
|
joachim99@8
|
642 {
|
joachim99@69
|
643 d->m_selection.reset();
|
joachim99@8
|
644 update();
|
joachim99@8
|
645 }
|
joachim99@8
|
646
|
joachim99@8
|
647 void DiffTextWindow::convertToLinePos( int x, int y, int& line, int& pos )
|
joachim99@8
|
648 {
|
joachim99@8
|
649 const QFontMetrics& fm = fontMetrics();
|
joachim99@8
|
650 int fontHeight = fm.height();
|
joachim99@8
|
651 int fontWidth = fm.width('W');
|
joachim99@69
|
652 int xOffset = ( d->leftInfoWidth() - d->m_firstColumn ) * fontWidth;
|
joachim99@8
|
653
|
joachim99@69
|
654 int yOffset = - d->m_firstLine * fontHeight;
|
joachim99@8
|
655
|
joachim99@8
|
656 line = ( y - yOffset ) / fontHeight;
|
joachim99@69
|
657 if ( ! d->m_pOptionDialog->m_bRightToLeftLanguage )
|
joachim99@68
|
658 pos = ( x - xOffset ) / fontWidth;
|
joachim99@68
|
659 else
|
joachim99@68
|
660 pos = ( (width() - 1 - x) - xOffset ) / fontWidth;
|
joachim99@8
|
661 }
|
joachim99@8
|
662
|
joachim99@8
|
663 int Selection::firstPosInLine(int l)
|
joachim99@8
|
664 {
|
joachim99@8
|
665 assert( firstLine != -1 );
|
joachim99@8
|
666
|
joachim99@8
|
667 int l1 = firstLine;
|
joachim99@8
|
668 int l2 = lastLine;
|
joachim99@8
|
669 int p1 = firstPos;
|
joachim99@8
|
670 int p2 = lastPos;
|
joachim99@8
|
671 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
|
joachim99@8
|
672 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
|
joachim99@8
|
673
|
joachim99@8
|
674 if ( l==l1 )
|
joachim99@8
|
675 return p1;
|
joachim99@8
|
676 return 0;
|
joachim99@8
|
677 }
|
joachim99@8
|
678
|
joachim99@8
|
679 int Selection::lastPosInLine(int l)
|
joachim99@8
|
680 {
|
joachim99@8
|
681 assert( firstLine != -1 );
|
joachim99@8
|
682
|
joachim99@8
|
683 int l1 = firstLine;
|
joachim99@8
|
684 int l2 = lastLine;
|
joachim99@8
|
685 int p1 = firstPos;
|
joachim99@8
|
686 int p2 = lastPos;
|
joachim99@8
|
687
|
joachim99@8
|
688 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
|
joachim99@8
|
689 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
|
joachim99@8
|
690
|
joachim99@8
|
691 if ( l==l2 )
|
joachim99@8
|
692 return p2;
|
joachim99@8
|
693 return INT_MAX;
|
joachim99@8
|
694 }
|
joachim99@8
|
695
|
joachim99@8
|
696 bool Selection::within( int l, int p )
|
joachim99@8
|
697 {
|
joachim99@8
|
698 if ( firstLine == -1 ) return false;
|
joachim99@8
|
699 int l1 = firstLine;
|
joachim99@8
|
700 int l2 = lastLine;
|
joachim99@8
|
701 int p1 = firstPos;
|
joachim99@8
|
702 int p2 = lastPos;
|
joachim99@8
|
703 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
|
joachim99@8
|
704 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
|
joachim99@8
|
705 if( l1 <= l && l <= l2 )
|
joachim99@8
|
706 {
|
joachim99@8
|
707 if ( l1==l2 )
|
joachim99@8
|
708 return p>=p1 && p<p2;
|
joachim99@8
|
709 if ( l==l1 )
|
joachim99@8
|
710 return p>=p1;
|
joachim99@8
|
711 if ( l==l2 )
|
joachim99@8
|
712 return p<p2;
|
joachim99@8
|
713 return true;
|
joachim99@8
|
714 }
|
joachim99@8
|
715 return false;
|
joachim99@8
|
716 }
|
joachim99@8
|
717
|
joachim99@8
|
718 bool Selection::lineWithin( int l )
|
joachim99@8
|
719 {
|
joachim99@8
|
720 if ( firstLine == -1 ) return false;
|
joachim99@8
|
721 int l1 = firstLine;
|
joachim99@8
|
722 int l2 = lastLine;
|
joachim99@8
|
723
|
joachim99@8
|
724 if ( l1>l2 ){ std::swap(l1,l2); }
|
joachim99@8
|
725
|
joachim99@8
|
726 return ( l1 <= l && l <= l2 );
|
joachim99@8
|
727 }
|
joachim99@8
|
728
|
joachim99@80
|
729 class DrawTextOptimizer
|
joachim99@80
|
730 // Drawing continuous text is much faster than drawing one char after another.
|
joachim99@80
|
731 {
|
joachim99@80
|
732 private:
|
joachim99@80
|
733 QFont m_font;
|
joachim99@80
|
734 QPen m_pen;
|
joachim99@80
|
735 QString m_text;
|
joachim99@80
|
736 QPoint m_pos;
|
joachim99@80
|
737 MyPainter* m_pPainter;
|
joachim99@80
|
738 QFontMetrics m_fm;
|
joachim99@80
|
739 void draw()
|
joachim99@80
|
740 {
|
joachim99@80
|
741 if ( m_pPainter && !m_text.isEmpty() )
|
joachim99@80
|
742 {
|
joachim99@80
|
743 m_pPainter->setFont( m_font );
|
joachim99@80
|
744 m_pPainter->setPen( m_pen );
|
joachim99@80
|
745 m_pPainter->drawText( m_pos.x(), m_pos.y(), m_text, true );
|
joachim99@80
|
746 m_text = QString();
|
joachim99@80
|
747 }
|
joachim99@80
|
748 }
|
joachim99@80
|
749 public:
|
joachim99@80
|
750 DrawTextOptimizer( MyPainter* pPainter )
|
joachim99@80
|
751 : m_fm(pPainter->fontMetrics())
|
joachim99@80
|
752 {
|
joachim99@80
|
753 m_pPainter = pPainter;
|
joachim99@80
|
754 m_font = m_pPainter->font();
|
joachim99@80
|
755 m_pen = m_pPainter->pen();
|
joachim99@80
|
756 }
|
joachim99@80
|
757 ~DrawTextOptimizer() { end(); }
|
joachim99@80
|
758 void setFont( const QFont& f )
|
joachim99@80
|
759 {
|
joachim99@80
|
760 if ( f!=m_font )
|
joachim99@80
|
761 {
|
joachim99@80
|
762 draw();
|
joachim99@80
|
763 m_font = f;
|
joachim99@80
|
764 m_fm = m_pPainter->fontMetrics();
|
joachim99@80
|
765 }
|
joachim99@80
|
766 }
|
joachim99@80
|
767 void setPen( const QPen& pen )
|
joachim99@80
|
768 {
|
joachim99@80
|
769 if ( pen!=m_pen )
|
joachim99@80
|
770 {
|
joachim99@80
|
771 draw();
|
joachim99@80
|
772 m_pen = pen;
|
joachim99@80
|
773 }
|
joachim99@80
|
774 }
|
joachim99@80
|
775 void drawText( int x, int y, const QString& s )
|
joachim99@80
|
776 {
|
joachim99@80
|
777 if ( y!=m_pos.y() || x != m_pos.x()+m_text.length()*m_fm.width("W") )
|
joachim99@80
|
778 {
|
joachim99@80
|
779 draw();
|
joachim99@80
|
780 m_pos = QPoint(x,y);
|
joachim99@80
|
781 }
|
joachim99@80
|
782 m_text += s;
|
joachim99@80
|
783 }
|
joachim99@80
|
784 void end()
|
joachim99@80
|
785 {
|
joachim99@80
|
786 draw();
|
joachim99@80
|
787 }
|
joachim99@80
|
788 };
|
joachim99@68
|
789
|
joachim99@69
|
790 void DiffTextWindowData::writeLine(
|
joachim99@68
|
791 MyPainter& p,
|
joachim99@8
|
792 const LineData* pld,
|
joachim99@8
|
793 const DiffList* pLineDiff1,
|
joachim99@8
|
794 const DiffList* pLineDiff2,
|
joachim99@8
|
795 int line,
|
joachim99@8
|
796 int whatChanged,
|
joachim99@8
|
797 int whatChanged2,
|
joachim99@69
|
798 int srcLineIdx,
|
joachim99@66
|
799 int wrapLineOffset,
|
joachim99@66
|
800 int wrapLineLength,
|
joachim99@69
|
801 bool bWrapLine,
|
joachim99@69
|
802 const QRect& invalidRect,
|
joachim99@69
|
803 int deviceWidth
|
joachim99@8
|
804 )
|
joachim99@8
|
805 {
|
joachim99@69
|
806 QFont normalFont = p.font();
|
joachim99@8
|
807 QFont diffFont = normalFont;
|
joachim99@8
|
808 diffFont.setItalic( m_pOptionDialog->m_bItalicForDeltas );
|
joachim99@69
|
809 const QFontMetrics& fm = p.fontMetrics();
|
joachim99@8
|
810 int fontHeight = fm.height();
|
joachim99@8
|
811 int fontAscent = fm.ascent();
|
joachim99@8
|
812 int fontDescent = fm.descent();
|
joachim99@8
|
813 int fontWidth = fm.width('W');
|
joachim99@8
|
814
|
joachim99@69
|
815 int xOffset = (leftInfoWidth() - m_firstColumn)*fontWidth;
|
joachim99@69
|
816 int yOffset = (line-m_firstLine) * fontHeight;
|
joachim99@8
|
817
|
joachim99@69
|
818 QRect lineRect( 0, yOffset, deviceWidth, fontHeight );
|
joachim99@69
|
819 if ( ! invalidRect.intersects( lineRect ) )
|
joachim99@69
|
820 {
|
joachim99@8
|
821 return;
|
joachim99@69
|
822 }
|
joachim99@8
|
823
|
joachim99@69
|
824 int fastSelectorLine1 = m_pDiffTextWindow->convertDiff3LineIdxToLine(m_fastSelectorLine1);
|
joachim99@69
|
825 int fastSelectorLine2 = m_pDiffTextWindow->convertDiff3LineIdxToLine(m_fastSelectorLine1+m_fastSelectorNofLines)-1;
|
joachim99@69
|
826
|
joachim99@66
|
827 bool bFastSelectionRange = (line>=fastSelectorLine1 && line<= fastSelectorLine2 );
|
joachim99@8
|
828 QColor bgColor = m_pOptionDialog->m_bgColor;
|
joachim99@8
|
829 QColor diffBgColor = m_pOptionDialog->m_diffBgColor;
|
joachim99@8
|
830
|
joachim99@8
|
831 if ( bFastSelectionRange )
|
joachim99@8
|
832 {
|
joachim99@8
|
833 bgColor = m_pOptionDialog->m_currentRangeBgColor;
|
joachim99@8
|
834 diffBgColor = m_pOptionDialog->m_currentRangeDiffBgColor;
|
joachim99@8
|
835 }
|
joachim99@8
|
836
|
joachim99@69
|
837 if ( yOffset+fontHeight<invalidRect.top() || invalidRect.bottom() < yOffset-fontHeight )
|
joachim99@8
|
838 return;
|
joachim99@8
|
839
|
joachim99@8
|
840 int changed = whatChanged;
|
joachim99@8
|
841 if ( pLineDiff1 != 0 ) changed |= 1;
|
joachim99@8
|
842 if ( pLineDiff2 != 0 ) changed |= 2;
|
joachim99@8
|
843
|
joachim99@8
|
844 QColor c = m_pOptionDialog->m_fgColor;
|
joachim99@80
|
845 p.setPen(c);
|
joachim99@8
|
846 if ( changed == 2 ) {
|
joachim99@8
|
847 c = m_cDiff2;
|
joachim99@8
|
848 } else if ( changed == 1 ) {
|
joachim99@8
|
849 c = m_cDiff1;
|
joachim99@8
|
850 } else if ( changed == 3 ) {
|
joachim99@8
|
851 c = m_cDiffBoth;
|
joachim99@8
|
852 }
|
joachim99@8
|
853
|
joachim99@69
|
854 p.fillRect( leftInfoWidth()*fontWidth, yOffset, deviceWidth, fontHeight, bgColor );
|
joachim99@51
|
855
|
joachim99@8
|
856 if (pld!=0)
|
joachim99@8
|
857 {
|
joachim99@8
|
858 // First calculate the "changed" information for each character.
|
joachim99@8
|
859 int i=0;
|
joachim99@80
|
860 QString lineString( pld->pLine, pld->size );
|
joachim99@8
|
861 std::vector<UINT8> charChanged( pld->size );
|
joachim99@80
|
862 Merger merger( pLineDiff1, pLineDiff2 );
|
joachim99@80
|
863 while( ! merger.isEndReached() && i<pld->size )
|
joachim99@8
|
864 {
|
joachim99@80
|
865 if ( i < pld->size )
|
joachim99@8
|
866 {
|
joachim99@80
|
867 charChanged[i] = merger.whatChanged();
|
joachim99@80
|
868 ++i;
|
joachim99@8
|
869 }
|
joachim99@80
|
870 merger.next();
|
joachim99@8
|
871 }
|
joachim99@8
|
872
|
joachim99@68
|
873 QString s=" ";
|
joachim99@8
|
874 // Convert tabs
|
joachim99@8
|
875 int outPos = 0;
|
joachim99@69
|
876
|
joachim99@68
|
877 int lineLength = m_bWordWrap ? wrapLineOffset+wrapLineLength : lineString.length();
|
joachim99@69
|
878
|
joachim99@80
|
879 DrawTextOptimizer dto( &p );
|
joachim99@80
|
880
|
joachim99@66
|
881 for( i=wrapLineOffset; i<lineLength; ++i )
|
joachim99@8
|
882 {
|
joachim99@8
|
883 int spaces = 1;
|
joachim99@8
|
884
|
joachim99@68
|
885 if ( lineString[i]=='\t' )
|
joachim99@8
|
886 {
|
joachim99@69
|
887 spaces = tabber( outPos, m_pOptionDialog->m_tabSize );
|
joachim99@8
|
888 s[0] = ' ';
|
joachim99@8
|
889 }
|
joachim99@8
|
890 else
|
joachim99@8
|
891 {
|
joachim99@68
|
892 s[0] = lineString[i];
|
joachim99@8
|
893 }
|
joachim99@8
|
894
|
joachim99@8
|
895 QColor c = m_pOptionDialog->m_fgColor;
|
joachim99@8
|
896 int cchanged = charChanged[i] | whatChanged;
|
joachim99@8
|
897
|
joachim99@8
|
898 if ( cchanged == 2 ) {
|
joachim99@8
|
899 c = m_cDiff2;
|
joachim99@8
|
900 } else if ( cchanged == 1 ) {
|
joachim99@8
|
901 c = m_cDiff1;
|
joachim99@8
|
902 } else if ( cchanged == 3 ) {
|
joachim99@8
|
903 c = m_cDiffBoth;
|
joachim99@8
|
904 }
|
joachim99@8
|
905
|
joachim99@51
|
906 if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 && !m_pOptionDialog->m_bShowWhiteSpace )
|
joachim99@51
|
907 {
|
joachim99@51
|
908 // The user doesn't want to see highlighted white space.
|
joachim99@51
|
909 c = m_pOptionDialog->m_fgColor;
|
joachim99@51
|
910 }
|
joachim99@51
|
911
|
joachim99@8
|
912 QRect outRect( xOffset + fontWidth*outPos, yOffset, fontWidth*spaces, fontHeight );
|
joachim99@68
|
913 if ( m_pOptionDialog->m_bRightToLeftLanguage )
|
joachim99@75
|
914 outRect = QRect( deviceWidth-1-(xOffset + fontWidth*outPos), yOffset, -fontWidth*spaces, fontHeight ).normalized();
|
joachim99@69
|
915 if ( invalidRect.intersects( outRect ) )
|
joachim99@8
|
916 {
|
joachim99@69
|
917 if( !m_selection.within( line, outPos ) )
|
joachim99@8
|
918 {
|
joachim99@51
|
919
|
joachim99@8
|
920 if( c!=m_pOptionDialog->m_fgColor )
|
joachim99@8
|
921 {
|
joachim99@8
|
922 QColor lightc = diffBgColor;
|
joachim99@8
|
923 p.fillRect( xOffset + fontWidth*outPos, yOffset,
|
joachim99@8
|
924 fontWidth*spaces, fontHeight, lightc );
|
joachim99@80
|
925 dto.setFont(diffFont);
|
joachim99@8
|
926 }
|
joachim99@8
|
927
|
joachim99@80
|
928 dto.setPen( c );
|
joachim99@8
|
929 if ( s[0]==' ' && c!=m_pOptionDialog->m_fgColor && charChanged[i]!=0 )
|
joachim99@8
|
930 {
|
joachim99@51
|
931 if ( m_pOptionDialog->m_bShowWhiteSpaceCharacters && m_pOptionDialog->m_bShowWhiteSpace)
|
joachim99@8
|
932 {
|
joachim99@8
|
933 p.fillRect( xOffset + fontWidth*outPos, yOffset+fontAscent,
|
joachim99@80
|
934 fontWidth*spaces-1, fontDescent, c );
|
joachim99@8
|
935 }
|
joachim99@8
|
936 }
|
joachim99@8
|
937 else
|
joachim99@8
|
938 {
|
joachim99@80
|
939 dto.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, s );
|
joachim99@8
|
940 }
|
joachim99@80
|
941 dto.setFont(normalFont);
|
joachim99@8
|
942 }
|
joachim99@8
|
943 else
|
joachim99@8
|
944 {
|
joachim99@8
|
945 p.fillRect( xOffset + fontWidth*outPos, yOffset,
|
joachim99@75
|
946 fontWidth*(spaces), fontHeight, m_pDiffTextWindow->palette().highlight() );
|
joachim99@8
|
947
|
joachim99@80
|
948 dto.setPen( m_pDiffTextWindow->palette().highlightedText().color() );
|
joachim99@80
|
949 dto.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, s );
|
joachim99@8
|
950
|
joachim99@69
|
951 m_selection.bSelectionContainsData = true;
|
joachim99@8
|
952 }
|
joachim99@8
|
953 }
|
joachim99@8
|
954
|
joachim99@8
|
955 outPos += spaces;
|
joachim99@80
|
956 } // end for
|
joachim99@80
|
957 dto.end();
|
joachim99@69
|
958 if( m_selection.lineWithin( line ) && m_selection.lineWithin( line+1 ) )
|
joachim99@8
|
959 {
|
joachim99@8
|
960 p.fillRect( xOffset + fontWidth*outPos, yOffset,
|
joachim99@75
|
961 deviceWidth, fontHeight, m_pDiffTextWindow->palette().highlight() );
|
joachim99@8
|
962 }
|
joachim99@8
|
963 }
|
joachim99@8
|
964
|
joachim99@69
|
965 p.fillRect( 0, yOffset, leftInfoWidth()*fontWidth, fontHeight, m_pOptionDialog->m_bgColor );
|
joachim99@8
|
966
|
joachim99@8
|
967 xOffset = (m_lineNumberWidth+2)*fontWidth;
|
joachim99@8
|
968 int xLeft = m_lineNumberWidth*fontWidth;
|
joachim99@8
|
969 p.setPen( m_pOptionDialog->m_fgColor );
|
joachim99@8
|
970 if ( pld!=0 )
|
joachim99@8
|
971 {
|
joachim99@66
|
972 if ( m_pOptionDialog->m_bShowLineNumbers && !bWrapLine )
|
joachim99@8
|
973 {
|
joachim99@8
|
974 QString num;
|
joachim99@69
|
975 num.sprintf( "%0*d", m_lineNumberWidth, srcLineIdx+1);
|
joachim99@8
|
976 p.drawText( 0, yOffset + fontAscent, num );
|
joachim99@8
|
977 //p.drawLine( xLeft -1, yOffset, xLeft -1, yOffset+fontHeight-1 );
|
joachim99@8
|
978 }
|
joachim99@66
|
979 if ( !bWrapLine || wrapLineLength>0 )
|
joachim99@66
|
980 {
|
joachim99@69
|
981 p.setPen( QPen( m_pOptionDialog->m_fgColor, 0, bWrapLine ? Qt::DotLine : Qt::SolidLine) );
|
joachim99@66
|
982 p.drawLine( xOffset +1, yOffset, xOffset +1, yOffset+fontHeight-1 );
|
joachim99@69
|
983 p.setPen( QPen( m_pOptionDialog->m_fgColor, 0, Qt::SolidLine) );
|
joachim99@66
|
984 }
|
joachim99@8
|
985 }
|
joachim99@8
|
986 if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 )//&& whatChanged==0 )
|
joachim99@8
|
987 {
|
joachim99@51
|
988 if ( m_pOptionDialog->m_bShowWhiteSpace )
|
joachim99@51
|
989 {
|
joachim99@51
|
990 p.setBrushOrigin(0,0);
|
joachim99@69
|
991 p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, QBrush(c,Qt::Dense5Pattern) );
|
joachim99@51
|
992 }
|
joachim99@8
|
993 }
|
joachim99@8
|
994 else
|
joachim99@8
|
995 {
|
joachim99@8
|
996 p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, c==m_pOptionDialog->m_fgColor ? bgColor : c );
|
joachim99@8
|
997 }
|
joachim99@8
|
998
|
joachim99@8
|
999 if ( bFastSelectionRange )
|
joachim99@8
|
1000 {
|
joachim99@8
|
1001 p.fillRect( xOffset + fontWidth-1, yOffset, 3, fontHeight, m_pOptionDialog->m_fgColor );
|
joachim99@8
|
1002 }
|
joachim99@69
|
1003
|
joachim99@69
|
1004 // Check if line needs a manual diff help mark
|
joachim99@69
|
1005 ManualDiffHelpList::const_iterator ci;
|
joachim99@69
|
1006 for( ci = m_pManualDiffHelpList->begin(); ci!=m_pManualDiffHelpList->end(); ++ci)
|
joachim99@69
|
1007 {
|
joachim99@69
|
1008 const ManualDiffHelpEntry& mdhe=*ci;
|
joachim99@69
|
1009 int rangeLine1 = -1;
|
joachim99@69
|
1010 int rangeLine2 = -1;
|
joachim99@69
|
1011 if (m_winIdx==1 ) { rangeLine1 = mdhe.lineA1; rangeLine2= mdhe.lineA2; }
|
joachim99@69
|
1012 if (m_winIdx==2 ) { rangeLine1 = mdhe.lineB1; rangeLine2= mdhe.lineB2; }
|
joachim99@69
|
1013 if (m_winIdx==3 ) { rangeLine1 = mdhe.lineC1; rangeLine2= mdhe.lineC2; }
|
joachim99@69
|
1014 if ( rangeLine1>=0 && rangeLine2>=0 && srcLineIdx >= rangeLine1 && srcLineIdx <= rangeLine2 )
|
joachim99@69
|
1015 {
|
joachim99@69
|
1016 p.fillRect( xOffset - fontWidth, yOffset, fontWidth-1, fontHeight, m_pOptionDialog->m_manualHelpRangeColor );
|
joachim99@69
|
1017 break;
|
joachim99@69
|
1018 }
|
joachim99@69
|
1019 }
|
joachim99@8
|
1020 }
|
joachim99@8
|
1021
|
joachim99@8
|
1022 void DiffTextWindow::paintEvent( QPaintEvent* e )
|
joachim99@8
|
1023 {
|
joachim99@98
|
1024 QRect invalidRect = e->rect();
|
joachim99@98
|
1025 if ( invalidRect.isEmpty() || ! d->m_bPaintingAllowed )
|
joachim99@66
|
1026 return;
|
joachim99@8
|
1027
|
joachim99@98
|
1028 if ( d->m_pDiff3LineVector==0 || ( d->m_diff3WrapLineVector.empty() && d->m_bWordWrap ) )
|
joachim99@98
|
1029 {
|
joachim99@98
|
1030 QPainter p(this);
|
joachim99@98
|
1031 p.fillRect( invalidRect, d->m_pOptionDialog->m_bgColor );
|
joachim99@69
|
1032 return;
|
joachim99@98
|
1033 }
|
joachim99@98
|
1034
|
joachim99@69
|
1035 bool bOldSelectionContainsData = d->m_selection.bSelectionContainsData;
|
joachim99@69
|
1036 d->m_selection.bSelectionContainsData = false;
|
joachim99@69
|
1037
|
joachim99@69
|
1038 int endLine = min2( d->m_firstLine + getNofVisibleLines()+2, getNofLines() );
|
joachim99@69
|
1039
|
joachim99@69
|
1040 //if ( invalidRect.size()==size() )
|
joachim99@69
|
1041 { // double buffering, obsolete with Qt4
|
joachim99@70
|
1042 //QPainter painter(this); // Remove for Qt4
|
joachim99@70
|
1043 //QPixmap pixmap( invalidRect.size() );// Remove for Qt4
|
joachim99@69
|
1044
|
joachim99@70
|
1045 MyPainter p( this, d->m_pOptionDialog->m_bRightToLeftLanguage, width(), fontMetrics().width('W') ); // For Qt4 change pixmap to this
|
joachim99@69
|
1046
|
joachim99@70
|
1047 //p.translate( -invalidRect.x(), -invalidRect.y() );// Remove for Qt4
|
joachim99@69
|
1048
|
joachim99@69
|
1049 p.setFont( font() );
|
joachim99@69
|
1050 p.QPainter::fillRect( invalidRect, d->m_pOptionDialog->m_bgColor );
|
joachim99@69
|
1051
|
joachim99@69
|
1052 d->draw( p, invalidRect, width(), d->m_firstLine, endLine );
|
joachim99@69
|
1053 // p.drawLine( m_invalidRect.x(), m_invalidRect.y(), m_invalidRect.right(), m_invalidRect.bottom() ); // For test only
|
joachim99@69
|
1054 p.end();
|
joachim99@69
|
1055
|
joachim99@70
|
1056 //painter.drawPixmap( invalidRect.x(), invalidRect.y(), pixmap );// Remove for Qt4
|
joachim99@69
|
1057 }
|
joachim99@69
|
1058 // else
|
joachim99@69
|
1059 // { // no double buffering
|
joachim99@69
|
1060 // MyPainter p( this, d->m_pOptionDialog->m_bRightToLeftLanguage, width(), fontMetrics().width('W') );
|
joachim99@69
|
1061 // p.setFont( font() );
|
joachim99@69
|
1062 // p.QPainter::fillRect( invalidRect, d->m_pOptionDialog->m_bgColor );
|
joachim99@69
|
1063 // d->draw( p, invalidRect, width(), d->m_firstLine, endLine );
|
joachim99@69
|
1064 // }
|
joachim99@69
|
1065
|
joachim99@69
|
1066
|
joachim99@69
|
1067 d->m_oldFirstLine = d->m_firstLine;
|
joachim99@69
|
1068 d->m_oldFirstColumn = d->m_firstColumn;
|
joachim99@69
|
1069 d->m_selection.oldLastLine = -1;
|
joachim99@69
|
1070 if ( d->m_selection.oldFirstLine !=-1 )
|
joachim99@69
|
1071 d->m_selection.oldFirstLine = -1;
|
joachim99@69
|
1072
|
joachim99@69
|
1073 if( !bOldSelectionContainsData && d->m_selection.bSelectionContainsData )
|
joachim99@69
|
1074 emit newSelection();
|
joachim99@69
|
1075 }
|
joachim99@69
|
1076
|
joachim99@69
|
1077 void DiffTextWindow::print( MyPainter& p, const QRect&, int firstLine, int nofLinesPerPage )
|
joachim99@69
|
1078 {
|
joachim99@69
|
1079 if ( d->m_pDiff3LineVector==0 || ! d->m_bPaintingAllowed ||
|
joachim99@69
|
1080 ( d->m_diff3WrapLineVector.empty() && d->m_bWordWrap ) )
|
joachim99@69
|
1081 return;
|
joachim99@69
|
1082 resetSelection();
|
joachim99@69
|
1083 // MyPainter p( this, d->m_pOptionDialog->m_bRightToLeftLanguage, width(), fontMetrics().width('W') );
|
joachim99@69
|
1084 int oldFirstLine = d->m_firstLine;
|
joachim99@69
|
1085 d->m_firstLine = firstLine;
|
joachim99@75
|
1086 QRect invalidRect = QRect(0,0,1000000000,1000000000);
|
joachim99@69
|
1087 QColor bgColor = d->m_pOptionDialog->m_bgColor;
|
joachim99@69
|
1088 d->m_pOptionDialog->m_bgColor = Qt::white;
|
joachim99@69
|
1089 d->draw( p, invalidRect, p.window().width(), firstLine, min2(firstLine+nofLinesPerPage,getNofLines()) );
|
joachim99@69
|
1090 d->m_pOptionDialog->m_bgColor = bgColor;
|
joachim99@69
|
1091 d->m_firstLine = oldFirstLine;
|
joachim99@69
|
1092 }
|
joachim99@69
|
1093
|
joachim99@69
|
1094 void DiffTextWindowData::draw( MyPainter& p, const QRect& invalidRect, int deviceWidth, int beginLine, int endLine )
|
joachim99@69
|
1095 {
|
joachim99@95
|
1096 m_lineNumberWidth = m_pOptionDialog->m_bShowLineNumbers ? (int)log10((double)qMax(m_size,1))+1 : 0;
|
joachim99@8
|
1097
|
joachim99@8
|
1098 if ( m_winIdx==1 )
|
joachim99@8
|
1099 {
|
joachim99@8
|
1100 m_cThis = m_pOptionDialog->m_colorA;
|
joachim99@8
|
1101 m_cDiff1 = m_pOptionDialog->m_colorB;
|
joachim99@8
|
1102 m_cDiff2 = m_pOptionDialog->m_colorC;
|
joachim99@8
|
1103 }
|
joachim99@8
|
1104 if ( m_winIdx==2 )
|
joachim99@8
|
1105 {
|
joachim99@8
|
1106 m_cThis = m_pOptionDialog->m_colorB;
|
joachim99@8
|
1107 m_cDiff1 = m_pOptionDialog->m_colorC;
|
joachim99@8
|
1108 m_cDiff2 = m_pOptionDialog->m_colorA;
|
joachim99@8
|
1109 }
|
joachim99@8
|
1110 if ( m_winIdx==3 )
|
joachim99@8
|
1111 {
|
joachim99@8
|
1112 m_cThis = m_pOptionDialog->m_colorC;
|
joachim99@8
|
1113 m_cDiff1 = m_pOptionDialog->m_colorA;
|
joachim99@8
|
1114 m_cDiff2 = m_pOptionDialog->m_colorB;
|
joachim99@8
|
1115 }
|
joachim99@8
|
1116 m_cDiffBoth = m_pOptionDialog->m_colorForConflict; // Conflict color
|
joachim99@8
|
1117
|
joachim99@69
|
1118 p.setPen( m_cThis );
|
joachim99@8
|
1119
|
joachim99@69
|
1120 for ( int line = beginLine; line<endLine; ++line )
|
joachim99@8
|
1121 {
|
joachim99@66
|
1122 int wrapLineOffset=0;
|
joachim99@66
|
1123 int wrapLineLength=0;
|
joachim99@66
|
1124 const Diff3Line* d3l =0;
|
joachim99@66
|
1125 bool bWrapLine = false;
|
joachim99@66
|
1126 if (m_bWordWrap)
|
joachim99@66
|
1127 {
|
joachim99@66
|
1128 Diff3WrapLine& d3wl = m_diff3WrapLineVector[line];
|
joachim99@66
|
1129 wrapLineOffset = d3wl.wrapLineOffset;
|
joachim99@66
|
1130 wrapLineLength = d3wl.wrapLineLength;
|
joachim99@66
|
1131 d3l = d3wl.pD3L;
|
joachim99@66
|
1132 bWrapLine = line > 0 && m_diff3WrapLineVector[line-1].pD3L == d3l;
|
joachim99@66
|
1133 }
|
joachim99@66
|
1134 else
|
joachim99@66
|
1135 {
|
joachim99@66
|
1136 d3l = (*m_pDiff3LineVector)[line];
|
joachim99@66
|
1137 }
|
joachim99@8
|
1138 DiffList* pFineDiff1;
|
joachim99@8
|
1139 DiffList* pFineDiff2;
|
joachim99@8
|
1140 int changed=0;
|
joachim99@8
|
1141 int changed2=0;
|
joachim99@8
|
1142
|
joachim99@69
|
1143 int srcLineIdx=-1;
|
joachim99@69
|
1144 getLineInfo( *d3l, srcLineIdx, pFineDiff1, pFineDiff2, changed, changed2 );
|
joachim99@8
|
1145
|
joachim99@8
|
1146 writeLine(
|
joachim99@8
|
1147 p, // QPainter
|
joachim99@69
|
1148 srcLineIdx == -1 ? 0 : &m_pLineData[srcLineIdx], // Text in this line
|
joachim99@8
|
1149 pFineDiff1,
|
joachim99@8
|
1150 pFineDiff2,
|
joachim99@8
|
1151 line, // Line on the screen
|
joachim99@8
|
1152 changed,
|
joachim99@8
|
1153 changed2,
|
joachim99@69
|
1154 srcLineIdx,
|
joachim99@66
|
1155 wrapLineOffset,
|
joachim99@66
|
1156 wrapLineLength,
|
joachim99@69
|
1157 bWrapLine,
|
joachim99@69
|
1158 invalidRect,
|
joachim99@69
|
1159 deviceWidth
|
joachim99@8
|
1160 );
|
joachim99@8
|
1161 }
|
joachim99@8
|
1162 }
|
joachim99@8
|
1163
|
joachim99@69
|
1164 QString DiffTextWindowData::getString( int d3lIdx )
|
joachim99@8
|
1165 {
|
joachim99@75
|
1166 if ( d3lIdx<0 || d3lIdx>=(int)m_pDiff3LineVector->size() )
|
joachim99@75
|
1167 return QString();
|
joachim99@66
|
1168 const Diff3Line* d3l = (*m_pDiff3LineVector)[d3lIdx];
|
joachim99@8
|
1169 DiffList* pFineDiff1;
|
joachim99@8
|
1170 DiffList* pFineDiff2;
|
joachim99@8
|
1171 int changed=0;
|
joachim99@8
|
1172 int changed2=0;
|
joachim99@8
|
1173 int lineIdx;
|
joachim99@8
|
1174 getLineInfo( *d3l, lineIdx, pFineDiff1, pFineDiff2, changed, changed2 );
|
joachim99@8
|
1175
|
joachim99@68
|
1176 if (lineIdx==-1) return QString();
|
joachim99@8
|
1177 else
|
joachim99@8
|
1178 {
|
joachim99@58
|
1179 const LineData* ld = &m_pLineData[lineIdx];
|
joachim99@68
|
1180 return QString( ld->pLine, ld->size );
|
joachim99@8
|
1181 }
|
joachim99@68
|
1182 return QString();
|
joachim99@8
|
1183 }
|
joachim99@8
|
1184
|
joachim99@69
|
1185 QString DiffTextWindowData::getLineString( int line )
|
joachim99@66
|
1186 {
|
joachim99@66
|
1187 if ( m_bWordWrap )
|
joachim99@66
|
1188 {
|
joachim99@69
|
1189 int d3LIdx = m_pDiffTextWindow->convertLineToDiff3LineIdx(line);
|
joachim99@66
|
1190 return getString( d3LIdx ).mid( m_diff3WrapLineVector[line].wrapLineOffset, m_diff3WrapLineVector[line].wrapLineLength );
|
joachim99@66
|
1191 }
|
joachim99@66
|
1192 else
|
joachim99@66
|
1193 {
|
joachim99@66
|
1194 return getString( line );
|
joachim99@66
|
1195 }
|
joachim99@66
|
1196 }
|
joachim99@8
|
1197
|
joachim99@69
|
1198 void DiffTextWindowData::getLineInfo(
|
joachim99@69
|
1199 const Diff3Line& d3l,
|
joachim99@8
|
1200 int& lineIdx,
|
joachim99@8
|
1201 DiffList*& pFineDiff1, DiffList*& pFineDiff2, // return values
|
joachim99@8
|
1202 int& changed, int& changed2
|
joachim99@8
|
1203 )
|
joachim99@8
|
1204 {
|
joachim99@8
|
1205 changed=0;
|
joachim99@8
|
1206 changed2=0;
|
joachim99@69
|
1207 bool bAEqB = d3l.bAEqB || ( d3l.bWhiteLineA && d3l.bWhiteLineB );
|
joachim99@69
|
1208 bool bAEqC = d3l.bAEqC || ( d3l.bWhiteLineA && d3l.bWhiteLineC );
|
joachim99@69
|
1209 bool bBEqC = d3l.bBEqC || ( d3l.bWhiteLineB && d3l.bWhiteLineC );
|
joachim99@8
|
1210 if ( m_winIdx == 1 ) {
|
joachim99@69
|
1211 lineIdx=d3l.lineA;
|
joachim99@69
|
1212 pFineDiff1=d3l.pFineAB;
|
joachim99@69
|
1213 pFineDiff2=d3l.pFineCA;
|
joachim99@69
|
1214 changed |= ((d3l.lineB==-1)!=(lineIdx==-1) ? 1 : 0) +
|
joachim99@69
|
1215 ((d3l.lineC==-1)!=(lineIdx==-1) && m_bTriple ? 2 : 0);
|
joachim99@8
|
1216 changed2 |= ( bAEqB ? 0 : 1 ) + (bAEqC || !m_bTriple ? 0 : 2);
|
joachim99@8
|
1217 }
|
joachim99@8
|
1218 else if ( m_winIdx == 2 ) {
|
joachim99@69
|
1219 lineIdx=d3l.lineB;
|
joachim99@69
|
1220 pFineDiff1=d3l.pFineBC;
|
joachim99@69
|
1221 pFineDiff2=d3l.pFineAB;
|
joachim99@69
|
1222 changed |= ((d3l.lineC==-1)!=(lineIdx==-1) && m_bTriple ? 1 : 0) +
|
joachim99@69
|
1223 ((d3l.lineA==-1)!=(lineIdx==-1) ? 2 : 0);
|
joachim99@8
|
1224 changed2 |= ( bBEqC || !m_bTriple ? 0 : 1 ) + (bAEqB ? 0 : 2);
|
joachim99@8
|
1225 }
|
joachim99@8
|
1226 else if ( m_winIdx == 3 ) {
|
joachim99@69
|
1227 lineIdx=d3l.lineC;
|
joachim99@69
|
1228 pFineDiff1=d3l.pFineCA;
|
joachim99@69
|
1229 pFineDiff2=d3l.pFineBC;
|
joachim99@69
|
1230 changed |= ((d3l.lineA==-1)!=(lineIdx==-1) ? 1 : 0) +
|
joachim99@69
|
1231 ((d3l.lineB==-1)!=(lineIdx==-1) ? 2 : 0);
|
joachim99@8
|
1232 changed2 |= ( bAEqC ? 0 : 1 ) + (bBEqC ? 0 : 2);
|
joachim99@8
|
1233 }
|
joachim99@8
|
1234 else assert(false);
|
joachim99@8
|
1235 }
|
joachim99@8
|
1236
|
joachim99@8
|
1237
|
joachim99@8
|
1238
|
joachim99@8
|
1239 void DiffTextWindow::resizeEvent( QResizeEvent* e )
|
joachim99@8
|
1240 {
|
joachim99@8
|
1241 QSize s = e->size();
|
joachim99@8
|
1242 QFontMetrics fm = fontMetrics();
|
joachim99@8
|
1243 int visibleLines = s.height()/fm.height()-2;
|
joachim99@69
|
1244 int visibleColumns = s.width()/fm.width('W') - d->leftInfoWidth();
|
joachim99@8
|
1245 emit resizeSignal( visibleColumns, visibleLines );
|
joachim99@8
|
1246 QWidget::resizeEvent(e);
|
joachim99@8
|
1247 }
|
joachim99@8
|
1248
|
joachim99@8
|
1249 int DiffTextWindow::getNofVisibleLines()
|
joachim99@8
|
1250 {
|
joachim99@8
|
1251 QFontMetrics fm = fontMetrics();
|
joachim99@8
|
1252 int fmh = fm.height();
|
joachim99@8
|
1253 int h = height();
|
joachim99@69
|
1254 return h/fmh -1;//height()/fm.height()-2;
|
joachim99@8
|
1255 }
|
joachim99@8
|
1256
|
joachim99@8
|
1257 int DiffTextWindow::getNofVisibleColumns()
|
joachim99@8
|
1258 {
|
joachim99@8
|
1259 QFontMetrics fm = fontMetrics();
|
joachim99@69
|
1260 return width()/fm.width('W') - d->leftInfoWidth();
|
joachim99@8
|
1261 }
|
joachim99@8
|
1262
|
joachim99@8
|
1263 QString DiffTextWindow::getSelection()
|
joachim99@8
|
1264 {
|
joachim99@80
|
1265 if ( d->m_pLineData==0 )
|
joachim99@80
|
1266 return QString();
|
joachim99@80
|
1267
|
joachim99@8
|
1268 QString selectionString;
|
joachim99@8
|
1269
|
joachim99@8
|
1270 int line=0;
|
joachim99@8
|
1271 int lineIdx=0;
|
joachim99@8
|
1272
|
joachim99@8
|
1273 int it;
|
joachim99@69
|
1274 int vectorSize = d->m_bWordWrap ? d->m_diff3WrapLineVector.size() : d->m_pDiff3LineVector->size();
|
joachim99@66
|
1275 for( it=0; it<vectorSize; ++it )
|
joachim99@8
|
1276 {
|
joachim99@69
|
1277 const Diff3Line* d3l = d->m_bWordWrap ? d->m_diff3WrapLineVector[it].pD3L : (*d->m_pDiff3LineVector)[it];
|
joachim99@69
|
1278 if ( d->m_winIdx == 1 ) { lineIdx=d3l->lineA; }
|
joachim99@69
|
1279 else if ( d->m_winIdx == 2 ) { lineIdx=d3l->lineB; }
|
joachim99@69
|
1280 else if ( d->m_winIdx == 3 ) { lineIdx=d3l->lineC; }
|
joachim99@8
|
1281 else assert(false);
|
joachim99@8
|
1282
|
joachim99@8
|
1283 if( lineIdx != -1 )
|
joachim99@69
|
1284 {
|
joachim99@69
|
1285 const QChar* pLine = d->m_pLineData[lineIdx].pLine;
|
joachim99@69
|
1286 int size = d->m_pLineData[lineIdx].size;
|
joachim99@68
|
1287 QString lineString = QString( pLine, size );
|
joachim99@69
|
1288
|
joachim99@69
|
1289 if ( d->m_bWordWrap )
|
joachim99@66
|
1290 {
|
joachim99@69
|
1291 size = d->m_diff3WrapLineVector[it].wrapLineLength;
|
joachim99@69
|
1292 lineString = lineString.mid( d->m_diff3WrapLineVector[it].wrapLineOffset, size );
|
joachim99@66
|
1293 }
|
joachim99@8
|
1294
|
joachim99@8
|
1295 // Consider tabs
|
joachim99@8
|
1296 int outPos = 0;
|
joachim99@8
|
1297 for( int i=0; i<size; ++i )
|
joachim99@8
|
1298 {
|
joachim99@8
|
1299 int spaces = 1;
|
joachim99@68
|
1300 if ( lineString[i]=='\t' )
|
joachim99@8
|
1301 {
|
joachim99@69
|
1302 spaces = tabber( outPos, d->m_pOptionDialog->m_tabSize );
|
joachim99@8
|
1303 }
|
joachim99@8
|
1304
|
joachim99@69
|
1305 if( d->m_selection.within( line, outPos ) )
|
joachim99@8
|
1306 {
|
joachim99@68
|
1307 selectionString += lineString[i];
|
joachim99@8
|
1308 }
|
joachim99@8
|
1309
|
joachim99@8
|
1310 outPos += spaces;
|
joachim99@69
|
1311 }
|
joachim99@66
|
1312
|
joachim99@69
|
1313 if( d->m_selection.within( line, outPos ) &&
|
joachim99@69
|
1314 !( d->m_bWordWrap && it+1<vectorSize && d3l == d->m_diff3WrapLineVector[it+1].pD3L )
|
joachim99@66
|
1315 )
|
joachim99@8
|
1316 {
|
joachim99@95
|
1317 #if defined(_WIN32) || defined(Q_OS_OS2)
|
joachim99@8
|
1318 selectionString += '\r';
|
joachim99@8
|
1319 #endif
|
joachim99@8
|
1320 selectionString += '\n';
|
joachim99@8
|
1321 }
|
joachim99@8
|
1322 }
|
joachim99@8
|
1323
|
joachim99@8
|
1324 ++line;
|
joachim99@8
|
1325 }
|
joachim99@8
|
1326
|
joachim99@8
|
1327 return selectionString;
|
joachim99@8
|
1328 }
|
joachim99@8
|
1329
|
joachim99@68
|
1330 bool DiffTextWindow::findString( const QString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive )
|
joachim99@8
|
1331 {
|
joachim99@8
|
1332 int it = d3vLine;
|
joachim99@69
|
1333 int endIt = bDirDown ? (int)d->m_pDiff3LineVector->size() : -1;
|
joachim99@8
|
1334 int step = bDirDown ? 1 : -1;
|
joachim99@8
|
1335 int startPos = posInLine;
|
joachim99@8
|
1336
|
joachim99@8
|
1337 for( ; it!=endIt; it+=step )
|
joachim99@8
|
1338 {
|
joachim99@69
|
1339 QString line = d->getString( it );
|
joachim99@8
|
1340 if ( !line.isEmpty() )
|
joachim99@8
|
1341 {
|
joachim99@75
|
1342 int pos = line.indexOf( s, startPos, bCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive );
|
joachim99@8
|
1343 if ( pos != -1 )
|
joachim99@8
|
1344 {
|
joachim99@8
|
1345 d3vLine = it;
|
joachim99@8
|
1346 posInLine = pos;
|
joachim99@8
|
1347 return true;
|
joachim99@8
|
1348 }
|
joachim99@8
|
1349
|
joachim99@69
|
1350 startPos = 0;
|
joachim99@8
|
1351 }
|
joachim99@8
|
1352 }
|
joachim99@8
|
1353 return false;
|
joachim99@8
|
1354 }
|
joachim99@8
|
1355
|
joachim99@66
|
1356 void DiffTextWindow::convertD3LCoordsToLineCoords( int d3LIdx, int d3LPos, int& line, int& pos )
|
joachim99@66
|
1357 {
|
joachim99@69
|
1358 if( d->m_bWordWrap )
|
joachim99@66
|
1359 {
|
joachim99@66
|
1360 int wrapPos = d3LPos;
|
joachim99@66
|
1361 int wrapLine = convertDiff3LineIdxToLine(d3LIdx);
|
joachim99@69
|
1362 while ( wrapPos > d->m_diff3WrapLineVector[wrapLine].wrapLineLength )
|
joachim99@66
|
1363 {
|
joachim99@69
|
1364 wrapPos -= d->m_diff3WrapLineVector[wrapLine].wrapLineLength;
|
joachim99@66
|
1365 ++wrapLine;
|
joachim99@66
|
1366 }
|
joachim99@66
|
1367 pos = wrapPos;
|
joachim99@66
|
1368 line = wrapLine;
|
joachim99@66
|
1369 }
|
joachim99@66
|
1370 else
|
joachim99@66
|
1371 {
|
joachim99@66
|
1372 pos = d3LPos;
|
joachim99@66
|
1373 line = d3LIdx;
|
joachim99@66
|
1374 }
|
joachim99@66
|
1375 }
|
joachim99@66
|
1376
|
joachim99@66
|
1377 void DiffTextWindow::convertLineCoordsToD3LCoords( int line, int pos, int& d3LIdx, int& d3LPos )
|
joachim99@66
|
1378 {
|
joachim99@69
|
1379 if( d->m_bWordWrap )
|
joachim99@66
|
1380 {
|
joachim99@66
|
1381 d3LPos = pos;
|
joachim99@66
|
1382 d3LIdx = convertLineToDiff3LineIdx( line );
|
joachim99@66
|
1383 int wrapLine = convertDiff3LineIdxToLine(d3LIdx); // First wrap line belonging to this d3LIdx
|
joachim99@66
|
1384 while ( wrapLine < line )
|
joachim99@66
|
1385 {
|
joachim99@69
|
1386 d3LPos += d->m_diff3WrapLineVector[wrapLine].wrapLineLength;
|
joachim99@66
|
1387 ++wrapLine;
|
joachim99@66
|
1388 }
|
joachim99@66
|
1389 }
|
joachim99@66
|
1390 else
|
joachim99@66
|
1391 {
|
joachim99@66
|
1392 d3LPos = pos;
|
joachim99@66
|
1393 d3LIdx = line;
|
joachim99@66
|
1394 }
|
joachim99@66
|
1395 }
|
joachim99@66
|
1396
|
joachim99@66
|
1397
|
joachim99@66
|
1398 void DiffTextWindow::setSelection( int firstLine, int startPos, int lastLine, int endPos, int& l, int& p )
|
joachim99@8
|
1399 {
|
joachim99@69
|
1400 d->m_selection.reset();
|
joachim99@69
|
1401 if ( lastLine >= getNofLines() )
|
joachim99@69
|
1402 {
|
joachim99@69
|
1403 lastLine = getNofLines()-1;
|
joachim99@69
|
1404
|
joachim99@69
|
1405 const Diff3Line* d3l = (*d->m_pDiff3LineVector)[convertLineToDiff3LineIdx(lastLine)];
|
joachim99@69
|
1406 int line = -1;
|
joachim99@69
|
1407 if ( d->m_winIdx==1 ) line = d3l->lineA;
|
joachim99@69
|
1408 if ( d->m_winIdx==2 ) line = d3l->lineB;
|
joachim99@69
|
1409 if ( d->m_winIdx==3 ) line = d3l->lineC;
|
joachim99@69
|
1410 if (line>=0)
|
joachim99@69
|
1411 endPos = d->m_pLineData[line].width( d->m_pOptionDialog->m_tabSize);
|
joachim99@69
|
1412 }
|
joachim99@69
|
1413
|
joachim99@69
|
1414 if ( d->m_bWordWrap && d->m_pDiff3LineVector!=0 )
|
joachim99@69
|
1415 {
|
joachim99@69
|
1416 QString s1 = d->getString(firstLine);
|
joachim99@66
|
1417 int firstWrapLine = convertDiff3LineIdxToLine(firstLine);
|
joachim99@66
|
1418 int wrapStartPos = startPos;
|
joachim99@69
|
1419 while ( wrapStartPos > d->m_diff3WrapLineVector[firstWrapLine].wrapLineLength )
|
joachim99@66
|
1420 {
|
joachim99@69
|
1421 wrapStartPos -= d->m_diff3WrapLineVector[firstWrapLine].wrapLineLength;
|
joachim99@69
|
1422 s1 = s1.mid(d->m_diff3WrapLineVector[firstWrapLine].wrapLineLength);
|
joachim99@66
|
1423 ++firstWrapLine;
|
joachim99@66
|
1424 }
|
joachim99@66
|
1425
|
joachim99@69
|
1426 QString s2 = d->getString(lastLine);
|
joachim99@66
|
1427 int lastWrapLine = convertDiff3LineIdxToLine(lastLine);
|
joachim99@66
|
1428 int wrapEndPos = endPos;
|
joachim99@69
|
1429 while ( wrapEndPos > d->m_diff3WrapLineVector[lastWrapLine].wrapLineLength )
|
joachim99@66
|
1430 {
|
joachim99@69
|
1431 wrapEndPos -= d->m_diff3WrapLineVector[lastWrapLine].wrapLineLength;
|
joachim99@69
|
1432 s2 = s2.mid(d->m_diff3WrapLineVector[lastWrapLine].wrapLineLength);
|
joachim99@66
|
1433 ++lastWrapLine;
|
joachim99@66
|
1434 }
|
joachim99@66
|
1435
|
joachim99@69
|
1436 d->m_selection.start( firstWrapLine, convertToPosOnScreen( s1, wrapStartPos, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@69
|
1437 d->m_selection.end( lastWrapLine, convertToPosOnScreen( s2, wrapEndPos, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@66
|
1438 l=firstWrapLine;
|
joachim99@66
|
1439 p=wrapStartPos;
|
joachim99@66
|
1440 }
|
joachim99@66
|
1441 else
|
joachim99@66
|
1442 {
|
joachim99@69
|
1443 d->m_selection.start( firstLine, convertToPosOnScreen( d->getString(firstLine), startPos, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@69
|
1444 d->m_selection.end( lastLine, convertToPosOnScreen( d->getString(lastLine), endPos, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@66
|
1445 l=firstLine;
|
joachim99@66
|
1446 p=startPos;
|
joachim99@66
|
1447 }
|
joachim99@8
|
1448 update();
|
joachim99@8
|
1449 }
|
joachim99@51
|
1450
|
joachim99@69
|
1451 int DiffTextWindowData::convertLineOnScreenToLineInSource( int lineOnScreen, e_CoordType coordType, bool bFirstLine )
|
joachim99@69
|
1452 {
|
joachim99@69
|
1453 int line=-1;
|
joachim99@69
|
1454 if (lineOnScreen>=0)
|
joachim99@69
|
1455 {
|
joachim99@69
|
1456 if (coordType==eWrapCoords) return lineOnScreen;
|
joachim99@69
|
1457 int d3lIdx = m_pDiffTextWindow->convertLineToDiff3LineIdx( lineOnScreen );
|
joachim99@69
|
1458 if ( !bFirstLine && d3lIdx >= (int)m_pDiff3LineVector->size() )
|
joachim99@69
|
1459 d3lIdx = m_pDiff3LineVector->size()-1;
|
joachim99@69
|
1460 if (coordType==eD3LLineCoords) return d3lIdx;
|
joachim99@69
|
1461 while ( line<0 && d3lIdx<(int)m_pDiff3LineVector->size() && d3lIdx>=0 )
|
joachim99@69
|
1462 {
|
joachim99@69
|
1463 const Diff3Line* d3l = (*m_pDiff3LineVector)[d3lIdx];
|
joachim99@69
|
1464 if ( m_winIdx==1 ) line = d3l->lineA;
|
joachim99@69
|
1465 if ( m_winIdx==2 ) line = d3l->lineB;
|
joachim99@69
|
1466 if ( m_winIdx==3 ) line = d3l->lineC;
|
joachim99@69
|
1467 if ( bFirstLine )
|
joachim99@69
|
1468 ++d3lIdx;
|
joachim99@69
|
1469 else
|
joachim99@69
|
1470 --d3lIdx;
|
joachim99@69
|
1471 }
|
joachim99@69
|
1472 if (coordType==eFileCoords) return line;
|
joachim99@69
|
1473 }
|
joachim99@69
|
1474 return line;
|
joachim99@69
|
1475 }
|
joachim99@69
|
1476
|
joachim99@69
|
1477
|
joachim99@69
|
1478 void DiffTextWindow::getSelectionRange( int* pFirstLine, int* pLastLine, e_CoordType coordType )
|
joachim99@69
|
1479 {
|
joachim99@69
|
1480 if (pFirstLine)
|
joachim99@69
|
1481 *pFirstLine = d->convertLineOnScreenToLineInSource( d->m_selection.beginLine(), coordType, true );
|
joachim99@69
|
1482 if (pLastLine)
|
joachim99@69
|
1483 *pLastLine = d->convertLineOnScreenToLineInSource( d->m_selection.endLine(), coordType, false );
|
joachim99@69
|
1484 }
|
joachim99@51
|
1485
|
joachim99@66
|
1486 // Returns the number of wrapped lines
|
joachim99@66
|
1487 // if pWrappedLines != 0 then the stringlist will contain the wrapped lines.
|
joachim99@66
|
1488 int wordWrap( const QString& origLine, int nofColumns, Diff3WrapLine* pDiff3WrapLine )
|
joachim99@69
|
1489 {
|
joachim99@66
|
1490 if (nofColumns<=0)
|
joachim99@66
|
1491 nofColumns = 1;
|
joachim99@69
|
1492
|
joachim99@66
|
1493 int nofNeededLines = 0;
|
joachim99@66
|
1494 int length = origLine.length();
|
joachim99@69
|
1495
|
joachim99@66
|
1496 if (length==0)
|
joachim99@66
|
1497 {
|
joachim99@66
|
1498 nofNeededLines = 1;
|
joachim99@66
|
1499 if( pDiff3WrapLine )
|
joachim99@66
|
1500 {
|
joachim99@66
|
1501 pDiff3WrapLine->wrapLineOffset=0;
|
joachim99@66
|
1502 pDiff3WrapLine->wrapLineLength=0;
|
joachim99@66
|
1503 }
|
joachim99@66
|
1504 }
|
joachim99@66
|
1505 else
|
joachim99@69
|
1506 {
|
joachim99@66
|
1507 int pos = 0;
|
joachim99@69
|
1508
|
joachim99@66
|
1509 while ( pos < length )
|
joachim99@66
|
1510 {
|
joachim99@66
|
1511 int wrapPos = pos + nofColumns;
|
joachim99@69
|
1512
|
joachim99@66
|
1513 if ( length-pos <= nofColumns )
|
joachim99@66
|
1514 {
|
joachim99@66
|
1515 wrapPos = length;
|
joachim99@66
|
1516 }
|
joachim99@66
|
1517 else
|
joachim99@69
|
1518 {
|
joachim99@75
|
1519 int wsPos = max2( origLine.lastIndexOf( ' ', wrapPos ), origLine.lastIndexOf( '\t', wrapPos ) );
|
joachim99@69
|
1520
|
joachim99@66
|
1521 if ( wsPos > pos )
|
joachim99@66
|
1522 {
|
joachim99@66
|
1523 // Wrap line at wsPos
|
joachim99@66
|
1524 wrapPos = wsPos;
|
joachim99@66
|
1525 }
|
joachim99@66
|
1526 }
|
joachim99@69
|
1527
|
joachim99@66
|
1528 if ( pDiff3WrapLine )
|
joachim99@66
|
1529 {
|
joachim99@66
|
1530 pDiff3WrapLine->wrapLineOffset = pos;
|
joachim99@66
|
1531 pDiff3WrapLine->wrapLineLength = wrapPos-pos;
|
joachim99@66
|
1532 ++pDiff3WrapLine;
|
joachim99@66
|
1533 }
|
joachim99@69
|
1534
|
joachim99@66
|
1535 pos = wrapPos;
|
joachim99@69
|
1536
|
joachim99@66
|
1537 ++nofNeededLines;
|
joachim99@66
|
1538 }
|
joachim99@66
|
1539 }
|
joachim99@69
|
1540 return nofNeededLines;
|
joachim99@66
|
1541 }
|
joachim99@66
|
1542
|
joachim99@66
|
1543 void DiffTextWindow::convertSelectionToD3LCoords()
|
joachim99@66
|
1544 {
|
joachim99@69
|
1545 if ( d->m_pDiff3LineVector==0 || ! d->m_bPaintingAllowed || !isVisible() || d->m_selection.isEmpty() )
|
joachim99@66
|
1546 {
|
joachim99@66
|
1547 return;
|
joachim99@66
|
1548 }
|
joachim99@66
|
1549
|
joachim99@69
|
1550 // convert the d->m_selection to unwrapped coordinates: Later restore to new coords
|
joachim99@66
|
1551 int firstD3LIdx, firstD3LPos;
|
joachim99@69
|
1552 QString s = d->getLineString( d->m_selection.beginLine() );
|
joachim99@69
|
1553 int firstPosInText = convertToPosInText( s, d->m_selection.beginPos(), d->m_pOptionDialog->m_tabSize );
|
joachim99@69
|
1554 convertLineCoordsToD3LCoords( d->m_selection.beginLine(), firstPosInText, firstD3LIdx, firstD3LPos );
|
joachim99@69
|
1555
|
joachim99@66
|
1556 int lastD3LIdx, lastD3LPos;
|
joachim99@69
|
1557 s = d->getLineString( d->m_selection.endLine() );
|
joachim99@69
|
1558 int lastPosInText = convertToPosInText( s, d->m_selection.endPos(), d->m_pOptionDialog->m_tabSize );
|
joachim99@69
|
1559 convertLineCoordsToD3LCoords( d->m_selection.endLine(), lastPosInText, lastD3LIdx, lastD3LPos );
|
joachim99@69
|
1560
|
joachim99@69
|
1561 //d->m_selection.reset();
|
joachim99@69
|
1562 d->m_selection.start( firstD3LIdx, firstD3LPos );
|
joachim99@69
|
1563 d->m_selection.end( lastD3LIdx, lastD3LPos );
|
joachim99@66
|
1564 }
|
joachim99@66
|
1565
|
joachim99@69
|
1566 void DiffTextWindow::recalcWordWrap( bool bWordWrap, int wrapLineVectorSize, int nofVisibleColumns )
|
joachim99@69
|
1567 {
|
joachim99@69
|
1568 if ( d->m_pDiff3LineVector==0 || ! d->m_bPaintingAllowed || !isVisible() )
|
joachim99@66
|
1569 {
|
joachim99@69
|
1570 d->m_bWordWrap = bWordWrap;
|
joachim99@69
|
1571 if (!bWordWrap) d->m_diff3WrapLineVector.resize( 0 );
|
joachim99@66
|
1572 return;
|
joachim99@66
|
1573 }
|
joachim99@69
|
1574
|
joachim99@69
|
1575 d->m_bWordWrap = bWordWrap;
|
joachim99@69
|
1576
|
joachim99@66
|
1577 if ( bWordWrap )
|
joachim99@69
|
1578 {
|
joachim99@69
|
1579 d->m_diff3WrapLineVector.resize( wrapLineVectorSize );
|
joachim99@69
|
1580
|
joachim99@69
|
1581 if (nofVisibleColumns<0)
|
joachim99@69
|
1582 nofVisibleColumns = getNofVisibleColumns();
|
joachim99@69
|
1583 else
|
joachim99@69
|
1584 nofVisibleColumns-= d->leftInfoWidth();
|
joachim99@66
|
1585 int i;
|
joachim99@66
|
1586 int wrapLineIdx = 0;
|
joachim99@69
|
1587 int size = d->m_pDiff3LineVector->size();
|
joachim99@66
|
1588 for( i=0; i<size; ++i )
|
joachim99@66
|
1589 {
|
joachim99@69
|
1590 QString s = d->getString( i );
|
joachim99@69
|
1591 int linesNeeded = wordWrap( s, nofVisibleColumns, wrapLineVectorSize==0 ? 0 : &d->m_diff3WrapLineVector[wrapLineIdx] );
|
joachim99@69
|
1592 Diff3Line& d3l = *(*d->m_pDiff3LineVector)[i];
|
joachim99@66
|
1593 if ( d3l.linesNeededForDisplay<linesNeeded )
|
joachim99@66
|
1594 {
|
joachim99@66
|
1595 d3l.linesNeededForDisplay = linesNeeded;
|
joachim99@66
|
1596 }
|
joachim99@69
|
1597
|
joachim99@66
|
1598 if ( wrapLineVectorSize>0 )
|
joachim99@66
|
1599 {
|
joachim99@66
|
1600 int j;
|
joachim99@66
|
1601 for( j=0; j<d3l.linesNeededForDisplay; ++j, ++wrapLineIdx )
|
joachim99@66
|
1602 {
|
joachim99@69
|
1603 Diff3WrapLine& d3wl = d->m_diff3WrapLineVector[wrapLineIdx];
|
joachim99@66
|
1604 d3wl.diff3LineIndex = i;
|
joachim99@69
|
1605 d3wl.pD3L = (*d->m_pDiff3LineVector)[i];
|
joachim99@66
|
1606 if ( j>=linesNeeded )
|
joachim99@66
|
1607 {
|
joachim99@66
|
1608 d3wl.wrapLineOffset=0;
|
joachim99@66
|
1609 d3wl.wrapLineLength=0;
|
joachim99@66
|
1610 }
|
joachim99@66
|
1611 }
|
joachim99@66
|
1612 }
|
joachim99@69
|
1613 }
|
joachim99@69
|
1614
|
joachim99@66
|
1615 if ( wrapLineVectorSize>0 )
|
joachim99@69
|
1616 {
|
joachim99@69
|
1617 d->m_firstLine = min2( d->m_firstLine, wrapLineVectorSize-1 );
|
joachim99@69
|
1618 d->m_firstColumn = 0;
|
joachim99@69
|
1619 d->m_pDiffTextWindowFrame->setFirstLine( d->m_firstLine );
|
joachim99@66
|
1620 }
|
joachim99@66
|
1621 }
|
joachim99@66
|
1622 else
|
joachim99@66
|
1623 {
|
joachim99@69
|
1624 d->m_diff3WrapLineVector.resize( 0 );
|
joachim99@66
|
1625 }
|
joachim99@69
|
1626
|
joachim99@69
|
1627 if ( !d->m_selection.isEmpty() && ( !d->m_bWordWrap || wrapLineVectorSize>0 ) )
|
joachim99@69
|
1628 {
|
joachim99@66
|
1629 // Assume unwrapped coordinates
|
joachim99@66
|
1630 //( Why? ->Conversion to unwrapped coords happened a few lines above in this method.
|
joachim99@66
|
1631 // Also see KDiff3App::recalcWordWrap() on the role of wrapLineVectorSize)
|
joachim99@69
|
1632
|
joachim99@66
|
1633 // Wrap them now.
|
joachim99@69
|
1634
|
joachim99@69
|
1635 // convert the d->m_selection to unwrapped coordinates.
|
joachim99@66
|
1636 int firstLine, firstPos;
|
joachim99@69
|
1637 convertD3LCoordsToLineCoords( d->m_selection.beginLine(), d->m_selection.beginPos(), firstLine, firstPos );
|
joachim99@69
|
1638
|
joachim99@66
|
1639 int lastLine, lastPos;
|
joachim99@69
|
1640 convertD3LCoordsToLineCoords( d->m_selection.endLine(), d->m_selection.endPos(), lastLine, lastPos );
|
joachim99@69
|
1641
|
joachim99@69
|
1642 //d->m_selection.reset();
|
joachim99@69
|
1643 d->m_selection.start( firstLine, convertToPosOnScreen( d->getLineString( firstLine ), firstPos, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@69
|
1644 d->m_selection.end( lastLine, convertToPosOnScreen( d->getLineString( lastLine ),lastPos, d->m_pOptionDialog->m_tabSize ) );
|
joachim99@69
|
1645 }
|
joachim99@66
|
1646 }
|
joachim99@66
|
1647
|
joachim99@66
|
1648
|
joachim99@69
|
1649 class DiffTextWindowFrameData
|
joachim99@69
|
1650 {
|
joachim99@69
|
1651 public:
|
joachim99@69
|
1652 DiffTextWindow* m_pDiffTextWindow;
|
joachim99@69
|
1653 QLineEdit* m_pFileSelection;
|
joachim99@69
|
1654 QPushButton* m_pBrowseButton;
|
joachim99@69
|
1655 OptionDialog* m_pOptionDialog;
|
joachim99@69
|
1656 QLabel* m_pLabel;
|
joachim99@69
|
1657 QLabel* m_pTopLine;
|
joachim99@92
|
1658 QLabel* m_pEncoding;
|
joachim99@92
|
1659 QLabel* m_pLineEndStyle;
|
joachim99@69
|
1660 QWidget* m_pTopLineWidget;
|
joachim99@80
|
1661 int m_winIdx;
|
joachim99@69
|
1662 };
|
joachim99@66
|
1663
|
joachim99@69
|
1664 DiffTextWindowFrame::DiffTextWindowFrame( QWidget* pParent, QStatusBar* pStatusBar, OptionDialog* pOptionDialog, int winIdx )
|
joachim99@69
|
1665 : QWidget( pParent )
|
joachim99@69
|
1666 {
|
joachim99@69
|
1667 d = new DiffTextWindowFrameData;
|
joachim99@80
|
1668 d->m_winIdx = winIdx;
|
joachim99@75
|
1669 setAutoFillBackground(true);
|
joachim99@69
|
1670 d->m_pOptionDialog = pOptionDialog;
|
joachim99@69
|
1671 d->m_pTopLineWidget = new QWidget(this);
|
joachim99@69
|
1672 d->m_pFileSelection = new QLineEdit(d->m_pTopLineWidget);
|
joachim99@69
|
1673 d->m_pBrowseButton = new QPushButton( "...",d->m_pTopLineWidget );
|
joachim99@69
|
1674 d->m_pBrowseButton->setFixedWidth( 30 );
|
joachim99@69
|
1675 connect(d->m_pBrowseButton,SIGNAL(clicked()), this, SLOT(slotBrowseButtonClicked()));
|
joachim99@69
|
1676 connect(d->m_pFileSelection,SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
|
joachim99@66
|
1677
|
joachim99@69
|
1678 d->m_pLabel = new QLabel("A:",d->m_pTopLineWidget);
|
joachim99@69
|
1679 d->m_pTopLine = new QLabel(d->m_pTopLineWidget);
|
joachim99@69
|
1680 d->m_pDiffTextWindow = 0;
|
joachim99@69
|
1681 d->m_pDiffTextWindow = new DiffTextWindow( this, pStatusBar, pOptionDialog, winIdx );
|
joachim99@92
|
1682
|
joachim99@92
|
1683 QVBoxLayout* pVTopLayout = new QVBoxLayout(d->m_pTopLineWidget);
|
joachim99@92
|
1684 pVTopLayout->setMargin(2);
|
joachim99@92
|
1685 pVTopLayout->setSpacing(0);
|
joachim99@92
|
1686 QHBoxLayout* pHL = new QHBoxLayout();
|
joachim99@92
|
1687 QHBoxLayout* pHL2 = new QHBoxLayout();
|
joachim99@92
|
1688 pVTopLayout->addLayout(pHL);
|
joachim99@92
|
1689 pVTopLayout->addLayout(pHL2);
|
joachim99@92
|
1690
|
joachim99@92
|
1691 // Upper line:
|
joachim99@92
|
1692 pHL->setMargin(0);
|
joachim99@69
|
1693 pHL->setSpacing(2);
|
joachim99@51
|
1694
|
joachim99@69
|
1695 pHL->addWidget( d->m_pLabel, 0 );
|
joachim99@69
|
1696 pHL->addWidget( d->m_pFileSelection, 1 );
|
joachim99@69
|
1697 pHL->addWidget( d->m_pBrowseButton, 0 );
|
joachim99@69
|
1698 pHL->addWidget( d->m_pTopLine, 0 );
|
joachim99@69
|
1699
|
joachim99@92
|
1700 // Lower line
|
joachim99@92
|
1701 pHL2->setMargin(0);
|
joachim99@92
|
1702 pHL2->setSpacing(2);
|
joachim99@92
|
1703 pHL2->addWidget( d->m_pTopLine, 0 );
|
joachim99@92
|
1704 d->m_pEncoding = new QLabel(i18n("Encoding:"));
|
joachim99@92
|
1705 d->m_pLineEndStyle = new QLabel(i18n("Line end style:"));
|
joachim99@92
|
1706 pHL2->addWidget(d->m_pEncoding);
|
joachim99@92
|
1707 pHL2->addWidget(d->m_pLineEndStyle);
|
joachim99@92
|
1708
|
joachim99@75
|
1709 QVBoxLayout* pVL = new QVBoxLayout( this );
|
joachim99@75
|
1710 pVL->setMargin(0);
|
joachim99@75
|
1711 pVL->setSpacing(0);
|
joachim99@69
|
1712 pVL->addWidget( d->m_pTopLineWidget, 0 );
|
joachim99@69
|
1713 pVL->addWidget( d->m_pDiffTextWindow, 1 );
|
joachim99@69
|
1714
|
joachim99@69
|
1715 d->m_pDiffTextWindow->installEventFilter( this );
|
joachim99@69
|
1716 d->m_pFileSelection->installEventFilter( this );
|
joachim99@69
|
1717 d->m_pBrowseButton->installEventFilter( this );
|
joachim99@69
|
1718 init();
|
joachim99@69
|
1719 }
|
joachim99@69
|
1720
|
joachim99@69
|
1721 DiffTextWindowFrame::~DiffTextWindowFrame()
|
joachim99@69
|
1722 {
|
joachim99@69
|
1723 delete d;
|
joachim99@69
|
1724 }
|
joachim99@69
|
1725
|
joachim99@69
|
1726 void DiffTextWindowFrame::init()
|
joachim99@69
|
1727 {
|
joachim99@69
|
1728 DiffTextWindow* pDTW = d->m_pDiffTextWindow;
|
joachim99@69
|
1729 if ( pDTW )
|
joachim99@69
|
1730 {
|
joachim99@75
|
1731 QString s = QDir::toNativeSeparators( pDTW->d->m_filename );
|
joachim99@69
|
1732 d->m_pFileSelection->setText( s );
|
joachim99@69
|
1733 QString winId = pDTW->d->m_winIdx==1 ?
|
joachim99@69
|
1734 ( pDTW->d->m_bTriple?"A (Base)":"A") :
|
joachim99@69
|
1735 ( pDTW->d->m_winIdx==2 ? "B" : "C" );
|
joachim99@69
|
1736 d->m_pLabel->setText( winId + ":" );
|
joachim99@92
|
1737 d->m_pEncoding->setText( i18n("Encoding:") + " " + (pDTW->d->m_pTextCodec!=0 ? pDTW->d->m_pTextCodec->name() : QString()) );
|
joachim99@92
|
1738 d->m_pLineEndStyle->setText( i18n("Line end style:") + " " + (pDTW->d->m_eLineEndStyle==eLineEndStyleDos ? i18n("DOS") : i18n("Unix")) );
|
joachim99@69
|
1739 }
|
joachim99@69
|
1740 }
|
joachim99@69
|
1741
|
joachim99@69
|
1742 // Search for the first visible line (search loop needed when no line exist for this file.)
|
joachim99@69
|
1743 int DiffTextWindow::calcTopLineInFile( int firstLine )
|
joachim99@69
|
1744 {
|
joachim99@69
|
1745 int l=-1;
|
joachim99@69
|
1746 for ( int i = convertLineToDiff3LineIdx(firstLine); i<(int)d->m_pDiff3LineVector->size(); ++i )
|
joachim99@69
|
1747 {
|
joachim99@69
|
1748 const Diff3Line* d3l = (*d->m_pDiff3LineVector)[i];
|
joachim99@69
|
1749 l = d3l->getLineInFile(d->m_winIdx);
|
joachim99@69
|
1750 if (l!=-1) break;
|
joachim99@69
|
1751 }
|
joachim99@69
|
1752 return l;
|
joachim99@69
|
1753 }
|
joachim99@69
|
1754
|
joachim99@69
|
1755 void DiffTextWindowFrame::setFirstLine( int firstLine )
|
joachim99@69
|
1756 {
|
joachim99@69
|
1757 DiffTextWindow* pDTW = d->m_pDiffTextWindow;
|
joachim99@69
|
1758 if ( pDTW && pDTW->d->m_pDiff3LineVector )
|
joachim99@69
|
1759 {
|
joachim99@69
|
1760 QString s= i18n("Top line");
|
joachim99@95
|
1761 int lineNumberWidth = (int)log10((double)qMax(pDTW->d->m_size,1))+1;
|
joachim99@69
|
1762
|
joachim99@69
|
1763 int l=pDTW->calcTopLineInFile(firstLine);
|
joachim99@69
|
1764
|
joachim99@69
|
1765 int w = d->m_pTopLine->fontMetrics().width(
|
joachim99@69
|
1766 s+" "+QString().fill('0',lineNumberWidth));
|
joachim99@69
|
1767 d->m_pTopLine->setMinimumWidth( w );
|
joachim99@69
|
1768
|
joachim99@69
|
1769 if (l==-1)
|
joachim99@69
|
1770 s = i18n("End");
|
joachim99@69
|
1771 else
|
joachim99@69
|
1772 s += " " + QString::number( l+1 );
|
joachim99@69
|
1773
|
joachim99@69
|
1774 d->m_pTopLine->setText( s );
|
joachim99@69
|
1775 d->m_pTopLine->repaint();
|
joachim99@69
|
1776 }
|
joachim99@69
|
1777 }
|
joachim99@69
|
1778
|
joachim99@69
|
1779 DiffTextWindow* DiffTextWindowFrame::getDiffTextWindow()
|
joachim99@69
|
1780 {
|
joachim99@69
|
1781 return d->m_pDiffTextWindow;
|
joachim99@69
|
1782 }
|
joachim99@69
|
1783
|
joachim99@69
|
1784 bool DiffTextWindowFrame::eventFilter( QObject* o, QEvent* e )
|
joachim99@69
|
1785 {
|
joachim99@69
|
1786 DiffTextWindow* pDTW = d->m_pDiffTextWindow;
|
joachim99@69
|
1787 if ( e->type()==QEvent::FocusIn || e->type()==QEvent::FocusOut )
|
joachim99@69
|
1788 {
|
joachim99@69
|
1789 QColor c1 = d->m_pOptionDialog->m_bgColor;
|
joachim99@80
|
1790 QColor c2;
|
joachim99@80
|
1791 if ( d->m_winIdx==1 ) c2 = d->m_pOptionDialog->m_colorA;
|
joachim99@80
|
1792 else if ( d->m_winIdx==2 ) c2 = d->m_pOptionDialog->m_colorB;
|
joachim99@80
|
1793 else if ( d->m_winIdx==3 ) c2 = d->m_pOptionDialog->m_colorC;
|
joachim99@80
|
1794
|
joachim99@69
|
1795 QPalette p = d->m_pTopLineWidget->palette();
|
joachim99@69
|
1796 if ( e->type()==QEvent::FocusOut )
|
joachim99@69
|
1797 std::swap(c1,c2);
|
joachim99@69
|
1798
|
joachim99@70
|
1799 p.setColor(QPalette::Window, c2);
|
joachim99@70
|
1800 setPalette( p );
|
joachim99@69
|
1801
|
joachim99@70
|
1802 p.setColor(QPalette::WindowText, c1);
|
joachim99@69
|
1803 d->m_pLabel->setPalette( p );
|
joachim99@69
|
1804 d->m_pTopLine->setPalette( p );
|
joachim99@92
|
1805 d->m_pEncoding->setPalette( p );
|
joachim99@92
|
1806 d->m_pLineEndStyle->setPalette( p );
|
joachim99@69
|
1807 }
|
joachim99@69
|
1808 if (o == d->m_pFileSelection && e->type()==QEvent::Drop)
|
joachim99@69
|
1809 {
|
joachim99@69
|
1810 QDropEvent* d = static_cast<QDropEvent*>(e);
|
joachim99@92
|
1811
|
joachim99@75
|
1812 if ( d->mimeData()->hasUrls() )
|
joachim99@69
|
1813 {
|
joachim99@75
|
1814 QList<QUrl> lst = d->mimeData()->urls();
|
joachim99@69
|
1815
|
joachim99@69
|
1816 if ( lst.count() > 0 )
|
joachim99@69
|
1817 {
|
joachim99@75
|
1818 static_cast<QLineEdit*>(o)->setText( lst[0].toString() );
|
joachim99@69
|
1819 static_cast<QLineEdit*>(o)->setFocus();
|
joachim99@75
|
1820 emit fileNameChanged( lst[0].toString(), pDTW->d->m_winIdx );
|
joachim99@69
|
1821 return true;
|
joachim99@69
|
1822 }
|
joachim99@69
|
1823 }
|
joachim99@69
|
1824 }
|
joachim99@69
|
1825 return false;
|
joachim99@69
|
1826 }
|
joachim99@69
|
1827
|
joachim99@69
|
1828 void DiffTextWindowFrame::slotReturnPressed()
|
joachim99@69
|
1829 {
|
joachim99@69
|
1830 DiffTextWindow* pDTW = d->m_pDiffTextWindow;
|
joachim99@69
|
1831 if ( pDTW->d->m_filename != d->m_pFileSelection->text() )
|
joachim99@69
|
1832 {
|
joachim99@69
|
1833 emit fileNameChanged( d->m_pFileSelection->text(), pDTW->d->m_winIdx );
|
joachim99@69
|
1834 }
|
joachim99@69
|
1835 }
|
joachim99@69
|
1836
|
joachim99@69
|
1837 void DiffTextWindowFrame::slotBrowseButtonClicked()
|
joachim99@69
|
1838 {
|
joachim99@69
|
1839 QString current = d->m_pFileSelection->text();
|
joachim99@69
|
1840
|
joachim99@80
|
1841 KUrl newURL = KFileDialog::getOpenUrl( current, 0, this);
|
joachim99@69
|
1842 if ( !newURL.isEmpty() )
|
joachim99@69
|
1843 {
|
joachim99@69
|
1844 DiffTextWindow* pDTW = d->m_pDiffTextWindow;
|
joachim99@69
|
1845 emit fileNameChanged( newURL.url(), pDTW->d->m_winIdx );
|
joachim99@69
|
1846 }
|
joachim99@69
|
1847 }
|