Mercurial > hg > easyhg-kdiff3
diff 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 |
line wrap: on
line diff
--- a/kdiff3/src/pdiff.cpp Sat Jan 31 14:25:47 2004 +0000 +++ b/kdiff3/src/pdiff.cpp Sun Mar 07 09:59:09 2004 +0000 @@ -1,8 +1,8 @@ /*************************************************************************** - kdiff.cpp - description - ------------------- + pdiff.cpp - Implementation for class KDiff3App + --------------- begin : Mon Mär 18 20:04:50 CET 2002 - copyright : (C) 2002 by Joachim Eibl + copyright : (C) 2002-2004 by Joachim Eibl email : joachim.eibl@gmx.de ***************************************************************************/ @@ -99,7 +99,7 @@ return fileName; } -bool KDiff3App::runDiff( LineData* p1, int size1, LineData* p2, int size2, DiffList& diffList ) +bool KDiff3App::runDiff( const LineData* p1, int size1, const LineData* p2, int size2, DiffList& diffList ) { static GnuDiff gnuDiff; @@ -164,8 +164,11 @@ if (size1-currentLine1==size2-currentLine2 ) { - Diff d( size1-currentLine1,0,0); - diffList.push_back(d); + if (size1-currentLine1>0) + { + Diff d( size1-currentLine1,0,0); + diffList.push_back(d); + } } else if ( !diffList.empty() ) { // Only necessary for a files that end with a newline @@ -204,209 +207,6 @@ g_pProgressDialog->setSubCurrent(1.0); return true; -#if 0 - - if ( m_pOptionDialog->m_bUseExternalDiff ) - { - bool bSuccess=false; - - bool bIgnoreWhiteSpace = m_pOptionDialog->m_bIgnoreWhiteSpace; - bool bIgnoreNumbers = m_pOptionDialog->m_bIgnoreNumbers; - - // Create two temp files (Remove all white spaces and carriage returns here) - // (Make sure that no existing files are overwritten.) - g_pProgressDialog->setSubCurrent(0); - QString fileName1 = createTempFile( p1, size1, bIgnoreWhiteSpace, bIgnoreNumbers ); - g_pProgressDialog->setSubCurrent(0.25); - QString fileName2 = createTempFile( p2, size2, bIgnoreWhiteSpace, bIgnoreNumbers ); - g_pProgressDialog->setSubCurrent(0.5); - QString fileNameOut = FileAccess::tempFileName(); - - if ( !fileName1.isEmpty() && !fileName2.isEmpty() ) - { - QString cmd; -#ifdef _WIN32 - // Under Windows it's better to search for diff.exe - char buf[200]; - int r= SearchPathA( 0, "diff.exe", 0, sizeof(buf), buf, 0 ); - - if (r!=0) { cmd = buf; } -#else - // under Un*x I assume that a diff command is in the PATH - cmd = "diff"; -#endif - if ( !cmd.isEmpty() ) - { - cmd += " -a "; // -a = treat all files as text - if ( m_pOptionDialog->m_bTryHard ) - cmd += "--minimal "; - //if ( m_pOptionDialog->m_bIgnoreWhiteSpace ) This I do myself, see below - // cmd += "--ignore-all-space "; - cmd += fileName1+" "+fileName2+" >"+fileNameOut; - // Run diff - //int status1 = ::system( 0 ); // ==0 if shell not found - int status = ::system( cmd.ascii() ); -#ifdef WEXITSTATUS - status = WEXITSTATUS(status); -#endif - //if (status<0) - //{ - // errorString = strerror( errno ); - //} - bSuccess = status>=0 && status!=127; - } - } - - g_pProgressDialog->setSubCurrent(0.75); - - int currentLine1 = 0; - int currentLine2 = 0; - if ( bSuccess ) - { - // Parse the output and create the difflist - QFile f( fileNameOut ); - bSuccess = f.open(IO_ReadOnly); - if (bSuccess) - { - const QByteArray buf = f.readAll(); - unsigned int bufSize=buf.size(); - unsigned int pos=0; - for(pos=0;pos<bufSize;++pos) - { - unsigned int lineStart = pos; - // Find end of line - while( buf.at(pos)!='\n' && pos<bufSize ) - ++pos; - - // parse it - char c = buf.at(lineStart); - if ( c == '>' || c == '-' || c=='<' ) - continue; // Not interested in the data - else - { - QCString line( &buf.at(lineStart), pos-lineStart+1 ); - int pa = line.find('a'); // add - int pc = line.find('c'); // change - int pd = line.find('d'); // delete - int p = pa>0 ? pa : (pc > 0 ? pc : pd); - if (p<0) break; // Unexpected error - QCString left = line.left(p); - QCString right = line.mid(p+1); - int pcommaleft = left.find(','); - int pcommaright = right.find(','); - int l1top=-1, l1bottom=-1, l2top=-1, l2bottom=-1; - if (pcommaleft>0) - { - l1top = left.left(pcommaleft).toInt(); - l1bottom = left.mid(pcommaleft+1).toInt(); - } - else - { - l1top = left.toInt(); - l1bottom = l1top; - } - if (pcommaright>0) - { - l2top = right.left(pcommaright).toInt(); - l2bottom = right.mid(pcommaright+1).toInt(); - } - else - { - l2top = right.toInt(); - l2bottom = l2top; - } - - Diff d(0,0,0); - - if ( pa>0 ) - { - d.nofEquals = l1top - currentLine1; - d.diff1 = 0; - d.diff2 = l2bottom - l2top + 1; - assert( d.nofEquals == l2top - 1 - currentLine2 ); - } - else if ( pd>0 ) - { - d.nofEquals = l2top - currentLine2; - d.diff1 = l1bottom - l1top + 1; - d.diff2 = 0; - assert( d.nofEquals == l1top - 1 - currentLine1 ); - } - else if ( pc>0 ) - { - d.nofEquals = l1top - 1 - currentLine1; - d.diff1 = l1bottom - l1top + 1; - d.diff2 = l2bottom - l2top + 1; - assert( d.nofEquals == l2top - 1 - currentLine2 ); - } - else - assert(false); - - currentLine1 += d.nofEquals + d.diff1; - currentLine2 += d.nofEquals + d.diff2; - diffList.push_back(d); - } - } - if (size1-currentLine1==size2-currentLine2 ) - { - Diff d( size1-currentLine1,0,0); - diffList.push_back(d); - currentLine1=size1; - currentLine2=size2; - } - - if ( currentLine1 == size1 && currentLine2 == size2 ) - bSuccess = true; - } - else - { - bSuccess = size1==size2; - } - } - if ( currentLine1==0 && currentLine2==0 ) - { - Diff d( 0, size1, size2 ); - diffList.push_back(d); - } - - g_pProgressDialog->setSubCurrent(1.0); - - if ( !bSuccess ) - { - KMessageBox::sorry(this, - i18n("Running the external diff failed.\n" - "Check if the diff works, if the program can write in the temp folder or if the disk is full.\n" - "The external diff option will be disabled now and the internal diff will be used."), - i18n("Warning")); - m_pOptionDialog->m_bUseExternalDiff = false; - } - - FileAccess::removeFile( fileName1 ); - FileAccess::removeFile( fileName2 ); - FileAccess::removeFile( fileNameOut ); - } - - if ( ! m_pOptionDialog->m_bUseExternalDiff ) - { - g_pProgressDialog->setSubCurrent(0.0); - if ( size1>0 && p1!=0 && p1->occurances==0 ) - { - prepareOccurances( p1, size1 ); - } - g_pProgressDialog->setSubCurrent(0.25); - - if ( size2>0 && p2!=0 && p2->occurances==0 ) - { - prepareOccurances( p2, size2 ); - } - g_pProgressDialog->setSubCurrent(0.5); - - calcDiff( p1, size1, p2, size2, diffList, 2, m_pOptionDialog->m_maxSearchLength ); - - g_pProgressDialog->setSubCurrent(1.0); - } - return true; -#endif } @@ -418,18 +218,44 @@ if ( bVisibleMergeResultWindow ) { bPreserveCarriageReturn = false; + + QString msg; + + if ( !m_pOptionDialog->m_PreProcessorCmd.isEmpty() ) + { + msg += "- " + i18n("PreprocessorCmd: ") + m_pOptionDialog->m_PreProcessorCmd + "\n"; + } + if ( m_pOptionDialog->m_bUpCase ) + { + msg += "- " + i18n("Convert to upper case\n"); + } + if ( !msg.isEmpty() ) + { + int result = KMessageBox::warningYesNo( this, + i18n("The following option(s) you selected might change data:\n") + msg + + i18n("\nMost likely this is not wanted during a merge.\n" + "Do you want to disable these settings or continue with these settings active?"), + i18n("Option unsafe for merging"), + i18n("Use these options during the merge"), i18n("Disable unsafe options") + ); + + if (result == KMessageBox::No ) + { + m_pOptionDialog->m_PreProcessorCmd = ""; + m_pOptionDialog->m_bUpCase = false; + } + } } m_diff3LineList.clear(); - bool bUseLineMatchingPP = !m_pOptionDialog->m_LineMatchingPreProcessorCmd.isEmpty() || - m_pOptionDialog->m_bIgnoreComments; - bool bUpCase = m_pOptionDialog->m_bUpCase; - + // Because of the progressdialog paintevents can occur, but data is invalid, + // so painting must be suppressed. if (m_pDiffTextWindow1) m_pDiffTextWindow1->setPaintingAllowed( false ); if (m_pDiffTextWindow2) m_pDiffTextWindow2->setPaintingAllowed( false ); if (m_pDiffTextWindow3) m_pDiffTextWindow3->setPaintingAllowed( false ); if (m_pOverview) m_pOverview->setPaintingAllowed( false ); + if (m_pMergeResultWindow) m_pMergeResultWindow->setPaintingAllowed( false ); if( m_sd3.isEmpty() ) @@ -441,95 +267,74 @@ // First get all input data. g_pProgressDialog->setInformation(i18n("Loading A")); - m_sd1.readPPFile( bPreserveCarriageReturn, m_pOptionDialog->m_PreProcessorCmd, bUpCase ); - m_sdlm1.readLMPPFile( &m_sd1, m_pOptionDialog->m_LineMatchingPreProcessorCmd, bUpCase, m_pOptionDialog->m_bIgnoreComments ); + m_sd1.readAndPreprocess(); g_pProgressDialog->step(); g_pProgressDialog->setInformation(i18n("Loading B")); - m_sd2.readPPFile( bPreserveCarriageReturn, m_pOptionDialog->m_PreProcessorCmd, bUpCase ); - m_sdlm2.readLMPPFile( &m_sd2, m_pOptionDialog->m_LineMatchingPreProcessorCmd, bUpCase, m_pOptionDialog->m_bIgnoreComments ); + m_sd2.readAndPreprocess(); g_pProgressDialog->step(); - m_sd3.m_bIsText = true; m_totalDiffStatus.reset(); // Run the diff. if ( m_sd3.isEmpty() ) { - 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); + m_totalDiffStatus.bBinaryAEqB = m_sd1.getSizeBytes()!=0 && m_sd1.isBinaryEqualWith( m_sd2 ); g_pProgressDialog->setInformation(i18n("Diff: A <-> B")); - if ( !bUseLineMatchingPP ) - runDiff( &m_sd1.m_v[0], m_sd1.m_vSize, &m_sd2.m_v[0], m_sd2.m_vSize, m_diffList12 ); - else - runDiff( &m_sdlm1.m_v[0], m_sdlm1.m_vSize, &m_sdlm2.m_v[0], m_sdlm2.m_vSize, m_diffList12 ); + + runDiff( m_sd1.getLineDataForDiff(), m_sd1.getSizeLines(), m_sd2.getLineDataForDiff(), m_sd2.getSizeLines(), m_diffList12 ); g_pProgressDialog->step(); g_pProgressDialog->setInformation(i18n("Linediff: A <-> B")); calcDiff3LineListUsingAB( &m_diffList12, m_diff3LineList ); - fineDiff( m_diff3LineList, 1, &m_sd1.m_v[0], &m_sd2.m_v[0], m_totalDiffStatus.bTextAEqB ); - if ( m_sd1.m_size==0 ) m_totalDiffStatus.bTextAEqB=false; + fineDiff( m_diff3LineList, 1, m_sd1.getLineDataForDisplay(), m_sd2.getLineDataForDisplay(), m_totalDiffStatus.bTextAEqB ); + if ( m_sd1.getSizeBytes()==0 ) m_totalDiffStatus.bTextAEqB=false; g_pProgressDialog->step(); } else { g_pProgressDialog->setInformation(i18n("Loading C")); - m_sd3.readPPFile( bPreserveCarriageReturn, m_pOptionDialog->m_PreProcessorCmd, bUpCase ); - m_sdlm3.readLMPPFile( &m_sd3, m_pOptionDialog->m_LineMatchingPreProcessorCmd, bUpCase, m_pOptionDialog->m_bIgnoreComments ); + m_sd3.readAndPreprocess(); g_pProgressDialog->step(); - 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); - 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); - 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); + m_totalDiffStatus.bBinaryAEqB = m_sd1.getSizeBytes()!=0 && m_sd1.isBinaryEqualWith(m_sd2); + m_totalDiffStatus.bBinaryAEqC = m_sd1.getSizeBytes()!=0 && m_sd1.isBinaryEqualWith(m_sd3); + m_totalDiffStatus.bBinaryBEqC = m_sd3.getSizeBytes()!=0 && m_sd3.isBinaryEqualWith(m_sd2); - if ( !bUseLineMatchingPP ) - { - g_pProgressDialog->setInformation(i18n("Diff: A <-> B")); - runDiff( &m_sd1.m_v[0], m_sd1.m_vSize, &m_sd2.m_v[0], m_sd2.m_vSize, m_diffList12 ); - g_pProgressDialog->step(); - g_pProgressDialog->setInformation(i18n("Diff: B <-> C")); - runDiff( &m_sd2.m_v[0], m_sd2.m_vSize, &m_sd3.m_v[0], m_sd3.m_vSize, m_diffList23 ); - g_pProgressDialog->step(); - g_pProgressDialog->setInformation(i18n("Diff: A <-> C")); - runDiff( &m_sd1.m_v[0], m_sd1.m_vSize, &m_sd3.m_v[0], m_sd3.m_vSize, m_diffList13 ); - g_pProgressDialog->step(); - } - else - { - g_pProgressDialog->setInformation(i18n("Diff: A <-> B")); - runDiff( &m_sdlm1.m_v[0], m_sd1.m_vSize, &m_sdlm2.m_v[0], m_sd2.m_vSize, m_diffList12 ); - g_pProgressDialog->step(); - g_pProgressDialog->setInformation(i18n("Diff: B <-> C")); - runDiff( &m_sdlm2.m_v[0], m_sd2.m_vSize, &m_sdlm3.m_v[0], m_sd3.m_vSize, m_diffList23 ); - g_pProgressDialog->step(); - g_pProgressDialog->setInformation(i18n("Diff: A <-> C")); - runDiff( &m_sdlm1.m_v[0], m_sd1.m_vSize, &m_sdlm3.m_v[0], m_sd3.m_vSize, m_diffList13 ); - g_pProgressDialog->step(); - } + g_pProgressDialog->setInformation(i18n("Diff: A <-> B")); + runDiff( m_sd1.getLineDataForDiff(), m_sd1.getSizeLines(), m_sd2.getLineDataForDiff(), m_sd2.getSizeLines(), m_diffList12 ); + g_pProgressDialog->step(); + g_pProgressDialog->setInformation(i18n("Diff: B <-> C")); + runDiff( m_sd2.getLineDataForDiff(), m_sd2.getSizeLines(), m_sd3.getLineDataForDiff(), m_sd3.getSizeLines(), m_diffList23 ); + g_pProgressDialog->step(); + g_pProgressDialog->setInformation(i18n("Diff: A <-> C")); + runDiff( m_sd1.getLineDataForDiff(), m_sd1.getSizeLines(), m_sd3.getLineDataForDiff(), m_sd3.getSizeLines(), m_diffList13 ); + g_pProgressDialog->step(); calcDiff3LineListUsingAB( &m_diffList12, m_diff3LineList ); calcDiff3LineListUsingAC( &m_diffList13, m_diff3LineList ); - calcDiff3LineListTrim( m_diff3LineList, &m_sd1.m_v[0], &m_sd2.m_v[0], &m_sd3.m_v[0] ); + calcDiff3LineListTrim( m_diff3LineList, m_sd1.getLineDataForDiff(), m_sd2.getLineDataForDiff(), m_sd3.getLineDataForDiff() ); calcDiff3LineListUsingBC( &m_diffList23, m_diff3LineList ); - calcDiff3LineListTrim( m_diff3LineList, &m_sd1.m_v[0], &m_sd2.m_v[0], &m_sd3.m_v[0] ); - debugLineCheck( m_diff3LineList, m_sd1.m_vSize, 1 ); - debugLineCheck( m_diff3LineList, m_sd2.m_vSize, 2 ); - debugLineCheck( m_diff3LineList, m_sd3.m_vSize, 3 ); + calcDiff3LineListTrim( m_diff3LineList, m_sd1.getLineDataForDiff(), m_sd2.getLineDataForDiff(), m_sd3.getLineDataForDiff() ); + debugLineCheck( m_diff3LineList, m_sd1.getSizeLines(), 1 ); + debugLineCheck( m_diff3LineList, m_sd2.getSizeLines(), 2 ); + debugLineCheck( m_diff3LineList, m_sd3.getSizeLines(), 3 ); g_pProgressDialog->setInformation(i18n("Linediff: A <-> B")); - fineDiff( m_diff3LineList, 1, &m_sd1.m_v[0], &m_sd2.m_v[0], m_totalDiffStatus.bTextAEqB ); + fineDiff( m_diff3LineList, 1, m_sd1.getLineDataForDisplay(), m_sd2.getLineDataForDisplay(), m_totalDiffStatus.bTextAEqB ); g_pProgressDialog->step(); g_pProgressDialog->setInformation(i18n("Linediff: B <-> C")); - fineDiff( m_diff3LineList, 2, &m_sd2.m_v[0], &m_sd3.m_v[0], m_totalDiffStatus.bTextBEqC ); + fineDiff( m_diff3LineList, 2, m_sd2.getLineDataForDisplay(), m_sd3.getLineDataForDisplay(), m_totalDiffStatus.bTextBEqC ); g_pProgressDialog->step(); g_pProgressDialog->setInformation(i18n("Linediff: A <-> C")); - fineDiff( m_diff3LineList, 3, &m_sd3.m_v[0], &m_sd1.m_v[0], m_totalDiffStatus.bTextAEqC ); + fineDiff( m_diff3LineList, 3, m_sd3.getLineDataForDisplay(), m_sd1.getLineDataForDisplay(), m_totalDiffStatus.bTextAEqC ); g_pProgressDialog->step(); - if ( m_sd1.m_size==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextAEqC=false; } - if ( m_sd2.m_size==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextBEqC=false; } + if ( m_sd1.getSizeBytes()==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextAEqC=false; } + if ( m_sd2.getSizeBytes()==0 ) { m_totalDiffStatus.bTextAEqB=false; m_totalDiffStatus.bTextBEqC=false; } } - calcWhiteDiff3Lines( m_diff3LineList, &m_sd1.m_v[0], &m_sd2.m_v[0], &m_sd3.m_v[0] ); + calcWhiteDiff3Lines( m_diff3LineList, m_sd1.getLineDataForDiff(), m_sd2.getLineDataForDiff(), m_sd3.getLineDataForDiff() ); calcDiff3LineVector( m_diff3LineList, m_diff3LineVector ); // Calc needed lines for display @@ -542,11 +347,11 @@ m_bTripleDiff = ! m_sd3.isEmpty(); m_pDiffTextWindow1->init( m_sd1.getAliasName(), - &m_sd1.m_v[0], m_sd1.m_vSize, &m_diff3LineVector, 1, m_bTripleDiff ); + m_sd1.getLineDataForDisplay(), m_sd1.getSizeLines(), &m_diff3LineVector, 1, m_bTripleDiff ); m_pDiffTextWindow2->init( m_sd2.getAliasName(), - &m_sd2.m_v[0], m_sd2.m_vSize, &m_diff3LineVector, 2, m_bTripleDiff ); + m_sd2.getLineDataForDisplay(), m_sd2.getSizeLines(), &m_diff3LineVector, 2, m_bTripleDiff ); m_pDiffTextWindow3->init( m_sd3.getAliasName(), - &m_sd3.m_v[0], m_sd3.m_vSize, &m_diff3LineVector, 3, m_bTripleDiff ); + m_sd3.getLineDataForDisplay(), m_sd3.getSizeLines(), &m_diff3LineVector, 3, m_bTripleDiff ); if (m_bTripleDiff) m_pDiffTextWindow3->show(); else m_pDiffTextWindow3->hide(); @@ -554,9 +359,9 @@ m_bOutputModified = bVisibleMergeResultWindow; m_pMergeResultWindow->init( - &m_sd1.m_v[0], - &m_sd2.m_v[0], - m_bTripleDiff ? &m_sd3.m_v[0] : 0, + m_sd1.getLineDataForDisplay(), + m_sd2.getLineDataForDisplay(), + m_bTripleDiff ? m_sd3.getLineDataForDisplay() : 0, &m_diff3LineList, &m_totalDiffStatus, m_outputFilename.isEmpty() ? QString("unnamed.txt") : m_outputFilename @@ -571,6 +376,8 @@ m_pDiffTextWindow2->setPaintingAllowed( true ); m_pDiffTextWindow3->setPaintingAllowed( true ); m_pOverview->setPaintingAllowed( true ); + m_pMergeResultWindow->setPaintingAllowed( true ); + if ( !bVisibleMergeResultWindow ) m_pMergeWindowFrame->hide(); @@ -604,7 +411,7 @@ KMessageBox::information( this, totalInfo ); } - if ( bVisibleMergeResultWindow && (!m_sd1.m_bIsText || !m_sd2.m_bIsText || !m_sd3.m_bIsText) ) + if ( bVisibleMergeResultWindow && (!m_sd1.isText() || !m_sd2.isText() || !m_sd3.isText()) ) { KMessageBox::information( this, i18n( "Some inputfiles don't seem to be pure textfiles.\n" @@ -949,7 +756,8 @@ return true; // eat event } - else if (e->type() == QEvent::Wheel ) { // wheel event + else if (e->type() == QEvent::Wheel ) // wheel event + { QWheelEvent *w = (QWheelEvent*)e; w->accept(); @@ -1001,10 +809,9 @@ if ( bDecodeSuccess && canContinue() ) { raise(); - bool bUpCase = m_pOptionDialog->m_bUpCase; - if ( o == m_pDiffTextWindow1 ) m_sd1.setData(text, bUpCase); - else if ( o == m_pDiffTextWindow2 ) m_sd2.setData(text, bUpCase); - else if ( o == m_pDiffTextWindow3 ) m_sd3.setData(text, bUpCase); + if ( o == m_pDiffTextWindow1 ) m_sd1.setData(text); + else if ( o == m_pDiffTextWindow2 ) m_sd2.setData(text); + else if ( o == m_pDiffTextWindow3 ) m_sd3.setData(text); init(); } } @@ -1037,6 +844,7 @@ connect( button, SIGNAL(clicked()), this, SLOT( selectFileA() ) ); QPushButton * button2 = new QPushButton( i18n("Dir..."), this ); connect( button2, SIGNAL(clicked()), this, SLOT( selectDirA() ) ); + connect( m_lineA, SIGNAL(textChanged(const QString&)), this, SLOT(inputFilenameChanged() ) ); h->addWidget( label, 0, 0 ); h->addWidget( m_lineA, 0, 1 ); @@ -1052,6 +860,7 @@ connect( button, SIGNAL(clicked()), this, SLOT( selectFileB() ) ); button2 = new QPushButton( i18n("Dir..."), this ); connect( button2, SIGNAL(clicked()), this, SLOT( selectDirB() ) ); + connect( m_lineB, SIGNAL(textChanged(const QString&)), this, SLOT(inputFilenameChanged() ) ); h->addWidget( label, 1, 0 ); h->addWidget( m_lineB, 1, 1 ); @@ -1067,6 +876,7 @@ connect( button, SIGNAL(clicked()), this, SLOT( selectFileC() ) ); button2 = new QPushButton( i18n("Dir..."), this ); connect( button2, SIGNAL(clicked()), this, SLOT( selectDirC() ) ); + connect( m_lineC, SIGNAL(textChanged(const QString&)), this, SLOT(inputFilenameChanged() ) ); h->addWidget( label, 2, 0 ); h->addWidget( m_lineC, 2, 1 ); @@ -1122,8 +932,44 @@ QSize sh = sizeHint(); setFixedHeight( sh.height() ); + m_bInputFileNameChanged = false; + +#ifdef KREPLACEMENTS_H + m_lineA->lineEdit()->installEventFilter( this ); + m_lineB->lineEdit()->installEventFilter( this ); + m_lineC->lineEdit()->installEventFilter( this ); + m_lineOut->lineEdit()->installEventFilter( this ); +#endif } +// Eventfilter: Only needed under Windows. +// Without this, files dropped in the line edit have URL-encoding. +// This eventfilter decodes the filenames as needed by KDiff3. +bool OpenDialog::eventFilter(QObject* o, QEvent* e) +{ + if (e->type()==QEvent::Drop) + { + QDropEvent* d = static_cast<QDropEvent*>(e); + + if ( !QUriDrag::canDecode( d ) ) { + return false; + } + + QStringList lst; + QUriDrag::decodeLocalFiles( d, lst ); + + if ( lst.count() > 0 ) + { + static_cast<QLineEdit*>(o)->setText( lst[0] ); + static_cast<QLineEdit*>(o)->setFocus(); + } + + return true; + } + return false; +} + + void OpenDialog::selectURL( QComboBox* pLine, bool bDir, int i, bool bSave ) { QString current = pLine->currentText(); @@ -1154,6 +1000,18 @@ emit internalSignal(i!=0); } +// Clear the output-filename when any input-filename changed, +// because users forgot to change the output and accidently overwrote it with +// wrong data during a merge. +void OpenDialog::inputFilenameChanged() +{ + if(!m_bInputFileNameChanged) + { + m_bInputFileNameChanged=true; + m_lineOut->clearEdit(); + } +} + void OpenDialog::accept() { unsigned int maxNofRecentFiles = 10; @@ -1209,9 +1067,9 @@ for(;;) { OpenDialog d(this, - m_sd1.m_bPreserve ? QString("") : m_sd1.getAliasName(), - m_sd2.m_bPreserve ? QString("") : m_sd2.getAliasName(), - m_sd3.m_bPreserve ? QString("") : m_sd3.getAliasName(), + m_sd1.isFromBuffer() ? QString("") : m_sd1.getAliasName(), + m_sd2.isFromBuffer() ? QString("") : m_sd2.getAliasName(), + m_sd3.isFromBuffer() ? QString("") : m_sd3.getAliasName(), !m_outputFilename.isEmpty(), m_bDefaultFilename ? QString("") : m_outputFilename, SLOT(slotConfigure()), m_pOptionDialog ); @@ -1253,17 +1111,17 @@ m_pDirectoryMergeSplitter->hide(); init(); - if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 || - ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 || - ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) + if ( ! m_sd1.isEmpty() && !m_sd1.hasData() || + ! m_sd2.isEmpty() && !m_sd2.hasData() || + ! m_sd3.isEmpty() && !m_sd3.hasData() ) { QString text( i18n("Opening of these files failed:") ); text += "\n\n"; - if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 ) + if ( ! m_sd1.isEmpty() && !m_sd1.hasData() ) text += " - " + m_sd1.getAliasName() + "\n"; - if ( ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 ) + if ( ! m_sd2.isEmpty() && !m_sd2.hasData() ) text += " - " + m_sd2.getAliasName() + "\n"; - if ( ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) + if ( ! m_sd3.isEmpty() && !m_sd3.hasData() ) text += " - " + m_sd3.getAliasName() + "\n"; KMessageBox::sorry( this, text, i18n("File open error") ); @@ -1314,17 +1172,17 @@ { init(); - if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 || - ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 || - ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) + if ( ! m_sd1.isEmpty() && ! m_sd1.hasData() || + ! m_sd2.isEmpty() && ! m_sd2.hasData() || + ! m_sd3.isEmpty() && ! m_sd3.hasData() ) { QString text( i18n("Opening of these files failed:") ); text += "\n\n"; - if ( ! m_sd1.isEmpty() && m_sd1.m_pBuf==0 ) + if ( ! m_sd1.isEmpty() && !m_sd1.hasData() ) text += " - " + m_sd1.getAliasName() + "\n"; - if ( ! m_sd2.isEmpty() && m_sd2.m_pBuf==0 ) + if ( ! m_sd2.isEmpty() && !m_sd2.hasData() ) text += " - " + m_sd2.getAliasName() + "\n"; - if ( ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 ) + if ( ! m_sd3.isEmpty() && !m_sd3.hasData() ) text += " - " + m_sd3.getAliasName() + "\n"; KMessageBox::sorry( this, text, i18n("File open error") ); @@ -1355,7 +1213,7 @@ if ( !s.isNull() ) { - QApplication::clipboard()->setText( s ); + QApplication::clipboard()->setText( s, QClipboard::Clipboard ); } slotStatusMsg(i18n("Ready.")); @@ -1371,7 +1229,7 @@ if ( s.isNull() && m_pMergeResultWindow!=0 ) s = m_pMergeResultWindow->getSelection(); if ( !s.isNull() ) { - QApplication::clipboard()->setText( s ); + QApplication::clipboard()->setText( s, QClipboard::Clipboard ); } slotStatusMsg(i18n("Ready.")); @@ -1387,20 +1245,19 @@ } else if ( canContinue() ) { - bool bUpCase = m_pOptionDialog->m_bUpCase; if ( m_pDiffTextWindow1->hasFocus() ) { - m_sd1.setData( QApplication::clipboard()->text(), bUpCase ); + m_sd1.setData( QApplication::clipboard()->text() ); init(); } else if ( m_pDiffTextWindow2->hasFocus() ) { - m_sd2.setData( QApplication::clipboard()->text(), bUpCase ); + m_sd2.setData( QApplication::clipboard()->text() ); init(); } else if ( m_pDiffTextWindow3->hasFocus() ) { - m_sd3.setData( QApplication::clipboard()->text(), bUpCase ); + m_sd3.setData( QApplication::clipboard()->text() ); init(); } } @@ -1585,6 +1442,23 @@ { slotEditCopy(); } + else + { + QClipboard *clipBoard = QApplication::clipboard(); + + if (clipBoard->supportsSelection ()) + { + QString s; + if ( m_pDiffTextWindow1!=0 ) s = m_pDiffTextWindow1->getSelection(); + if ( s.isNull() && m_pDiffTextWindow2!=0 ) s = m_pDiffTextWindow2->getSelection(); + if ( s.isNull() && m_pDiffTextWindow3!=0 ) s = m_pDiffTextWindow3->getSelection(); + if ( s.isNull() && m_pMergeResultWindow!=0 ) s = m_pMergeResultWindow->getSelection(); + if ( !s.isNull() ) + { + clipBoard->setText( s, QClipboard::Selection ); + } + } + } } void KDiff3App::slotClipboardChanged() @@ -1922,15 +1796,15 @@ if ( !canContinue() ) return; if ( m_outputFilename.isEmpty() ) { - if ( !m_sd3.isEmpty() && !m_sd3.m_bPreserve ) + if ( !m_sd3.isEmpty() && !m_sd3.isFromBuffer() ) { m_outputFilename = m_sd3.getFilename(); } - else if ( !m_sd2.isEmpty() && !m_sd2.m_bPreserve ) + else if ( !m_sd2.isEmpty() && !m_sd2.isFromBuffer() ) { m_outputFilename = m_sd2.getFilename(); } - else if ( !m_sd1.isEmpty() && !m_sd1.m_bPreserve ) + else if ( !m_sd1.isEmpty() && !m_sd1.isFromBuffer() ) { m_outputFilename = m_sd1.getFilename(); } @@ -2016,7 +1890,7 @@ void KDiff3App::slotUpdateAvailabilities() { - bool bTextDataAvailable = (m_sd1.m_pBuf != 0 || m_sd2.m_pBuf != 0 || m_sd3.m_pBuf != 0 ); + bool bTextDataAvailable = ( m_sd1.hasData() || m_sd2.hasData() || m_sd3.hasData() ); if( dirShowBoth->isChecked() ) { if ( m_bDirCompare )