comparison kdiff3/src/pdiff.cpp @ 58:8af4bb9d9a5a

Version 0.9.83
author joachim99
date Sun, 07 Mar 2004 09:59:09 +0000
parents 32d5cbf9db71
children efe33e938730
comparison
equal deleted inserted replaced
57:023fbd76c1e3 58:8af4bb9d9a5a
1 /*************************************************************************** 1 /***************************************************************************
2 kdiff.cpp - description 2 pdiff.cpp - Implementation for class KDiff3App
3 ------------------- 3 ---------------
4 begin : Mon Mär 18 20:04:50 CET 2002 4 begin : Mon Mär 18 20:04:50 CET 2002
5 copyright : (C) 2002 by Joachim Eibl 5 copyright : (C) 2002-2004 by Joachim Eibl
6 email : joachim.eibl@gmx.de 6 email : joachim.eibl@gmx.de
7 ***************************************************************************/ 7 ***************************************************************************/
8 8
9 /*************************************************************************** 9 /***************************************************************************
10 * * 10 * *
97 return ""; 97 return "";
98 } 98 }
99 return fileName; 99 return fileName;
100 } 100 }
101 101
102 bool KDiff3App::runDiff( LineData* p1, int size1, LineData* p2, int size2, DiffList& diffList ) 102 bool KDiff3App::runDiff( const LineData* p1, int size1, const LineData* p2, int size2, DiffList& diffList )
103 { 103 {
104 static GnuDiff gnuDiff; 104 static GnuDiff gnuDiff;
105 105
106 g_pProgressDialog->setSubCurrent(0); 106 g_pProgressDialog->setSubCurrent(0);
107 107
162 currentLine2 += equalLinesAtStart; 162 currentLine2 += equalLinesAtStart;
163 } 163 }
164 164
165 if (size1-currentLine1==size2-currentLine2 ) 165 if (size1-currentLine1==size2-currentLine2 )
166 { 166 {
167 Diff d( size1-currentLine1,0,0); 167 if (size1-currentLine1>0)
168 diffList.push_back(d); 168 {
169 Diff d( size1-currentLine1,0,0);
170 diffList.push_back(d);
171 }
169 } 172 }
170 else if ( !diffList.empty() ) 173 else if ( !diffList.empty() )
171 { // Only necessary for a files that end with a newline 174 { // Only necessary for a files that end with a newline
172 int nofEquals = min2(size1-currentLine1,size2-currentLine2); 175 int nofEquals = min2(size1-currentLine1,size2-currentLine2);
173 if ( nofEquals==0 ) 176 if ( nofEquals==0 )
202 #endif 205 #endif
203 206
204 g_pProgressDialog->setSubCurrent(1.0); 207 g_pProgressDialog->setSubCurrent(1.0);
205 208
206 return true; 209 return true;
207 #if 0
208
209 if ( m_pOptionDialog->m_bUseExternalDiff )
210 {
211 bool bSuccess=false;
212
213 bool bIgnoreWhiteSpace = m_pOptionDialog->m_bIgnoreWhiteSpace;
214 bool bIgnoreNumbers = m_pOptionDialog->m_bIgnoreNumbers;
215
216 // Create two temp files (Remove all white spaces and carriage returns here)
217 // (Make sure that no existing files are overwritten.)
218 g_pProgressDialog->setSubCurrent(0);
219 QString fileName1 = createTempFile( p1, size1, bIgnoreWhiteSpace, bIgnoreNumbers );
220 g_pProgressDialog->setSubCurrent(0.25);
221 QString fileName2 = createTempFile( p2, size2, bIgnoreWhiteSpace, bIgnoreNumbers );
222 g_pProgressDialog->setSubCurrent(0.5);
223 QString fileNameOut = FileAccess::tempFileName();
224
225 if ( !fileName1.isEmpty() && !fileName2.isEmpty() )
226 {
227 QString cmd;
228 #ifdef _WIN32
229 // Under Windows it's better to search for diff.exe
230 char buf[200];
231 int r= SearchPathA( 0, "diff.exe", 0, sizeof(buf), buf, 0 );
232
233 if (r!=0) { cmd = buf; }
234 #else
235 // under Un*x I assume that a diff command is in the PATH
236 cmd = "diff";
237 #endif
238 if ( !cmd.isEmpty() )
239 {
240 cmd += " -a "; // -a = treat all files as text
241 if ( m_pOptionDialog->m_bTryHard )
242 cmd += "--minimal ";
243 //if ( m_pOptionDialog->m_bIgnoreWhiteSpace ) This I do myself, see below
244 // cmd += "--ignore-all-space ";
245 cmd += fileName1+" "+fileName2+" >"+fileNameOut;
246 // Run diff
247 //int status1 = ::system( 0 ); // ==0 if shell not found
248 int status = ::system( cmd.ascii() );
249 #ifdef WEXITSTATUS
250 status = WEXITSTATUS(status);
251 #endif
252 //if (status<0)
253 //{
254 // errorString = strerror( errno );
255 //}
256 bSuccess = status>=0 && status!=127;
257 }
258 }
259
260 g_pProgressDialog->setSubCurrent(0.75);
261
262 int currentLine1 = 0;
263 int currentLine2 = 0;
264 if ( bSuccess )
265 {
266 // Parse the output and create the difflist
267 QFile f( fileNameOut );
268 bSuccess = f.open(IO_ReadOnly);
269 if (bSuccess)
270 {
271 const QByteArray buf = f.readAll();
272 unsigned int bufSize=buf.size();
273 unsigned int pos=0;
274 for(pos=0;pos<bufSize;++pos)
275 {
276 unsigned int lineStart = pos;
277 // Find end of line
278 while( buf.at(pos)!='\n' && pos<bufSize )
279 ++pos;
280
281 // parse it
282 char c = buf.at(lineStart);
283 if ( c == '>' || c == '-' || c=='<' )
284 continue; // Not interested in the data
285 else
286 {
287 QCString line( &buf.at(lineStart), pos-lineStart+1 );
288 int pa = line.find('a'); // add
289 int pc = line.find('c'); // change
290 int pd = line.find('d'); // delete
291 int p = pa>0 ? pa : (pc > 0 ? pc : pd);
292 if (p<0) break; // Unexpected error
293 QCString left = line.left(p);
294 QCString right = line.mid(p+1);
295 int pcommaleft = left.find(',');
296 int pcommaright = right.find(',');
297 int l1top=-1, l1bottom=-1, l2top=-1, l2bottom=-1;
298 if (pcommaleft>0)
299 {
300 l1top = left.left(pcommaleft).toInt();
301 l1bottom = left.mid(pcommaleft+1).toInt();
302 }
303 else
304 {
305 l1top = left.toInt();
306 l1bottom = l1top;
307 }
308 if (pcommaright>0)
309 {
310 l2top = right.left(pcommaright).toInt();
311 l2bottom = right.mid(pcommaright+1).toInt();
312 }
313 else
314 {
315 l2top = right.toInt();
316 l2bottom = l2top;
317 }
318
319 Diff d(0,0,0);
320
321 if ( pa>0 )
322 {
323 d.nofEquals = l1top - currentLine1;
324 d.diff1 = 0;
325 d.diff2 = l2bottom - l2top + 1;
326 assert( d.nofEquals == l2top - 1 - currentLine2 );
327 }
328 else if ( pd>0 )
329 {
330 d.nofEquals = l2top - currentLine2;
331 d.diff1 = l1bottom - l1top + 1;
332 d.diff2 = 0;
333 assert( d.nofEquals == l1top - 1 - currentLine1 );
334 }
335 else if ( pc>0 )
336 {
337 d.nofEquals = l1top - 1 - currentLine1;
338 d.diff1 = l1bottom - l1top + 1;
339 d.diff2 = l2bottom - l2top + 1;
340 assert( d.nofEquals == l2top - 1 - currentLine2 );
341 }
342 else
343 assert(false);
344
345 currentLine1 += d.nofEquals + d.diff1;
346 currentLine2 += d.nofEquals + d.diff2;
347 diffList.push_back(d);
348 }
349 }
350 if (size1-currentLine1==size2-currentLine2 )
351 {
352 Diff d( size1-currentLine1,0,0);
353 diffList.push_back(d);
354 currentLine1=size1;
355 currentLine2=size2;
356 }
357
358 if ( currentLine1 == size1 && currentLine2 == size2 )
359 bSuccess = true;
360 }
361 else
362 {
363 bSuccess = size1==size2;
364 }
365 }
366 if ( currentLine1==0 && currentLine2==0 )
367 {
368 Diff d( 0, size1, size2 );
369 diffList.push_back(d);
370 }
371
372 g_pProgressDialog->setSubCurrent(1.0);
373
374 if ( !bSuccess )
375 {
376 KMessageBox::sorry(this,
377 i18n("Running the external diff failed.\n"
378 "Check if the diff works, if the program can write in the temp folder or if the disk is full.\n"
379 "The external diff option will be disabled now and the internal diff will be used."),
380 i18n("Warning"));
381 m_pOptionDialog->m_bUseExternalDiff = false;
382 }
383
384 FileAccess::removeFile( fileName1 );
385 FileAccess::removeFile( fileName2 );
386 FileAccess::removeFile( fileNameOut );
387 }
388
389 if ( ! m_pOptionDialog->m_bUseExternalDiff )
390 {
391 g_pProgressDialog->setSubCurrent(0.0);
392 if ( size1>0 && p1!=0 && p1->occurances==0 )
393 {
394 prepareOccurances( p1, size1 );
395 }
396 g_pProgressDialog->setSubCurrent(0.25);
397
398 if ( size2>0 && p2!=0 && p2->occurances==0 )
399 {
400 prepareOccurances( p2, size2 );
401 }
402 g_pProgressDialog->setSubCurrent(0.5);
403
404 calcDiff( p1, size1, p2, size2, diffList, 2, m_pOptionDialog->m_maxSearchLength );
405
406 g_pProgressDialog->setSubCurrent(1.0);
407 }
408 return true;
409 #endif
410 } 210 }
411 211
412 212
413 void KDiff3App::init( bool bAuto ) 213 void KDiff3App::init( bool bAuto )
414 { 214 {
416 216
417 bool bVisibleMergeResultWindow = ! m_outputFilename.isEmpty(); 217 bool bVisibleMergeResultWindow = ! m_outputFilename.isEmpty();
418 if ( bVisibleMergeResultWindow ) 218 if ( bVisibleMergeResultWindow )
419 { 219 {
420 bPreserveCarriageReturn = false; 220 bPreserveCarriageReturn = false;
221
222 QString msg;
223
224 if ( !m_pOptionDialog->m_PreProcessorCmd.isEmpty() )
225 {
226 msg += "- " + i18n("PreprocessorCmd: ") + m_pOptionDialog->m_PreProcessorCmd + "\n";
227 }
228 if ( m_pOptionDialog->m_bUpCase )
229 {
230 msg += "- " + i18n("Convert to upper case\n");
231 }
232 if ( !msg.isEmpty() )
233 {
234 int result = KMessageBox::warningYesNo( this,
235 i18n("The following option(s) you selected might change data:\n") + msg +
236 i18n("\nMost likely this is not wanted during a merge.\n"
237 "Do you want to disable these settings or continue with these settings active?"),
238 i18n("Option unsafe for merging"),
239 i18n("Use these options during the merge"), i18n("Disable unsafe options")
240 );
241
242 if (result == KMessageBox::No )
243 {
244 m_pOptionDialog->m_PreProcessorCmd = "";
245 m_pOptionDialog->m_bUpCase = false;
246 }
247 }
421 } 248 }
422 249
423 m_diff3LineList.clear(); 250 m_diff3LineList.clear();
424 251
425 bool bUseLineMatchingPP = !m_pOptionDialog->m_LineMatchingPreProcessorCmd.isEmpty() || 252 // Because of the progressdialog paintevents can occur, but data is invalid,
426 m_pOptionDialog->m_bIgnoreComments; 253 // so painting must be suppressed.
427 bool bUpCase = m_pOptionDialog->m_bUpCase;
428
429 if (m_pDiffTextWindow1) m_pDiffTextWindow1->setPaintingAllowed( false ); 254 if (m_pDiffTextWindow1) m_pDiffTextWindow1->setPaintingAllowed( false );
430 if (m_pDiffTextWindow2) m_pDiffTextWindow2->setPaintingAllowed( false ); 255 if (m_pDiffTextWindow2) m_pDiffTextWindow2->setPaintingAllowed( false );
431 if (m_pDiffTextWindow3) m_pDiffTextWindow3->setPaintingAllowed( false ); 256 if (m_pDiffTextWindow3) m_pDiffTextWindow3->setPaintingAllowed( false );
432 if (m_pOverview) m_pOverview->setPaintingAllowed( false ); 257 if (m_pOverview) m_pOverview->setPaintingAllowed( false );
258 if (m_pMergeResultWindow) m_pMergeResultWindow->setPaintingAllowed( false );
433 259
434 260
435 if( m_sd3.isEmpty() ) 261 if( m_sd3.isEmpty() )
436 g_pProgressDialog->setMaximum( 4 ); // Read 2 files, 1 comparison, 1 finediff 262 g_pProgressDialog->setMaximum( 4 ); // Read 2 files, 1 comparison, 1 finediff
437 else 263 else
439 265
440 g_pProgressDialog->start(); 266 g_pProgressDialog->start();
441 267
442 // First get all input data. 268 // First get all input data.
443 g_pProgressDialog->setInformation(i18n("Loading A")); 269 g_pProgressDialog->setInformation(i18n("Loading A"));
444 m_sd1.readPPFile( bPreserveCarriageReturn, m_pOptionDialog->m_PreProcessorCmd, bUpCase ); 270 m_sd1.readAndPreprocess();
445 m_sdlm1.readLMPPFile( &m_sd1, m_pOptionDialog->m_LineMatchingPreProcessorCmd, bUpCase, m_pOptionDialog->m_bIgnoreComments );
446 g_pProgressDialog->step(); 271 g_pProgressDialog->step();
447 272
448 g_pProgressDialog->setInformation(i18n("Loading B")); 273 g_pProgressDialog->setInformation(i18n("Loading B"));
449 m_sd2.readPPFile( bPreserveCarriageReturn, m_pOptionDialog->m_PreProcessorCmd, bUpCase ); 274 m_sd2.readAndPreprocess();
450 m_sdlm2.readLMPPFile( &m_sd2, m_pOptionDialog->m_LineMatchingPreProcessorCmd, bUpCase, m_pOptionDialog->m_bIgnoreComments );
451 g_pProgressDialog->step(); 275 g_pProgressDialog->step();
452 276
453 m_sd3.m_bIsText = true;
454 m_totalDiffStatus.reset(); 277 m_totalDiffStatus.reset();
455 // Run the diff. 278 // Run the diff.
456 if ( m_sd3.isEmpty() ) 279 if ( m_sd3.isEmpty() )
457 { 280 {
458 m_totalDiffStatus.bBinaryAEqB = (m_sd1.m_size!=0 && m_sd1.m_size==m_sd2.m_size && memcmp(m_sd1.m_pBuf,m_sd2.m_pBuf,m_sd1.m_size)==0); 281 m_totalDiffStatus.bBinaryAEqB = m_sd1.getSizeBytes()!=0 && m_sd1.isBinaryEqualWith( m_sd2 );
459 g_pProgressDialog->setInformation(i18n("Diff: A <-> B")); 282 g_pProgressDialog->setInformation(i18n("Diff: A <-> B"));
460 if ( !bUseLineMatchingPP ) 283
461 runDiff( &m_sd1.m_v[0], m_sd1.m_vSize, &m_sd2.m_v[0], m_sd2.m_vSize, m_diffList12 ); 284 runDiff( m_sd1.getLineDataForDiff(), m_sd1.getSizeLines(), m_sd2.getLineDataForDiff(), m_sd2.getSizeLines(), m_diffList12 );
462 else
463 runDiff( &m_sdlm1.m_v[0], m_sdlm1.m_vSize, &m_sdlm2.m_v[0], m_sdlm2.m_vSize, m_diffList12 );
464 285
465 g_pProgressDialog->step(); 286 g_pProgressDialog->step();
466 287
467 g_pProgressDialog->setInformation(i18n("Linediff: A <-> B")); 288 g_pProgressDialog->setInformation(i18n("Linediff: A <-> B"));
468 calcDiff3LineListUsingAB( &m_diffList12, m_diff3LineList ); 289 calcDiff3LineListUsingAB( &m_diffList12, m_diff3LineList );
469 fineDiff( m_diff3LineList, 1, &m_sd1.m_v[0], &m_sd2.m_v[0], m_totalDiffStatus.bTextAEqB ); 290 fineDiff( m_diff3LineList, 1, m_sd1.getLineDataForDisplay(), m_sd2.getLineDataForDisplay(), m_totalDiffStatus.bTextAEqB );
470 if ( m_sd1.m_size==0 ) m_totalDiffStatus.bTextAEqB=false; 291 if ( m_sd1.getSizeBytes()==0 ) m_totalDiffStatus.bTextAEqB=false;
471 292
472 g_pProgressDialog->step(); 293 g_pProgressDialog->step();
473 } 294 }
474 else 295 else
475 { 296 {
476 g_pProgressDialog->setInformation(i18n("Loading C")); 297 g_pProgressDialog->setInformation(i18n("Loading C"));
477 m_sd3.readPPFile( bPreserveCarriageReturn, m_pOptionDialog->m_PreProcessorCmd, bUpCase ); 298 m_sd3.readAndPreprocess();
478 m_sdlm3.readLMPPFile( &m_sd3, m_pOptionDialog->m_LineMatchingPreProcessorCmd, bUpCase, m_pOptionDialog->m_bIgnoreComments );
479 g_pProgressDialog->step(); 299 g_pProgressDialog->step();
480 300
481 m_totalDiffStatus.bBinaryAEqB = (m_sd1.m_size!=0 && m_sd1.m_size==m_sd2.m_size && memcmp(m_sd1.m_pBuf,m_sd2.m_pBuf,m_sd1.m_size)==0); 301 m_totalDiffStatus.bBinaryAEqB = m_sd1.getSizeBytes()!=0 && m_sd1.isBinaryEqualWith(m_sd2);
482 m_totalDiffStatus.bBinaryAEqC = (m_sd1.m_size!=0 && m_sd1.m_size==m_sd3.m_size && memcmp(m_sd1.m_pBuf,m_sd3.m_pBuf,m_sd1.m_size)==0); 302 m_totalDiffStatus.bBinaryAEqC = m_sd1.getSizeBytes()!=0 && m_sd1.isBinaryEqualWith(m_sd3);
483 m_totalDiffStatus.bBinaryBEqC = (m_sd3.m_size!=0 && m_sd3.m_size==m_sd2.m_size && memcmp(m_sd3.m_pBuf,m_sd2.m_pBuf,m_sd3.m_size)==0); 303 m_totalDiffStatus.bBinaryBEqC = m_sd3.getSizeBytes()!=0 && m_sd3.isBinaryEqualWith(m_sd2);
484 304
485 if ( !bUseLineMatchingPP ) 305 g_pProgressDialog->setInformation(i18n("Diff: A <-> B"));
486 { 306 runDiff( m_sd1.getLineDataForDiff(), m_sd1.getSizeLines(), m_sd2.getLineDataForDiff(), m_sd2.getSizeLines(), m_diffList12 );
487 g_pProgressDialog->setInformation(i18n("Diff: A <-> B")); 307 g_pProgressDialog->step();
488 runDiff( &m_sd1.m_v[0], m_sd1.m_vSize, &m_sd2.m_v[0], m_sd2.m_vSize, m_diffList12 ); 308 g_pProgressDialog->setInformation(i18n("Diff: B <-> C"));
489 g_pProgressDialog->step(); 309 runDiff( m_sd2.getLineDataForDiff(), m_sd2.getSizeLines(), m_sd3.getLineDataForDiff(), m_sd3.getSizeLines(), m_diffList23 );
490 g_pProgressDialog->setInformation(i18n("Diff: B <-> C")); 310 g_pProgressDialog->step();
491 runDiff( &m_sd2.m_v[0], m_sd2.m_vSize, &m_sd3.m_v[0], m_sd3.m_vSize, m_diffList23 ); 311 g_pProgressDialog->setInformation(i18n("Diff: A <-> C"));
492 g_pProgressDialog->step(); 312 runDiff( m_sd1.getLineDataForDiff(), m_sd1.getSizeLines(), m_sd3.getLineDataForDiff(), m_sd3.getSizeLines(), m_diffList13 );
493 g_pProgressDialog->setInformation(i18n("Diff: A <-> C")); 313 g_pProgressDialog->step();
494 runDiff( &m_sd1.m_v[0], m_sd1.m_vSize, &m_sd3.m_v[0], m_sd3.m_vSize, m_diffList13 );
495 g_pProgressDialog->step();
496 }
497 else
498 {
499 g_pProgressDialog->setInformation(i18n("Diff: A <-> B"));
500 runDiff( &m_sdlm1.m_v[0], m_sd1.m_vSize, &m_sdlm2.m_v[0], m_sd2.m_vSize, m_diffList12 );
501 g_pProgressDialog->step();
502 g_pProgressDialog->setInformation(i18n("Diff: B <-> C"));
503 runDiff( &m_sdlm2.m_v[0], m_sd2.m_vSize, &m_sdlm3.m_v[0], m_sd3.m_vSize, m_diffList23 );
504 g_pProgressDialog->step();
505 g_pProgressDialog->setInformation(i18n("Diff: A <-> C"));
506 runDiff( &m_sdlm1.m_v[0], m_sd1.m_vSize, &m_sdlm3.m_v[0], m_sd3.m_vSize, m_diffList13 );
507 g_pProgressDialog->step();
508 }
509 314
510 calcDiff3LineListUsingAB( &m_diffList12, m_diff3LineList ); 315 calcDiff3LineListUsingAB( &m_diffList12, m_diff3LineList );
511 calcDiff3LineListUsingAC( &m_diffList13, m_diff3LineList ); 316 calcDiff3LineListUsingAC( &m_diffList13, m_diff3LineList );
512 calcDiff3LineListTrim( m_diff3LineList, &m_sd1.m_v[0], &m_sd2.m_v[0], &m_sd3.m_v[0] ); 317 calcDiff3LineListTrim( m_diff3LineList, m_sd1.getLineDataForDiff(), m_sd2.getLineDataForDiff(), m_sd3.getLineDataForDiff() );
513 318
514 calcDiff3LineListUsingBC( &m_diffList23, m_diff3LineList ); 319 calcDiff3LineListUsingBC( &m_diffList23, m_diff3LineList );
515 calcDiff3LineListTrim( m_diff3LineList, &m_sd1.m_v[0], &m_sd2.m_v[0], &m_sd3.m_v[0] ); 320 calcDiff3LineListTrim( m_diff3LineList, m_sd1.getLineDataForDiff(), m_sd2.getLineDataForDiff(), m_sd3.getLineDataForDiff() );
516 debugLineCheck( m_diff3LineList, m_sd1.m_vSize, 1 ); 321 debugLineCheck( m_diff3LineList, m_sd1.getSizeLines(), 1 );
517 debugLineCheck( m_diff3LineList, m_sd2.m_vSize, 2 ); 322 debugLineCheck( m_diff3LineList, m_sd2.getSizeLines(), 2 );
518 debugLineCheck( m_diff3LineList, m_sd3.m_vSize, 3 ); 323 debugLineCheck( m_diff3LineList, m_sd3.getSizeLines(), 3 );
519 324
520 g_pProgressDialog->setInformation(i18n("Linediff: A <-> B")); 325 g_pProgressDialog->setInformation(i18n("Linediff: A <-> B"));
521 fineDiff( m_diff3LineList, 1, &m_sd1.m_v[0], &m_sd2.m_v[0], m_totalDiffStatus.bTextAEqB ); 326 fineDiff( m_diff3LineList, 1, m_sd1.getLineDataForDisplay(), m_sd2.getLineDataForDisplay(), m_totalDiffStatus.bTextAEqB );
522 g_pProgressDialog->step(); 327 g_pProgressDialog->step();
523 g_pProgressDialog->setInformation(i18n("Linediff: B <-> C")); 328 g_pProgressDialog->setInformation(i18n("Linediff: B <-> C"));
524 fineDiff( m_diff3LineList, 2, &m_sd2.m_v[0], &m_sd3.m_v[0], m_totalDiffStatus.bTextBEqC ); 329 fineDiff( m_diff3LineList, 2, m_sd2.getLineDataForDisplay(), m_sd3.getLineDataForDisplay(), m_totalDiffStatus.bTextBEqC );
525 g_pProgressDialog->step(); 330 g_pProgressDialog->step();
526 g_pProgressDialog->setInformation(i18n("Linediff: A <-> C")); 331 g_pProgressDialog->setInformation(i18n("Linediff: A <-> C"));
527 fineDiff( m_diff3LineList, 3, &m_sd3.m_v[0], &m_sd1.m_v[0], m_totalDiffStatus.bTextAEqC ); 332 fineDiff( m_diff3LineList, 3, m_sd3.getLineDataForDisplay(), m_sd1.getLineDataForDisplay(), m_totalDiffStatus.bTextAEqC );
528 g_pProgressDialog->step(); 333 g_pProgressDialog->step();
529 if ( m_sd1.m_size==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextAEqC=false; } 334 if ( m_sd1.getSizeBytes()==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextAEqC=false; }
530 if ( m_sd2.m_size==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextBEqC=false; } 335 if ( m_sd2.getSizeBytes()==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextBEqC=false; }
531 } 336 }
532 calcWhiteDiff3Lines( m_diff3LineList, &m_sd1.m_v[0], &m_sd2.m_v[0], &m_sd3.m_v[0] ); 337 calcWhiteDiff3Lines( m_diff3LineList, m_sd1.getLineDataForDiff(), m_sd2.getLineDataForDiff(), m_sd3.getLineDataForDiff() );
533 calcDiff3LineVector( m_diff3LineList, m_diff3LineVector ); 338 calcDiff3LineVector( m_diff3LineList, m_diff3LineVector );
534 339
535 // Calc needed lines for display 340 // Calc needed lines for display
536 m_neededLines = m_diff3LineList.size(); 341 m_neededLines = m_diff3LineList.size();
537 342
540 m_pDirectoryMergeWindow->allowResizeEvents(true); 345 m_pDirectoryMergeWindow->allowResizeEvents(true);
541 346
542 m_bTripleDiff = ! m_sd3.isEmpty(); 347 m_bTripleDiff = ! m_sd3.isEmpty();
543 348
544 m_pDiffTextWindow1->init( m_sd1.getAliasName(), 349 m_pDiffTextWindow1->init( m_sd1.getAliasName(),
545 &m_sd1.m_v[0], m_sd1.m_vSize, &m_diff3LineVector, 1, m_bTripleDiff ); 350 m_sd1.getLineDataForDisplay(), m_sd1.getSizeLines(), &m_diff3LineVector, 1, m_bTripleDiff );
546 m_pDiffTextWindow2->init( m_sd2.getAliasName(), 351 m_pDiffTextWindow2->init( m_sd2.getAliasName(),
547 &m_sd2.m_v[0], m_sd2.m_vSize, &m_diff3LineVector, 2, m_bTripleDiff ); 352 m_sd2.getLineDataForDisplay(), m_sd2.getSizeLines(), &m_diff3LineVector, 2, m_bTripleDiff );
548 m_pDiffTextWindow3->init( m_sd3.getAliasName(), 353 m_pDiffTextWindow3->init( m_sd3.getAliasName(),
549 &m_sd3.m_v[0], m_sd3.m_vSize, &m_diff3LineVector, 3, m_bTripleDiff ); 354 m_sd3.getLineDataForDisplay(), m_sd3.getSizeLines(), &m_diff3LineVector, 3, m_bTripleDiff );
550 355
551 if (m_bTripleDiff) m_pDiffTextWindow3->show(); 356 if (m_bTripleDiff) m_pDiffTextWindow3->show();
552 else m_pDiffTextWindow3->hide(); 357 else m_pDiffTextWindow3->hide();
553 358
554 m_bOutputModified = bVisibleMergeResultWindow; 359 m_bOutputModified = bVisibleMergeResultWindow;
555 360
556 m_pMergeResultWindow->init( 361 m_pMergeResultWindow->init(
557 &m_sd1.m_v[0], 362 m_sd1.getLineDataForDisplay(),
558 &m_sd2.m_v[0], 363 m_sd2.getLineDataForDisplay(),
559 m_bTripleDiff ? &m_sd3.m_v[0] : 0, 364 m_bTripleDiff ? m_sd3.getLineDataForDisplay() : 0,
560 &m_diff3LineList, 365 &m_diff3LineList,
561 &m_totalDiffStatus, 366 &m_totalDiffStatus,
562 m_outputFilename.isEmpty() ? QString("unnamed.txt") : m_outputFilename 367 m_outputFilename.isEmpty() ? QString("unnamed.txt") : m_outputFilename
563 ); 368 );
564 369
569 g_pProgressDialog->hide(); 374 g_pProgressDialog->hide();
570 m_pDiffTextWindow1->setPaintingAllowed( true ); 375 m_pDiffTextWindow1->setPaintingAllowed( true );
571 m_pDiffTextWindow2->setPaintingAllowed( true ); 376 m_pDiffTextWindow2->setPaintingAllowed( true );
572 m_pDiffTextWindow3->setPaintingAllowed( true ); 377 m_pDiffTextWindow3->setPaintingAllowed( true );
573 m_pOverview->setPaintingAllowed( true ); 378 m_pOverview->setPaintingAllowed( true );
379 m_pMergeResultWindow->setPaintingAllowed( true );
380
574 381
575 if ( !bVisibleMergeResultWindow ) 382 if ( !bVisibleMergeResultWindow )
576 m_pMergeWindowFrame->hide(); 383 m_pMergeWindowFrame->hide();
577 else 384 else
578 m_pMergeWindowFrame->show(); 385 m_pMergeWindowFrame->show();
602 409
603 if ( !totalInfo.isEmpty() ) 410 if ( !totalInfo.isEmpty() )
604 KMessageBox::information( this, totalInfo ); 411 KMessageBox::information( this, totalInfo );
605 } 412 }
606 413
607 if ( bVisibleMergeResultWindow && (!m_sd1.m_bIsText || !m_sd2.m_bIsText || !m_sd3.m_bIsText) ) 414 if ( bVisibleMergeResultWindow && (!m_sd1.isText() || !m_sd2.isText() || !m_sd3.isText()) )
608 { 415 {
609 KMessageBox::information( this, i18n( 416 KMessageBox::information( this, i18n(
610 "Some inputfiles don't seem to be pure textfiles.\n" 417 "Some inputfiles don't seem to be pure textfiles.\n"
611 "Note that the KDiff3-merge was not meant for binary data.\n" 418 "Note that the KDiff3-merge was not meant for binary data.\n"
612 "Continue at your own risk.") ); 419 "Continue at your own risk.") );
947 754
948 scrollDiffTextWindow( deltaX, deltaY ); 755 scrollDiffTextWindow( deltaX, deltaY );
949 756
950 return true; // eat event 757 return true; // eat event
951 } 758 }
952 else if (e->type() == QEvent::Wheel ) { // wheel event 759 else if (e->type() == QEvent::Wheel ) // wheel event
760 {
953 QWheelEvent *w = (QWheelEvent*)e; 761 QWheelEvent *w = (QWheelEvent*)e;
954 w->accept(); 762 w->accept();
955 763
956 int deltaX=0; 764 int deltaX=0;
957 765
999 QString text; 807 QString text;
1000 bool bDecodeSuccess = QTextDrag::decode( pDropEvent, text ); 808 bool bDecodeSuccess = QTextDrag::decode( pDropEvent, text );
1001 if ( bDecodeSuccess && canContinue() ) 809 if ( bDecodeSuccess && canContinue() )
1002 { 810 {
1003 raise(); 811 raise();
1004 bool bUpCase = m_pOptionDialog->m_bUpCase; 812 if ( o == m_pDiffTextWindow1 ) m_sd1.setData(text);
1005 if ( o == m_pDiffTextWindow1 ) m_sd1.setData(text, bUpCase); 813 else if ( o == m_pDiffTextWindow2 ) m_sd2.setData(text);
1006 else if ( o == m_pDiffTextWindow2 ) m_sd2.setData(text, bUpCase); 814 else if ( o == m_pDiffTextWindow3 ) m_sd3.setData(text);
1007 else if ( o == m_pDiffTextWindow3 ) m_sd3.setData(text, bUpCase);
1008 init(); 815 init();
1009 } 816 }
1010 } 817 }
1011 818
1012 return true; 819 return true;
1035 m_lineA->setMinimumSize( 200, m_lineA->size().height() ); 842 m_lineA->setMinimumSize( 200, m_lineA->size().height() );
1036 QPushButton * button = new QPushButton( i18n("File..."), this ); 843 QPushButton * button = new QPushButton( i18n("File..."), this );
1037 connect( button, SIGNAL(clicked()), this, SLOT( selectFileA() ) ); 844 connect( button, SIGNAL(clicked()), this, SLOT( selectFileA() ) );
1038 QPushButton * button2 = new QPushButton( i18n("Dir..."), this ); 845 QPushButton * button2 = new QPushButton( i18n("Dir..."), this );
1039 connect( button2, SIGNAL(clicked()), this, SLOT( selectDirA() ) ); 846 connect( button2, SIGNAL(clicked()), this, SLOT( selectDirA() ) );
847 connect( m_lineA, SIGNAL(textChanged(const QString&)), this, SLOT(inputFilenameChanged() ) );
1040 848
1041 h->addWidget( label, 0, 0 ); 849 h->addWidget( label, 0, 0 );
1042 h->addWidget( m_lineA, 0, 1 ); 850 h->addWidget( m_lineA, 0, 1 );
1043 h->addWidget( button, 0, 2 ); 851 h->addWidget( button, 0, 2 );
1044 h->addWidget( button2, 0, 3 ); 852 h->addWidget( button2, 0, 3 );
1050 m_lineB->setMinimumSize( 200, m_lineB->size().height() ); 858 m_lineB->setMinimumSize( 200, m_lineB->size().height() );
1051 button = new QPushButton( i18n("File..."), this ); 859 button = new QPushButton( i18n("File..."), this );
1052 connect( button, SIGNAL(clicked()), this, SLOT( selectFileB() ) ); 860 connect( button, SIGNAL(clicked()), this, SLOT( selectFileB() ) );
1053 button2 = new QPushButton( i18n("Dir..."), this ); 861 button2 = new QPushButton( i18n("Dir..."), this );
1054 connect( button2, SIGNAL(clicked()), this, SLOT( selectDirB() ) ); 862 connect( button2, SIGNAL(clicked()), this, SLOT( selectDirB() ) );
863 connect( m_lineB, SIGNAL(textChanged(const QString&)), this, SLOT(inputFilenameChanged() ) );
1055 864
1056 h->addWidget( label, 1, 0 ); 865 h->addWidget( label, 1, 0 );
1057 h->addWidget( m_lineB, 1, 1 ); 866 h->addWidget( m_lineB, 1, 1 );
1058 h->addWidget( button, 1, 2 ); 867 h->addWidget( button, 1, 2 );
1059 h->addWidget( button2, 1, 3 ); 868 h->addWidget( button2, 1, 3 );
1065 m_lineC->setMinimumSize( 200, m_lineC->size().height() ); 874 m_lineC->setMinimumSize( 200, m_lineC->size().height() );
1066 button = new QPushButton( i18n("File..."), this ); 875 button = new QPushButton( i18n("File..."), this );
1067 connect( button, SIGNAL(clicked()), this, SLOT( selectFileC() ) ); 876 connect( button, SIGNAL(clicked()), this, SLOT( selectFileC() ) );
1068 button2 = new QPushButton( i18n("Dir..."), this ); 877 button2 = new QPushButton( i18n("Dir..."), this );
1069 connect( button2, SIGNAL(clicked()), this, SLOT( selectDirC() ) ); 878 connect( button2, SIGNAL(clicked()), this, SLOT( selectDirC() ) );
879 connect( m_lineC, SIGNAL(textChanged(const QString&)), this, SLOT(inputFilenameChanged() ) );
1070 880
1071 h->addWidget( label, 2, 0 ); 881 h->addWidget( label, 2, 0 );
1072 h->addWidget( m_lineC, 2, 1 ); 882 h->addWidget( m_lineC, 2, 1 );
1073 h->addWidget( button, 2, 2 ); 883 h->addWidget( button, 2, 2 );
1074 h->addWidget( button2, 2, 3 ); 884 h->addWidget( button2, 2, 3 );
1120 connect( button, SIGNAL(clicked()), this, SLOT( reject() ) ); 930 connect( button, SIGNAL(clicked()), this, SLOT( reject() ) );
1121 l->addWidget( button,1 ); 931 l->addWidget( button,1 );
1122 932
1123 QSize sh = sizeHint(); 933 QSize sh = sizeHint();
1124 setFixedHeight( sh.height() ); 934 setFixedHeight( sh.height() );
1125 } 935 m_bInputFileNameChanged = false;
936
937 #ifdef KREPLACEMENTS_H
938 m_lineA->lineEdit()->installEventFilter( this );
939 m_lineB->lineEdit()->installEventFilter( this );
940 m_lineC->lineEdit()->installEventFilter( this );
941 m_lineOut->lineEdit()->installEventFilter( this );
942 #endif
943 }
944
945 // Eventfilter: Only needed under Windows.
946 // Without this, files dropped in the line edit have URL-encoding.
947 // This eventfilter decodes the filenames as needed by KDiff3.
948 bool OpenDialog::eventFilter(QObject* o, QEvent* e)
949 {
950 if (e->type()==QEvent::Drop)
951 {
952 QDropEvent* d = static_cast<QDropEvent*>(e);
953
954 if ( !QUriDrag::canDecode( d ) ) {
955 return false;
956 }
957
958 QStringList lst;
959 QUriDrag::decodeLocalFiles( d, lst );
960
961 if ( lst.count() > 0 )
962 {
963 static_cast<QLineEdit*>(o)->setText( lst[0] );
964 static_cast<QLineEdit*>(o)->setFocus();
965 }
966
967 return true;
968 }
969 return false;
970 }
971
1126 972
1127 void OpenDialog::selectURL( QComboBox* pLine, bool bDir, int i, bool bSave ) 973 void OpenDialog::selectURL( QComboBox* pLine, bool bDir, int i, bool bSave )
1128 { 974 {
1129 QString current = pLine->currentText(); 975 QString current = pLine->currentText();
1130 if (current.isEmpty() && i>3 ){ current = m_lineC->currentText(); } 976 if (current.isEmpty() && i>3 ){ current = m_lineC->currentText(); }
1152 void OpenDialog::internalSlot(int i) 998 void OpenDialog::internalSlot(int i)
1153 { 999 {
1154 emit internalSignal(i!=0); 1000 emit internalSignal(i!=0);
1155 } 1001 }
1156 1002
1003 // Clear the output-filename when any input-filename changed,
1004 // because users forgot to change the output and accidently overwrote it with
1005 // wrong data during a merge.
1006 void OpenDialog::inputFilenameChanged()
1007 {
1008 if(!m_bInputFileNameChanged)
1009 {
1010 m_bInputFileNameChanged=true;
1011 m_lineOut->clearEdit();
1012 }
1013 }
1014
1157 void OpenDialog::accept() 1015 void OpenDialog::accept()
1158 { 1016 {
1159 unsigned int maxNofRecentFiles = 10; 1017 unsigned int maxNofRecentFiles = 10;
1160 1018
1161 QString s = m_lineA->currentText(); 1019 QString s = m_lineA->currentText();
1207 slotStatusMsg(i18n("Opening files...")); 1065 slotStatusMsg(i18n("Opening files..."));
1208 1066
1209 for(;;) 1067 for(;;)
1210 { 1068 {
1211 OpenDialog d(this, 1069 OpenDialog d(this,
1212 m_sd1.m_bPreserve ? QString("") : m_sd1.getAliasName(), 1070 m_sd1.isFromBuffer() ? QString("") : m_sd1.getAliasName(),
1213 m_sd2.m_bPreserve ? QString("") : m_sd2.getAliasName(), 1071 m_sd2.isFromBuffer() ? QString("") : m_sd2.getAliasName(),
1214 m_sd3.m_bPreserve ? QString("") : m_sd3.getAliasName(), 1072 m_sd3.isFromBuffer() ? QString("") : m_sd3.getAliasName(),
1215 !m_outputFilename.isEmpty(), 1073 !m_outputFilename.isEmpty(),
1216 m_bDefaultFilename ? QString("") : m_outputFilename, 1074 m_bDefaultFilename ? QString("") : m_outputFilename,
1217 SLOT(slotConfigure()), m_pOptionDialog ); 1075 SLOT(slotConfigure()), m_pOptionDialog );
1218 int status = d.exec(); 1076 int status = d.exec();
1219 if ( status == QDialog::Accepted ) 1077 if ( status == QDialog::Accepted )
1251 else 1109 else
1252 { 1110 {
1253 m_pDirectoryMergeSplitter->hide(); 1111 m_pDirectoryMergeSplitter->hide();
1254 init(); 1112 init();
1255 1113
1256 if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 || 1114 if ( ! m_sd1.isEmpty() && !m_sd1.hasData() ||
1257 ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 || 1115 ! m_sd2.isEmpty() && !m_sd2.hasData() ||
1258 ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) 1116 ! m_sd3.isEmpty() && !m_sd3.hasData() )
1259 { 1117 {
1260 QString text( i18n("Opening of these files failed:") ); 1118 QString text( i18n("Opening of these files failed:") );
1261 text += "\n\n"; 1119 text += "\n\n";
1262 if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 ) 1120 if ( ! m_sd1.isEmpty() && !m_sd1.hasData() )
1263 text += " - " + m_sd1.getAliasName() + "\n"; 1121 text += " - " + m_sd1.getAliasName() + "\n";
1264 if ( ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 ) 1122 if ( ! m_sd2.isEmpty() && !m_sd2.hasData() )
1265 text += " - " + m_sd2.getAliasName() + "\n"; 1123 text += " - " + m_sd2.getAliasName() + "\n";
1266 if ( ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) 1124 if ( ! m_sd3.isEmpty() && !m_sd3.hasData() )
1267 text += " - " + m_sd3.getAliasName() + "\n"; 1125 text += " - " + m_sd3.getAliasName() + "\n";
1268 1126
1269 KMessageBox::sorry( this, text, i18n("File open error") ); 1127 KMessageBox::sorry( this, text, i18n("File open error") );
1270 continue; 1128 continue;
1271 } 1129 }
1312 } 1170 }
1313 else 1171 else
1314 { 1172 {
1315 init(); 1173 init();
1316 1174
1317 if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 || 1175 if ( ! m_sd1.isEmpty() && ! m_sd1.hasData() ||
1318 ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 || 1176 ! m_sd2.isEmpty() && ! m_sd2.hasData() ||
1319 ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) 1177 ! m_sd3.isEmpty() && ! m_sd3.hasData() )
1320 { 1178 {
1321 QString text( i18n("Opening of these files failed:") ); 1179 QString text( i18n("Opening of these files failed:") );
1322 text += "\n\n"; 1180 text += "\n\n";
1323 if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 ) 1181 if ( ! m_sd1.isEmpty() && !m_sd1.hasData() )
1324 text += " - " + m_sd1.getAliasName() + "\n"; 1182 text += " - " + m_sd1.getAliasName() + "\n";
1325 if ( ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 ) 1183 if ( ! m_sd2.isEmpty() && !m_sd2.hasData() )
1326 text += " - " + m_sd2.getAliasName() + "\n"; 1184 text += " - " + m_sd2.getAliasName() + "\n";
1327 if ( ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) 1185 if ( ! m_sd3.isEmpty() && !m_sd3.hasData() )
1328 text += " - " + m_sd3.getAliasName() + "\n"; 1186 text += " - " + m_sd3.getAliasName() + "\n";
1329 1187
1330 KMessageBox::sorry( this, text, i18n("File open error") ); 1188 KMessageBox::sorry( this, text, i18n("File open error") );
1331 } 1189 }
1332 else 1190 else
1353 m_pMergeResultWindow->update(); 1211 m_pMergeResultWindow->update();
1354 } 1212 }
1355 1213
1356 if ( !s.isNull() ) 1214 if ( !s.isNull() )
1357 { 1215 {
1358 QApplication::clipboard()->setText( s ); 1216 QApplication::clipboard()->setText( s, QClipboard::Clipboard );
1359 } 1217 }
1360 1218
1361 slotStatusMsg(i18n("Ready.")); 1219 slotStatusMsg(i18n("Ready."));
1362 } 1220 }
1363 1221
1369 if ( s.isNull() && m_pDiffTextWindow2!=0 ) s = m_pDiffTextWindow2->getSelection(); 1227 if ( s.isNull() && m_pDiffTextWindow2!=0 ) s = m_pDiffTextWindow2->getSelection();
1370 if ( s.isNull() && m_pDiffTextWindow3!=0 ) s = m_pDiffTextWindow3->getSelection(); 1228 if ( s.isNull() && m_pDiffTextWindow3!=0 ) s = m_pDiffTextWindow3->getSelection();
1371 if ( s.isNull() && m_pMergeResultWindow!=0 ) s = m_pMergeResultWindow->getSelection(); 1229 if ( s.isNull() && m_pMergeResultWindow!=0 ) s = m_pMergeResultWindow->getSelection();
1372 if ( !s.isNull() ) 1230 if ( !s.isNull() )
1373 { 1231 {
1374 QApplication::clipboard()->setText( s ); 1232 QApplication::clipboard()->setText( s, QClipboard::Clipboard );
1375 } 1233 }
1376 1234
1377 slotStatusMsg(i18n("Ready.")); 1235 slotStatusMsg(i18n("Ready."));
1378 } 1236 }
1379 1237
1385 { 1243 {
1386 m_pMergeResultWindow->pasteClipboard(); 1244 m_pMergeResultWindow->pasteClipboard();
1387 } 1245 }
1388 else if ( canContinue() ) 1246 else if ( canContinue() )
1389 { 1247 {
1390 bool bUpCase = m_pOptionDialog->m_bUpCase;
1391 if ( m_pDiffTextWindow1->hasFocus() ) 1248 if ( m_pDiffTextWindow1->hasFocus() )
1392 { 1249 {
1393 m_sd1.setData( QApplication::clipboard()->text(), bUpCase ); 1250 m_sd1.setData( QApplication::clipboard()->text() );
1394 init(); 1251 init();
1395 } 1252 }
1396 else if ( m_pDiffTextWindow2->hasFocus() ) 1253 else if ( m_pDiffTextWindow2->hasFocus() )
1397 { 1254 {
1398 m_sd2.setData( QApplication::clipboard()->text(), bUpCase ); 1255 m_sd2.setData( QApplication::clipboard()->text() );
1399 init(); 1256 init();
1400 } 1257 }
1401 else if ( m_pDiffTextWindow3->hasFocus() ) 1258 else if ( m_pDiffTextWindow3->hasFocus() )
1402 { 1259 {
1403 m_sd3.setData( QApplication::clipboard()->text(), bUpCase ); 1260 m_sd3.setData( QApplication::clipboard()->text() );
1404 init(); 1261 init();
1405 } 1262 }
1406 } 1263 }
1407 1264
1408 slotStatusMsg(i18n("Ready.")); 1265 slotStatusMsg(i18n("Ready."));
1582 //editCopy->setEnabled(true); 1439 //editCopy->setEnabled(true);
1583 //editCut->setEnabled( s==m_pMergeResultWindow ); 1440 //editCut->setEnabled( s==m_pMergeResultWindow );
1584 if ( m_pOptionDialog->m_bAutoCopySelection ) 1441 if ( m_pOptionDialog->m_bAutoCopySelection )
1585 { 1442 {
1586 slotEditCopy(); 1443 slotEditCopy();
1444 }
1445 else
1446 {
1447 QClipboard *clipBoard = QApplication::clipboard();
1448
1449 if (clipBoard->supportsSelection ())
1450 {
1451 QString s;
1452 if ( m_pDiffTextWindow1!=0 ) s = m_pDiffTextWindow1->getSelection();
1453 if ( s.isNull() && m_pDiffTextWindow2!=0 ) s = m_pDiffTextWindow2->getSelection();
1454 if ( s.isNull() && m_pDiffTextWindow3!=0 ) s = m_pDiffTextWindow3->getSelection();
1455 if ( s.isNull() && m_pMergeResultWindow!=0 ) s = m_pMergeResultWindow->getSelection();
1456 if ( !s.isNull() )
1457 {
1458 clipBoard->setText( s, QClipboard::Selection );
1459 }
1460 }
1587 } 1461 }
1588 } 1462 }
1589 1463
1590 void KDiff3App::slotClipboardChanged() 1464 void KDiff3App::slotClipboardChanged()
1591 { 1465 {
1920 else if ( m_pMainWidget != 0 && m_pMainWidget->isVisible() ) 1794 else if ( m_pMainWidget != 0 && m_pMainWidget->isVisible() )
1921 { 1795 {
1922 if ( !canContinue() ) return; 1796 if ( !canContinue() ) return;
1923 if ( m_outputFilename.isEmpty() ) 1797 if ( m_outputFilename.isEmpty() )
1924 { 1798 {
1925 if ( !m_sd3.isEmpty() && !m_sd3.m_bPreserve ) 1799 if ( !m_sd3.isEmpty() && !m_sd3.isFromBuffer() )
1926 { 1800 {
1927 m_outputFilename = m_sd3.getFilename(); 1801 m_outputFilename = m_sd3.getFilename();
1928 } 1802 }
1929 else if ( !m_sd2.isEmpty() && !m_sd2.m_bPreserve ) 1803 else if ( !m_sd2.isEmpty() && !m_sd2.isFromBuffer() )
1930 { 1804 {
1931 m_outputFilename = m_sd2.getFilename(); 1805 m_outputFilename = m_sd2.getFilename();
1932 } 1806 }
1933 else if ( !m_sd1.isEmpty() && !m_sd1.m_bPreserve ) 1807 else if ( !m_sd1.isEmpty() && !m_sd1.isFromBuffer() )
1934 { 1808 {
1935 m_outputFilename = m_sd1.getFilename(); 1809 m_outputFilename = m_sd1.getFilename();
1936 } 1810 }
1937 else 1811 else
1938 { 1812 {
2014 } 1888 }
2015 } 1889 }
2016 1890
2017 void KDiff3App::slotUpdateAvailabilities() 1891 void KDiff3App::slotUpdateAvailabilities()
2018 { 1892 {
2019 bool bTextDataAvailable = (m_sd1.m_pBuf != 0 || m_sd2.m_pBuf != 0 || m_sd3.m_pBuf != 0 ); 1893 bool bTextDataAvailable = ( m_sd1.hasData() || m_sd2.hasData() || m_sd3.hasData() );
2020 if( dirShowBoth->isChecked() ) 1894 if( dirShowBoth->isChecked() )
2021 { 1895 {
2022 if ( m_bDirCompare ) 1896 if ( m_bDirCompare )
2023 m_pDirectoryMergeSplitter->show(); 1897 m_pDirectoryMergeSplitter->show();
2024 else 1898 else