OSDN Git Service

Add "Next Conflict", "Previous Conflict" and "Auto Merge" menu items
authorsdottaka <none@none>
Sun, 12 Jan 2014 03:10:51 +0000 (12:10 +0900)
committersdottaka <none@none>
Sun, 12 Jan 2014 03:10:51 +0000 (12:10 +0900)
--HG--
branch : stable

14 files changed:
Src/DiffList.cpp
Src/DiffList.h
Src/MainFrm.cpp
Src/Merge.rc
Src/Merge2.rc
Src/MergeDoc.cpp
Src/MergeDoc.h
Src/MergeEditView.cpp
Src/MergeEditView.h
Src/res/ToolbarDisabled.bmp
Src/res/ToolbarDisabled32.bmp
Src/res/ToolbarEnabled.bmp
Src/res/ToolbarEnabled32.bmp
Src/resource.h

index dbf6b50..d4baef3 100644 (file)
@@ -65,12 +65,14 @@ DiffList::DiffList()
 , m_firstSignificantLeftOnly(-1)
 , m_firstSignificantMiddleOnly(-1)
 , m_firstSignificantRightOnly(-1)
+, m_firstSignificantConflict(-1)
 , m_lastSignificantLeftMiddle(-1)
 , m_lastSignificantLeftRight(-1)
 , m_lastSignificantMiddleRight(-1)
 , m_lastSignificantLeftOnly(-1)
 , m_lastSignificantMiddleOnly(-1)
 , m_lastSignificantRightOnly(-1)
+, m_lastSignificantConflict(-1)
 {
        m_diffs.reserve(64); // Reserve some initial space to avoid allocations.
 }
@@ -89,12 +91,14 @@ void DiffList::Clear()
        m_firstSignificantLeftOnly = -1;
        m_firstSignificantMiddleOnly = -1;
        m_firstSignificantRightOnly = -1;
+       m_firstSignificantConflict = -1;
        m_lastSignificantLeftMiddle = -1;
        m_lastSignificantLeftRight = -1;
        m_lastSignificantMiddleRight = -1;
        m_lastSignificantLeftOnly = -1;
        m_lastSignificantMiddleOnly = -1;
        m_lastSignificantRightOnly = -1;
+       m_lastSignificantConflict = -1;
 }
 
 /**
@@ -444,9 +448,11 @@ void DiffList::ConstructSignificantChain()
        m_firstSignificantLeftMiddle = -1;
        m_firstSignificantLeftRight = -1;
        m_firstSignificantMiddleRight = -1;
+       m_firstSignificantConflict = -1;
        m_lastSignificantLeftMiddle = -1;
        m_lastSignificantLeftRight = -1;
        m_lastSignificantMiddleRight = -1;
+       m_lastSignificantConflict = -1;
        int prev = -1;
        const int size = (int) m_diffs.size();
 
@@ -503,6 +509,12 @@ void DiffList::ConstructSignificantChain()
                                        m_firstSignificantRightOnly = i;
                                m_lastSignificantRightOnly = i;
                        }
+                       if (m_diffs[i].op == OP_DIFF)
+                       {
+                               if (m_firstSignificantConflict == -1)
+                                       m_firstSignificantConflict = i;
+                               m_lastSignificantConflict = i;
+                       }
                }
        }
 }
@@ -604,6 +616,10 @@ int DiffList::PrevSignificant3wayDiffFromLine(unsigned nLine, int nDiffType) con
                        if (dfi->op == OP_3RDONLY && dfi->dend[0] <= nLine)
                                return i;
                        break;
+               case THREEWAYDIFFTYPE_CONFLICT:
+                       if (dfi->op == OP_DIFF && dfi->dend[0] <= nLine)
+                               return i;
+                       break;
                }
        }
        return -1;
@@ -647,6 +663,10 @@ int DiffList::NextSignificant3wayDiffFromLine(unsigned nLine, int nDiffType) con
                        if (dfi->op == OP_3RDONLY && dfi->dbegin[0] >= nLine)
                                return i;
                        break;
+               case THREEWAYDIFFTYPE_CONFLICT:
+                       if (dfi->op == OP_DIFF && dfi->dbegin[0] >= nLine)
+                               return i;
+                       break;
                }
        }
        return -1;
@@ -672,6 +692,8 @@ int DiffList::FirstSignificant3wayDiff(int nDiffType) const
                return m_firstSignificantLeftOnly;
        case THREEWAYDIFFTYPE_RIGHTONLY:
                return m_firstSignificantRightOnly;
+       case THREEWAYDIFFTYPE_CONFLICT:
+               return m_firstSignificantConflict;
        }
        return -1;
 }
@@ -712,6 +734,10 @@ int DiffList::NextSignificant3wayDiff(int nDiff, int nDiffType) const
                        if (m_diffs[nDiff].op == OP_3RDONLY)
                                return nDiff;
                        break;
+               case THREEWAYDIFFTYPE_CONFLICT:
+                       if (m_diffs[nDiff].op == OP_DIFF)
+                               return nDiff;
+                       break;
                }
        }
        return -1;
@@ -753,6 +779,10 @@ int DiffList::PrevSignificant3wayDiff(int nDiff, int nDiffType) const
                        if (m_diffs[nDiff].op == OP_3RDONLY)
                                return nDiff;
                        break;
+               case THREEWAYDIFFTYPE_CONFLICT:
+                       if (m_diffs[nDiff].op == OP_DIFF)
+                               return nDiff;
+                       break;
                }
        }
        return -1;
@@ -778,6 +808,8 @@ int DiffList::LastSignificant3wayDiff(int nDiffType) const
                return m_lastSignificantLeftOnly;
        case THREEWAYDIFFTYPE_RIGHTONLY:
                return m_lastSignificantRightOnly;
+       case THREEWAYDIFFTYPE_CONFLICT:
+               return m_lastSignificantRightOnly;
        }
        return -1;
 }
@@ -808,6 +840,9 @@ const DIFFRANGE * DiffList::FirstSignificant3wayDiffRange(int nDiffType) const
        case THREEWAYDIFFTYPE_RIGHTONLY:
                if (m_firstSignificantRightOnly == -1) return NULL;
                return DiffRangeAt(m_firstSignificantRightOnly);
+       case THREEWAYDIFFTYPE_CONFLICT:
+               if (m_firstSignificantConflict == -1) return NULL;
+               return DiffRangeAt(m_firstSignificantConflict);
        }
        return NULL;
 }
@@ -838,6 +873,9 @@ const DIFFRANGE * DiffList::LastSignificant3wayDiffRange(int nDiffType) const
        case THREEWAYDIFFTYPE_RIGHTONLY:
                if (m_lastSignificantRightOnly == -1) return NULL;
                return DiffRangeAt(m_lastSignificantRightOnly);
+       case THREEWAYDIFFTYPE_CONFLICT:
+               if (m_lastSignificantConflict == -1) return NULL;
+               return DiffRangeAt(m_lastSignificantConflict);
        }
        return NULL;
 }
@@ -909,3 +947,22 @@ void DiffList::AppendDiffList(const DiffList& list, int offset[], int doffset[])
                AddDiff(dr);
        }
 }
+
+int DiffList::GetMergeableSrcIndex(int nDiff, int nDestIndex) const
+{
+       const DIFFRANGE *pdr = DiffRangeAt(nDiff);
+       switch (nDestIndex)
+       {
+       case 0:
+       case 2:
+               if (pdr->op == OP_2NDONLY)
+                       return 1;
+               return -1;
+       case 1:
+               if (pdr->op == OP_1STONLY)
+                       return 0;
+               else if (pdr->op == OP_3RDONLY)
+                       return 2;
+               return -1;
+       }
+}
\ No newline at end of file
index ddc0522..7782cf4 100644 (file)
@@ -51,6 +51,7 @@ enum
        THREEWAYDIFFTYPE_LEFTONLY,
        THREEWAYDIFFTYPE_MIDDLEONLY,
        THREEWAYDIFFTYPE_RIGHTONLY,
+       THREEWAYDIFFTYPE_CONFLICT,
 };
 
 /**
@@ -164,6 +165,7 @@ public:
        int LastSignificant3wayDiff(int nDiffType) const;
        const DIFFRANGE * FirstSignificant3wayDiffRange(int nDiffType) const;
        const DIFFRANGE * LastSignificant3wayDiffRange(int nDiffType) const;
+       int GetMergeableSrcIndex(int nDiff, int nDestIndex) const;
 
        const DIFFRANGE * DiffRangeAt(int nDiff) const;
 
@@ -185,12 +187,14 @@ private:
        int m_firstSignificantLeftOnly;
        int m_firstSignificantMiddleOnly;
        int m_firstSignificantRightOnly;
+       int m_firstSignificantConflict;
        int m_lastSignificantLeftMiddle;
        int m_lastSignificantLeftRight;
        int m_lastSignificantMiddleRight;
        int m_lastSignificantLeftOnly;
        int m_lastSignificantMiddleOnly;
        int m_lastSignificantRightOnly;
+       int m_lastSignificantConflict;
 };
 
 #endif // _DIFFLIST_H_
index be65a3b..252f5e7 100644 (file)
@@ -3066,7 +3066,7 @@ static void LoadHiColImageList(UINT nIDResource, int nWidth, int nHeight, int nC
 static void LoadToolbarImageList(CMainFrame::TOOLBAR_SIZE size, UINT nIDResource,
                CImageList& ImgList)
 {
-       const int ImageCount = 19;
+       const int ImageCount = 22;
        int imageWidth = 0;
        int imageHeight = 0;
 
index e4529aa..cd31756 100644 (file)
@@ -446,6 +446,9 @@ BEGIN
         MENUITEM "&Next Difference\tAlt+Down",  ID_NEXTDIFF
         MENUITEM "&Previous Difference\tAlt+Up", ID_PREVDIFF
         MENUITEM SEPARATOR
+        MENUITEM "Ne&xt Conflict\tAlt+Shift+Down",   ID_NEXTCONFLICT
+        MENUITEM "Pre&vious Conflict\tAlt+Shift+Up", ID_PREVCONFLICT
+        MENUITEM SEPARATOR
        POPUP "A&dvanced"
        BEGIN
         MENUITEM "Copy &Left to Middle\tAlt+4",              ID_L2M
@@ -483,6 +486,8 @@ BEGIN
         MENUITEM "Copy &All to Right",          ID_ALL_RIGHT
         MENUITEM "Cop&y All to Left",           ID_ALL_LEFT
         MENUITEM SEPARATOR
+        MENUITEM "A&uto Merge\tAlt+Ctrl+M",     ID_AUTO_MERGE
+        MENUITEM SEPARATOR
         MENUITEM "Add &Synchronization Point\tAlt+S",  ID_ADD_SYNCPOINT
         MENUITEM "Clear Sync&hronization Points", ID_CLEAR_SYNCPOINTS
     END
@@ -669,6 +674,7 @@ BEGIN
     "G",            ID_EDIT_WMGOTO,         VIRTKEY, CONTROL, NOINVERT
     "H",            ID_EDIT_REPLACE,        VIRTKEY, CONTROL, NOINVERT
     "J",            ID_FILE_OPENPROJECT,    VIRTKEY, CONTROL, NOINVERT
+    "M",            ID_AUTO_MERGE,          VIRTKEY, ALT, CONTROL, NOINVERT
     "N",            ID_FILE_NEW,            VIRTKEY, CONTROL, NOINVERT
     "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL, NOINVERT
     "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL, NOINVERT
@@ -685,8 +691,11 @@ BEGIN
     VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT, NOINVERT
     VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT, NOINVERT
     VK_DOWN,        ID_NEXTDIFF,            VIRTKEY, ALT, NOINVERT
+    VK_DOWN,        ID_NEXTCONFLICT,        VIRTKEY, ALT, SHIFT, NOINVERT
     VK_F8,          ID_NEXTDIFF,            VIRTKEY, NOINVERT
+    VK_F8,          ID_NEXTCONFLICT,        VIRTKEY, SHIFT, NOINVERT
     VK_F7,          ID_PREVDIFF,            VIRTKEY, NOINVERT
+    VK_F7,          ID_PREVCONFLICT,        VIRTKEY, SHIFT, NOINVERT
     VK_END,         ID_LASTDIFF,            VIRTKEY, ALT, NOINVERT
     VK_F2,          ID_DIR_ITEM_RENAME,     VIRTKEY, NOINVERT
     VK_F3,          ID_EDIT_REPEAT,         VIRTKEY, SHIFT, NOINVERT
@@ -708,6 +717,7 @@ BEGIN
     VK_RIGHT,       ID_L2R,                 VIRTKEY, ALT, NOINVERT
     VK_RIGHT,       ID_L2RNEXT,             VIRTKEY, CONTROL, ALT, NOINVERT
     VK_UP,          ID_PREVDIFF,            VIRTKEY, ALT, NOINVERT
+    VK_UP,          ID_PREVCONFLICT,        VIRTKEY, ALT, SHIFT, NOINVERT
     VK_ADD,         ID_VIEW_ZOOMIN,         VIRTKEY, CONTROL, NOINVERT
     VK_SUBTRACT,    ID_VIEW_ZOOMOUT,        VIRTKEY, CONTROL, NOINVERT
     VK_MULTIPLY,    ID_VIEW_ZOOMNORMAL,     VIRTKEY, CONTROL, NOINVERT
@@ -2235,6 +2245,7 @@ BEGIN
     IDS_STATUS_CREATEREPORT "Creating the report..."
     IDS_STATUS_UNDO         "Undoing the last operation..."
     IDS_STATUS_REDO         "Redoing the previous operation..."
+    IDS_STATUS_AUTOMERGE    "Doing Auto Merge..."
 END
 
 // STATUS BAR : OTHER PANES (MOSTLY FOR EDITOR)
@@ -2637,6 +2648,13 @@ BEGIN
     IDS_MERGE_MODE          "You are now entering Merge Mode. If you want to turn off Merge Mode, press F9 key"
 END
 
+
+// EDITOR : AUTO MERGE
+STRINGTABLE
+BEGIN
+    IDS_AUTO_MERGE          "The number of automatically merged changes: %1\nThe number of unresolved conflicts: %2"
+END
+
 // FILE COMPARE: PANE CAPTIONS
 STRINGTABLE
 BEGIN
@@ -2813,6 +2831,8 @@ STRINGTABLE
 BEGIN
     ID_PREVDIFF             "Scroll to the previous difference\nPrevious Difference (Alt+Up)"
     ID_NEXTDIFF             "Scroll to the next difference\nNext Difference (Alt+Down)"
+    ID_PREVCONFLICT         "Scroll to the previous conflict\nPrevious Conflict (Alt+Shift+Up)"
+    ID_NEXTCONFLICT         "Scroll to the next conflict\nNext Conflict (Alt+Shift+Down)"
     ID_PREVDIFFLM           "Scroll to the previous difference between left and middle\nPrevious Difference Between Left And Middle(Alt+Shift+1)"
     ID_NEXTDIFFLM           "Scroll to the next difference between left and middle\nNext Difference Between Left And Middle(Alt+1)"
     ID_PREVDIFFLR           "Scroll to the previous difference between left and right\nPrevious Difference Between Left And Middle(Alt+Shift+2)"
@@ -2838,6 +2858,7 @@ BEGIN
     ID_MERGE_COMPARE        "Compare selected item (compare first item if multiple items selected)"
     ID_ADD_SYNCPOINT        "Add a manual point for synchronization of changes between files"
     ID_CLEAR_SYNCPOINTS     "Clear manual change synchronization points "
+    ID_AUTO_MERGE           "Automatically merge changes\nAuto Merge (Ctrl+Alt+M)"
 END
 
 // TOOLS MENU
index 3f4eff4..85ee4e6 100644 (file)
@@ -76,6 +76,9 @@ BEGIN
     BUTTON      ID_NEXTDIFF
     BUTTON      ID_PREVDIFF
     SEPARATOR
+    BUTTON      ID_NEXTCONFLICT
+    BUTTON      ID_PREVCONFLICT
+    SEPARATOR
     BUTTON      ID_FIRSTDIFF
     BUTTON      ID_CURDIFF
     BUTTON      ID_LASTDIFF
@@ -91,6 +94,8 @@ BEGIN
     BUTTON      ID_ALL_RIGHT
     BUTTON      ID_ALL_LEFT
     SEPARATOR
+    BUTTON      ID_AUTO_MERGE
+    SEPARATOR
     BUTTON      ID_REFRESH
 END
 
index 6b5fb37..5a6ae9a 100644 (file)
@@ -138,6 +138,7 @@ CMergeDoc::CMergeDoc()
 , m_pInfoUnpacker(new PackingInfo)
 , m_pEncodingErrorBar(NULL)
 , m_bHasSyncPoints(false)
+, m_bAutoMerged(false)
 {
        DIFFOPTIONS options = {0};
 
@@ -925,6 +926,76 @@ void CMergeDoc::CopyMultipleList(int srcPane, int dstPane, int firstDiff, int la
 }
 
 /**
+ * @brief Do auto-merge.
+ * @param [in] dstPane Destination side
+ */
+void CMergeDoc::DoAutoMerge(int dstPane)
+{
+       const int lastDiff = m_diffList.GetSize() - 1;
+       const int firstDiff = 0;
+       bool bGroupWithPrevious = false;
+       int autoMergedCount = 0;
+       int unresolvedConflictCount = 0;
+
+       RescanSuppress suppressRescan(*this);
+
+       // Note we don't care about m_nDiffs count to become zero,
+       // because we don't rescan() so it does not change
+
+       SetCurrentDiff(lastDiff);
+
+       SetEditedAfterRescan(dstPane);
+
+       CPoint currentPosDst = m_pView[dstPane]->GetCursorPos();
+       currentPosDst.x = 0;
+
+       // copy from bottom up is more efficient
+       for (int i = lastDiff; i >= firstDiff; --i)
+       {
+               const DIFFRANGE *pdi = m_diffList.DiffRangeAt(i);
+               const int srcPane = m_diffList.GetMergeableSrcIndex(i, dstPane);
+               if (srcPane != -1)
+               {
+                       SetCurrentDiff(i);
+                       if (currentPosDst.y > pdi->dend[dstPane])
+                       {
+                               if (pdi->blank[dstPane] >= 0)
+                                       currentPosDst.y -= pdi->dend[dstPane] - pdi->blank[dstPane] + 1;
+                               else if (pdi->blank[srcPane] >= 0)
+                                       currentPosDst.y -= pdi->dend[dstPane] - pdi->blank[srcPane] + 1;
+                       }                       
+                       // Group merge with previous (merge undo data to one action)
+                       if (!ListCopy(srcPane, dstPane, -1, bGroupWithPrevious, false))
+                               break; // sync failure
+                       if (!bGroupWithPrevious)
+                               bGroupWithPrevious = true;
+                       ++autoMergedCount;
+               }
+               if (pdi->op == OP_DIFF)
+                       ++unresolvedConflictCount;
+       }
+
+       m_pView[dstPane]->SetCursorPos(currentPosDst);
+       m_pView[dstPane]->SetNewSelection(currentPosDst, currentPosDst, false);
+       m_pView[dstPane]->SetNewAnchor(currentPosDst);
+       m_pDetailView[dstPane]->SetCursorPos(currentPosDst);
+       m_pDetailView[dstPane]->SetNewSelection(currentPosDst, currentPosDst, false);
+       m_pDetailView[dstPane]->SetNewAnchor(currentPosDst);
+
+       suppressRescan.Clear(); // done suppress Rescan
+       FlushAndRescan();
+
+       if (autoMergedCount > 0)
+               m_bAutoMerged = true;
+
+       AfxMessageBox(
+               LangFormatString2(IDS_AUTO_MERGE, 
+                       string_format(_T("%d"), autoMergedCount).c_str(),
+                       string_format(_T("%d"), unresolvedConflictCount).c_str()).c_str(),
+               MB_ICONINFORMATION|MB_DONT_DISPLAY_AGAIN);
+}
+
+/**
  * @brief Sanity check difference.
  *
  * Checks that lines in difference are inside difference in both files.
index 11d2b66..1834db7 100644 (file)
@@ -207,6 +207,7 @@ public:
        bool Undo();
        void CopyAllList(int srcPane, int dstPane);
        void CopyMultipleList(int srcPane, int dstPane, int firstDiff, int lastDiff);
+       void DoAutoMerge(int dstPane);
        bool SanityCheckDiff(DIFFRANGE dr) const;
        bool ListCopy(int srcPane, int dstPane, int nDiff = -1, bool bGroupWithPrevious = false, bool bUpdateView = true);
        bool TrySaveAs(String& strPath, int &nLastErrorCode, String & sError,
@@ -284,6 +285,22 @@ public:
        bool IsMixedEOL(int nBuffer) const;
        bool OpenWithUnpackerDialog();
        bool GenerateReport(LPCTSTR szFileName);
+       void SetAutoMerged(bool bAutoMerged) { m_bAutoMerged = bAutoMerged; }
+       bool GetAutoMerged() const { return m_bAutoMerged; };
+       bool IsModified() const
+       {
+               for (int nBuffer = 0; nBuffer < m_nBuffers; ++nBuffer)
+                       if (m_ptBuf[nBuffer]->IsModified())
+                               return true;
+               return false;
+       }
+       bool CanUndo() const
+       {
+               for (int nBuffer = 0; nBuffer < m_nBuffers; ++nBuffer)
+                       if (m_ptBuf[nBuffer]->CanUndo())
+                               return true;
+               return false;
+       }
 
 // implementation methods
 private:
@@ -313,6 +330,7 @@ protected:
        bool m_bMixedEol; /**< Does this document have mixed EOL style? */
        CEncodingErrorBar *m_pEncodingErrorBar;
        bool m_bHasSyncPoints;
+       bool m_bAutoMerged;
 // friend access
        friend class RescanSuppress;
 
index 9b80b35..a9315ec 100644 (file)
@@ -106,6 +106,10 @@ BEGIN_MESSAGE_MAP(CMergeEditView, CCrystalEditViewEx)
        ON_UPDATE_COMMAND_UI(ID_NEXTDIFF, OnUpdateNextdiff)
        ON_COMMAND(ID_PREVDIFF, OnPrevdiff)
        ON_UPDATE_COMMAND_UI(ID_PREVDIFF, OnUpdatePrevdiff)
+       ON_COMMAND(ID_NEXTCONFLICT, OnNextConflict)
+       ON_UPDATE_COMMAND_UI(ID_NEXTCONFLICT, OnUpdateNextConflict)
+       ON_COMMAND(ID_PREVCONFLICT, OnPrevConflict)
+       ON_UPDATE_COMMAND_UI(ID_PREVCONFLICT, OnUpdatePrevConflict)
        ON_COMMAND(ID_NEXTDIFFLM, OnNextdiffLM)
        ON_UPDATE_COMMAND_UI(ID_NEXTDIFFLM, OnUpdateNextdiffLM)
        ON_COMMAND(ID_PREVDIFFLM, OnPrevdiffLM)
@@ -136,6 +140,8 @@ BEGIN_MESSAGE_MAP(CMergeEditView, CCrystalEditViewEx)
        ON_UPDATE_COMMAND_UI(ID_ALL_LEFT, OnUpdateAllLeft)
        ON_COMMAND(ID_ALL_RIGHT, OnAllRight)
        ON_UPDATE_COMMAND_UI(ID_ALL_RIGHT, OnUpdateAllRight)
+       ON_COMMAND(ID_AUTO_MERGE, OnAutoMerge)
+       ON_UPDATE_COMMAND_UI(ID_AUTO_MERGE, OnUpdateAutoMerge)
        ON_COMMAND(ID_L2R, OnL2r)
        ON_UPDATE_COMMAND_UI(ID_L2R, OnUpdateL2r)
        ON_COMMAND(ID_R2L, OnR2l)
@@ -996,6 +1002,8 @@ void CMergeEditView::OnEditUndo()
        {
                tgt->SendMessage(WM_COMMAND, ID_EDIT_UNDO);
        }
+       if (!pDoc->CanUndo())
+               pDoc->SetAutoMerged(false);
 }
 
 /**
@@ -1226,6 +1234,32 @@ void CMergeEditView::OnUpdatePrevdiff(CCmdUI* pCmdUI)
        }
 }
 
+void CMergeEditView::OnNextConflict()
+{
+       OnNext3wayDiff(THREEWAYDIFFTYPE_CONFLICT);
+}
+
+/**
+ * @brief Update "Next Conflict" UI items
+ */
+void CMergeEditView::OnUpdateNextConflict(CCmdUI* pCmdUI)
+{
+       OnUpdateNext3wayDiff(pCmdUI, THREEWAYDIFFTYPE_CONFLICT);
+}
+
+void CMergeEditView::OnPrevConflict()
+{
+       OnPrev3wayDiff(THREEWAYDIFFTYPE_CONFLICT);
+}
+
+/**
+ * @brief Update "Prev Conflict" UI items
+ */
+void CMergeEditView::OnUpdatePrevConflict(CCmdUI* pCmdUI)
+{
+       OnUpdatePrev3wayDiff(pCmdUI, THREEWAYDIFFTYPE_CONFLICT);
+}
+
 /**
  * @brief Go to next 3-way diff and select it.
  */
@@ -1981,6 +2015,31 @@ void CMergeEditView::OnUpdateAllRight(CCmdUI* pCmdUI)
 }
 
 /**
+ * @brief Do Auto merge
+ */
+void CMergeEditView::OnAutoMerge()
+{
+       // Check current pane is not readonly
+       if (GetDocument()->IsModified() || GetDocument()->GetAutoMerged() || IsReadOnly(m_nThisPane))
+               return;
+
+       WaitStatusCursor waitstatus(IDS_STATUS_AUTOMERGE);
+
+       GetDocument()->DoAutoMerge(m_nThisPane);
+}
+
+/**
+ * @brief Called when "Auto Merge" item is updated
+ */
+void CMergeEditView::OnUpdateAutoMerge(CCmdUI* pCmdUI)
+{
+       pCmdUI->Enable(GetDocument()->m_nBuffers == 3 && 
+               !GetDocument()->IsModified() && 
+               !GetDocument()->GetAutoMerged() && 
+               !IsReadOnly(m_nThisPane));
+}
+
+/**
  * @brief Add synchronization point
  */
 void CMergeEditView::OnAddSyncPoint()
@@ -2052,7 +2111,7 @@ void CMergeEditView::OnEditOperation(int nAction, LPCTSTR pszText, int cchText)
        // If automatic rescan enabled, rescan after edit events
        if (m_bAutomaticRescan)
        {
-               // keep document up to date
+               // keep document up to date     
                // (Re)start timer to rescan only when user edits text
                // If timer starting fails, rescan immediately
                if (nAction == CE_ACTION_TYPING ||
index 31f0062..ad4c7ba 100644 (file)
@@ -229,6 +229,10 @@ protected:
        afx_msg void OnUpdateNextdiff(CCmdUI* pCmdUI);
        afx_msg void OnPrevdiff();
        afx_msg void OnUpdatePrevdiff(CCmdUI* pCmdUI);
+       afx_msg void OnNextConflict();
+       afx_msg void OnUpdateNextConflict(CCmdUI* pCmdUI);
+       afx_msg void OnPrevConflict();
+       afx_msg void OnUpdatePrevConflict(CCmdUI* pCmdUI);
        afx_msg void OnNextdiffLM();
        afx_msg void OnUpdateNextdiffLM(CCmdUI* pCmdUI);
        afx_msg void OnPrevdiffLM();
@@ -259,6 +263,8 @@ protected:
        afx_msg void OnUpdateAllLeft(CCmdUI* pCmdUI);
        afx_msg void OnAllRight();
        afx_msg void OnUpdateAllRight(CCmdUI* pCmdUI);
+       afx_msg void OnAutoMerge();
+       afx_msg void OnUpdateAutoMerge(CCmdUI* pCmdUI);
        afx_msg void OnL2r();
        afx_msg void OnUpdateL2r(CCmdUI* pCmdUI);
        afx_msg void OnR2l();
index 9db3520..0220231 100644 (file)
Binary files a/Src/res/ToolbarDisabled.bmp and b/Src/res/ToolbarDisabled.bmp differ
index e3e19cd..c3b60ca 100644 (file)
Binary files a/Src/res/ToolbarDisabled32.bmp and b/Src/res/ToolbarDisabled32.bmp differ
index b8d36d9..dff49e5 100644 (file)
Binary files a/Src/res/ToolbarEnabled.bmp and b/Src/res/ToolbarEnabled.bmp differ
index c78a768..90aea8e 100644 (file)
Binary files a/Src/res/ToolbarEnabled32.bmp and b/Src/res/ToolbarEnabled32.bmp differ
index 5df036f..2f636d8 100644 (file)
 #define IDS_STATUS_CREATEREPORT         16825
 #define IDS_STATUS_UNDO                 16826
 #define IDS_STATUS_REDO                 16827
+#define IDS_STATUS_AUTOMERGE            16828
 #define IDS_LINE_STATUS_INFO_EOL        16832
 #define IDS_EMPTY_LINE_STATUS_INFO      16833
 #define IDS_LINE_STATUS_INFO            16834
 #define IDS_CLOSE_RIGHT_TABS            33195
 #define IDS_CLOSE_LEFT_TABS             33196
 #define IDS_CONFIRM_CLOSE_WINDOW        33197
+#define ID_AUTO_MERGE                   33198
+#define ID_NEXTCONFLICT                 33199
+#define ID_PREVCONFLICT                 33200
+#define IDS_AUTO_MERGE                  33201
 
 // Next default values for new objects
 //
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        239
-#define _APS_NEXT_COMMAND_VALUE         33198
+#define _APS_NEXT_COMMAND_VALUE         33202
 #define _APS_NEXT_CONTROL_VALUE         1352
 #define _APS_NEXT_SYMED_VALUE           113
 #endif