diff --git a/komparemodellist.cpp b/komparemodellist.cpp --- a/komparemodellist.cpp +++ b/komparemodellist.cpp @@ -268,7 +268,7 @@ if ( !blendOriginalIntoModelList( m_info->localSource ) ) { qCDebug(LIBKOMPAREDIFF2) << "Oops cant blend original file into modellist : " << m_info->localSource; - emit( i18n( "There were problems applying the diff %1 to the file %2.", m_info->destination.url(), m_info->source.url() ) ); + emit error( i18n( "There were problems applying the diff %1 to the file %2.", m_info->source.url(), m_info->destination.url() ) ); return false; } @@ -295,7 +295,7 @@ { // Trouble blending the original into the model qCDebug(LIBKOMPAREDIFF2) << "Oops cant blend original dir into modellist : " << m_info->localSource; - emit error( i18n( "There were problems applying the diff %1 to the folder %2.", m_info->destination.url(), m_info->source.url() ) ); + emit error( i18n( "There were problems applying the diff %1 to the folder %2.", m_info->source.url(), m_info->destination.url() ) ); return false; } @@ -987,12 +987,41 @@ return 0; } +QString adjustDepthInPath(const QString localURL, const QString sourcePath, const QString destinationPath) +{ + QString basePath = localURL; + if( !basePath.endsWith("/") ) + { + basePath += "/"; + } + + QStringList sourcePathParts = sourcePath.split("/", QString::SkipEmptyParts); + QStringList destinationPathParts = destinationPath.split("/", QString::SkipEmptyParts); + + // Scan source and destination paths' parts going backward and keeping only the common parts + int sourceIdx = sourcePathParts.size() - 1; + int destinationIdx = destinationPathParts.size() - 1; + QString commonPath = ""; + + while( sourceIdx >= 0 && destinationIdx >= 0 && sourcePathParts.at( sourceIdx ) == destinationPathParts.at( destinationIdx ) ) + { + if(!commonPath.isEmpty()) + commonPath = "/" + commonPath; + + commonPath = sourcePathParts.at( sourceIdx ) + commonPath; + sourceIdx--; + destinationIdx--; + }; + + return basePath + commonPath; +} + bool KompareModelList::blendOriginalIntoModelList( const QString& localURL ) { qCDebug(LIBKOMPAREDIFF2) << "Hurrah we are blending..."; QFileInfo fi( localURL ); - bool result = false; + bool result = true; DiffModel* model; QString fileContents; @@ -1009,20 +1038,22 @@ qCDebug(LIBKOMPAREDIFF2) << "Model : " << model; QString filename = model->source(); if ( !filename.startsWith( localURL ) ) - filename = QDir(localURL).filePath(filename); + { + filename = adjustDepthInPath(localURL, model->source(), model->destination()); + } QFileInfo fi2( filename ); if ( fi2.exists() ) { qCDebug(LIBKOMPAREDIFF2) << "Reading from: " << filename; fileContents = readFile( filename ); - result = blendFile( model, fileContents ); + result = result && blendFile( model, fileContents ); } else { qCDebug(LIBKOMPAREDIFF2) << "File " << filename << " does not exist !"; qCDebug(LIBKOMPAREDIFF2) << "Assume empty file !"; fileContents.truncate( 0 ); - result = blendFile( model, fileContents ); + result = result && blendFile( model, fileContents ); } } qCDebug(LIBKOMPAREDIFF2) << "End of Blend Dir"; @@ -1033,7 +1064,7 @@ qCDebug(LIBKOMPAREDIFF2) << "Reading from: " << localURL; fileContents = readFile( localURL ); - result = blendFile( (*m_models)[ 0 ], fileContents ); + result = result && blendFile( (*m_models)[ 0 ], fileContents ); qCDebug(LIBKOMPAREDIFF2) << "End of Blend File"; } @@ -1042,6 +1073,7 @@ bool KompareModelList::blendFile( DiffModel* model, const QString& fileContents ) { + bool hasConflicts = false; if ( !model ) { qCDebug(LIBKOMPAREDIFF2) << "**** model is null :("; @@ -1053,13 +1085,12 @@ int srcLineNo = 1, destLineNo = 1; QStringList list = split( fileContents ); - QLinkedList lines; + QStringList lines; foreach (const QString &str, list) { lines.append(str); } - QLinkedList::ConstIterator linesIt = lines.begin(); - QLinkedList::ConstIterator lEnd = lines.end(); + int lineIndex = 0; DiffHunkList* hunks = model->hunks(); qCDebug(LIBKOMPAREDIFF2) << "Hunks in hunklist: " << hunks->count(); @@ -1077,6 +1108,22 @@ { // Do we need to insert a new hunk before this one ? DiffHunk* hunk = *hunkIt; + + // In case we are blending diff with files, check for conflicts + if( m_info->mode == Kompare::BlendingDir || m_info->mode == Kompare::BlendingFile ) + { + for (int i = 0; i < hunk->differences().count(); ++i) { + Difference *diff = hunk->differences().at(i); + for (int j = 0; j < diff->destinationLineCount(); ++j) { + if (lines.size() > diff->destinationLineNumber() + j - 1 && + lines.at(diff->destinationLineNumber() + j - 1) != diff->destinationLineAt(j)->string()) { + diff->setConflict(true); + hasConflicts = true; + } + } + } + } + if ( srcLineNo < hunk->sourceLineNumber() ) { newHunk = new DiffHunk( srcLineNo, destLineNo, "", DiffHunk::AddedByBlend ); @@ -1088,29 +1135,29 @@ newHunk->add( newDiff ); - while ( srcLineNo < hunk->sourceLineNumber() && linesIt != lEnd ) + while ( destLineNo < hunk->destinationLineNumber() && lineIndex < lines.size() ) { - newDiff->addSourceLine( *linesIt ); - newDiff->addDestinationLine( *linesIt ); + newDiff->addSourceLine( lines.at(lineIndex) ); + newDiff->addDestinationLine( lines.at(lineIndex) ); srcLineNo++; destLineNo++; - ++linesIt; + ++lineIndex; } } // Now we add the linecount difference for the hunk that follows - int size = hunk->sourceLineCount(); + int size = hunk->destinationLineCount(); for ( int i = 0; i < size; ++i ) { - ++linesIt; + ++lineIndex; } - srcLineNo += size; - destLineNo += hunk->destinationLineCount(); + srcLineNo += hunk->sourceLineCount(); + destLineNo += size; } - if ( linesIt != lEnd ) + if ( lineIndex < lines.size() ) { newHunk = new DiffHunk( srcLineNo, destLineNo, "", DiffHunk::AddedByBlend ); @@ -1120,11 +1167,11 @@ newHunk->add( newDiff ); - while ( linesIt != lEnd ) + while ( lineIndex < lines.size() ) { - newDiff->addSourceLine( *linesIt ); - newDiff->addDestinationLine( *linesIt ); - ++linesIt; + newDiff->addSourceLine( lines.at(lineIndex) ); + newDiff->addDestinationLine( lines.at(lineIndex) ); + ++lineIndex; } } #if 0 @@ -1274,7 +1321,7 @@ m_selectedDifference = m_selectedModel->firstDifference(); - return true; + return !hasConflicts; } void KompareModelList::show()