joachim99@8: /*************************************************************************** joachim99@8: mergeresultwindow.cpp - description joachim99@8: ------------------- joachim99@8: begin : Sun Apr 14 2002 joachim99@58: copyright : (C) 2002-2004 by Joachim Eibl joachim99@8: email : joachim.eibl@gmx.de joachim99@8: ***************************************************************************/ joachim99@8: joachim99@8: /*************************************************************************** joachim99@8: * * joachim99@8: * This program is free software; you can redistribute it and/or modify * joachim99@8: * it under the terms of the GNU General Public License as published by * joachim99@8: * the Free Software Foundation; either version 2 of the License, or * joachim99@8: * (at your option) any later version. * joachim99@8: * * joachim99@8: ***************************************************************************/ joachim99@8: joachim99@8: #include "diff.h" joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@58: #include joachim99@8: joachim99@8: int g_bAutoSolve = true; joachim99@8: joachim99@53: #undef leftInfoWidth joachim99@8: #define leftInfoWidth 3 joachim99@8: joachim99@8: MergeResultWindow::MergeResultWindow( joachim99@8: QWidget* pParent, joachim99@8: OptionDialog* pOptionDialog joachim99@8: ) joachim99@8: : QWidget( pParent, 0, WRepaintNoErase ) joachim99@8: { joachim99@8: setFocusPolicy( QWidget::ClickFocus ); joachim99@8: joachim99@8: m_firstLine = 0; joachim99@8: m_firstColumn = 0; joachim99@8: m_nofColumns = 0; joachim99@8: m_nofLines = 0; joachim99@58: m_totalSize = 0; joachim99@8: m_bMyUpdate = false; joachim99@8: m_bInsertMode = true; joachim99@8: m_scrollDeltaX = 0; joachim99@8: m_scrollDeltaY = 0; joachim99@8: m_bModified = false; joachim99@8: joachim99@8: m_fileName = ""; joachim99@8: m_pldA = 0; joachim99@8: m_pldB = 0; joachim99@8: m_pldC = 0; joachim99@8: joachim99@8: m_pDiff3LineList = 0; joachim99@8: m_pTotalDiffStatus = 0; joachim99@58: joachim99@8: m_pOptionDialog = pOptionDialog; joachim99@58: m_bPaintingAllowed = false; joachim99@8: joachim99@8: m_cursorXPos=0; joachim99@8: m_cursorOldXPos=0; joachim99@8: m_cursorYPos=0; joachim99@8: m_bCursorOn = true; joachim99@8: connect( &m_cursorTimer, SIGNAL(timeout()), this, SLOT( slotCursorUpdate() ) ); joachim99@8: m_cursorTimer.start( 500 /*ms*/, true /*single shot*/ ); joachim99@8: m_selection.reset(); joachim99@8: joachim99@8: setMinimumSize( QSize(20,20) ); joachim99@27: setFont( m_pOptionDialog->m_font ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::init( joachim99@8: const LineData* pLineDataA, joachim99@8: const LineData* pLineDataB, joachim99@8: const LineData* pLineDataC, joachim99@8: const Diff3LineList* pDiff3LineList, joachim99@8: const TotalDiffStatus* pTotalDiffStatus, joachim99@8: QString fileName joachim99@8: ) joachim99@8: { joachim99@8: m_firstLine = 0; joachim99@8: m_firstColumn = 0; joachim99@8: m_nofColumns = 0; joachim99@8: m_nofLines = 0; joachim99@8: m_bMyUpdate = false; joachim99@8: m_bInsertMode = true; joachim99@8: m_scrollDeltaX = 0; joachim99@8: m_scrollDeltaY = 0; joachim99@8: m_bModified = false; joachim99@8: joachim99@8: m_fileName = fileName; joachim99@8: m_pldA = pLineDataA; joachim99@8: m_pldB = pLineDataB; joachim99@8: m_pldC = pLineDataC; joachim99@8: joachim99@8: m_pDiff3LineList = pDiff3LineList; joachim99@8: m_pTotalDiffStatus = pTotalDiffStatus; joachim99@8: joachim99@8: m_selection.reset(); joachim99@8: m_cursorXPos=0; joachim99@8: m_cursorOldXPos=0; joachim99@8: m_cursorYPos=0; joachim99@8: joachim99@8: merge( g_bAutoSolve, -1 ); joachim99@8: g_bAutoSolve = true; joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: joachim99@8: // Calculate the merge information for the given Diff3Line. joachim99@8: // Results will be stored in mergeDetails, bConflict, bLineRemoved and src. joachim99@8: void mergeOneLine( joachim99@8: const Diff3Line& d, e_MergeDetails& mergeDetails, bool& bConflict, joachim99@8: bool& bLineRemoved, int& src, bool bTwoInputs joachim99@8: ) joachim99@8: { joachim99@8: mergeDetails = eDefault; joachim99@8: bConflict = false; joachim99@8: bLineRemoved = false; joachim99@8: src = 0; joachim99@8: joachim99@8: if ( bTwoInputs ) // Only two input files joachim99@8: { joachim99@8: if ( d.lineA!=-1 && d.lineB!=-1 ) joachim99@8: { joachim99@8: if ( d.pFineAB == 0 ) joachim99@8: { joachim99@8: mergeDetails = eNoChange; src = A; joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: mergeDetails = eBChanged; bConflict = true; joachim99@8: } joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: if ( d.lineA!=-1 && d.lineB==-1 ) joachim99@8: { joachim99@8: mergeDetails = eBDeleted; bConflict = true; joachim99@8: } joachim99@8: else if ( d.lineA==-1 && d.lineB!=-1 ) joachim99@8: { joachim99@8: mergeDetails = eBDeleted; bConflict = true; joachim99@8: } joachim99@8: } joachim99@8: return; joachim99@8: } joachim99@8: joachim99@8: // A is base. joachim99@8: if ( d.lineA!=-1 && d.lineB!=-1 && d.lineC!=-1 ) joachim99@8: { joachim99@8: if ( d.pFineAB == 0 && d.pFineBC == 0 && d.pFineCA == 0) joachim99@8: { joachim99@8: mergeDetails = eNoChange; src = A; joachim99@8: } joachim99@8: else if( d.pFineAB == 0 && d.pFineBC != 0 && d.pFineCA != 0 ) joachim99@8: { joachim99@8: mergeDetails = eCChanged; src = C; joachim99@8: } joachim99@8: else if( d.pFineAB != 0 && d.pFineBC != 0 && d.pFineCA == 0 ) joachim99@8: { joachim99@8: mergeDetails = eBChanged; src = B; joachim99@8: } joachim99@8: else if( d.pFineAB != 0 && d.pFineBC == 0 && d.pFineCA != 0 ) joachim99@8: { joachim99@8: mergeDetails = eBCChangedAndEqual; src = C; joachim99@8: } joachim99@8: else if( d.pFineAB != 0 && d.pFineBC != 0 && d.pFineCA != 0 ) joachim99@8: { joachim99@8: mergeDetails = eBCChanged; bConflict = true; joachim99@8: } joachim99@8: else joachim99@8: assert(false); joachim99@8: } joachim99@8: else if ( d.lineA!=-1 && d.lineB!=-1 && d.lineC==-1 ) joachim99@8: { joachim99@8: if( d.pFineAB != 0 ) joachim99@8: { joachim99@8: mergeDetails = eBChanged_CDeleted; bConflict = true; joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: mergeDetails = eCDeleted; bLineRemoved = true; src = C; joachim99@8: } joachim99@8: } joachim99@8: else if ( d.lineA!=-1 && d.lineB==-1 && d.lineC!=-1 ) joachim99@8: { joachim99@8: if( d.pFineCA != 0 ) joachim99@8: { joachim99@8: mergeDetails = eCChanged_BDeleted; bConflict = true; joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: mergeDetails = eBDeleted; bLineRemoved = true; src = B; joachim99@8: } joachim99@8: } joachim99@8: else if ( d.lineA==-1 && d.lineB!=-1 && d.lineC!=-1 ) joachim99@8: { joachim99@8: if( d.pFineBC != 0 ) joachim99@8: { joachim99@8: mergeDetails = eBCAdded; bConflict = true; joachim99@8: } joachim99@8: else // B==C joachim99@8: { joachim99@8: mergeDetails = eBCAddedAndEqual; src = C; joachim99@8: } joachim99@8: } joachim99@8: else if ( d.lineA==-1 && d.lineB==-1 && d.lineC!= -1 ) joachim99@8: { joachim99@8: mergeDetails = eCAdded; src = C; joachim99@8: } joachim99@8: else if ( d.lineA==-1 && d.lineB!=-1 && d.lineC== -1 ) joachim99@8: { joachim99@8: mergeDetails = eBAdded; src = B; joachim99@8: } joachim99@8: else if ( d.lineA!=-1 && d.lineB==-1 && d.lineC==-1 ) joachim99@8: { joachim99@8: mergeDetails = eBCDeleted; bLineRemoved = true; src = C; joachim99@8: } joachim99@8: else joachim99@8: assert(false); joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::sameKindCheck( const MergeLine& ml1, const MergeLine& ml2 ) joachim99@8: { joachim99@8: if ( ml1.bConflict && ml2.bConflict ) joachim99@8: { joachim99@51: // Both lines have conflicts: If one is only a white space conflict and joachim99@51: // the other one is a real conflict, then this line returns false. joachim99@8: return ml1.id3l->bAEqC == ml2.id3l->bAEqC && ml1.id3l->bAEqB == ml2.id3l->bAEqB; joachim99@8: } joachim99@8: else joachim99@8: return ( joachim99@8: !ml1.bConflict && !ml2.bConflict && ml1.bDelta && ml2.bDelta && ml1.srcSelect == ml2.srcSelect || joachim99@8: !ml1.bDelta && !ml2.bDelta joachim99@8: ); joachim99@8: } joachim99@8: joachim99@51: void MergeResultWindow::merge(bool bAutoSolve, int defaultSelector, bool bConflictsOnly, bool bWhiteSpaceOnly ) joachim99@51: { joachim99@51: if ( !bConflictsOnly ) joachim99@8: { joachim99@51: if(m_bModified) joachim99@8: { joachim99@51: int result = KMessageBox::warningYesNo(this, joachim99@51: i18n("The output has been modified.\n" joachim99@51: "If you continue your changes will be lost."), joachim99@51: i18n("Warning"), i18n("C&ontinue"), i18n("&Cancel")); joachim99@51: if ( result==KMessageBox::No ) joachim99@51: return; joachim99@8: } joachim99@8: joachim99@51: m_mergeLineList.clear(); joachim99@58: m_totalSize = 0; joachim99@51: int lineIdx = 0; joachim99@51: Diff3LineList::const_iterator it; joachim99@51: for( it=m_pDiff3LineList->begin(); it!=m_pDiff3LineList->end(); ++it, ++lineIdx ) joachim99@8: { joachim99@51: const Diff3Line& d = *it; joachim99@51: joachim99@51: MergeLine ml; joachim99@51: bool bLineRemoved; joachim99@51: mergeOneLine( d, ml.mergeDetails, ml.bConflict, bLineRemoved, ml.srcSelect, m_pldC==0 ); joachim99@51: joachim99@51: // Automatic solving for only whitespace changes. joachim99@51: if ( ml.bConflict && joachim99@51: ( m_pldC==0 && (d.bAEqB || d.bWhiteLineA && d.bWhiteLineB) || joachim99@51: m_pldC!=0 && (d.bAEqB && d.bAEqC || d.bWhiteLineA && d.bWhiteLineB && d.bWhiteLineC ) ) ) joachim99@51: { joachim99@51: ml.bWhiteSpaceConflict = true; joachim99@51: } joachim99@51: joachim99@51: ml.d3lLineIdx = lineIdx; joachim99@51: ml.bDelta = ml.srcSelect != A; joachim99@51: ml.id3l = it; joachim99@51: ml.srcRangeLength = 1; joachim99@51: joachim99@51: MergeLine* back = m_mergeLineList.empty() ? 0 : &m_mergeLineList.back(); joachim99@51: joachim99@51: bool bSame = back!=0 && sameKindCheck( ml, *back ); joachim99@51: if( bSame ) joachim99@51: { joachim99@51: ++back->srcRangeLength; joachim99@51: if ( back->bWhiteSpaceConflict && !ml.bWhiteSpaceConflict ) joachim99@51: back->bWhiteSpaceConflict = false; joachim99@51: } joachim99@51: else joachim99@51: { joachim99@51: if (back!=0 && back->bWhiteSpaceConflict ) joachim99@51: { joachim99@51: if ( m_pldC==0 && m_pOptionDialog->m_whiteSpace2FileMergeDefault != 0 ) // Only two inputs joachim99@51: { joachim99@51: back->srcSelect = m_pOptionDialog->m_whiteSpace2FileMergeDefault; joachim99@51: back->bConflict = false; joachim99@51: } joachim99@51: else if ( m_pldC!=0 && m_pOptionDialog->m_whiteSpace3FileMergeDefault != 0 ) joachim99@51: { joachim99@51: back->srcSelect = m_pOptionDialog->m_whiteSpace3FileMergeDefault; joachim99@51: back->bConflict = false; joachim99@51: } joachim99@51: } joachim99@58: ml.mergeEditLineList.setTotalSizePtr(&m_totalSize); joachim99@51: m_mergeLineList.push_back( ml ); joachim99@51: } joachim99@51: joachim99@51: if ( ! ml.bConflict ) joachim99@51: { joachim99@51: MergeLine& tmpBack = m_mergeLineList.back(); joachim99@51: MergeEditLine mel; joachim99@51: mel.setSource( ml.srcSelect, ml.id3l, bLineRemoved ); joachim99@51: tmpBack.mergeEditLineList.push_back(mel); joachim99@51: } joachim99@51: else if ( back==0 || ! back->bConflict || !bSame ) joachim99@51: { joachim99@51: MergeLine& tmpBack = m_mergeLineList.back(); joachim99@51: MergeEditLine mel; joachim99@51: mel.setConflict(); joachim99@51: tmpBack.mergeEditLineList.push_back(mel); joachim99@51: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: if ( !bAutoSolve ) joachim99@8: { joachim99@8: // Change all auto selections joachim99@8: MergeLineList::iterator mlIt; joachim99@8: for( mlIt=m_mergeLineList.begin(); mlIt!=m_mergeLineList.end(); ++mlIt ) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@51: bool bConflict = ml.mergeEditLineList.empty() || ml.mergeEditLineList.begin()->isConflict(); joachim99@51: if ( ml.bDelta && ( !bConflictsOnly || bConflict ) && (!bWhiteSpaceOnly || ml.bWhiteSpaceConflict )) joachim99@8: { joachim99@8: ml.mergeEditLineList.clear(); joachim99@8: if ( defaultSelector==-1 && ml.bDelta ) joachim99@8: { joachim99@8: MergeEditLine mel; joachim99@8: mel.setConflict(); joachim99@8: ml.bConflict = true; joachim99@8: ml.mergeEditLineList.push_back(mel); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: Diff3LineList::const_iterator d3llit=ml.id3l; joachim99@8: int j; joachim99@8: joachim99@8: for( j=0; jlineA : joachim99@8: defaultSelector==2 ? d3llit->lineB : joachim99@8: defaultSelector==3 ? d3llit->lineC : -1; joachim99@51: joachim99@8: if ( srcLine != -1 ) joachim99@8: { joachim99@8: ml.mergeEditLineList.push_back(mel); joachim99@8: } joachim99@8: joachim99@8: ++d3llit; joachim99@8: } joachim99@8: joachim99@8: if ( ml.mergeEditLineList.empty() ) // Make a line nevertheless joachim99@8: { joachim99@8: MergeEditLine mel; joachim99@8: mel.setSource( defaultSelector, ml.id3l, false ); joachim99@8: mel.setRemoved( defaultSelector ); joachim99@8: ml.mergeEditLineList.push_back(mel); joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: MergeLineList::iterator mlIt; joachim99@8: for( mlIt=m_mergeLineList.begin(); mlIt!=m_mergeLineList.end(); ++mlIt ) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: // Remove all lines that are empty, because no src lines are there. joachim99@8: joachim99@8: int oldSrcLine = -1; joachim99@8: int oldSrc = -1; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: int melsrc = mel.src(); joachim99@8: joachim99@8: int srcLine = melsrc==1 ? mel.id3l()->lineA : joachim99@8: melsrc==2 ? mel.id3l()->lineB : joachim99@8: melsrc==3 ? mel.id3l()->lineC : -1; joachim99@8: joachim99@8: if ( srcLine == -1 && oldSrcLine==-1 && oldSrc == melsrc ) joachim99@8: melIt = ml.mergeEditLineList.erase( melIt ); joachim99@8: else joachim99@8: ++melIt; joachim99@8: joachim99@8: oldSrcLine = srcLine; joachim99@8: oldSrc = melsrc; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: m_currentMergeLineIt = m_mergeLineList.begin(); joachim99@8: m_cursorXPos=0; joachim99@8: m_cursorOldXPos=0; joachim99@8: m_cursorYPos=0; joachim99@8: m_firstLine = 0; joachim99@8: m_firstColumn = 0; joachim99@51: joachim99@8: m_bModified = false; joachim99@8: updateAvailabilities(); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::setFirstLine(int firstLine) joachim99@8: { joachim99@8: m_firstLine = max2(0,firstLine); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::setFirstColumn(int firstCol) joachim99@8: { joachim99@8: m_firstColumn = max2(0,firstCol); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: int MergeResultWindow::getNofColumns() joachim99@8: { joachim99@8: return m_nofColumns; joachim99@8: } joachim99@8: joachim99@8: int MergeResultWindow::getNofLines() joachim99@8: { joachim99@58: return m_totalSize; joachim99@8: } joachim99@8: joachim99@8: int MergeResultWindow::getNofVisibleColumns() joachim99@8: { joachim99@8: QFontMetrics fm = fontMetrics(); joachim99@8: return width()/fm.width('W')-4; joachim99@8: } joachim99@8: joachim99@8: int MergeResultWindow::getNofVisibleLines() joachim99@8: { joachim99@8: QFontMetrics fm = fontMetrics(); joachim99@8: return (height()-3)/fm.height()-2; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::resizeEvent( QResizeEvent* e ) joachim99@8: { joachim99@8: QWidget::resizeEvent(e); joachim99@8: emit resizeSignal(); joachim99@8: } joachim99@8: joachim99@8: // Go to prev/next delta/conflict or first/last delta. joachim99@8: void MergeResultWindow::go( e_Direction eDir, e_EndPoint eEndPoint ) joachim99@8: { joachim99@8: assert( eDir==eUp || eDir==eDown ); joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@51: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@8: if( eEndPoint==eEnd ) joachim99@8: { joachim99@8: if (eDir==eUp) i = m_mergeLineList.begin(); // first mergeline joachim99@8: else i = --m_mergeLineList.end(); // last mergeline joachim99@8: joachim99@51: while ( i!=m_mergeLineList.end() && ! i->bDelta ) joachim99@8: { joachim99@8: if ( eDir==eUp ) ++i; // search downwards joachim99@8: else --i; // search upwards joachim99@8: } joachim99@8: } joachim99@8: else if ( eEndPoint == eDelta && i!=m_mergeLineList.end()) joachim99@8: { joachim99@8: do joachim99@8: { joachim99@8: if ( eDir==eUp ) --i; joachim99@8: else ++i; joachim99@8: } joachim99@51: while ( i!=m_mergeLineList.end() && ( i->bDelta == false || bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ); joachim99@8: } joachim99@51: else if ( eEndPoint == eConflict && i!=m_mergeLineList.end() ) joachim99@8: { joachim99@8: do joachim99@8: { joachim99@8: if ( eDir==eUp ) --i; joachim99@8: else ++i; joachim99@8: } joachim99@51: while ( i!=m_mergeLineList.end() && (i->bConflict == false || bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ); joachim99@8: } joachim99@51: else if ( i!=m_mergeLineList.end() && eEndPoint == eUnsolvedConflict ) joachim99@8: { joachim99@8: do joachim99@8: { joachim99@8: if ( eDir==eUp ) --i; joachim99@8: else ++i; joachim99@8: } joachim99@8: while ( i!=m_mergeLineList.end() && ! i->mergeEditLineList.begin()->isConflict() ); joachim99@8: } joachim99@8: joachim99@8: setFastSelector( i ); joachim99@53: joachim99@53: if ( isVisible() ) joachim99@53: setFocus(); joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isDeltaAboveCurrent() joachim99@8: { joachim99@51: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@8: --i; joachim99@8: for( ; i!=m_mergeLineList.end(); --i ) joachim99@8: { joachim99@51: if ( i->bDelta && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isDeltaBelowCurrent() joachim99@8: { joachim99@51: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@8: ++i; joachim99@8: for( ; i!=m_mergeLineList.end(); ++i ) joachim99@8: { joachim99@51: if ( i->bDelta && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isConflictAboveCurrent() joachim99@8: { joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@8: --i; joachim99@8: for( ; i!=m_mergeLineList.end(); --i ) joachim99@8: { joachim99@8: if ( i->bConflict ) return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isConflictBelowCurrent() joachim99@8: { joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@8: ++i; joachim99@8: for( ; i!=m_mergeLineList.end(); ++i ) joachim99@8: { joachim99@8: if ( i->bConflict ) return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isUnsolvedConflictAboveCurrent() joachim99@8: { joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@8: --i; joachim99@8: for( ; i!=m_mergeLineList.end(); --i ) joachim99@8: { joachim99@8: if ( i->mergeEditLineList.begin()->isConflict() ) return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isUnsolvedConflictBelowCurrent() joachim99@8: { joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@8: ++i; joachim99@8: for( ; i!=m_mergeLineList.end(); ++i ) joachim99@8: { joachim99@8: if ( i->mergeEditLineList.begin()->isConflict() ) return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoTop() joachim99@8: { joachim99@8: go( eUp, eEnd ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoCurrent() joachim99@8: { joachim99@8: setFastSelector( m_currentMergeLineIt ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoBottom() joachim99@8: { joachim99@8: go( eDown, eEnd ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoPrevDelta() joachim99@8: { joachim99@8: go( eUp, eDelta ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoNextDelta() joachim99@8: { joachim99@8: go( eDown, eDelta ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoPrevConflict() joachim99@8: { joachim99@8: go( eUp, eConflict ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoNextConflict() joachim99@8: { joachim99@8: go( eDown, eConflict ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoPrevUnsolvedConflict() joachim99@8: { joachim99@8: go( eUp, eUnsolvedConflict ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotGoNextUnsolvedConflict() joachim99@8: { joachim99@8: go( eDown, eUnsolvedConflict ); joachim99@8: } joachim99@8: joachim99@8: /** The line is given as a index in the Diff3LineList. joachim99@8: The function calculates the corresponding iterator. */ joachim99@8: void MergeResultWindow::slotSetFastSelectorLine( int line ) joachim99@8: { joachim99@8: MergeLineList::iterator i; joachim99@8: for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@8: { joachim99@8: if ( line>=i->d3lLineIdx && line < i->d3lLineIdx + i->srcRangeLength ) joachim99@8: { joachim99@8: if ( i->bDelta ) joachim99@8: { joachim99@8: setFastSelector( i ); joachim99@8: } joachim99@8: break; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: int MergeResultWindow::getNrOfUnsolvedConflicts() joachim99@8: { joachim99@8: int nrOfUnsolvedConflicts = 0; joachim99@8: joachim99@8: MergeLineList::iterator mlIt = m_mergeLineList.begin(); joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: MergeEditLineList::iterator melIt = ml.mergeEditLineList.begin(); joachim99@8: if ( melIt->isConflict() ) joachim99@8: ++nrOfUnsolvedConflicts; joachim99@8: } joachim99@8: joachim99@8: return nrOfUnsolvedConflicts; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::showNrOfConflicts() joachim99@8: { joachim99@8: int nrOfSolvedConflicts = 0; joachim99@8: int nrOfUnsolvedConflicts = 0; joachim99@8: joachim99@8: MergeLineList::iterator i; joachim99@8: for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@8: { joachim99@8: if ( i->bConflict ) joachim99@8: ++nrOfUnsolvedConflicts; joachim99@8: else if ( i->bDelta ) joachim99@8: ++nrOfSolvedConflicts; joachim99@8: } joachim99@8: QString totalInfo; joachim99@8: if ( m_pTotalDiffStatus->bBinaryAEqB && m_pTotalDiffStatus->bBinaryAEqC ) joachim99@8: totalInfo += i18n("All input files are binary equal."); joachim99@8: else if ( m_pTotalDiffStatus->bTextAEqB && m_pTotalDiffStatus->bTextAEqC ) joachim99@8: totalInfo += i18n("All input files contain the same text."); joachim99@8: else { joachim99@8: if ( m_pTotalDiffStatus->bBinaryAEqB ) totalInfo += i18n("Files A and B are binary equal.\n"); joachim99@8: else if ( m_pTotalDiffStatus->bTextAEqB ) totalInfo += i18n("Files A and B have equal text. \n"); joachim99@8: if ( m_pTotalDiffStatus->bBinaryAEqC ) totalInfo += i18n("Files A and C are binary equal.\n"); joachim99@8: else if ( m_pTotalDiffStatus->bTextAEqC ) totalInfo += i18n("Files A and C have equal text. \n"); joachim99@8: if ( m_pTotalDiffStatus->bBinaryBEqC ) totalInfo += i18n("Files B and C are binary equal.\n"); joachim99@8: else if ( m_pTotalDiffStatus->bTextBEqC ) totalInfo += i18n("Files B and C have equal text. \n"); joachim99@8: } joachim99@8: KMessageBox::information( this, joachim99@8: i18n("Total number of conflicts: ") + QString::number(nrOfSolvedConflicts + nrOfUnsolvedConflicts) + joachim99@8: i18n("\nNr of automatically solved conflicts: ") + QString::number(nrOfSolvedConflicts) + joachim99@8: i18n("\nNr of unsolved conflicts: ") + QString::number(nrOfUnsolvedConflicts) + joachim99@8: "\n"+totalInfo, joachim99@8: i18n("Conflicts") joachim99@8: ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::setFastSelector(MergeLineList::iterator i) joachim99@8: { joachim99@8: if ( i==m_mergeLineList.end() ) joachim99@8: return; joachim99@8: m_currentMergeLineIt = i; joachim99@8: emit setFastSelectorRange( i->d3lLineIdx, i->srcRangeLength ); joachim99@8: joachim99@8: int line1 = 0; joachim99@8: joachim99@8: MergeLineList::iterator mlIt = m_mergeLineList.begin(); joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: if(mlIt==m_currentMergeLineIt) joachim99@8: break; joachim99@8: line1 += mlIt->mergeEditLineList.size(); joachim99@8: } joachim99@8: joachim99@8: int nofLines = m_currentMergeLineIt->mergeEditLineList.size(); joachim99@8: int newFirstLine = getBestFirstLine( line1, nofLines, m_firstLine, getNofVisibleLines() ); joachim99@8: if ( newFirstLine != m_firstLine ) joachim99@8: { joachim99@8: scroll( 0, newFirstLine - m_firstLine ); joachim99@8: } joachim99@8: joachim99@8: if ( m_selection.isEmpty() ) joachim99@8: { joachim99@8: m_cursorXPos = 0; joachim99@8: m_cursorOldXPos = 0; joachim99@8: m_cursorYPos = line1; joachim99@8: } joachim99@8: joachim99@8: update(); joachim99@8: emit updateAvailabilities(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::choose( int selector ) joachim99@8: { joachim99@8: setModified(); joachim99@8: joachim99@8: // First find range for which this change works. joachim99@8: MergeLine& ml = *m_currentMergeLineIt; joachim99@8: joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: joachim99@8: // Now check if selector is active for this range already. joachim99@8: bool bActive = false; joachim99@8: joachim99@8: // Remove unneeded lines in the range. joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: if ( mel.src()==selector ) joachim99@8: bActive = true; joachim99@8: joachim99@8: if ( mel.src()==selector || !mel.isEditableText() || mel.isModified() ) joachim99@8: melIt = ml.mergeEditLineList.erase( melIt ); joachim99@8: else joachim99@8: ++melIt; joachim99@8: } joachim99@8: joachim99@8: if ( !bActive ) // Selected source wasn't active. joachim99@8: { // Append the lines from selected source here at rangeEnd. joachim99@8: Diff3LineList::const_iterator d3llit=ml.id3l; joachim99@8: int j; joachim99@8: joachim99@8: for( j=0; jlineA : joachim99@8: mel.src()==2 ? mel.id3l()->lineB : joachim99@8: mel.src()==3 ? mel.id3l()->lineC : -1; joachim99@8: joachim99@8: if ( srcLine == -1 ) joachim99@8: melIt = ml.mergeEditLineList.erase( melIt ); joachim99@8: else joachim99@8: ++melIt; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: if ( ml.mergeEditLineList.empty() ) joachim99@8: { joachim99@8: // Insert a dummy line: joachim99@8: MergeEditLine mel; joachim99@8: joachim99@8: if ( bActive ) mel.setConflict(); // All src entries deleted => conflict joachim99@8: else mel.setRemoved(selector); // No lines in corresponding src found. joachim99@8: joachim99@8: ml.mergeEditLineList.push_back(mel); joachim99@8: } joachim99@58: joachim99@58: if ( m_cursorYPos >= m_totalSize ) joachim99@58: { joachim99@58: m_cursorYPos = m_totalSize-1; joachim99@58: m_cursorXPos = 0; joachim99@58: } joachim99@8: joachim99@8: update(); joachim99@8: emit updateAvailabilities(); joachim99@8: } joachim99@8: joachim99@51: // bConflictsOnly: automatically choose for conflicts only (true) or for everywhere (false) joachim99@51: void MergeResultWindow::chooseGlobal(int selector, bool bConflictsOnly, bool bWhiteSpaceOnly ) joachim99@8: { joachim99@8: resetSelection(); joachim99@8: joachim99@51: merge( false, selector, bConflictsOnly, bWhiteSpaceOnly ); joachim99@8: emit modified(); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotAutoSolve() joachim99@8: { joachim99@8: resetSelection(); joachim99@8: merge( true, -1 ); joachim99@8: emit modified(); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotUnsolve() joachim99@8: { joachim99@8: resetSelection(); joachim99@8: merge( false, -1 ); joachim99@8: emit modified(); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::myUpdate(int afterMilliSecs) joachim99@8: { joachim99@8: killTimers(); joachim99@8: m_bMyUpdate = true; joachim99@8: startTimer( afterMilliSecs ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::timerEvent(QTimerEvent*) joachim99@8: { joachim99@8: killTimers(); joachim99@8: joachim99@8: if ( m_bMyUpdate ) joachim99@8: { joachim99@8: update();//paintEvent( 0 ); joachim99@8: m_bMyUpdate = false; joachim99@8: } joachim99@8: joachim99@8: if ( m_scrollDeltaX != 0 || m_scrollDeltaY != 0 ) joachim99@8: { joachim99@8: m_selection.end( m_selection.lastLine + m_scrollDeltaY, m_selection.lastPos + m_scrollDeltaX ); joachim99@8: emit scroll( m_scrollDeltaX, m_scrollDeltaY ); joachim99@8: killTimers(); joachim99@8: startTimer(50); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: const char* MergeResultWindow::MergeEditLine::getString( const MergeResultWindow* mrw, int& size ) joachim99@8: { joachim99@8: size=-1; joachim99@8: if ( isRemoved() ) { size=0; return ""; } joachim99@8: joachim99@8: if ( ! isModified() ) joachim99@8: { joachim99@8: int src = m_src; joachim99@8: const Diff3Line& d3l = *m_id3l; joachim99@8: if ( src == 0 ) { size=0; return ""; } joachim99@8: joachim99@8: const LineData* pld = 0; joachim99@8: assert( src == A || src == B || src == C ); joachim99@8: if ( src == A && d3l.lineA!=-1 ) pld = &mrw->m_pldA[ d3l.lineA ]; joachim99@8: else if ( src == B && d3l.lineB!=-1 ) pld = &mrw->m_pldB[ d3l.lineB ]; joachim99@8: else if ( src == C && d3l.lineC!=-1 ) pld = &mrw->m_pldC[ d3l.lineC ]; joachim99@8: joachim99@8: if ( pld == 0 ) joachim99@8: { joachim99@8: // assert(false); This is no error. joachim99@8: size = 0; joachim99@8: return ""; joachim99@8: } joachim99@8: joachim99@8: size = pld->size; joachim99@8: return pld->pLine; joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: size = m_str.length(); joachim99@8: return m_str; joachim99@8: } joachim99@8: return 0; joachim99@8: } joachim99@8: joachim99@8: /// Converts the cursor-posOnScreen into a text index, considering tabulators. joachim99@8: int convertToPosInText( const char* p, int size, int posOnScreen ) joachim99@8: { joachim99@8: int localPosOnScreen = 0; joachim99@8: for ( int i=0; i=posOnScreen ) joachim99@8: return i; joachim99@8: joachim99@8: // All letters except tabulator have width one. joachim99@8: int letterWidth = p[i]!='\t' ? 1 : tabber( localPosOnScreen, g_tabSize ); joachim99@8: joachim99@8: localPosOnScreen += letterWidth; joachim99@8: joachim99@8: if ( localPosOnScreen>posOnScreen ) joachim99@8: return i; joachim99@8: } joachim99@8: return size; joachim99@8: } joachim99@8: joachim99@8: joachim99@8: /// Converts the index into the text to a cursor-posOnScreen considering tabulators. joachim99@8: int convertToPosOnScreen( const char* p, int posInText ) joachim99@8: { joachim99@8: int posOnScreen = 0; joachim99@8: for ( int i=0; i height() ) joachim99@8: return; joachim99@8: joachim99@8: yOffset += topLineYOffset; joachim99@8: joachim99@8: QString srcName = " "; joachim99@8: if ( bUserModified ) srcName = "m"; joachim99@8: else if ( srcSelect == A && mergeDetails != eNoChange ) srcName = "A"; joachim99@8: else if ( srcSelect == B ) srcName = "B"; joachim99@8: else if ( srcSelect == C ) srcName = "C"; joachim99@8: joachim99@8: if ( rangeMark & 4 ) joachim99@8: { joachim99@8: p.fillRect( xOffset, yOffset, width(), fontHeight, m_pOptionDialog->m_currentRangeBgColor ); joachim99@8: } joachim99@8: joachim99@8: if( (srcSelect > 0 || bUserModified ) && !bLineRemoved ) joachim99@8: { joachim99@8: int outPos = 0; joachim99@8: QCString s; joachim99@8: for ( int i=0; i0) m_selection.bSelectionContainsData = true; joachim99@8: joachim99@8: if ( lengthInLine < int(s.length()) ) joachim99@8: { // Draw a normal line first joachim99@8: p.setPen( m_pOptionDialog->m_fgColor ); joachim99@51: p.drawText( xOffset, yOffset+fontAscent, decodeString( s.mid(m_firstColumn),m_pOptionDialog) ); joachim99@8: } joachim99@8: int firstPosInLine2 = max2( firstPosInLine, m_firstColumn ); joachim99@8: int lengthInLine2 = max2(0,lastPosInLine - firstPosInLine2); joachim99@8: joachim99@8: if( m_selection.lineWithin( line+1 ) ) joachim99@8: p.fillRect( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset, joachim99@8: width(), fontHeight, colorGroup().highlight() ); joachim99@8: else joachim99@8: p.fillRect( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset, joachim99@8: fontWidth*lengthInLine2, fontHeight, colorGroup().highlight() ); joachim99@8: joachim99@8: p.setPen( colorGroup().highlightedText() ); joachim99@8: p.drawText( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset+fontAscent, joachim99@51: decodeString( s.mid(firstPosInLine2,lengthInLine2), m_pOptionDialog ) ); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: p.setPen( m_pOptionDialog->m_fgColor ); joachim99@51: p.drawText( xOffset, yOffset+fontAscent, decodeString( s.mid(m_firstColumn), m_pOptionDialog ) ); joachim99@8: } joachim99@8: joachim99@8: p.setPen( m_pOptionDialog->m_fgColor ); joachim99@8: if ( m_cursorYPos==line ) joachim99@8: { joachim99@8: m_cursorXPos = minMaxLimiter( m_cursorXPos, 0, outPos ); joachim99@8: m_cursorXPos = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_cursorXPos ) ); joachim99@8: } joachim99@8: joachim99@8: p.drawText( 1, yOffset+fontAscent, srcName ); joachim99@8: } joachim99@8: else if ( bLineRemoved ) joachim99@8: { joachim99@8: p.setPen( m_pOptionDialog->m_colorForConflict ); joachim99@8: p.drawText( xOffset, yOffset+fontAscent, i18n("") ); joachim99@8: p.drawText( 1, yOffset+fontAscent, srcName ); joachim99@8: if ( m_cursorYPos==line ) m_cursorXPos = 0; joachim99@8: } joachim99@8: else if ( srcSelect == 0 ) joachim99@8: { joachim99@8: p.setPen( m_pOptionDialog->m_colorForConflict ); joachim99@8: p.drawText( xOffset, yOffset+fontAscent, i18n("") ); joachim99@8: p.drawText( 1, yOffset+fontAscent, "?" ); joachim99@8: if ( m_cursorYPos==line ) m_cursorXPos = 0; joachim99@8: } joachim99@8: else assert(false); joachim99@8: joachim99@8: xOffset -= fontWidth; joachim99@8: p.setPen( m_pOptionDialog->m_fgColor ); joachim99@8: if ( rangeMark & 1 ) // begin mark joachim99@8: { joachim99@8: p.drawLine( xOffset, yOffset+1, xOffset, yOffset+fontHeight/2 ); joachim99@8: p.drawLine( xOffset, yOffset+1, xOffset-2, yOffset+1 ); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: p.drawLine( xOffset, yOffset, xOffset, yOffset+fontHeight/2 ); joachim99@8: } joachim99@8: joachim99@8: if ( rangeMark & 2 ) // end mark joachim99@8: { joachim99@8: p.drawLine( xOffset, yOffset+fontHeight/2, xOffset, yOffset+fontHeight-1 ); joachim99@8: p.drawLine( xOffset, yOffset+fontHeight-1, xOffset-2, yOffset+fontHeight-1 ); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: p.drawLine( xOffset, yOffset+fontHeight/2, xOffset, yOffset+fontHeight ); joachim99@8: } joachim99@8: joachim99@8: if ( rangeMark & 4 ) joachim99@8: { joachim99@8: p.fillRect( xOffset + 3, yOffset, 3, fontHeight, m_pOptionDialog->m_fgColor ); joachim99@8: /* p.setPen( blue ); joachim99@8: p.drawLine( xOffset+2, yOffset, xOffset+2, yOffset+fontHeight-1 ); joachim99@8: p.drawLine( xOffset+3, yOffset, xOffset+3, yOffset+fontHeight-1 );*/ joachim99@8: } joachim99@8: } joachim99@8: joachim99@58: void MergeResultWindow::setPaintingAllowed(bool bPaintingAllowed) joachim99@58: { joachim99@58: m_bPaintingAllowed = bPaintingAllowed; joachim99@58: } joachim99@58: joachim99@8: void MergeResultWindow::paintEvent( QPaintEvent* e ) joachim99@8: { joachim99@58: if (m_pDiff3LineList==0 || !m_bPaintingAllowed) return; joachim99@8: joachim99@8: bool bOldSelectionContainsData = m_selection.bSelectionContainsData; joachim99@8: const QFontMetrics& fm = fontMetrics(); joachim99@8: int fontHeight = fm.height(); joachim99@8: int fontWidth = fm.width("W"); joachim99@8: int fontAscent = fm.ascent(); joachim99@8: joachim99@8: if ( e!= 0 ) // e==0 for blinking cursor joachim99@8: { joachim99@8: m_selection.bSelectionContainsData = false; joachim99@8: if ( size() != m_pixmap.size() ) joachim99@8: m_pixmap.resize(size()); joachim99@8: joachim99@8: QPainter p(&m_pixmap); joachim99@8: p.setFont( font() ); joachim99@8: p.fillRect( rect(), m_pOptionDialog->m_bgColor ); joachim99@8: joachim99@8: //int visibleLines = height() / fontHeight; joachim99@8: joachim99@8: { // Draw the topline joachim99@58: QString s = " " +i18n("Output") + " : " + m_fileName + " "; joachim99@8: if (m_bModified) joachim99@8: s += i18n("[Modified]"); joachim99@8: joachim99@8: int topLineYOffset = fontHeight + 3; joachim99@8: joachim99@8: if (hasFocus()) joachim99@8: { joachim99@8: p.fillRect( 0, 0, width(), topLineYOffset, lightGray /*m_pOptionDialog->m_diffBgColor*/ ); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: p.fillRect( 0, 0, width(), topLineYOffset, m_pOptionDialog->m_bgColor ); joachim99@8: } joachim99@8: p.setPen( m_pOptionDialog->m_fgColor ); joachim99@8: p.drawText( 0, fontAscent+1, s ); joachim99@8: p.drawLine( 0, fontHeight + 2, width(), fontHeight + 2 ); joachim99@8: } joachim99@8: joachim99@8: int lastVisibleLine = m_firstLine + getNofVisibleLines() + 5; joachim99@8: int nofColumns = 0; joachim99@8: int line = 0; joachim99@8: MergeLineList::iterator mlIt = m_mergeLineList.begin(); joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: if ( line > lastVisibleLine || line + ml.mergeEditLineList.size() < m_firstLine) joachim99@8: { joachim99@8: line += ml.mergeEditLineList.size(); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@8: if (line>=m_firstLine && line<=lastVisibleLine) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: MergeEditLineList::iterator melIt1 = melIt; joachim99@8: ++melIt1; joachim99@8: joachim99@8: int rangeMark = 0; joachim99@8: if ( melIt==ml.mergeEditLineList.begin() ) rangeMark |= 1; // Begin range mark joachim99@8: if ( melIt1==ml.mergeEditLineList.end() ) rangeMark |= 2; // End range mark joachim99@8: joachim99@8: if ( mlIt == m_currentMergeLineIt ) rangeMark |= 4; // Mark of the current line joachim99@8: joachim99@8: const char* s; joachim99@8: int size; joachim99@8: s = mel.getString( this, size ); joachim99@8: if (size>nofColumns) joachim99@8: nofColumns = size; joachim99@8: joachim99@8: writeLine( p, line, s, size, mel.src(), ml.mergeDetails, rangeMark, joachim99@8: mel.isModified(), mel.isRemoved() ); joachim99@8: } joachim99@8: ++line; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: if ( line != m_nofLines || nofColumns != m_nofColumns ) joachim99@8: { joachim99@8: m_nofLines = line; joachim99@58: assert( m_nofLines == m_totalSize ); joachim99@8: joachim99@8: m_nofColumns = nofColumns; joachim99@8: emit resizeSignal(); joachim99@8: } joachim99@8: joachim99@8: if( m_currentMergeLineIt == m_mergeLineList.end() ) joachim99@8: emit sourceMask( 0, 0 ); joachim99@8: else joachim99@8: { joachim99@8: int enabledMask = m_pldC==0 ? 3 : 7; joachim99@8: MergeLine& ml = *m_currentMergeLineIt; joachim99@8: joachim99@8: int srcMask = 0; joachim99@8: bool bModified = false; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: if ( mel.src()==1 ) srcMask |= 1; joachim99@8: if ( mel.src()==2 ) srcMask |= 2; joachim99@8: if ( mel.src()==3 ) srcMask |= 4; joachim99@8: if ( mel.isModified() || !mel.isEditableText() ) bModified = true; joachim99@8: } joachim99@8: joachim99@53: if (hasFocus()) joachim99@53: { joachim99@53: if ( ml.mergeDetails == eNoChange ) emit sourceMask( 0, bModified ? 1 : 0 ); joachim99@53: else emit sourceMask( srcMask, enabledMask ); joachim99@53: } joachim99@8: } joachim99@8: p.end(); joachim99@8: } joachim99@8: joachim99@8: QPainter painter(this); joachim99@8: if ( e!= 0 ) joachim99@8: { joachim99@8: painter.drawPixmap(0,0, m_pixmap); joachim99@8: } joachim99@8: joachim99@8: int topLineYOffset = fontHeight + 3; joachim99@8: int xOffset = fontWidth * leftInfoWidth; joachim99@8: int yOffset = ( m_cursorYPos - m_firstLine ) * fontHeight + topLineYOffset; joachim99@8: int xCursor = ( m_cursorXPos - m_firstColumn ) * fontWidth + xOffset; joachim99@8: joachim99@8: if ( e!= 0 ) joachim99@8: painter.drawPixmap(0,0, m_pixmap); joachim99@8: else joachim99@8: painter.drawPixmap(xCursor-2, yOffset, m_pixmap, joachim99@8: xCursor-2, yOffset, 5, fontAscent+2 ); joachim99@8: joachim99@8: joachim99@8: if ( m_bCursorOn && hasFocus() && m_cursorYPos>=m_firstLine ) joachim99@8: { joachim99@8: int topLineYOffset = fontHeight + 3; joachim99@8: int xOffset = fontWidth * leftInfoWidth; joachim99@8: joachim99@8: int yOffset = ( m_cursorYPos-m_firstLine ) * fontHeight + topLineYOffset; joachim99@8: joachim99@8: int xCursor = ( m_cursorXPos - m_firstColumn ) * fontWidth + xOffset; joachim99@8: painter.drawLine( xCursor, yOffset, xCursor, yOffset+fontAscent ); joachim99@8: painter.drawLine( xCursor-2, yOffset, xCursor+2, yOffset ); joachim99@8: painter.drawLine( xCursor-2, yOffset+fontAscent+1, xCursor+2, yOffset+fontAscent+1 ); joachim99@8: } joachim99@8: joachim99@8: if( !bOldSelectionContainsData && m_selection.bSelectionContainsData ) joachim99@8: emit newSelection(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::convertToLinePos( int x, int y, int& line, int& pos ) joachim99@8: { joachim99@8: const QFontMetrics& fm = fontMetrics(); joachim99@8: int fontHeight = fm.height(); joachim99@8: int fontWidth = fm.width('W'); joachim99@8: int xOffset = (leftInfoWidth-m_firstColumn)*fontWidth; joachim99@8: int topLineYOffset = fontHeight + 3; joachim99@8: joachim99@8: int yOffset = topLineYOffset - m_firstLine * fontHeight; joachim99@8: joachim99@58: line = min2( ( y - yOffset ) / fontHeight, m_totalSize-1 ); joachim99@8: pos = ( x - xOffset ) / fontWidth; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::mousePressEvent ( QMouseEvent* e ) joachim99@8: { joachim99@8: m_bCursorOn = true; joachim99@8: joachim99@8: int line; joachim99@8: int pos; joachim99@8: convertToLinePos( e->x(), e->y(), line, pos ); joachim99@8: joachim99@8: bool bLMB = e->button() == LeftButton; joachim99@8: bool bMMB = e->button() == MidButton; joachim99@8: bool bRMB = e->button() == RightButton; joachim99@8: joachim99@8: if ( bLMB && pos < m_firstColumn || bRMB ) // Fast range selection joachim99@8: { joachim99@8: m_cursorXPos = 0; joachim99@8: m_cursorOldXPos = 0; joachim99@8: m_cursorYPos = max2(line,0); joachim99@8: int l = 0; joachim99@8: MergeLineList::iterator i = m_mergeLineList.begin(); joachim99@8: for(i = m_mergeLineList.begin();i!=m_mergeLineList.end(); ++i) joachim99@8: { joachim99@8: if (l==line) joachim99@8: break; joachim99@8: joachim99@8: l += i->mergeEditLineList.size(); joachim99@8: if (l>line) joachim99@8: break; joachim99@8: } joachim99@8: m_selection.reset(); // Disable current selection joachim99@8: joachim99@8: m_bCursorOn = true; joachim99@8: setFastSelector( i ); joachim99@8: joachim99@8: if (bRMB) joachim99@8: { joachim99@8: showPopupMenu( QCursor::pos() ); joachim99@8: } joachim99@8: } joachim99@8: else if ( bLMB ) // Normal cursor placement joachim99@8: { joachim99@8: pos = max2(pos,0); joachim99@8: line = max2(line,0); joachim99@8: if ( e->state() & ShiftButton ) joachim99@8: { joachim99@8: if (m_selection.firstLine==-1) joachim99@8: m_selection.start( line, pos ); joachim99@8: m_selection.end( line, pos ); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: // Selection joachim99@8: m_selection.reset(); joachim99@8: m_selection.start( line, pos ); joachim99@8: m_selection.end( line, pos ); joachim99@8: } joachim99@8: m_cursorXPos = pos; joachim99@8: m_cursorOldXPos = pos; joachim99@8: m_cursorYPos = line; joachim99@8: joachim99@8: update(); joachim99@8: //showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar ); joachim99@8: } joachim99@8: else if ( bMMB ) // Paste clipboard joachim99@8: { joachim99@8: pos = max2(pos,0); joachim99@8: line = max2(line,0); joachim99@8: joachim99@8: m_selection.reset(); joachim99@8: m_cursorXPos = pos; joachim99@8: m_cursorOldXPos = pos; joachim99@8: m_cursorYPos = line; joachim99@8: joachim99@8: pasteClipboard(); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::mouseDoubleClickEvent( QMouseEvent* e ) joachim99@8: { joachim99@8: if ( e->button() == LeftButton ) joachim99@8: { joachim99@8: int line; joachim99@8: int pos; joachim99@8: convertToLinePos( e->x(), e->y(), line, pos ); joachim99@8: m_cursorXPos = pos; joachim99@8: m_cursorOldXPos = pos; joachim99@8: m_cursorYPos = line; joachim99@8: joachim99@8: // Get the string data of the current line joachim99@8: joachim99@8: int size; joachim99@8: MergeLineList::iterator mlIt; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: calcIteratorFromLineNr( line, mlIt, melIt ); joachim99@8: const char* s = melIt->getString( this, size ); joachim99@8: joachim99@8: if ( s!=0 && size>0 ) joachim99@8: { joachim99@8: int pos1, pos2; joachim99@8: joachim99@8: calcTokenPos( s, size, pos, pos1, pos2 ); joachim99@8: joachim99@8: resetSelection(); joachim99@8: m_selection.start( line, convertToPosOnScreen( s, pos1 ) ); joachim99@8: m_selection.end( line, convertToPosOnScreen( s, pos2 ) ); joachim99@8: joachim99@8: update(); joachim99@8: // emit selectionEnd() happens in the mouseReleaseEvent. joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::mouseReleaseEvent ( QMouseEvent * e ) joachim99@8: { joachim99@8: if ( e->button() == LeftButton ) joachim99@8: { joachim99@8: killTimers(); joachim99@8: joachim99@8: if (m_selection.firstLine != -1 ) joachim99@8: { joachim99@8: emit selectionEnd(); joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::mouseMoveEvent ( QMouseEvent * e ) joachim99@8: { joachim99@8: int line; joachim99@8: int pos; joachim99@8: convertToLinePos( e->x(), e->y(), line, pos ); joachim99@8: m_cursorXPos = pos; joachim99@8: m_cursorOldXPos = pos; joachim99@8: m_cursorYPos = line; joachim99@8: if (m_selection.firstLine != -1 ) joachim99@8: { joachim99@8: m_selection.end( line, pos ); joachim99@8: myUpdate(0); joachim99@8: joachim99@8: //showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar ); joachim99@8: joachim99@8: // Scroll because mouse moved out of the window joachim99@8: const QFontMetrics& fm = fontMetrics(); joachim99@8: int fontHeight = fm.height(); joachim99@8: int fontWidth = fm.width('W'); joachim99@8: int topLineYOffset = fontHeight + 3; joachim99@8: int deltaX=0; joachim99@8: int deltaY=0; joachim99@8: if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1; joachim99@8: if ( e->x() > width() ) deltaX=+1; joachim99@8: if ( e->y() < topLineYOffset ) deltaY=-1; joachim99@8: if ( e->y() > height() ) deltaY=+1; joachim99@8: m_scrollDeltaX = deltaX; joachim99@8: m_scrollDeltaY = deltaY; joachim99@8: if ( deltaX != 0 || deltaY!= 0) joachim99@8: { joachim99@8: emit scroll( deltaX, deltaY ); joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: joachim99@8: void MergeResultWindow::slotCursorUpdate() joachim99@8: { joachim99@8: m_cursorTimer.stop(); joachim99@8: m_bCursorOn = !m_bCursorOn; joachim99@8: joachim99@8: if ( isVisible() ) joachim99@8: paintEvent(0); joachim99@8: joachim99@8: m_cursorTimer.start(500,true); joachim99@8: } joachim99@8: joachim99@8: joachim99@8: void MergeResultWindow::wheelEvent( QWheelEvent* e ) joachim99@8: { joachim99@8: int d = -e->delta()*QApplication::wheelScrollLines()/120; joachim99@8: e->accept(); joachim99@8: scroll( 0, min2(d, getNofVisibleLines()) ); joachim99@8: } joachim99@8: joachim99@51: joachim99@8: void MergeResultWindow::keyPressEvent( QKeyEvent* e ) joachim99@8: { joachim99@8: int y = m_cursorYPos; joachim99@8: MergeLineList::iterator mlIt; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: calcIteratorFromLineNr( y, mlIt, melIt ); joachim99@8: joachim99@8: int stringLength; joachim99@8: const char* ps = melIt->getString( this, stringLength ); joachim99@8: int x = convertToPosInText( ps, stringLength, m_cursorXPos ); joachim99@8: joachim99@8: bool bCtrl = ( e->state() & ControlButton ) != 0 ; joachim99@8: bool bShift = ( e->state() & ShiftButton ) != 0 ; joachim99@8: #ifdef _WIN32 joachim99@8: bool bAlt = ( e->state() & AltButton ) != 0 ; joachim99@8: if ( bCtrl && bAlt ){ bCtrl=false; bAlt=false; } // AltGr-Key pressed. joachim99@8: #endif joachim99@8: joachim99@8: bool bYMoveKey = false; joachim99@8: // Special keys joachim99@8: switch ( e->key() ) joachim99@8: { joachim99@8: case Key_Escape: break; joachim99@8: //case Key_Tab: break; joachim99@8: case Key_Backtab: break; joachim99@8: case Key_Delete: joachim99@8: { joachim99@8: if ( deleteSelection2( ps, stringLength, x, y, mlIt, melIt )) break; joachim99@8: if( !melIt->isEditableText() ) break; joachim99@8: if (x>=stringLength) joachim99@8: { joachim99@58: if ( yisEditableText() ) joachim99@8: { joachim99@8: int stringLength1; joachim99@8: ps = melIt1->getString( this, stringLength1 ); joachim99@8: assert(ps!=0); joachim99@8: QCString s2( ps, stringLength1+1 ); joachim99@8: melIt->setString( s1 + s2 ); joachim99@8: joachim99@8: // Remove the line joachim99@8: if ( mlIt1->mergeEditLineList.size()>1 ) joachim99@8: mlIt1->mergeEditLineList.erase( melIt1 ); joachim99@8: else joachim99@8: melIt1->setRemoved(); joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: QCString s( ps, x+1 ); joachim99@8: s += QCString( ps+x+1, stringLength - x ); joachim99@8: melIt->setString( s ); joachim99@8: setModified(); joachim99@8: } joachim99@8: break; joachim99@8: } joachim99@8: case Key_Backspace: joachim99@8: { joachim99@8: if ( deleteSelection2( ps, stringLength, x, y, mlIt, melIt )) break; joachim99@8: if( !melIt->isEditableText() ) break; joachim99@8: if (x==0) joachim99@8: { joachim99@8: if ( y>0 ) joachim99@8: { joachim99@8: setModified(); joachim99@8: QCString s2( ps, stringLength+1 ); joachim99@8: MergeLineList::iterator mlIt1; joachim99@8: MergeEditLineList::iterator melIt1; joachim99@8: calcIteratorFromLineNr( y-1, mlIt1, melIt1 ); joachim99@8: if ( melIt1->isEditableText() ) joachim99@8: { joachim99@8: int stringLength1; joachim99@8: ps = melIt1->getString( this, stringLength1 ); joachim99@8: QCString s1( ps, stringLength1+1 ); joachim99@8: melIt1->setString( s1 + s2 ); joachim99@8: joachim99@8: // Remove the previous line joachim99@8: if ( mlIt->mergeEditLineList.size()>1 ) joachim99@8: mlIt->mergeEditLineList.erase( melIt ); joachim99@8: else joachim99@8: melIt->setRemoved(); joachim99@8: joachim99@8: --y; joachim99@8: x=stringLength1; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: QCString s( ps, x ); joachim99@8: s += QCString( ps+x, stringLength - x + 1 ); joachim99@8: --x; joachim99@8: melIt->setString( s ); joachim99@8: setModified(); joachim99@8: } joachim99@8: break; joachim99@8: } joachim99@8: case Key_Return: joachim99@8: case Key_Enter: joachim99@8: { joachim99@8: if( !melIt->isEditableText() ) break; joachim99@8: deleteSelection2( ps, stringLength, x, y, mlIt, melIt ); joachim99@8: setModified(); joachim99@8: QCString indentation; joachim99@8: if ( m_pOptionDialog->m_bAutoIndentation ) joachim99@8: { // calc last indentation joachim99@8: MergeLineList::iterator mlIt1 = mlIt; joachim99@8: MergeEditLineList::iterator melIt1 = melIt; joachim99@8: for(;;) { joachim99@8: int size; joachim99@8: const char* s = melIt1->getString(this, size); joachim99@8: if ( s!=0 ) { joachim99@8: int i; joachim99@8: for( i=0; imergeEditLineList.end() ) { joachim99@8: --mlIt1; joachim99@8: if ( mlIt1 == m_mergeLineList.end() ) break; joachim99@8: melIt1 = mlIt1->mergeEditLineList.end(); joachim99@8: --melIt1; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: MergeEditLine mel; joachim99@8: mel.setString( indentation + QCString( ps+x, stringLength - x + 1 ) ); joachim99@8: joachim99@8: if ( xstr, first copy it into a temporary. joachim99@8: QCString temp = QCString( ps, x + 1 ); joachim99@8: melIt->setString( temp ); joachim99@8: } joachim99@8: joachim99@8: ++melIt; joachim99@8: mlIt->mergeEditLineList.insert( melIt, mel ); joachim99@8: x=indentation.length(); joachim99@8: ++y; joachim99@8: break; joachim99@8: } joachim99@8: case Key_Insert: m_bInsertMode = !m_bInsertMode; break; joachim99@8: case Key_Pause: break; joachim99@8: case Key_Print: break; joachim99@8: case Key_SysReq: break; joachim99@8: case Key_Home: x=0; if(bCtrl){y=0; } break; // cursor movement joachim99@8: case Key_End: x=INT_MAX; if(bCtrl){y=INT_MAX;} break; joachim99@8: joachim99@8: case Key_Left: joachim99@8: if ( !bCtrl ) joachim99@8: { joachim99@8: --x; joachim99@8: if(x<0 && y>0){--y; x=INT_MAX;} joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: while( x>0 && (ps[x-1]==' ' || ps[x-1]=='\t') ) --x; joachim99@8: while( x>0 && (ps[x-1]!=' ' && ps[x-1]!='\t') ) --x; joachim99@8: } joachim99@8: break; joachim99@8: joachim99@8: case Key_Right: joachim99@8: if ( !bCtrl ) joachim99@8: { joachim99@58: ++x; if(x>stringLength && ytext(); joachim99@8: if( t.isEmpty() || bCtrl ) joachim99@8: { e->ignore(); return; } joachim99@8: else joachim99@8: { joachim99@8: if( bCtrl ) joachim99@8: { joachim99@8: e->ignore(); return; joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: if( !melIt->isEditableText() ) break; joachim99@8: deleteSelection2( ps, stringLength, x, y, mlIt, melIt ); joachim99@8: joachim99@8: setModified(); joachim99@8: // Characters to insert joachim99@8: QCString s( ps, stringLength+1 ); joachim99@8: if ( t[0]=='\t' && m_pOptionDialog->m_bReplaceTabs ) joachim99@8: { joachim99@8: int spaces = (m_cursorXPos / g_tabSize + 1)*g_tabSize - m_cursorXPos; joachim99@8: t.fill( ' ', spaces ); joachim99@8: } joachim99@8: if ( m_bInsertMode ) joachim99@58: s.insert( x, encodeString(t, m_pOptionDialog) ); joachim99@8: else joachim99@58: s.replace( x, t.length(), encodeString(t, m_pOptionDialog) ); joachim99@8: joachim99@8: melIt->setString( s ); joachim99@8: x += t.length(); joachim99@8: bShift = false; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@58: y = minMaxLimiter( y, 0, m_totalSize-1 ); joachim99@8: joachim99@8: calcIteratorFromLineNr( y, mlIt, melIt ); joachim99@8: ps = melIt->getString( this, stringLength ); joachim99@8: joachim99@8: x = minMaxLimiter( x, 0, stringLength ); joachim99@8: joachim99@8: int newFirstLine = m_firstLine; joachim99@8: int newFirstColumn = m_firstColumn; joachim99@8: joachim99@8: if ( y m_firstLine + getNofVisibleLines() ) joachim99@8: newFirstLine = y - getNofVisibleLines(); joachim99@8: joachim99@8: if (bYMoveKey) joachim99@8: x=convertToPosInText( ps, stringLength, m_cursorOldXPos ); joachim99@8: joachim99@8: int xOnScreen = convertToPosOnScreen( ps, x ); joachim99@8: if ( xOnScreen m_firstColumn + getNofVisibleColumns() ) joachim99@8: newFirstColumn = xOnScreen - getNofVisibleColumns(); joachim99@8: joachim99@8: if ( bShift ) joachim99@8: { joachim99@8: if (m_selection.firstLine==-1) joachim99@8: m_selection.start( m_cursorYPos, m_cursorXPos ); joachim99@8: joachim99@8: m_selection.end( y, xOnScreen ); joachim99@8: } joachim99@8: else joachim99@8: m_selection.reset(); joachim99@8: joachim99@8: m_cursorYPos = y; joachim99@8: m_cursorXPos = xOnScreen; joachim99@8: if ( ! bYMoveKey ) joachim99@8: m_cursorOldXPos = m_cursorXPos; joachim99@8: joachim99@8: m_bCursorOn = false; joachim99@8: joachim99@8: if ( newFirstLine!=m_firstLine || newFirstColumn!=m_firstColumn ) joachim99@8: { joachim99@8: m_bCursorOn = true; joachim99@8: scroll( newFirstColumn-m_firstColumn, newFirstLine-m_firstLine ); joachim99@8: return; joachim99@8: } joachim99@8: joachim99@8: m_bCursorOn = true; joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::calcIteratorFromLineNr( joachim99@8: int line, joachim99@8: MergeResultWindow::MergeLineList::iterator& mlIt, joachim99@8: MergeResultWindow::MergeEditLineList::iterator& melIt joachim99@8: ) joachim99@8: { joachim99@8: for( mlIt = m_mergeLineList.begin(); mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: if ( line > ml.mergeEditLineList.size() ) joachim99@8: { joachim99@8: line -= ml.mergeEditLineList.size(); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@8: --line; joachim99@8: if (line<0) return; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: assert(false); joachim99@8: } joachim99@8: joachim99@8: joachim99@8: QString MergeResultWindow::getSelection() joachim99@8: { joachim99@8: QString selectionString; joachim99@8: joachim99@8: int line = 0; joachim99@8: MergeLineList::iterator mlIt = m_mergeLineList.begin(); joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: joachim99@8: if ( m_selection.lineWithin(line) ) joachim99@8: { joachim99@8: int outPos = 0; joachim99@8: if (mel.isEditableText()) joachim99@8: { joachim99@8: int size; joachim99@8: const char* pLine = mel.getString( this, size ); joachim99@8: joachim99@8: // Consider tabs joachim99@8: joachim99@8: for( int i=0; i"); joachim99@8: } joachim99@8: joachim99@8: if( m_selection.within( line, outPos ) ) joachim99@8: { joachim99@8: #ifdef _WIN32 joachim99@8: selectionString += '\r'; joachim99@8: #endif joachim99@8: selectionString += '\n'; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: ++line; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: return selectionString; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::deleteSelection2( const char*& ps, int& stringLength, int& x, int& y, joachim99@8: MergeLineList::iterator& mlIt, MergeEditLineList::iterator& melIt ) joachim99@8: { joachim99@8: if (m_selection.firstLine!=-1 && m_selection.bSelectionContainsData ) joachim99@8: { joachim99@8: deleteSelection(); joachim99@8: y = m_cursorYPos; joachim99@8: calcIteratorFromLineNr( y, mlIt, melIt ); joachim99@8: ps = melIt->getString( this, stringLength ); joachim99@8: x = convertToPosInText( ps, stringLength, m_cursorXPos ); joachim99@8: return true; joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::deleteSelection() joachim99@8: { joachim99@8: if ( m_selection.firstLine==-1 || !m_selection.bSelectionContainsData ) joachim99@8: { joachim99@8: return; joachim99@8: } joachim99@8: setModified(); joachim99@8: joachim99@8: int line = 0; joachim99@8: MergeLineList::iterator mlItFirst; joachim99@8: MergeEditLineList::iterator melItFirst; joachim99@8: QCString firstLineString; joachim99@8: joachim99@8: int firstLine = -1; joachim99@8: int lastLine = -1; joachim99@8: joachim99@8: MergeLineList::iterator mlIt; joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: joachim99@8: if ( mel.isEditableText() && m_selection.lineWithin(line) ) joachim99@8: { joachim99@8: if ( firstLine==-1 ) joachim99@8: firstLine = line; joachim99@8: lastLine = line; joachim99@8: } joachim99@8: joachim99@8: ++line; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: if ( firstLine == -1 ) joachim99@8: { joachim99@8: return; // Nothing to delete. joachim99@8: } joachim99@8: joachim99@8: line = 0; joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: MergeEditLineList::iterator melIt, melIt1; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: melIt1 = melIt; joachim99@8: ++melIt1; joachim99@8: joachim99@8: if ( mel.isEditableText() && m_selection.lineWithin(line) ) joachim99@8: { joachim99@8: int size; joachim99@8: const char* pLine = mel.getString( this, size ); joachim99@8: joachim99@8: int firstPosInLine = m_selection.firstPosInLine(line); joachim99@8: int lastPosInLine = m_selection.lastPosInLine(line); joachim99@8: joachim99@8: if ( line==firstLine ) joachim99@8: { joachim99@8: mlItFirst = mlIt; joachim99@8: melItFirst = melIt; joachim99@8: int pos = convertToPosInText( pLine, size, firstPosInLine ); joachim99@8: firstLineString = QCString( pLine, pos+1 ); joachim99@8: } joachim99@8: joachim99@8: if ( line==lastLine ) joachim99@8: { joachim99@8: // This is the last line in the selection joachim99@8: int pos = convertToPosInText( pLine, size, lastPosInLine ); joachim99@8: firstLineString += QCString( pLine+pos, 1+max2( 0,size-pos)); joachim99@8: melItFirst->setString( firstLineString ); joachim99@8: } joachim99@8: joachim99@8: if ( line!=firstLine ) joachim99@8: { joachim99@8: // Remove the line joachim99@8: if ( mlIt->mergeEditLineList.size()>1 ) joachim99@58: mlIt->mergeEditLineList.erase( melIt ); joachim99@8: else joachim99@58: melIt->setRemoved(); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: ++line; joachim99@8: melIt = melIt1; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: m_cursorYPos = m_selection.beginLine(); joachim99@8: m_cursorXPos = m_selection.beginPos(); joachim99@8: m_cursorOldXPos = m_cursorXPos; joachim99@8: joachim99@8: m_selection.reset(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::pasteClipboard() joachim99@8: { joachim99@8: if (m_selection.firstLine != -1 ) joachim99@8: deleteSelection(); joachim99@8: joachim99@8: setModified(); joachim99@8: joachim99@8: int y = m_cursorYPos; joachim99@8: MergeLineList::iterator mlIt; joachim99@8: MergeEditLineList::iterator melIt, melItAfter; joachim99@8: calcIteratorFromLineNr( y, mlIt, melIt ); joachim99@8: melItAfter = melIt; joachim99@8: ++melItAfter; joachim99@8: int stringLength; joachim99@8: const char* ps = melIt->getString( this, stringLength ); joachim99@8: int x = convertToPosInText( ps, stringLength, m_cursorXPos ); joachim99@8: joachim99@58: QCString clipBoard = encodeString( QApplication::clipboard()->text(), m_pOptionDialog ); joachim99@8: joachim99@8: QCString currentLine = QCString( ps, x+1 ); joachim99@8: QCString endOfLine = QCString( ps+x, stringLength-x+1 ); joachim99@8: int i; joachim99@8: for( i=0; i<(int)clipBoard.length(); ++i ) joachim99@8: { joachim99@58: char c = clipBoard[i]; joachim99@8: if ( c == '\r' ) continue; joachim99@8: if ( c == '\n' ) joachim99@8: { joachim99@8: melIt->setString( currentLine ); joachim99@8: joachim99@8: melIt = mlIt->mergeEditLineList.insert( melItAfter, MergeEditLine() ); joachim99@8: currentLine = ""; joachim99@8: x=0; joachim99@8: ++y; joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: currentLine += c; joachim99@8: ++x; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: currentLine += endOfLine; joachim99@8: melIt->setString( currentLine ); joachim99@8: joachim99@8: m_cursorYPos = y; joachim99@8: m_cursorXPos = convertToPosOnScreen( currentLine, x ); joachim99@8: m_cursorOldXPos = m_cursorXPos; joachim99@8: joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::resetSelection() joachim99@8: { joachim99@8: m_selection.reset(); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::setModified() joachim99@8: { joachim99@8: if (!m_bModified) joachim99@8: { joachim99@8: m_bModified = true; joachim99@8: emit modified(); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: /// Saves and returns true when successful. joachim99@8: bool MergeResultWindow::saveDocument( const QString& fileName ) joachim99@8: { joachim99@8: m_fileName = fileName; joachim99@8: joachim99@8: // Are still conflicts somewhere? joachim99@8: if ( getNrOfUnsolvedConflicts()>0 ) joachim99@8: { joachim99@8: KMessageBox::error( this, joachim99@8: i18n("Not all conflicts are solved yet.\n" joachim99@8: "File not saved.\n"), joachim99@51: i18n("Conflicts Left")); joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: update(); joachim99@8: joachim99@8: FileAccess file( fileName, true /*bWantToWrite*/ ); joachim99@8: if ( m_pOptionDialog->m_bDmCreateBakFiles && file.exists() ) joachim99@8: { joachim99@8: bool bSuccess = file.createBackup(".orig"); joachim99@8: if ( !bSuccess ) joachim99@8: { joachim99@51: KMessageBox::error( this, file.getStatusText() + i18n("\n\nFile not saved."), i18n("File Save Error") ); joachim99@8: return false; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: // Loop twice over all data: First to calculate the needed size, joachim99@8: // then alloc memory and in the second loop copy the data into the memory. joachim99@8: long neededBufferSize = 0; joachim99@8: long dataIndex = 0; joachim99@8: QByteArray dataArray; joachim99@8: for ( int i=0; i<2; ++i ) joachim99@8: { joachim99@8: if(i==1) joachim99@8: { joachim99@8: if ( ! dataArray.resize(neededBufferSize) ) joachim99@8: { joachim99@8: KMessageBox::error(this, i18n("Out of memory while preparing to save.") ); joachim99@8: return false; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: int line = 0; joachim99@8: MergeLineList::iterator mlIt = m_mergeLineList.begin(); joachim99@8: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@8: MergeLine& ml = *mlIt; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@8: MergeEditLine& mel = *melIt; joachim99@8: joachim99@8: if ( mel.isEditableText() ) joachim99@8: { joachim99@8: int size; joachim99@8: const char* pLine = mel.getString( this, size ); joachim99@8: joachim99@8: QCString s(pLine, size+1); joachim99@8: joachim99@8: if (line>0) // Prepend line feed, but not for first line joachim99@8: { joachim99@58: if ( m_pOptionDialog->m_lineEndStyle == eLineEndDos ) joachim99@58: { s.prepend("\r\n"); size+=2; } joachim99@58: else joachim99@58: { s.prepend("\n"); size+=1; } joachim99@8: } joachim99@8: joachim99@8: if (i==0) neededBufferSize += size; joachim99@8: else joachim99@8: { joachim99@8: memcpy( dataArray.data() + dataIndex, s, size ); joachim99@8: dataIndex+=size; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: ++line; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: bool bSuccess = file.writeFile( dataArray.data(), neededBufferSize ); joachim99@8: if ( ! bSuccess ) joachim99@8: { joachim99@51: KMessageBox::error( this, i18n("Error while writing."), i18n("File Save Error") ); joachim99@8: return false; joachim99@8: } joachim99@8: g_pProgressDialog->hide(); joachim99@8: joachim99@8: m_bModified = false; joachim99@8: update(); joachim99@8: joachim99@8: return true; joachim99@8: } joachim99@8: joachim99@8: QCString MergeResultWindow::getString( int lineIdx ) joachim99@8: { joachim99@8: MergeResultWindow::MergeLineList::iterator mlIt; joachim99@8: MergeResultWindow::MergeEditLineList::iterator melIt; joachim99@8: calcIteratorFromLineNr( lineIdx, mlIt, melIt ); joachim99@8: int length=0; joachim99@8: const char* p = melIt->getString( this, length ); joachim99@8: QCString line( p, length+1 ); joachim99@8: return line; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ) joachim99@8: { joachim99@8: int it = d3vLine; joachim99@8: int endIt = bDirDown ? getNofLines() : -1; joachim99@8: int step = bDirDown ? 1 : -1; joachim99@8: int startPos = posInLine; joachim99@8: joachim99@8: for( ; it!=endIt; it+=step ) joachim99@8: { joachim99@8: QCString line = getString( it ); joachim99@8: if ( !line.isEmpty() ) joachim99@8: { joachim99@8: int pos = line.find( s, startPos, bCaseSensitive ); joachim99@8: if ( pos != -1 ) joachim99@8: { joachim99@8: d3vLine = it; joachim99@8: posInLine = pos; joachim99@8: return true; joachim99@8: } joachim99@8: joachim99@8: startPos = 0; joachim99@8: } joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::setSelection( int firstLine, int startPos, int lastLine, int endPos ) joachim99@8: { joachim99@8: m_selection.reset(); joachim99@8: m_selection.start( firstLine, convertToPosOnScreen( getString(firstLine), startPos ) ); joachim99@8: m_selection.end( lastLine, convertToPosOnScreen( getString(lastLine), endPos ) ); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: Overview::Overview( QWidget* pParent, OptionDialog* pOptions ) joachim99@8: : QWidget( pParent, 0, WRepaintNoErase ) joachim99@8: { joachim99@8: m_pDiff3LineList = 0; joachim99@8: m_pOptions = pOptions; joachim99@8: m_bTripleDiff = false; joachim99@8: setFixedWidth(20); joachim99@8: } joachim99@8: joachim99@8: void Overview::init( Diff3LineList* pDiff3LineList, bool bTripleDiff ) joachim99@8: { joachim99@8: m_pDiff3LineList = pDiff3LineList; joachim99@8: m_bTripleDiff = bTripleDiff; joachim99@8: m_pixmap.resize( QSize(0,0) ); // make sure that a redraw happens joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@51: void Overview::slotRedraw() joachim99@51: { joachim99@51: m_pixmap.resize( QSize(0,0) ); // make sure that a redraw happens joachim99@51: update(); joachim99@51: } joachim99@51: joachim99@8: void Overview::setRange( int firstLine, int pageHeight ) joachim99@8: { joachim99@8: m_firstLine = firstLine; joachim99@8: m_pageHeight = pageHeight; joachim99@8: update(); joachim99@8: } joachim99@8: void Overview::setFirstLine( int firstLine ) joachim99@8: { joachim99@8: m_firstLine = firstLine; joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@8: void Overview::mousePressEvent( QMouseEvent* e ) joachim99@8: { joachim99@8: int h = height()-1; joachim99@8: int nofLines = m_pDiff3LineList->size(); joachim99@8: int h1 = h * m_pageHeight / nofLines+3; joachim99@8: if ( h>0 ) joachim99@8: emit setLine( ( e->y() - h1/2 )*nofLines/h ); joachim99@8: } joachim99@8: joachim99@8: void Overview::mouseMoveEvent( QMouseEvent* e ) joachim99@8: { joachim99@8: mousePressEvent(e); joachim99@8: } joachim99@8: joachim99@8: void Overview::setPaintingAllowed( bool bAllowPainting ) joachim99@8: { joachim99@8: if (m_bPaintingAllowed != bAllowPainting) joachim99@8: { joachim99@8: m_bPaintingAllowed = bAllowPainting; joachim99@8: if ( m_bPaintingAllowed ) update(); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: void Overview::paintEvent( QPaintEvent* ) joachim99@8: { joachim99@8: if (m_pDiff3LineList==0 || !m_bPaintingAllowed ) return; joachim99@8: int h = height()-1; joachim99@8: int w = width(); joachim99@8: int nofLines = m_pDiff3LineList->size(); joachim99@8: joachim99@8: if ( m_pixmap.size() != size() ) joachim99@8: { joachim99@8: m_pixmap.resize( size() ); joachim99@8: joachim99@8: QPainter p(&m_pixmap); joachim99@8: joachim99@8: p.fillRect( rect(), m_pOptions->m_bgColor ); joachim99@8: p.setPen(black); joachim99@8: p.drawLine( 0, 0, 0, h ); joachim99@8: joachim99@8: if (nofLines==0) return; joachim99@8: joachim99@8: int line = 0; joachim99@8: int oldY = 0; joachim99@8: int oldConflictY = -1; joachim99@8: Diff3LineList::const_iterator i; joachim99@8: for( i = m_pDiff3LineList->begin(); i!= m_pDiff3LineList->end(); ++i ) joachim99@8: { joachim99@8: const Diff3Line& d3l = *i; joachim99@8: int y = h * (line+1) / nofLines; joachim99@8: e_MergeDetails md; joachim99@8: bool bConflict; joachim99@8: bool bLineRemoved; joachim99@8: int src; joachim99@8: mergeOneLine( d3l, md, bConflict, bLineRemoved, src, !m_bTripleDiff ); joachim99@8: joachim99@8: QColor c; joachim99@8: bool bWhiteSpaceChange = false; joachim99@8: //if( bConflict ) c=m_pOptions->m_colorForConflict; joachim99@8: //else joachim99@8: { joachim99@8: switch( md ) joachim99@8: { joachim99@8: case eDefault: joachim99@8: case eNoChange: joachim99@8: c = m_pOptions->m_bgColor; joachim99@8: break; joachim99@8: joachim99@8: case eBAdded: joachim99@8: case eBDeleted: joachim99@8: case eBChanged: joachim99@8: c = bConflict ? m_pOptions->m_colorForConflict : m_pOptions->m_colorB; joachim99@8: bWhiteSpaceChange = d3l.bAEqB || d3l.bWhiteLineA && d3l.bWhiteLineB; joachim99@8: break; joachim99@8: joachim99@8: case eCAdded: joachim99@8: case eCDeleted: joachim99@8: case eCChanged: joachim99@8: bWhiteSpaceChange = d3l.bAEqC || d3l.bWhiteLineA && d3l.bWhiteLineC; joachim99@8: c = bConflict ? m_pOptions->m_colorForConflict : m_pOptions->m_colorC; joachim99@8: break; joachim99@8: joachim99@8: case eBCChanged: // conflict joachim99@8: case eBCChangedAndEqual: // possible conflict joachim99@8: case eBCDeleted: // possible conflict joachim99@8: case eBChanged_CDeleted: // conflict joachim99@8: case eCChanged_BDeleted: // conflict joachim99@8: case eBCAdded: // conflict joachim99@8: case eBCAddedAndEqual: // possible conflict joachim99@8: c=m_pOptions->m_colorForConflict; joachim99@8: break; joachim99@8: default: assert(false); break; joachim99@8: } joachim99@8: } joachim99@8: joachim99@51: if (!bWhiteSpaceChange || m_pOptions->m_bShowWhiteSpace ) joachim99@8: { joachim99@51: // Make sure that lines with conflict are not overwritten. joachim99@51: if ( c == m_pOptions->m_colorForConflict ) joachim99@51: { joachim99@51: p.fillRect(1, oldY, w, max2(1,y-oldY), bWhiteSpaceChange ? QBrush(c,Dense4Pattern) : c ); joachim99@51: oldConflictY = oldY; joachim99@51: } joachim99@51: else if ( c!=m_pOptions->m_bgColor && oldY>oldConflictY ) joachim99@51: { joachim99@51: p.fillRect(1, oldY, w, max2(1,y-oldY), bWhiteSpaceChange ? QBrush(c,Dense4Pattern) : c ); joachim99@51: } joachim99@8: } joachim99@8: joachim99@8: oldY = y; joachim99@8: joachim99@8: ++line; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: QPainter painter( this ); joachim99@8: painter.drawPixmap( 0,0, m_pixmap ); joachim99@8: joachim99@8: int y1 = h * m_firstLine / nofLines-1; joachim99@8: int h1 = h * m_pageHeight / nofLines+3; joachim99@8: painter.setPen(black); joachim99@8: painter.drawRect( 1, y1, w-1, h1 ); joachim99@8: } joachim99@8: joachim99@8: