joachim99@8: /*************************************************************************** joachim99@8: mergeresultwindow.cpp - description joachim99@8: ------------------- joachim99@8: begin : Sun Apr 14 2002 joachim99@77: copyright : (C) 2002-2007 by Joachim Eibl joachim99@69: email : joachim.eibl at 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@69: #include "mergeresultwindow.h" joachim99@69: #include "optiondialog.h" joachim99@69: joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@70: #include joachim99@70: #include joachim99@70: #include joachim99@69: joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@75: #include joachim99@80: //Added by qt3to4: joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include joachim99@80: #include Chris@113: #include joachim99@75: 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@66: OptionDialog* pOptionDialog, joachim99@66: QStatusBar* pStatusBar joachim99@8: ) joachim99@75: : QWidget( pParent ) joachim99@8: { joachim99@75: setObjectName( "MergeResultWindow" ); joachim99@70: setFocusPolicy( Qt::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@69: m_eOverviewMode=Overview::eOMNormal; joachim99@8: joachim99@8: m_pldA = 0; joachim99@8: m_pldB = 0; joachim99@8: m_pldC = 0; joachim99@69: m_sizeA = 0; joachim99@69: m_sizeB = 0; joachim99@69: m_sizeC = 0; joachim99@8: joachim99@8: m_pDiff3LineList = 0; joachim99@8: m_pTotalDiffStatus = 0; joachim99@66: m_pStatusBar = pStatusBar; joachim99@58: joachim99@8: m_pOptionDialog = pOptionDialog; joachim99@58: m_bPaintingAllowed = false; joachim99@69: m_delayedDrawTimer = 0; joachim99@8: joachim99@8: m_cursorXPos=0; joachim99@8: m_cursorOldXPos=0; joachim99@8: m_cursorYPos=0; joachim99@8: m_bCursorOn = true; joachim99@69: m_bCursorUpdate = false; joachim99@8: connect( &m_cursorTimer, SIGNAL(timeout()), this, SLOT( slotCursorUpdate() ) ); joachim99@75: m_cursorTimer.setSingleShot(true); joachim99@75: m_cursorTimer.start( 500 /*ms*/ ); 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@69: const LineData* pLineDataA, int sizeA, joachim99@69: const LineData* pLineDataB, int sizeB, joachim99@69: const LineData* pLineDataC, int sizeC, joachim99@8: const Diff3LineList* pDiff3LineList, joachim99@75: TotalDiffStatus* pTotalDiffStatus 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@75: setModified( false ); joachim99@8: joachim99@8: m_pldA = pLineDataA; joachim99@8: m_pldB = pLineDataB; joachim99@8: m_pldC = pLineDataC; joachim99@69: m_sizeA = sizeA; joachim99@69: m_sizeB = sizeB; joachim99@69: m_sizeC = sizeC; 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@66: updateSourceMask(); joachim99@68: joachim99@68: int wsc; joachim99@69: int nofUnsolved = getNrOfUnsolvedConflicts(&wsc); joachim99@73: if (m_pStatusBar) joachim99@80: m_pStatusBar->showMessage( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)" joachim99@80: ,nofUnsolved,wsc) ); joachim99@8: } joachim99@8: joachim99@69: void MergeResultWindow::reset() joachim99@69: { joachim99@69: m_pDiff3LineList = 0; joachim99@69: m_pTotalDiffStatus = 0; joachim99@69: m_pldA = 0; joachim99@69: m_pldB = 0; joachim99@69: m_pldC = 0; joachim99@69: } 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@103: !ml1.bConflict && !ml2.bConflict && ml1.bDelta && ml2.bDelta && ml1.srcSelect == ml2.srcSelect joachim99@103: && (ml1.mergeDetails==ml2.mergeDetails || ml1.mergeDetails!=eBCAddedAndEqual && ml2.mergeDetails!=eBCAddedAndEqual ) joachim99@103: || 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@80: i18n("Warning"), joachim99@80: KStandardGuiItem::cont(), joachim99@80: KStandardGuiItem::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@69: MergeEditLine mel(ml.id3l); joachim99@69: mel.setSource( ml.srcSelect, 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@69: MergeEditLine mel(ml.id3l); 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@69: MergeEditLine mel(ml.id3l);; 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@69: MergeEditLine mel(ml.id3l); 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@69: int srcLine = mel.isRemoved() ? -1 : joachim99@69: melsrc==1 ? mel.id3l()->lineA : joachim99@8: melsrc==2 ? mel.id3l()->lineB : joachim99@8: melsrc==3 ? mel.id3l()->lineC : -1; joachim99@8: joachim99@69: // At least one line remains because oldSrc != melsrc for first line in list joachim99@69: // Other empty lines will be removed 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@69: if ( bAutoSolve && !bConflictsOnly ) joachim99@69: { joachim99@69: if ( m_pOptionDialog->m_bRunHistoryAutoMergeOnMergeStart ) joachim99@69: slotMergeHistory(); joachim99@69: if ( m_pOptionDialog->m_bRunRegExpAutoMergeOnMergeStart ) joachim99@69: slotRegExpAutoMerge(); joachim99@69: if ( m_pldC != 0 && ! doRelevantChangesExist() ) joachim99@69: emit noRelevantChangesDetected(); joachim99@69: } joachim99@69: joachim99@66: int nrOfSolvedConflicts = 0; joachim99@66: int nrOfUnsolvedConflicts = 0; joachim99@66: int nrOfWhiteSpaceConflicts = 0; joachim99@66: joachim99@66: MergeLineList::iterator i; joachim99@66: for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@66: { joachim99@66: if ( i->bConflict ) joachim99@66: ++nrOfUnsolvedConflicts; joachim99@66: else if ( i->bDelta ) joachim99@66: ++nrOfSolvedConflicts; joachim99@68: joachim99@66: if ( i->bWhiteSpaceConflict ) joachim99@66: ++nrOfWhiteSpaceConflicts; joachim99@66: } joachim99@68: joachim99@66: m_pTotalDiffStatus->nofUnsolvedConflicts = nrOfUnsolvedConflicts; joachim99@66: m_pTotalDiffStatus->nofSolvedConflicts = nrOfSolvedConflicts; joachim99@66: m_pTotalDiffStatus->nofWhitespaceConflicts = nrOfWhiteSpaceConflicts; joachim99@66: joachim99@66: joachim99@8: m_cursorXPos=0; joachim99@8: m_cursorOldXPos=0; joachim99@8: m_cursorYPos=0; joachim99@66: //m_firstLine = 0; // Must not set line/column without scrolling there joachim99@66: //m_firstColumn = 0; joachim99@51: joachim99@75: setModified(false); joachim99@66: joachim99@66: m_currentMergeLineIt = m_mergeLineList.begin(); joachim99@66: slotGoTop(); joachim99@66: 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@69: Overview::e_OverviewMode MergeResultWindow::getOverviewMode() joachim99@69: { joachim99@69: return m_eOverviewMode; joachim99@69: } joachim99@69: joachim99@69: void MergeResultWindow::setOverviewMode( Overview::e_OverviewMode eOverviewMode ) joachim99@69: { joachim99@69: m_eOverviewMode = eOverviewMode; joachim99@69: } joachim99@69: joachim99@69: // Check whether we should ignore current delta when moving to next/previous delta joachim99@69: bool MergeResultWindow::checkOverviewIgnore(MergeLineList::iterator &i) joachim99@69: { joachim99@69: if (m_eOverviewMode == Overview::eOMNormal) return false; joachim99@69: if (m_eOverviewMode == Overview::eOMAvsB) joachim99@69: return i->mergeDetails == eCAdded || i->mergeDetails == eCDeleted || i->mergeDetails == eCChanged; joachim99@69: if (m_eOverviewMode == Overview::eOMAvsC) joachim99@69: return i->mergeDetails == eBAdded || i->mergeDetails == eBDeleted || i->mergeDetails == eBChanged; joachim99@69: if (m_eOverviewMode == Overview::eOMBvsC) joachim99@69: return i->mergeDetails == eBCAddedAndEqual || i->mergeDetails == eBCDeleted || i->mergeDetails == eBCChangedAndEqual; joachim99@69: return false; joachim99@69: } joachim99@69: 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@77: while ( isItAtEnd(eDir==eUp, i) && ! i->bDelta ) joachim99@8: { joachim99@8: if ( eDir==eUp ) ++i; // search downwards joachim99@8: else --i; // search upwards joachim99@8: } joachim99@8: } joachim99@77: else if ( eEndPoint == eDelta && isItAtEnd(eDir!=eUp, i) ) joachim99@8: { joachim99@8: do joachim99@8: { joachim99@8: if ( eDir==eUp ) --i; joachim99@8: else ++i; joachim99@8: } joachim99@77: while ( isItAtEnd(eDir!=eUp, i) && ( i->bDelta == false || checkOverviewIgnore(i) || bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ); joachim99@8: } joachim99@77: else if ( eEndPoint == eConflict && isItAtEnd(eDir!=eUp, i) ) joachim99@8: { joachim99@8: do joachim99@8: { joachim99@8: if ( eDir==eUp ) --i; joachim99@8: else ++i; joachim99@8: } joachim99@77: while ( isItAtEnd(eDir!=eUp, i) && (i->bConflict == false || bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ); joachim99@8: } joachim99@77: else if ( isItAtEnd(eDir!=eUp, i) && eEndPoint == eUnsolvedConflict ) joachim99@8: { joachim99@8: do joachim99@8: { joachim99@8: if ( eDir==eUp ) --i; joachim99@8: else ++i; joachim99@8: } joachim99@77: while ( isItAtEnd(eDir!=eUp, i) && ! i->mergeEditLineList.begin()->isConflict() ); joachim99@8: } joachim99@8: joachim99@53: if ( isVisible() ) joachim99@53: setFocus(); joachim99@68: joachim99@66: setFastSelector( i ); joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isDeltaAboveCurrent() joachim99@8: { joachim99@51: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@66: if (m_mergeLineList.empty()) return false; joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@66: if (i == m_mergeLineList.begin()) return false; joachim99@66: do joachim99@8: { joachim99@66: --i; joachim99@77: if ( i->bDelta && !checkOverviewIgnore(i) && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true; joachim99@68: } joachim99@66: while (i!=m_mergeLineList.begin()); joachim99@68: joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isDeltaBelowCurrent() joachim99@8: { joachim99@51: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@66: if (m_mergeLineList.empty()) return false; joachim99@68: joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@66: if (i!=m_mergeLineList.end()) joachim99@8: { joachim99@66: ++i; joachim99@66: for( ; i!=m_mergeLineList.end(); ++i ) joachim99@66: { joachim99@77: if ( i->bDelta && !checkOverviewIgnore(i) && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true; joachim99@66: } joachim99@8: } joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isConflictAboveCurrent() joachim99@8: { joachim99@66: if (m_mergeLineList.empty()) return false; joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@66: if (i == m_mergeLineList.begin()) return false; joachim99@68: joachim99@77: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@77: joachim99@66: do joachim99@8: { joachim99@66: --i; joachim99@77: if ( i->bConflict && !(bSkipWhiteConflicts && i->bWhiteSpaceConflict) ) return true; joachim99@66: } joachim99@66: while (i!=m_mergeLineList.begin()); joachim99@66: joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isConflictBelowCurrent() joachim99@8: { joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@66: if (m_mergeLineList.empty()) return false; joachim99@77: joachim99@77: bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; joachim99@77: joachim99@66: if (i!=m_mergeLineList.end()) joachim99@8: { joachim99@66: ++i; joachim99@66: for( ; i!=m_mergeLineList.end(); ++i ) joachim99@66: { joachim99@77: if ( i->bConflict && !(bSkipWhiteConflicts && i->bWhiteSpaceConflict) ) return true; joachim99@66: } joachim99@8: } joachim99@69: return false; joachim99@8: } joachim99@8: joachim99@77: bool MergeResultWindow::isUnsolvedConflictAtCurrent() joachim99@77: { joachim99@77: if (m_mergeLineList.empty()) return false; joachim99@77: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@77: return i->mergeEditLineList.begin()->isConflict(); joachim99@77: } joachim99@77: joachim99@8: bool MergeResultWindow::isUnsolvedConflictAboveCurrent() joachim99@8: { joachim99@66: if (m_mergeLineList.empty()) return false; joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@66: if (i == m_mergeLineList.begin()) return false; joachim99@66: joachim99@66: do joachim99@8: { joachim99@66: --i; joachim99@8: if ( i->mergeEditLineList.begin()->isConflict() ) return true; joachim99@66: } joachim99@66: while (i!=m_mergeLineList.begin()); joachim99@66: joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: bool MergeResultWindow::isUnsolvedConflictBelowCurrent() joachim99@8: { joachim99@8: MergeLineList::iterator i = m_currentMergeLineIt; joachim99@66: if (m_mergeLineList.empty()) return false; joachim99@66: joachim99@66: if (i!=m_mergeLineList.end()) joachim99@8: { joachim99@66: ++i; joachim99@66: for( ; i!=m_mergeLineList.end(); ++i ) joachim99@66: { joachim99@66: if ( i->mergeEditLineList.begin()->isConflict() ) return true; joachim99@66: } 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@68: //if ( i->bDelta ) joachim99@8: { joachim99@8: setFastSelector( i ); joachim99@8: } joachim99@8: break; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: joachim99@68: int MergeResultWindow::getNrOfUnsolvedConflicts( int* pNrOfWhiteSpaceConflicts ) joachim99@8: { joachim99@8: int nrOfUnsolvedConflicts = 0; joachim99@68: if (pNrOfWhiteSpaceConflicts!=0) joachim99@68: *pNrOfWhiteSpaceConflicts = 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@68: { joachim99@8: ++nrOfUnsolvedConflicts; joachim99@68: if ( ml.bWhiteSpaceConflict && pNrOfWhiteSpaceConflicts!=0 ) joachim99@68: ++ *pNrOfWhiteSpaceConflicts; joachim99@68: } joachim99@8: } joachim99@8: joachim99@8: return nrOfUnsolvedConflicts; joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::showNrOfConflicts() joachim99@8: { joachim99@80: if (!m_pOptionDialog->m_bShowInfoDialogs) joachim99@80: return; joachim99@69: int nrOfConflicts = 0; joachim99@8: MergeLineList::iterator i; joachim99@8: for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@8: { joachim99@69: if ( i->bConflict || i->bDelta ) joachim99@69: ++nrOfConflicts; 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@80: if ( m_pTotalDiffStatus->bBinaryAEqB ) totalInfo += i18n("Files %1 and %2 are binary equal.\n",QString("A"),QString("B")); joachim99@80: else if ( m_pTotalDiffStatus->bTextAEqB ) totalInfo += i18n("Files %1 and %2 have equal text.\n",QString("A"),QString("B")); joachim99@80: if ( m_pTotalDiffStatus->bBinaryAEqC ) totalInfo += i18n("Files %1 and %2 are binary equal.\n",QString("A"),QString("C")); joachim99@80: else if ( m_pTotalDiffStatus->bTextAEqC ) totalInfo += i18n("Files %1 and %2 have equal text.\n",QString("A"),QString("C")); joachim99@80: if ( m_pTotalDiffStatus->bBinaryBEqC ) totalInfo += i18n("Files %1 and %2 are binary equal.\n",QString("B"),QString("C")); joachim99@80: else if ( m_pTotalDiffStatus->bTextBEqC ) totalInfo += i18n("Files %1 and %2 have equal text.\n",QString("B"),QString("C")); joachim99@8: } joachim99@69: joachim99@69: int nrOfUnsolvedConflicts = getNrOfUnsolvedConflicts(); joachim99@69: joachim99@8: KMessageBox::information( this, joachim99@69: i18n("Total number of conflicts: ") + QString::number(nrOfConflicts) + joachim99@69: i18n("\nNr of automatically solved conflicts: ") + QString::number(nrOfConflicts-nrOfUnsolvedConflicts) + 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@66: updateSourceMask(); joachim99@8: emit updateAvailabilities(); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::choose( int selector ) joachim99@8: { joachim99@66: if ( m_currentMergeLineIt==m_mergeLineList.end() ) joachim99@66: return; joachim99@68: 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@69: MergeEditLine mel(ml.id3l); 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@68: 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@66: updateSourceMask(); joachim99@8: emit updateAvailabilities(); joachim99@68: int wsc; joachim99@69: int nofUnsolved = getNrOfUnsolvedConflicts(&wsc); joachim99@80: m_pStatusBar->showMessage( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)" joachim99@80: ,nofUnsolved,wsc) ); 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@75: setModified( true ); joachim99@8: update(); joachim99@68: int wsc; joachim99@69: int nofUnsolved = getNrOfUnsolvedConflicts(&wsc); joachim99@80: m_pStatusBar->showMessage( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)" joachim99@80: ,nofUnsolved,wsc) ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotAutoSolve() joachim99@8: { joachim99@8: resetSelection(); joachim99@8: merge( true, -1 ); joachim99@75: setModified( true ); joachim99@8: update(); joachim99@68: int wsc; joachim99@69: int nofUnsolved = getNrOfUnsolvedConflicts(&wsc); joachim99@80: m_pStatusBar->showMessage( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)" joachim99@80: ,nofUnsolved,wsc) ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::slotUnsolve() joachim99@8: { joachim99@8: resetSelection(); joachim99@8: merge( false, -1 ); joachim99@75: setModified( true ); joachim99@8: update(); joachim99@68: int wsc; joachim99@69: int nofUnsolved = getNrOfUnsolvedConflicts(&wsc); joachim99@80: m_pStatusBar->showMessage( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)" joachim99@80: ,nofUnsolved,wsc) ); joachim99@69: } joachim99@69: joachim99@77: static QString calcHistoryLead(const QString& s ) joachim99@77: { joachim99@77: // Return the start of the line until the first white char after the first non white char. joachim99@77: int i; joachim99@77: for( i=0; ibegin(), idxBegin=0; iBegin!=pD3LList->end(); ++iBegin, ++idxBegin ) joachim99@69: { joachim99@69: if ( historyStart.exactMatch( iBegin->getString(A) ) && joachim99@69: historyStart.exactMatch( iBegin->getString(B) ) && joachim99@69: ( !bThreeFiles || historyStart.exactMatch( iBegin->getString(C) ) ) ) joachim99@69: { joachim99@77: historyLead = calcHistoryLead( iBegin->getString(A) ); joachim99@69: break; joachim99@69: } joachim99@69: } joachim99@69: // Search for end of history joachim99@69: for( iEnd = iBegin, idxEnd = idxBegin; iEnd!=pD3LList->end(); ++iEnd, ++idxEnd ) joachim99@69: { joachim99@69: QString sA = iEnd->getString(A); joachim99@69: QString sB = iEnd->getString(B); joachim99@69: QString sC = iEnd->getString(C); joachim99@77: if ( ! ((sA.isNull() || historyLead == calcHistoryLead(sA) ) && joachim99@77: (sB.isNull() || historyLead == calcHistoryLead(sB) ) && joachim99@77: (!bThreeFiles || sC.isNull() || historyLead == calcHistoryLead(sC) ) joachim99@69: )) joachim99@69: { joachim99@69: break; // End of the history joachim99@69: } joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: bool findParenthesesGroups( const QString& s, QStringList& sl ) joachim99@69: { joachim99@69: sl.clear(); joachim99@69: int i=0; joachim99@69: std::list startPosStack; joachim99@69: int length = s.length(); joachim99@69: for( i=0; i(int)parenthesesGroupList.size() ) joachim99@69: continue; joachim99@69: QString s = matchedRegExpr.cap( groupIdx ); joachim99@69: if ( groupIdx == 0 ) joachim99@69: { joachim99@69: key += s + " "; joachim99@69: continue; joachim99@69: } joachim99@69: joachim99@69: QString groupRegExp = parenthesesGroupList[groupIdx-1]; joachim99@75: if( groupRegExp.indexOf('|')<0 || groupRegExp.indexOf('(')>=0 ) joachim99@69: { joachim99@69: bool bOk = false; joachim99@69: int i = s.toInt( &bOk ); joachim99@69: if ( bOk && i>=0 && i<10000 ) joachim99@69: s.sprintf("%04d", i); // This should help for correct sorting of numbers. joachim99@69: key += s + " "; joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: // Assume that the groupRegExp consists of something like "Jan|Feb|Mar|Apr" joachim99@69: // s is the string that managed to match. joachim99@69: // Now we want to know at which position it occurred. e.g. Jan=0, Feb=1, Mar=2, etc. joachim99@75: QStringList sl = groupRegExp.split( '|' ); joachim99@75: int idx = sl.indexOf( s ); joachim99@69: if (idx<0) joachim99@69: { joachim99@69: // Didn't match joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: QString sIdx; joachim99@69: sIdx.sprintf("%02d", idx+1 ); // Up to 99 words in the groupRegExp (more than 12 aren't expected) joachim99@69: key += sIdx + " "; joachim99@69: } joachim99@69: } joachim99@69: } joachim99@69: return key; joachim99@69: } joachim99@69: joachim99@69: void MergeResultWindow::collectHistoryInformation( joachim99@69: int src, Diff3LineList::const_iterator iHistoryBegin, Diff3LineList::const_iterator iHistoryEnd, joachim99@69: HistoryMap& historyMap, joachim99@69: std::list< HistoryMap::iterator >& hitList // list of iterators joachim99@69: ) joachim99@69: { joachim99@69: std::list< HistoryMap::iterator >::iterator itHitListFront = hitList.begin(); joachim99@69: Diff3LineList::const_iterator id3l = iHistoryBegin; joachim99@69: QString historyLead; joachim99@69: { joachim99@69: const LineData* pld = id3l->getLineData(src); joachim99@69: QString s( pld->pLine, pld->size ); joachim99@77: historyLead = calcHistoryLead(s); joachim99@69: } joachim99@70: QRegExp historyStart( m_pOptionDialog->m_historyStartRegExp ); joachim99@80: if ( id3l == iHistoryEnd ) joachim99@80: return; joachim99@69: ++id3l; // Skip line with "$Log ... $" joachim99@70: QRegExp newHistoryEntry( m_pOptionDialog->m_historyEntryStartRegExp ); joachim99@69: QStringList parenthesesGroups; joachim99@69: findParenthesesGroups( m_pOptionDialog->m_historyEntryStartRegExp, parenthesesGroups ); joachim99@69: QString key; joachim99@69: MergeEditLineList melList; joachim99@69: bool bPrevLineIsEmpty = true; joachim99@69: bool bUseRegExp = !m_pOptionDialog->m_historyEntryStartRegExp.isEmpty(); joachim99@69: for(; id3l != iHistoryEnd; ++id3l ) joachim99@69: { joachim99@69: const LineData* pld = id3l->getLineData(src); joachim99@69: if ( !pld ) continue; joachim99@69: QString s( pld->pLine, pld->size ); joachim99@77: if (historyLead.isNull()) historyLead = calcHistoryLead(s); joachim99@69: QString sLine = s.mid(historyLead.length()); joachim99@75: if ( ( !bUseRegExp && !sLine.trimmed().isEmpty() && bPrevLineIsEmpty ) joachim99@69: || bUseRegExp && newHistoryEntry.exactMatch( sLine ) joachim99@69: ) joachim99@69: { joachim99@69: if ( !key.isEmpty() && !melList.empty() ) joachim99@69: { joachim99@69: // Only insert new HistoryMapEntry if key not found; in either case p.first is a valid iterator to element key. joachim99@69: std::pair p = historyMap.insert(HistoryMap::value_type(key,HistoryMapEntry())); joachim99@69: HistoryMapEntry& hme = p.first->second; joachim99@69: if ( src==A ) hme.mellA = melList; joachim99@69: if ( src==B ) hme.mellB = melList; joachim99@69: if ( src==C ) hme.mellC = melList; joachim99@69: if ( p.second ) // Not in list yet? joachim99@69: { joachim99@69: hitList.insert( itHitListFront, p.first ); joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: if ( ! bUseRegExp ) joachim99@69: key = sLine; joachim99@69: else joachim99@69: key = calcHistorySortKey(m_pOptionDialog->m_historyEntryStartSortKeyOrder,newHistoryEntry,parenthesesGroups); joachim99@69: joachim99@69: melList.clear(); joachim99@69: melList.push_back( MergeEditLine(id3l,src) ); joachim99@69: } joachim99@69: else if ( ! historyStart.exactMatch( s ) ) joachim99@69: { joachim99@69: melList.push_back( MergeEditLine(id3l,src) ); joachim99@69: } joachim99@69: joachim99@75: bPrevLineIsEmpty = sLine.trimmed().isEmpty(); joachim99@69: } joachim99@69: if ( !key.isEmpty() ) joachim99@69: { joachim99@69: // Only insert new HistoryMapEntry if key not found; in either case p.first is a valid iterator to element key. joachim99@69: std::pair p = historyMap.insert(HistoryMap::value_type(key,HistoryMapEntry())); joachim99@69: HistoryMapEntry& hme = p.first->second; joachim99@69: if ( src==A ) hme.mellA = melList; joachim99@69: if ( src==B ) hme.mellB = melList; joachim99@69: if ( src==C ) hme.mellC = melList; joachim99@69: if ( p.second ) // Not in list yet? joachim99@69: { joachim99@69: hitList.insert( itHitListFront, p.first ); joachim99@69: } joachim99@69: } joachim99@69: // End of the history joachim99@69: } joachim99@69: joachim99@69: MergeResultWindow::MergeEditLineList& MergeResultWindow::HistoryMapEntry::choice( bool bThreeInputs ) joachim99@69: { joachim99@69: if ( !bThreeInputs ) joachim99@69: return mellA.empty() ? mellB : mellA; joachim99@69: else joachim99@69: { joachim99@69: if ( mellA.empty() ) joachim99@69: return mellC.empty() ? mellB : mellC; // A doesn't exist, return one that exists joachim99@69: else if ( ! mellB.empty() && ! mellC.empty() ) joachim99@69: { // A, B and C exist joachim99@69: return mellA; joachim99@69: } joachim99@69: else joachim99@69: return mellB.empty() ? mellB : mellC; // A exists, return the one that doesn't exist joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: bool MergeResultWindow::HistoryMapEntry::staysInPlace( bool bThreeInputs, Diff3LineList::const_iterator& iHistoryEnd ) joachim99@69: { joachim99@69: // The entry should stay in place if the decision made by the automerger is correct. joachim99@69: Diff3LineList::const_iterator& iHistoryLast = iHistoryEnd; joachim99@69: --iHistoryLast; joachim99@69: if ( !bThreeInputs ) joachim99@69: { joachim99@69: if ( !mellA.empty() && !mellB.empty() && mellA.begin()->id3l()==mellB.begin()->id3l() && joachim99@69: mellA.back().id3l() == iHistoryLast && mellB.back().id3l() == iHistoryLast ) joachim99@69: { joachim99@69: iHistoryEnd = mellA.begin()->id3l(); joachim99@69: return true; joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: return false; joachim99@69: } joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: if ( !mellA.empty() && !mellB.empty() && !mellC.empty() joachim99@69: && mellA.begin()->id3l()==mellB.begin()->id3l() && mellA.begin()->id3l()==mellC.begin()->id3l() joachim99@69: && mellA.back().id3l() == iHistoryLast && mellB.back().id3l() == iHistoryLast && mellC.back().id3l() == iHistoryLast ) joachim99@69: { joachim99@69: iHistoryEnd = mellA.begin()->id3l(); joachim99@69: return true; joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: return false; joachim99@69: } joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: void MergeResultWindow::slotMergeHistory() joachim99@69: { joachim99@69: Diff3LineList::const_iterator iD3LHistoryBegin; joachim99@69: Diff3LineList::const_iterator iD3LHistoryEnd; joachim99@69: int d3lHistoryBeginLineIdx = -1; joachim99@69: int d3lHistoryEndLineIdx = -1; joachim99@69: joachim99@69: // Search for history start, history end in the diff3LineList joachim99@77: findHistoryRange( QRegExp(m_pOptionDialog->m_historyStartRegExp), m_pldC!=0, m_pDiff3LineList, iD3LHistoryBegin, iD3LHistoryEnd, d3lHistoryBeginLineIdx, d3lHistoryEndLineIdx ); joachim99@69: joachim99@69: if ( iD3LHistoryBegin != m_pDiff3LineList->end() ) joachim99@69: { joachim99@69: // Now collect the historyMap information joachim99@69: HistoryMap historyMap; joachim99@69: std::list< HistoryMap::iterator > hitList; joachim99@69: if (m_pldC==0) joachim99@69: { joachim99@69: collectHistoryInformation( A, iD3LHistoryBegin, iD3LHistoryEnd, historyMap, hitList ); joachim99@69: collectHistoryInformation( B, iD3LHistoryBegin, iD3LHistoryEnd, historyMap, hitList ); joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: collectHistoryInformation( A, iD3LHistoryBegin, iD3LHistoryEnd, historyMap, hitList ); joachim99@69: collectHistoryInformation( B, iD3LHistoryBegin, iD3LHistoryEnd, historyMap, hitList ); joachim99@69: collectHistoryInformation( C, iD3LHistoryBegin, iD3LHistoryEnd, historyMap, hitList ); joachim99@69: } joachim99@69: joachim99@69: Diff3LineList::const_iterator iD3LHistoryOrigEnd = iD3LHistoryEnd; joachim99@69: joachim99@69: bool bHistoryMergeSorting = m_pOptionDialog->m_bHistoryMergeSorting && ! m_pOptionDialog->m_historyEntryStartSortKeyOrder.isEmpty() && joachim99@69: ! m_pOptionDialog->m_historyEntryStartRegExp.isEmpty(); joachim99@69: joachim99@77: if ( m_pOptionDialog->m_maxNofHistoryEntries==-1 ) joachim99@69: { joachim99@77: // Remove parts from the historyMap and hitList that stay in place joachim99@77: if ( bHistoryMergeSorting ) joachim99@69: { joachim99@77: while ( ! historyMap.empty() ) joachim99@77: { joachim99@77: HistoryMap::iterator hMapIt = historyMap.begin(); joachim99@77: if( hMapIt->second.staysInPlace( m_pldC!=0, iD3LHistoryEnd ) ) joachim99@77: historyMap.erase(hMapIt); joachim99@77: else joachim99@77: break; joachim99@77: } joachim99@69: } joachim99@77: else joachim99@69: { joachim99@77: while ( ! hitList.empty() ) joachim99@77: { joachim99@77: HistoryMap::iterator hMapIt = hitList.back(); joachim99@77: if( hMapIt->second.staysInPlace( m_pldC!=0, iD3LHistoryEnd ) ) joachim99@77: hitList.pop_back(); joachim99@77: else joachim99@77: break; joachim99@77: } joachim99@69: } joachim99@77: while (iD3LHistoryOrigEnd != iD3LHistoryEnd) joachim99@77: { joachim99@77: --iD3LHistoryOrigEnd; joachim99@77: --d3lHistoryEndLineIdx; joachim99@77: } joachim99@69: } joachim99@69: joachim99@69: MergeLineList::iterator iMLLStart = splitAtDiff3LineIdx(d3lHistoryBeginLineIdx); joachim99@69: MergeLineList::iterator iMLLEnd = splitAtDiff3LineIdx(d3lHistoryEndLineIdx); joachim99@69: // Now join all MergeLines in the history joachim99@69: MergeLineList::iterator i = iMLLStart; joachim99@69: if ( i != iMLLEnd ) joachim99@69: { joachim99@69: ++i; joachim99@69: while ( i!=iMLLEnd ) joachim99@69: { joachim99@69: iMLLStart->join(*i); joachim99@69: i = m_mergeLineList.erase( i ); joachim99@69: } joachim99@69: } joachim99@69: iMLLStart->mergeEditLineList.clear(); joachim99@69: // Now insert the complete history into the first MergeLine of the history joachim99@69: iMLLStart->mergeEditLineList.push_back( MergeEditLine( iD3LHistoryBegin, m_pldC == 0 ? B : C ) ); joachim99@77: QString lead = calcHistoryLead( iD3LHistoryBegin->getString(A) ); joachim99@69: MergeEditLine mel( m_pDiff3LineList->end() ); joachim99@69: mel.setString( lead ); joachim99@69: iMLLStart->mergeEditLineList.push_back(mel); joachim99@69: joachim99@77: int historyCount = 0; joachim99@69: if ( bHistoryMergeSorting ) joachim99@69: { joachim99@69: // Create a sorted history joachim99@69: HistoryMap::reverse_iterator hmit; joachim99@69: for ( hmit = historyMap.rbegin(); hmit != historyMap.rend(); ++hmit ) joachim99@69: { joachim99@77: if ( historyCount==m_pOptionDialog->m_maxNofHistoryEntries ) joachim99@77: break; joachim99@77: ++historyCount; joachim99@69: HistoryMapEntry& hme = hmit->second; joachim99@69: MergeEditLineList& mell = hme.choice(m_pldC!=0); joachim99@69: if (!mell.empty()) joachim99@69: iMLLStart->mergeEditLineList.splice( iMLLStart->mergeEditLineList.end(), mell, mell.begin(), mell.end() ); joachim99@69: } joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: // Create history in order of appearance joachim99@69: std::list< HistoryMap::iterator >::iterator hlit; joachim99@69: for ( hlit = hitList.begin(); hlit != hitList.end(); ++hlit ) joachim99@69: { joachim99@77: if ( historyCount==m_pOptionDialog->m_maxNofHistoryEntries ) joachim99@77: break; joachim99@77: ++historyCount; joachim99@69: HistoryMapEntry& hme = (*hlit)->second; joachim99@69: MergeEditLineList& mell = hme.choice(m_pldC!=0); joachim99@69: if (!mell.empty()) joachim99@69: iMLLStart->mergeEditLineList.splice( iMLLStart->mergeEditLineList.end(), mell, mell.begin(), mell.end() ); joachim99@69: } joachim99@98: // If the end of start is empty and the first line at the end is empty remove the last line of start joachim99@98: if ( !iMLLStart->mergeEditLineList.empty() && !iMLLEnd->mergeEditLineList.empty() ) joachim99@98: { joachim99@98: QString lastLineOfStart = iMLLStart->mergeEditLineList.back().getString(this); joachim99@98: QString firstLineOfEnd = iMLLEnd->mergeEditLineList.front().getString(this); joachim99@98: if ( lastLineOfStart.mid(lead.length()).trimmed().isEmpty() && firstLineOfEnd.mid(lead.length()).trimmed().isEmpty() ) joachim99@98: iMLLStart->mergeEditLineList.pop_back(); joachim99@98: } joachim99@69: } joachim99@69: setFastSelector( iMLLStart ); joachim99@69: update(); joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: void MergeResultWindow::slotRegExpAutoMerge() joachim99@69: { joachim99@69: if ( m_pOptionDialog->m_autoMergeRegExp.isEmpty() ) joachim99@69: return; joachim99@69: joachim99@70: QRegExp vcsKeywords( m_pOptionDialog->m_autoMergeRegExp ); joachim99@69: MergeLineList::iterator i; joachim99@69: for ( i=m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@69: { joachim99@69: if (i->bConflict ) joachim99@69: { joachim99@69: Diff3LineList::const_iterator id3l = i->id3l; joachim99@69: if ( vcsKeywords.exactMatch( id3l->getString(A) ) && joachim99@69: vcsKeywords.exactMatch( id3l->getString(B) ) && joachim99@69: (m_pldC==0 || vcsKeywords.exactMatch( id3l->getString(C) ))) joachim99@69: { joachim99@69: MergeEditLine& mel = *i->mergeEditLineList.begin(); joachim99@69: mel.setSource( m_pldC==0 ? B : C, false ); joachim99@69: splitAtDiff3LineIdx( i->d3lLineIdx+1 ); joachim99@69: } joachim99@69: } joachim99@69: } joachim99@69: update(); joachim99@69: } joachim99@69: joachim99@69: // This doesn't detect user modifications and should only be called after automatic merge joachim99@69: // This will only do something for three file merge. joachim99@69: // Irrelevant changes are those where all contributions from B are already contained in C. joachim99@69: // Also irrelevant are conflicts automatically solved (automerge regexp and history automerge) joachim99@69: // Precondition: The VCS-keyword would also be C. joachim99@69: bool MergeResultWindow::doRelevantChangesExist() joachim99@69: { joachim99@69: if ( m_pldC==0 || m_mergeLineList.size() <= 1 ) joachim99@69: return true; joachim99@69: joachim99@69: MergeLineList::iterator i; joachim99@69: for ( i=m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@69: { joachim99@69: if ( ( i->bConflict && i->mergeEditLineList.begin()->src()!=C ) joachim99@69: || i->srcSelect == B ) joachim99@69: { joachim99@69: return true; joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: return false; joachim99@69: } joachim99@69: joachim99@69: // Returns the iterator to the MergeLine after the split joachim99@69: MergeResultWindow::MergeLineList::iterator MergeResultWindow::splitAtDiff3LineIdx( int d3lLineIdx ) joachim99@69: { joachim99@69: MergeLineList::iterator i; joachim99@69: for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@69: { joachim99@69: if ( i->d3lLineIdx==d3lLineIdx ) joachim99@69: { joachim99@69: // No split needed, this is the beginning of a MergeLine joachim99@69: return i; joachim99@69: } joachim99@69: else if ( i->d3lLineIdx > d3lLineIdx ) joachim99@69: { joachim99@69: // The split must be in the previous MergeLine joachim99@69: --i; joachim99@69: MergeLine& ml = *i; joachim99@69: MergeLine newML; joachim99@69: ml.split(newML,d3lLineIdx); joachim99@69: ++i; joachim99@69: return m_mergeLineList.insert( i, newML ); joachim99@69: } joachim99@69: } joachim99@69: // The split must be in the previous MergeLine joachim99@69: --i; joachim99@69: MergeLine& ml = *i; joachim99@69: MergeLine newML; joachim99@69: ml.split(newML,d3lLineIdx); joachim99@69: ++i; joachim99@69: return m_mergeLineList.insert( i, newML ); joachim99@69: } joachim99@69: joachim99@69: void MergeResultWindow::slotSplitDiff( int firstD3lLineIdx, int lastD3lLineIdx ) joachim99@69: { joachim99@69: if (lastD3lLineIdx>=0) joachim99@69: splitAtDiff3LineIdx( lastD3lLineIdx + 1 ); joachim99@69: setFastSelector( splitAtDiff3LineIdx(firstD3lLineIdx) ); joachim99@69: } joachim99@69: joachim99@69: void MergeResultWindow::slotJoinDiffs( int firstD3lLineIdx, int lastD3lLineIdx ) joachim99@69: { joachim99@69: MergeLineList::iterator i; joachim99@69: MergeLineList::iterator iMLLStart = m_mergeLineList.end(); joachim99@69: MergeLineList::iterator iMLLEnd = m_mergeLineList.end(); joachim99@69: for ( i=m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i ) joachim99@69: { joachim99@69: MergeLine& ml = *i; joachim99@69: if ( firstD3lLineIdx >= ml.d3lLineIdx && firstD3lLineIdx < ml.d3lLineIdx + ml.srcRangeLength ) joachim99@69: { joachim99@69: iMLLStart = i; joachim99@69: } joachim99@69: if ( lastD3lLineIdx >= ml.d3lLineIdx && lastD3lLineIdx < ml.d3lLineIdx + ml.srcRangeLength ) joachim99@69: { joachim99@69: iMLLEnd = i; joachim99@69: ++iMLLEnd; joachim99@69: break; joachim99@69: } joachim99@69: } joachim99@69: joachim99@69: bool bJoined = false; joachim99@69: for( i=iMLLStart; i!=iMLLEnd && i!=m_mergeLineList.end(); ) joachim99@69: { joachim99@69: if ( i==iMLLStart ) joachim99@69: { joachim99@69: ++i; joachim99@69: } joachim99@69: else joachim99@69: { joachim99@69: iMLLStart->join(*i); joachim99@69: i = m_mergeLineList.erase( i ); joachim99@69: bJoined = true; joachim99@69: } joachim99@69: } joachim99@69: if (bJoined) joachim99@69: { joachim99@69: iMLLStart->mergeEditLineList.clear(); joachim99@69: // Insert a conflict line as placeholder joachim99@69: iMLLStart->mergeEditLineList.push_back( MergeEditLine( iMLLStart->id3l ) ); joachim99@69: } joachim99@69: setFastSelector( iMLLStart ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::myUpdate(int afterMilliSecs) joachim99@8: { joachim99@75: if ( m_delayedDrawTimer ) joachim99@75: killTimer(m_delayedDrawTimer); joachim99@8: m_bMyUpdate = true; joachim99@69: m_delayedDrawTimer = startTimer( afterMilliSecs ); joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::timerEvent(QTimerEvent*) joachim99@8: { joachim99@69: killTimer(m_delayedDrawTimer); joachim99@69: m_delayedDrawTimer = 0; joachim99@8: joachim99@8: if ( m_bMyUpdate ) joachim99@8: { joachim99@69: update(); 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@69: killTimer(m_delayedDrawTimer); joachim99@69: m_delayedDrawTimer = startTimer(50); joachim99@8: } joachim99@8: } joachim99@8: joachim99@68: QString MergeResultWindow::MergeEditLine::getString( const MergeResultWindow* mrw ) joachim99@8: { joachim99@68: if ( isRemoved() ) { return QString(); } joachim99@8: joachim99@8: if ( ! isModified() ) joachim99@8: { joachim99@8: int src = m_src; joachim99@77: if ( src == 0 ) { return QString(); } joachim99@8: const Diff3Line& d3l = *m_id3l; 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@68: return QString(); joachim99@8: } joachim99@8: joachim99@68: return QString( pld->pLine, pld->size ); joachim99@8: } joachim99@8: else joachim99@8: { 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@69: int convertToPosInText( const QString& s, int posOnScreen, int tabSize ) joachim99@8: { joachim99@8: int localPosOnScreen = 0; joachim99@68: int size=s.length(); joachim99@8: for ( int i=0; i=posOnScreen ) joachim99@8: return i; joachim99@8: joachim99@8: // All letters except tabulator have width one. joachim99@69: int letterWidth = s[i]!='\t' ? 1 : tabber( localPosOnScreen, 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@69: int convertToPosOnScreen( const QString& p, int posInText, int tabSize ) 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@68: joachim99@8: if( (srcSelect > 0 || bUserModified ) && !bLineRemoved ) joachim99@8: { joachim99@8: int outPos = 0; joachim99@68: QString s; joachim99@68: int size = str.length(); joachim99@8: for ( int i=0; im_tabSize ); joachim99@8: for( int j=0; jm_tabSize ),m_pOptionDialog->m_tabSize ); joachim99@69: int lastPosInLine = convertToPosOnScreen( str, convertToPosInText( str, m_selection.lastPosInLine(line), m_pOptionDialog->m_tabSize ), m_pOptionDialog->m_tabSize ); joachim99@8: int lengthInLine = max2(0,lastPosInLine - firstPosInLine); joachim99@8: if (lengthInLine>0) 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@68: p.drawText( xOffset, yOffset+fontAscent, s.mid(m_firstColumn), true ); 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@75: width(), fontHeight, palette().highlight() ); joachim99@69: else if ( lengthInLine2>0 ) joachim99@8: p.fillRect( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset, joachim99@75: fontWidth*lengthInLine2, fontHeight, palette().highlight() ); joachim99@75: joachim99@75: p.setPen( palette().highlightedText().color() ); joachim99@8: p.drawText( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset+fontAscent, joachim99@68: s.mid(firstPosInLine2,lengthInLine2), true ); joachim99@8: } joachim99@8: else joachim99@8: { joachim99@8: p.setPen( m_pOptionDialog->m_fgColor ); joachim99@68: p.drawText( xOffset, yOffset+fontAscent, s.mid(m_firstColumn), true ); 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@69: m_cursorXPos = convertToPosOnScreen( str, convertToPosInText( str, m_cursorXPos, m_pOptionDialog->m_tabSize ),m_pOptionDialog->m_tabSize ); joachim99@8: } joachim99@8: joachim99@68: p.drawText( 1, yOffset+fontAscent, srcName, true ); 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@68: if ( bWhiteSpaceConflict ) joachim99@68: p.drawText( xOffset, yOffset+fontAscent, i18n("") ); joachim99@68: else joachim99@68: 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@66: if ( !m_bPaintingAllowed ) joachim99@69: { joachim99@66: m_currentMergeLineIt = m_mergeLineList.end(); joachim99@69: reset(); joachim99@69: } joachim99@80: update(); joachim99@58: } joachim99@58: joachim99@80: void MergeResultWindow::paintEvent( QPaintEvent* ) joachim99@8: { joachim99@80: if (m_pDiff3LineList==0 || !m_bPaintingAllowed) joachim99@80: 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@69: if ( !m_bCursorUpdate ) // Don't redraw everything for blinking cursor? joachim99@8: { joachim99@8: m_selection.bSelectionContainsData = false; joachim99@8: if ( size() != m_pixmap.size() ) joachim99@75: m_pixmap = QPixmap(size()); joachim99@8: joachim99@68: MyPainter p(&m_pixmap, m_pOptionDialog->m_bRightToLeftLanguage, width(), fontWidth); joachim99@8: p.setFont( font() ); joachim99@68: p.QPainter::fillRect( rect(), m_pOptionDialog->m_bgColor ); joachim99@8: joachim99@8: //int visibleLines = height() / fontHeight; 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@68: QString s; joachim99@68: s = mel.getString( this ); joachim99@69: if ( convertToPosOnScreen(s,s.length(),m_pOptionDialog->m_tabSize) >nofColumns) joachim99@68: nofColumns = s.length(); joachim99@8: joachim99@68: writeLine( p, line, s, mel.src(), ml.mergeDetails, rangeMark, joachim99@68: mel.isModified(), mel.isRemoved(), ml.bWhiteSpaceConflict ); 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: p.end(); joachim99@8: } joachim99@8: joachim99@8: QPainter painter(this); joachim99@8: joachim99@75: int topLineYOffset = 0; 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@69: if ( !m_bCursorUpdate ) joachim99@8: painter.drawPixmap(0,0, m_pixmap); joachim99@8: else joachim99@68: { joachim99@80: painter.drawPixmap(0,0, m_pixmap ); // Draw everything. (Internally cursor rect is clipped anyway.) joachim99@80: //if (!m_pOptionDialog->m_bRightToLeftLanguage) joachim99@80: // painter.drawPixmap(xCursor-2, yOffset, m_pixmap, joachim99@80: // xCursor-2, yOffset, 5, fontAscent+2 ); joachim99@80: //else joachim99@80: // painter.drawPixmap(width()-1-4-(xCursor-2), yOffset, m_pixmap, joachim99@80: // width()-1-4-(xCursor-2), yOffset, 5, fontAscent+2 ); joachim99@69: m_bCursorUpdate = false; joachim99@68: } joachim99@69: painter.end(); joachim99@8: joachim99@8: if ( m_bCursorOn && hasFocus() && m_cursorYPos>=m_firstLine ) joachim99@8: { joachim99@68: MyPainter painter(this, m_pOptionDialog->m_bRightToLeftLanguage, width(), fontWidth); joachim99@75: int topLineYOffset = 0; 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@66: joachim99@66: painter.setPen( m_pOptionDialog->m_fgColor ); joachim99@66: 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@66: void MergeResultWindow::updateSourceMask() joachim99@66: { joachim99@66: int srcMask=0; joachim99@66: int enabledMask = 0; joachim99@66: if( !hasFocus() || m_pDiff3LineList==0 || !m_bPaintingAllowed || m_currentMergeLineIt == m_mergeLineList.end() ) joachim99@66: { joachim99@66: srcMask = 0; joachim99@66: enabledMask = 0; joachim99@66: } joachim99@66: else joachim99@66: { joachim99@66: enabledMask = m_pldC==0 ? 3 : 7; joachim99@66: MergeLine& ml = *m_currentMergeLineIt; joachim99@66: joachim99@66: srcMask = 0; joachim99@66: bool bModified = false; joachim99@66: MergeEditLineList::iterator melIt; joachim99@66: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@66: { joachim99@66: MergeEditLine& mel = *melIt; joachim99@66: if ( mel.src()==1 ) srcMask |= 1; joachim99@66: if ( mel.src()==2 ) srcMask |= 2; joachim99@66: if ( mel.src()==3 ) srcMask |= 4; joachim99@66: if ( mel.isModified() || !mel.isEditableText() ) bModified = true; joachim99@66: } joachim99@68: joachim99@66: if ( ml.mergeDetails == eNoChange ) joachim99@69: { joachim99@66: srcMask = 0; joachim99@66: enabledMask = bModified ? 1 : 0; joachim99@66: } joachim99@66: } joachim99@68: joachim99@66: emit sourceMask( srcMask, enabledMask ); joachim99@66: } joachim99@66: joachim99@66: void MergeResultWindow::focusInEvent( QFocusEvent* e ) joachim99@66: { joachim99@66: updateSourceMask(); joachim99@66: QWidget::focusInEvent(e); joachim99@66: } joachim99@66: 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@75: int topLineYOffset = 0; joachim99@8: joachim99@8: int yOffset = topLineYOffset - m_firstLine * fontHeight; joachim99@8: joachim99@58: line = min2( ( y - yOffset ) / fontHeight, m_totalSize-1 ); joachim99@68: if ( ! m_pOptionDialog->m_bRightToLeftLanguage ) joachim99@68: pos = ( x - xOffset ) / fontWidth; joachim99@68: else joachim99@68: pos = ( (width() - 1 - 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@69: bool bLMB = e->button() == Qt::LeftButton; joachim99@69: bool bMMB = e->button() == Qt::MidButton; joachim99@69: bool bRMB = e->button() == Qt::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@75: if ( e->QInputEvent::modifiers() & Qt::ShiftModifier ) 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@66: pasteClipboard( true ); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: void MergeResultWindow::mouseDoubleClickEvent( QMouseEvent* e ) joachim99@8: { joachim99@69: if ( e->button() == Qt::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: MergeLineList::iterator mlIt; joachim99@8: MergeEditLineList::iterator melIt; joachim99@8: calcIteratorFromLineNr( line, mlIt, melIt ); joachim99@68: QString s = melIt->getString( this ); joachim99@8: joachim99@68: if ( !s.isEmpty() ) joachim99@8: { joachim99@8: int pos1, pos2; joachim99@8: joachim99@69: calcTokenPos( s, pos, pos1, pos2, m_pOptionDialog->m_tabSize ); joachim99@8: joachim99@8: resetSelection(); joachim99@69: m_selection.start( line, convertToPosOnScreen( s, pos1, m_pOptionDialog->m_tabSize ) ); joachim99@69: m_selection.end( line, convertToPosOnScreen( s, pos2, m_pOptionDialog->m_tabSize ) ); 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@69: if ( e->button() == Qt::LeftButton ) joachim99@8: { joachim99@75: if (m_delayedDrawTimer) joachim99@75: { joachim99@75: killTimer(m_delayedDrawTimer); joachim99@75: m_delayedDrawTimer = 0; joachim99@75: } 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 fontWidth = fm.width('W'); joachim99@75: int topLineYOffset = 0; joachim99@8: int deltaX=0; joachim99@8: int deltaY=0; joachim99@68: if ( ! m_pOptionDialog->m_bRightToLeftLanguage ) joachim99@68: { joachim99@68: if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1; joachim99@68: if ( e->x() > width() ) deltaX=+1; joachim99@68: } joachim99@68: else joachim99@68: { joachim99@68: if ( e->x() > width()-1-leftInfoWidth*fontWidth ) deltaX=-1; joachim99@68: if ( e->x() < fontWidth ) deltaX=+1; joachim99@68: } 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@69: { joachim99@69: m_bCursorUpdate = true; joachim99@69: joachim99@69: const QFontMetrics& fm = fontMetrics(); joachim99@69: int fontWidth = fm.width("W"); joachim99@75: int topLineYOffset = 0; joachim99@69: int xOffset = fontWidth * leftInfoWidth; joachim99@69: int yOffset = ( m_cursorYPos - m_firstLine ) * fm.height() + topLineYOffset; joachim99@69: int xCursor = ( m_cursorXPos - m_firstColumn ) * fontWidth + xOffset; joachim99@69: joachim99@69: if (!m_pOptionDialog->m_bRightToLeftLanguage) joachim99@69: repaint( xCursor-2, yOffset, 5, fm.ascent()+2 ); joachim99@69: else joachim99@69: repaint( width()-1-4-(xCursor-2), yOffset, 5, fm.ascent()+2 ); joachim99@69: joachim99@69: m_bCursorUpdate=false; joachim99@69: } joachim99@8: joachim99@75: m_cursorTimer.start(500); 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@68: QString str = melIt->getString( this ); joachim99@69: int x = convertToPosInText( str, m_cursorXPos, m_pOptionDialog->m_tabSize ); joachim99@69: joachim99@75: bool bCtrl = ( e->QInputEvent::modifiers() & Qt::ControlModifier ) != 0 ; joachim99@75: bool bShift = ( e->QInputEvent::modifiers() & Qt::ShiftModifier ) != 0 ; joachim99@8: #ifdef _WIN32 joachim99@75: bool bAlt = ( e->QInputEvent::modifiers() & Qt::AltModifier ) != 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@69: case Qt::Key_Escape: break; joachim99@8: //case Key_Tab: break; joachim99@69: case Qt::Key_Backtab: break; joachim99@69: case Qt::Key_Delete: joachim99@8: { joachim99@68: if ( deleteSelection2( str, x, y, mlIt, melIt )) break; joachim99@8: if( !melIt->isEditableText() ) break; joachim99@68: if (x>=(int)str.length()) joachim99@8: { joachim99@58: if ( yisEditableText() ) joachim99@8: { joachim99@68: QString s2 = melIt1->getString( this ); joachim99@68: melIt->setString( str + 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@68: QString s = str.left(x); joachim99@68: s += str.mid( x+1 ); joachim99@8: melIt->setString( s ); joachim99@8: setModified(); joachim99@8: } joachim99@8: break; joachim99@8: } joachim99@69: case Qt::Key_Backspace: joachim99@8: { joachim99@68: if ( deleteSelection2( str, 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: MergeLineList::iterator mlIt1; joachim99@8: MergeEditLineList::iterator melIt1; joachim99@8: calcIteratorFromLineNr( y-1, mlIt1, melIt1 ); joachim99@8: if ( melIt1->isEditableText() ) joachim99@8: { joachim99@68: QString s1 = melIt1->getString( this ); joachim99@68: melIt1->setString( s1 + str ); 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@68: x=str.length(); joachim99@8: } joachim99@8: } joachim99@8: } joachim99@8: else joachim99@8: { joachim99@68: QString s = str.left( x-1 ); joachim99@68: s += str.mid( x ); joachim99@8: --x; joachim99@8: melIt->setString( s ); joachim99@8: setModified(); joachim99@8: } joachim99@8: break; joachim99@8: } joachim99@69: case Qt::Key_Return: joachim99@69: case Qt::Key_Enter: joachim99@8: { joachim99@8: if( !melIt->isEditableText() ) break; joachim99@68: deleteSelection2( str, x, y, mlIt, melIt ); joachim99@8: setModified(); joachim99@68: QString 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@68: const QString s = melIt1->getString(this); joachim99@68: if ( !s.isEmpty() ) { joachim99@70: int i; joachim99@68: for( i=0; imergeEditLineList.begin() ) joachim99@77: --melIt1; joachim99@77: else joachim99@77: { joachim99@77: if ( mlIt1 == m_mergeLineList.begin() ) break; joachim99@8: --mlIt1; joachim99@8: melIt1 = mlIt1->mergeEditLineList.end(); joachim99@8: --melIt1; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@69: MergeEditLine mel(mlIt->id3l); // Associate every mel with an id3l, even if not really valid. joachim99@68: mel.setString( indentation + str.mid(x) ); joachim99@8: joachim99@68: if ( x<(int)str.length() ) // Cut off the old line. joachim99@8: { joachim99@8: // Since ps possibly points into melIt->str, first copy it into a temporary. joachim99@68: QString temp = str.left(x); joachim99@8: melIt->setString( temp ); joachim99@8: } joachim99@8: joachim99@8: ++melIt; joachim99@8: mlIt->mergeEditLineList.insert( melIt, mel ); joachim99@68: x = indentation.length(); joachim99@8: ++y; joachim99@8: break; joachim99@8: } joachim99@69: case Qt::Key_Insert: m_bInsertMode = !m_bInsertMode; break; joachim99@69: case Qt::Key_Pause: break; joachim99@69: case Qt::Key_Print: break; joachim99@69: case Qt::Key_SysReq: break; joachim99@69: case Qt::Key_Home: x=0; if(bCtrl){y=0; } break; // cursor movement joachim99@69: case Qt::Key_End: x=INT_MAX; if(bCtrl){y=INT_MAX;} break; joachim99@69: joachim99@69: case Qt::Key_Left: joachim99@69: case Qt::Key_Right: joachim99@69: if ( (e->key()==Qt::Key_Left) ^ m_pOptionDialog->m_bRightToLeftLanguage ) // operator^: XOR joachim99@8: { joachim99@68: if ( !bCtrl ) joachim99@68: { joachim99@68: --x; joachim99@68: if(x<0 && y>0){--y; x=INT_MAX;} joachim99@68: } joachim99@68: else joachim99@68: { joachim99@68: while( x>0 && (str[x-1]==' ' || str[x-1]=='\t') ) --x; joachim99@68: while( x>0 && (str[x-1]!=' ' && str[x-1]!='\t') ) --x; joachim99@68: } joachim99@8: } joachim99@8: else joachim99@8: { joachim99@68: if ( !bCtrl ) joachim99@68: { joachim99@68: ++x; if(x>(int)str.length() && 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@68: deleteSelection2( str, x, y, mlIt, melIt ); joachim99@8: joachim99@8: setModified(); joachim99@8: // Characters to insert joachim99@68: QString s=str; joachim99@8: if ( t[0]=='\t' && m_pOptionDialog->m_bReplaceTabs ) joachim99@8: { joachim99@69: int spaces = (m_cursorXPos / m_pOptionDialog->m_tabSize + 1)*m_pOptionDialog->m_tabSize - m_cursorXPos; joachim99@8: t.fill( ' ', spaces ); joachim99@8: } joachim99@8: if ( m_bInsertMode ) joachim99@68: s.insert( x, t ); joachim99@8: else joachim99@68: s.replace( x, t.length(), t ); 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@68: str = melIt->getString( this ); joachim99@8: joachim99@68: x = minMaxLimiter( x, 0, (int)str.length() ); 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@69: x=convertToPosInText( str, m_cursorOldXPos, m_pOptionDialog->m_tabSize ); joachim99@69: joachim99@69: int xOnScreen = convertToPosOnScreen( str, x, m_pOptionDialog->m_tabSize ); 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@92: if ( m_cursorXPos>m_nofColumns ) joachim99@92: { joachim99@92: m_nofColumns = m_cursorXPos; joachim99@92: emit resizeSignal(); joachim99@92: } 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@68: const QString str = mel.getString( this ); joachim99@8: joachim99@8: // Consider tabs joachim99@8: joachim99@70: for( int i=0; im_tabSize ); joachim99@8: } joachim99@8: joachim99@8: if( m_selection.within( line, outPos ) ) joachim99@8: { joachim99@68: selectionString += str[i]; joachim99@8: } joachim99@8: joachim99@8: outPos += spaces; joachim99@8: } joachim99@8: } joachim99@8: else if ( mel.isConflict() ) joachim99@8: { joachim99@58: selectionString += i18n(""); joachim99@8: } joachim99@68: 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@68: bool MergeResultWindow::deleteSelection2( QString& s, 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@68: s = melIt->getString( this ); joachim99@69: x = convertToPosInText( s, m_cursorXPos, m_pOptionDialog->m_tabSize ); 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@68: QString 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@68: QString lineString = mel.getString( this ); 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@69: int pos = convertToPosInText( lineString, firstPosInLine, m_pOptionDialog->m_tabSize ); joachim99@68: firstLineString = lineString.left( pos ); joachim99@8: } joachim99@8: joachim99@8: if ( line==lastLine ) joachim99@8: { joachim99@8: // This is the last line in the selection joachim99@69: int pos = convertToPosInText( lineString, lastPosInLine, m_pOptionDialog->m_tabSize ); joachim99@68: firstLineString += lineString.mid( pos ); // rest of line 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@66: void MergeResultWindow::pasteClipboard( bool bFromSelection ) 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@68: QString str = melIt->getString( this ); joachim99@69: int x = convertToPosInText( str, m_cursorXPos, m_pOptionDialog->m_tabSize ); joachim99@8: joachim99@66: if ( !QApplication::clipboard()->supportsSelection() ) joachim99@66: bFromSelection = false; joachim99@8: joachim99@68: QString clipBoard = QApplication::clipboard()->text( bFromSelection ? QClipboard::Selection : QClipboard::Clipboard ); joachim99@68: joachim99@68: QString currentLine = str.left(x); joachim99@68: QString endOfLine = str.mid(x); joachim99@8: int i; joachim99@68: int len = clipBoard.length(); joachim99@68: for( i=0; isetString( currentLine ); joachim99@69: MergeEditLine mel(mlIt->id3l); // Associate every mel with an id3l, even if not really valid. joachim99@69: melIt = mlIt->mergeEditLineList.insert( melItAfter, mel ); 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@69: m_cursorXPos = convertToPosOnScreen( currentLine, x, m_pOptionDialog->m_tabSize ); 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@75: void MergeResultWindow::setModified(bool bModified) joachim99@8: { joachim99@75: if (bModified != m_bModified) joachim99@8: { joachim99@75: m_bModified = bModified; joachim99@75: emit modifiedChanged(m_bModified); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: /// Saves and returns true when successful. joachim99@80: bool MergeResultWindow::saveDocument( const QString& fileName, QTextCodec* pEncoding, e_LineEndStyle eLineEndStyle ) 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@80: if ( eLineEndStyle==eLineEndStyleConflict || eLineEndStyle==eLineEndStyleUndefined ) joachim99@80: { joachim99@80: KMessageBox::error( this, joachim99@80: i18n("There is a line end style conflict. Please choose the line end style manually.\n" joachim99@80: "File not saved.\n"), joachim99@80: i18n("Conflicts Left")); joachim99@80: return false; joachim99@80: } joachim99@80: 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@68: KMessageBox::error( this, file.getStatusText() + i18n("\n\nCreating backup failed. File not saved."), i18n("File Save Error") ); joachim99@8: return false; joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: QByteArray dataArray; joachim99@75: QTextStream textOutStream(&dataArray, QIODevice::WriteOnly); joachim99@91: if ( pEncoding->name()=="UTF-8" ) joachim99@91: textOutStream.setGenerateByteOrderMark( false ); // Shouldn't be necessary. Bug in Qt or docs joachim99@91: else joachim99@91: textOutStream.setGenerateByteOrderMark( true ); // Only for UTF-16 joachim99@75: textOutStream.setCodec( pEncoding ); joachim99@68: joachim99@68: int line = 0; joachim99@68: MergeLineList::iterator mlIt = m_mergeLineList.begin(); joachim99@68: for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) joachim99@8: { joachim99@68: MergeLine& ml = *mlIt; joachim99@68: MergeEditLineList::iterator melIt; joachim99@68: for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) joachim99@8: { joachim99@68: MergeEditLine& mel = *melIt; joachim99@68: joachim99@68: if ( mel.isEditableText() ) joachim99@8: { joachim99@68: QString str = mel.getString( this ); joachim99@8: joachim99@68: if (line>0) // Prepend line feed, but not for first line joachim99@8: { joachim99@80: if ( eLineEndStyle == eLineEndStyleDos ) joachim99@68: { str.prepend("\r\n"); } joachim99@8: else joachim99@68: { str.prepend("\n"); } joachim99@8: } joachim99@8: joachim99@68: textOutStream << str; joachim99@77: ++line; joachim99@8: } joachim99@8: } joachim99@8: } joachim99@75: textOutStream.flush(); joachim99@68: bool bSuccess = file.writeFile( dataArray.data(), dataArray.size() ); 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: joachim99@75: setModified( false ); joachim99@8: update(); joachim99@8: joachim99@8: return true; joachim99@8: } joachim99@8: joachim99@68: QString 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@68: QString s = melIt->getString( this ); joachim99@68: return s; joachim99@8: } joachim99@8: joachim99@68: bool MergeResultWindow::findString( const QString& 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@68: QString line = getString( it ); joachim99@8: if ( !line.isEmpty() ) joachim99@8: { joachim99@75: int pos = line.indexOf( s, startPos, bCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive ); 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@69: if ( lastLine >= getNofLines() ) joachim99@69: { joachim99@69: lastLine = getNofLines()-1; joachim99@69: QString s = getString( lastLine ); joachim99@69: endPos = s.length(); joachim99@69: } joachim99@8: m_selection.reset(); joachim99@69: m_selection.start( firstLine, convertToPosOnScreen( getString(firstLine), startPos, m_pOptionDialog->m_tabSize ) ); joachim99@69: m_selection.end( lastLine, convertToPosOnScreen( getString(lastLine), endPos, m_pOptionDialog->m_tabSize ) ); joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@75: Overview::Overview( OptionDialog* pOptions ) joachim99@75: //: QWidget( pParent, 0, Qt::WNoAutoErase ) joachim99@8: { joachim99@8: m_pDiff3LineList = 0; joachim99@8: m_pOptions = pOptions; joachim99@8: m_bTripleDiff = false; joachim99@66: m_eOverviewMode = eOMNormal; joachim99@66: m_nofLines = 1; joachim99@69: m_bPaintingAllowed = 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@75: m_pixmap = QPixmap( QSize(0,0) ); // make sure that a redraw happens joachim99@8: update(); joachim99@8: } joachim99@8: joachim99@69: void Overview::reset() joachim99@69: { joachim99@69: m_pDiff3LineList = 0; joachim99@69: } joachim99@69: joachim99@51: void Overview::slotRedraw() joachim99@51: { joachim99@75: m_pixmap = QPixmap( 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@66: void Overview::setOverviewMode( e_OverviewMode eOverviewMode ) joachim99@66: { joachim99@66: m_eOverviewMode = eOverviewMode; joachim99@69: slotRedraw(); joachim99@66: } joachim99@66: joachim99@66: Overview::e_OverviewMode Overview::getOverviewMode() joachim99@66: { joachim99@66: return m_eOverviewMode; joachim99@66: } joachim99@66: joachim99@8: void Overview::mousePressEvent( QMouseEvent* e ) joachim99@8: { joachim99@8: int h = height()-1; joachim99@66: int h1 = h * m_pageHeight / max2(1,m_nofLines)+3; joachim99@8: if ( h>0 ) joachim99@66: emit setLine( ( e->y() - h1/2 )*m_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@69: else reset(); joachim99@8: } joachim99@8: } joachim99@8: joachim99@66: void Overview::drawColumn( QPainter& p, e_OverviewMode eOverviewMode, int x, int w, int h, int nofLines ) joachim99@66: { joachim99@69: p.setPen(Qt::black); joachim99@66: p.drawLine( x, 0, x, h ); joachim99@66: joachim99@66: if (nofLines==0) return; joachim99@66: joachim99@66: int line = 0; joachim99@66: int oldY = 0; joachim99@66: int oldConflictY = -1; joachim99@66: int wrapLineIdx=0; joachim99@66: Diff3LineList::const_iterator i; joachim99@66: for( i = m_pDiff3LineList->begin(); i!= m_pDiff3LineList->end(); ) joachim99@66: { joachim99@66: const Diff3Line& d3l = *i; joachim99@66: int y = h * (line+1) / nofLines; joachim99@66: e_MergeDetails md; joachim99@66: bool bConflict; joachim99@66: bool bLineRemoved; joachim99@66: int src; joachim99@66: mergeOneLine( d3l, md, bConflict, bLineRemoved, src, !m_bTripleDiff ); joachim99@66: joachim99@66: QColor c = m_pOptions->m_bgColor; joachim99@66: bool bWhiteSpaceChange = false; joachim99@66: //if( bConflict ) c=m_pOptions->m_colorForConflict; joachim99@66: //else joachim99@66: if ( eOverviewMode==eOMNormal ) joachim99@66: { joachim99@66: switch( md ) joachim99@66: { joachim99@66: case eDefault: joachim99@66: case eNoChange: joachim99@66: c = m_pOptions->m_bgColor; joachim99@66: break; joachim99@66: joachim99@66: case eBAdded: joachim99@66: case eBDeleted: joachim99@66: case eBChanged: joachim99@66: c = bConflict ? m_pOptions->m_colorForConflict : m_pOptions->m_colorB; joachim99@66: bWhiteSpaceChange = d3l.bAEqB || d3l.bWhiteLineA && d3l.bWhiteLineB; joachim99@66: break; joachim99@66: joachim99@66: case eCAdded: joachim99@66: case eCDeleted: joachim99@66: case eCChanged: joachim99@66: bWhiteSpaceChange = d3l.bAEqC || d3l.bWhiteLineA && d3l.bWhiteLineC; joachim99@66: c = bConflict ? m_pOptions->m_colorForConflict : m_pOptions->m_colorC; joachim99@66: break; joachim99@66: joachim99@66: case eBCChanged: // conflict joachim99@66: case eBCChangedAndEqual: // possible conflict joachim99@66: case eBCDeleted: // possible conflict joachim99@66: case eBChanged_CDeleted: // conflict joachim99@66: case eCChanged_BDeleted: // conflict joachim99@66: case eBCAdded: // conflict joachim99@66: case eBCAddedAndEqual: // possible conflict joachim99@66: c=m_pOptions->m_colorForConflict; joachim99@66: break; joachim99@66: default: assert(false); break; joachim99@66: } joachim99@66: } joachim99@66: else if ( eOverviewMode==eOMAvsB ) joachim99@66: { joachim99@66: switch( md ) joachim99@66: { joachim99@66: case eDefault: joachim99@66: case eNoChange: joachim99@66: case eCAdded: joachim99@66: case eCDeleted: joachim99@66: case eCChanged: break; joachim99@66: default: c = m_pOptions->m_colorForConflict; joachim99@66: bWhiteSpaceChange = d3l.bAEqB || d3l.bWhiteLineA && d3l.bWhiteLineB; joachim99@66: break; joachim99@66: } joachim99@66: } joachim99@66: else if ( eOverviewMode==eOMAvsC ) joachim99@66: { joachim99@66: switch( md ) joachim99@66: { joachim99@66: case eDefault: joachim99@66: case eNoChange: joachim99@66: case eBAdded: joachim99@66: case eBDeleted: joachim99@66: case eBChanged: break; joachim99@66: default: c = m_pOptions->m_colorForConflict; joachim99@66: bWhiteSpaceChange = d3l.bAEqC || d3l.bWhiteLineA && d3l.bWhiteLineC; joachim99@69: break; joachim99@66: } joachim99@66: } joachim99@66: else if ( eOverviewMode==eOMBvsC ) joachim99@66: { joachim99@66: switch( md ) joachim99@66: { joachim99@66: case eDefault: joachim99@66: case eNoChange: joachim99@66: case eBCChangedAndEqual: joachim99@66: case eBCDeleted: joachim99@66: case eBCAddedAndEqual: break; joachim99@66: default: c=m_pOptions->m_colorForConflict; joachim99@66: bWhiteSpaceChange = d3l.bBEqC || d3l.bWhiteLineB && d3l.bWhiteLineC; joachim99@66: break; joachim99@66: } joachim99@66: } joachim99@66: joachim99@66: if (!bWhiteSpaceChange || m_pOptions->m_bShowWhiteSpace ) joachim99@66: { joachim99@66: // Make sure that lines with conflict are not overwritten. joachim99@66: if ( c == m_pOptions->m_colorForConflict ) joachim99@66: { joachim99@69: p.fillRect(x+1, oldY, w, max2(1,y-oldY), bWhiteSpaceChange ? QBrush(c,Qt::Dense4Pattern) : QBrush(c) ); joachim99@66: oldConflictY = oldY; joachim99@66: } joachim99@66: else if ( c!=m_pOptions->m_bgColor && oldY>oldConflictY ) joachim99@66: { joachim99@69: p.fillRect(x+1, oldY, w, max2(1,y-oldY), bWhiteSpaceChange ? QBrush(c,Qt::Dense4Pattern) : QBrush(c) ); joachim99@66: } joachim99@66: } joachim99@66: joachim99@66: oldY = y; joachim99@66: joachim99@66: ++line; joachim99@66: if ( m_pOptions->m_bWordWrap ) joachim99@66: { joachim99@66: ++wrapLineIdx; joachim99@66: if(wrapLineIdx>=d3l.linesNeededForDisplay) joachim99@66: { joachim99@66: wrapLineIdx=0; joachim99@66: ++i; joachim99@66: } joachim99@66: } joachim99@66: else joachim99@66: { joachim99@66: ++i; joachim99@66: } joachim99@66: } joachim99@66: } joachim99@66: 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@66: joachim99@8: joachim99@8: if ( m_pixmap.size() != size() ) joachim99@8: { joachim99@66: if ( m_pOptions->m_bWordWrap ) joachim99@66: { joachim99@66: m_nofLines = 0; joachim99@66: Diff3LineList::const_iterator i; joachim99@66: for( i = m_pDiff3LineList->begin(); i!= m_pDiff3LineList->end(); ++i ) joachim99@66: { joachim99@66: m_nofLines += i->linesNeededForDisplay; joachim99@69: } joachim99@66: } joachim99@66: else joachim99@66: { joachim99@66: m_nofLines = m_pDiff3LineList->size(); joachim99@66: } joachim99@66: joachim99@75: m_pixmap = QPixmap( size() ); joachim99@8: joachim99@8: QPainter p(&m_pixmap); joachim99@66: p.fillRect( rect(), m_pOptions->m_bgColor ); joachim99@8: joachim99@66: if ( !m_bTripleDiff || m_eOverviewMode == eOMNormal ) joachim99@8: { joachim99@66: drawColumn( p, eOMNormal, 0, w, h, m_nofLines ); joachim99@8: } joachim99@66: else joachim99@66: { joachim99@66: drawColumn( p, eOMNormal, 0, w/2, h, m_nofLines ); joachim99@66: drawColumn( p, m_eOverviewMode, w/2, w/2, h, m_nofLines ); joachim99@69: } joachim99@8: } joachim99@8: joachim99@8: QPainter painter( this ); joachim99@8: painter.drawPixmap( 0,0, m_pixmap ); joachim99@8: joachim99@66: int y1 = h * m_firstLine / m_nofLines-1; joachim99@66: int h1 = h * m_pageHeight / m_nofLines+3; joachim99@69: painter.setPen(Qt::black); joachim99@8: painter.drawRect( 1, y1, w-1, h1 ); joachim99@8: } joachim99@8: joachim99@75: WindowTitleWidget::WindowTitleWidget(OptionDialog* pOptionDialog) joachim99@75: { joachim99@75: m_pOptionDialog = pOptionDialog; joachim99@75: setAutoFillBackground(true); joachim99@75: joachim99@75: QHBoxLayout* pHLayout = new QHBoxLayout(this); joachim99@75: pHLayout->setMargin(2); joachim99@75: pHLayout->setSpacing(2); joachim99@75: joachim99@75: m_pLabel = new QLabel(i18n("Output")+":"); joachim99@75: pHLayout->addWidget( m_pLabel ); joachim99@75: joachim99@75: m_pFileNameLineEdit = new QLineEdit(); joachim99@75: pHLayout->addWidget( m_pFileNameLineEdit, 6 ); joachim99@75: m_pFileNameLineEdit->installEventFilter( this ); joachim99@75: m_pFileNameLineEdit->setReadOnly( true ); joachim99@75: joachim99@75: //m_pBrowseButton = new QPushButton("..."); joachim99@75: //pHLayout->addWidget( m_pBrowseButton, 0 ); joachim99@75: //connect( m_pBrowseButton, SIGNAL(clicked()), this, SLOT(slotBrowseButtonClicked())); joachim99@75: joachim99@75: m_pModifiedLabel = new QLabel(i18n("[Modified]")); joachim99@75: pHLayout->addWidget( m_pModifiedLabel ); joachim99@75: m_pModifiedLabel->setMinimumSize( m_pModifiedLabel->sizeHint() ); joachim99@75: m_pModifiedLabel->setText(""); joachim99@75: joachim99@75: pHLayout->addStretch(1); joachim99@75: joachim99@75: m_pEncodingLabel = new QLabel(i18n("Encoding for saving")+":"); joachim99@75: pHLayout->addWidget( m_pEncodingLabel ); joachim99@75: joachim99@75: m_pEncodingSelector = new QComboBox(); joachim99@80: m_pEncodingSelector->setSizeAdjustPolicy( QComboBox::AdjustToContents ); joachim99@75: pHLayout->addWidget( m_pEncodingSelector, 2 ); joachim99@75: setEncodings(0,0,0); joachim99@80: joachim99@80: m_pLineEndStyleLabel = new QLabel( i18n("Line end style:") ); joachim99@80: pHLayout->addWidget( m_pLineEndStyleLabel ); joachim99@80: m_pLineEndStyleSelector = new QComboBox(); joachim99@80: m_pLineEndStyleSelector->setSizeAdjustPolicy( QComboBox::AdjustToContents ); joachim99@80: pHLayout->addWidget( m_pLineEndStyleSelector ); joachim99@80: setLineEndStyles(eLineEndStyleUndefined,eLineEndStyleUndefined,eLineEndStyleUndefined); joachim99@75: } joachim99@75: joachim99@75: void WindowTitleWidget::setFileName( const QString& fileName ) joachim99@75: { joachim99@75: m_pFileNameLineEdit->setText( QDir::toNativeSeparators(fileName) ); joachim99@75: } joachim99@75: joachim99@75: QString WindowTitleWidget::getFileName() joachim99@75: { joachim99@75: return m_pFileNameLineEdit->text(); joachim99@75: } joachim99@75: joachim99@80: static QString getLineEndStyleName( e_LineEndStyle eLineEndStyle ) joachim99@80: { joachim99@80: if ( eLineEndStyle == eLineEndStyleDos ) joachim99@80: return "DOS"; joachim99@80: else if ( eLineEndStyle == eLineEndStyleUnix ) joachim99@80: return "Unix"; joachim99@80: return QString(); joachim99@80: } joachim99@80: joachim99@80: void WindowTitleWidget::setLineEndStyles( e_LineEndStyle eLineEndStyleA, e_LineEndStyle eLineEndStyleB, e_LineEndStyle eLineEndStyleC) joachim99@80: { joachim99@80: m_pLineEndStyleSelector->clear(); joachim99@80: QString dosUsers; joachim99@80: if ( eLineEndStyleA == eLineEndStyleDos ) joachim99@80: dosUsers += "A"; joachim99@80: if ( eLineEndStyleB == eLineEndStyleDos ) joachim99@80: dosUsers += (dosUsers.isEmpty() ? "" : ", ") + QString("B"); joachim99@80: if ( eLineEndStyleC == eLineEndStyleDos ) joachim99@80: dosUsers += (dosUsers.isEmpty() ? "" : ", ") + QString("C"); joachim99@80: QString unxUsers; joachim99@80: if ( eLineEndStyleA == eLineEndStyleUnix ) joachim99@80: unxUsers += "A"; joachim99@80: if ( eLineEndStyleB == eLineEndStyleUnix ) joachim99@80: unxUsers += (unxUsers.isEmpty() ? "" : ", ") + QString("B"); joachim99@80: if ( eLineEndStyleC == eLineEndStyleUnix ) joachim99@80: unxUsers += (unxUsers.isEmpty() ? "" : ", ") + QString("C"); joachim99@80: joachim99@80: m_pLineEndStyleSelector->addItem( i18n("Unix") + (unxUsers.isEmpty() ? "" : " (" + unxUsers + ")" ) ); joachim99@80: m_pLineEndStyleSelector->addItem( i18n("DOS") + (dosUsers.isEmpty() ? "" : " (" + dosUsers + ")" ) ); joachim99@80: joachim99@80: e_LineEndStyle autoChoice = (e_LineEndStyle)m_pOptionDialog->m_lineEndStyle; joachim99@80: joachim99@80: if ( m_pOptionDialog->m_lineEndStyle == eLineEndStyleAutoDetect ) joachim99@80: { joachim99@80: if ( eLineEndStyleA != eLineEndStyleUndefined && eLineEndStyleB != eLineEndStyleUndefined && eLineEndStyleC != eLineEndStyleUndefined ) joachim99@80: { joachim99@80: if ( eLineEndStyleA == eLineEndStyleB ) joachim99@80: autoChoice = eLineEndStyleC; joachim99@80: else if ( eLineEndStyleA == eLineEndStyleC ) joachim99@80: autoChoice = eLineEndStyleB; joachim99@80: else joachim99@80: autoChoice = eLineEndStyleConflict; //conflict (not likely while only two values exist) joachim99@80: } joachim99@80: else joachim99@80: { joachim99@80: e_LineEndStyle c1, c2; joachim99@80: if ( eLineEndStyleA == eLineEndStyleUndefined ) { c1 = eLineEndStyleB; c2 = eLineEndStyleC; } joachim99@80: else if( eLineEndStyleB == eLineEndStyleUndefined ) { c1 = eLineEndStyleA; c2 = eLineEndStyleC; } joachim99@80: else /*if( eLineEndStyleC == eLineEndStyleUndefined )*/ { c1 = eLineEndStyleA; c2 = eLineEndStyleB; } joachim99@80: if ( c1 == c2 && c1!=eLineEndStyleUndefined ) joachim99@80: autoChoice = c1; joachim99@80: else joachim99@80: autoChoice = eLineEndStyleConflict; joachim99@80: } joachim99@80: } joachim99@80: joachim99@80: if ( autoChoice == eLineEndStyleUnix ) joachim99@80: m_pLineEndStyleSelector->setCurrentIndex(0); joachim99@80: else if ( autoChoice == eLineEndStyleDos ) joachim99@80: m_pLineEndStyleSelector->setCurrentIndex(1); joachim99@80: else if ( autoChoice == eLineEndStyleConflict ) joachim99@80: { joachim99@80: m_pLineEndStyleSelector->addItem( i18n("Conflict") ); joachim99@80: m_pLineEndStyleSelector->setCurrentIndex(2); joachim99@80: } joachim99@80: } joachim99@80: joachim99@80: e_LineEndStyle WindowTitleWidget::getLineEndStyle( ) joachim99@80: { joachim99@80: joachim99@80: int current = m_pLineEndStyleSelector->currentIndex(); joachim99@80: if (current == 0) joachim99@80: return eLineEndStyleUnix; joachim99@80: else if (current == 1) joachim99@80: return eLineEndStyleDos; joachim99@80: else joachim99@80: return eLineEndStyleConflict; joachim99@80: } joachim99@80: joachim99@75: void WindowTitleWidget::setEncodings( QTextCodec* pCodecForA, QTextCodec* pCodecForB, QTextCodec* pCodecForC ) joachim99@75: { joachim99@75: m_pEncodingSelector->clear(); joachim99@75: joachim99@75: // First sort codec names: joachim99@75: std::map names; joachim99@75: QList mibs = QTextCodec::availableMibs(); joachim99@75: foreach(int i, mibs) joachim99@75: { joachim99@75: QTextCodec* c = QTextCodec::codecForMib(i); joachim99@75: if ( c!=0 ) joachim99@75: names[QString(c->name())]=c; joachim99@75: } joachim99@75: joachim99@75: if ( pCodecForA ) joachim99@75: m_pEncodingSelector->addItem( i18n("Codec from") + " A: " + pCodecForA->name(), QVariant::fromValue((void*)pCodecForA) ); joachim99@75: if ( pCodecForB ) joachim99@75: m_pEncodingSelector->addItem( i18n("Codec from") + " B: " + pCodecForB->name(), QVariant::fromValue((void*)pCodecForB) ); joachim99@75: if ( pCodecForC ) joachim99@75: m_pEncodingSelector->addItem( i18n("Codec from") + " C: " + pCodecForC->name(), QVariant::fromValue((void*)pCodecForC) ); joachim99@75: joachim99@75: std::map::iterator it; joachim99@75: for(it=names.begin();it!=names.end();++it) joachim99@75: { joachim99@75: m_pEncodingSelector->addItem( it->first, QVariant::fromValue((void*)it->second) ); joachim99@75: } joachim99@75: m_pEncodingSelector->setMinimumSize( m_pEncodingSelector->sizeHint() ); joachim99@75: joachim99@75: if ( pCodecForC && pCodecForB && pCodecForA ) joachim99@75: { joachim99@75: if ( pCodecForA == pCodecForB ) joachim99@75: m_pEncodingSelector->setCurrentIndex( 2 ); // C joachim99@75: else if ( pCodecForA == pCodecForC ) joachim99@75: m_pEncodingSelector->setCurrentIndex( 1 ); // B joachim99@75: else joachim99@75: m_pEncodingSelector->setCurrentIndex( 2 ); // C joachim99@75: } joachim99@75: else if ( pCodecForA && pCodecForB ) joachim99@75: m_pEncodingSelector->setCurrentIndex( 1 ); // B joachim99@75: else joachim99@75: m_pEncodingSelector->setCurrentIndex( 0 ); joachim99@75: } joachim99@75: joachim99@75: QTextCodec* WindowTitleWidget::getEncoding() joachim99@75: { joachim99@75: return (QTextCodec*)m_pEncodingSelector->itemData( m_pEncodingSelector->currentIndex() ).value(); joachim99@75: } joachim99@75: joachim99@75: void WindowTitleWidget::setEncoding(QTextCodec* pEncoding) joachim99@75: { joachim99@75: int idx = m_pEncodingSelector->findText( pEncoding->name() ); joachim99@75: if (idx>=0) joachim99@75: m_pEncodingSelector->setCurrentIndex( idx ); joachim99@75: } joachim99@75: joachim99@75: //void WindowTitleWidget::slotBrowseButtonClicked() joachim99@75: //{ joachim99@75: // QString current = m_pFileNameLineEdit->text(); joachim99@75: // joachim99@80: // KUrl newURL = KFileDialog::getSaveUrl( current, 0, this, i18n("Select file (not saving yet)")); joachim99@75: // if ( !newURL.isEmpty() ) joachim99@75: // { joachim99@75: // m_pFileNameLineEdit->setText( newURL.url() ); joachim99@75: // } joachim99@75: //} joachim99@75: joachim99@75: void WindowTitleWidget::slotSetModified( bool bModified ) joachim99@75: { joachim99@75: m_pModifiedLabel->setText( bModified ? i18n("[Modified]") : "" ); joachim99@75: } joachim99@75: joachim99@75: bool WindowTitleWidget::eventFilter( QObject* o, QEvent* e ) joachim99@75: { joachim99@75: if ( e->type()==QEvent::FocusIn || e->type()==QEvent::FocusOut ) joachim99@75: { joachim99@75: QPalette p = m_pLabel->palette(); joachim99@75: joachim99@75: QColor c1 = m_pOptionDialog->m_fgColor; joachim99@75: QColor c2 = Qt::lightGray; joachim99@75: if ( e->type()==QEvent::FocusOut ) joachim99@75: c2 = m_pOptionDialog->m_bgColor; joachim99@75: joachim99@75: p.setColor(QPalette::Window, c2); joachim99@75: setPalette( p ); joachim99@75: joachim99@75: p.setColor(QPalette::WindowText, c1); joachim99@75: m_pLabel->setPalette( p ); joachim99@75: m_pEncodingLabel->setPalette( p ); joachim99@75: m_pEncodingSelector->setPalette( p ); joachim99@75: } joachim99@75: if (o == m_pFileNameLineEdit && e->type()==QEvent::Drop) joachim99@75: { joachim99@75: QDropEvent* d = static_cast(e); joachim99@75: joachim99@75: if ( d->mimeData()->hasUrls() ) joachim99@75: { joachim99@75: QList lst = d->mimeData()->urls(); joachim99@75: joachim99@75: if ( lst.count() > 0 ) joachim99@75: { joachim99@75: static_cast(o)->setText( lst[0].toString() ); joachim99@75: static_cast(o)->setFocus(); joachim99@75: return true; joachim99@75: } joachim99@75: } joachim99@75: } joachim99@75: return false; joachim99@75: } joachim99@8: joachim99@70: //#include "mergeresultwindow.moc"