[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Issue 284: TortoiseMerge Accelerator Key & Menu Reorganisation

From: Jeremy Whitby <jeremy.whitby_at_googlemail.com>
Date: 2006-09-10 22:09:33 CEST

Stefan Küng wrote:
> Jeremy Whitby wrote:
>> Should all three functions (Search, differences, conflicts) use the
>> same cursor or should we introduce a search cursor and a view cursor
>> to go alongside the difference and conflict cursors? Or have I
>> missed something when looking at the code?
>
> I think we should just use the same cursor for all three functions
> (search, diffs/conflicts and views).
>
> Stefan
>
OK, Please find attached patch to implement Issue 284.

Note:

1. Previously, each view (left, right, bottom) had their own independent
cursors, this patch synchronises the cursors between views. As each
window scrolled when any cursor was changed this does not seem to me to
be a problem.

2. I have done nothing with the langauge po file as I'm unsure how the
internationalisation stuff is handled.

3. The new icons on the toolbar are just smudged clones of the diff,
conflict ones. Since my skills are nowhere near Lubbe's I took a
shortcut here.

I hope the patch is of use

Regards

Jeremy Whitby

Index: src/Resources/Toolbar.bmp
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/bmp
Index: src/Resources/TortoiseMergeENG.rc
===================================================================
--- src/Resources/TortoiseMergeENG.rc (revision 7434)
+++ src/Resources/TortoiseMergeENG.rc (working copy)
@@ -289,13 +289,18 @@
     BUTTON ID_FILE_RELOAD
     BUTTON ID_EDIT_UNDO
     SEPARATOR
- BUTTON ID_MERGE_PREVIOUSDIFFERENCE
- BUTTON ID_MERGE_NEXTDIFFERENCE
- BUTTON ID_MERGE_PREVIOUSCONFLICT
- BUTTON ID_MERGE_NEXTCONFLICT
+ BUTTON ID_NAVIGATE_PREVIOUSDIFFERENCE
+ BUTTON ID_NAVIGATE_NEXTDIFFERENCE
+ BUTTON ID_NAVIGATE_PREVIOUSCONFLICT
+ BUTTON ID_NAVIGATE_NEXTCONFLICT
     SEPARATOR
- BUTTON ID_MERGE_MARKASRESOLVED
+ BUTTON ID_EDIT_USETHEIRBLOCK
+ BUTTON ID_EDIT_USEMYBLOCK
+ BUTTON ID_EDIT_USETHEIRTHENMYBLOCK
+ BUTTON ID_EDIT_USEMINETHENTHEIRBLOCK
     SEPARATOR
+ BUTTON ID_EDIT_MARKASRESOLVED
+ SEPARATOR
     BUTTON ID_VIEW_WHITESPACES
     BUTTON ID_VIEW_ONEWAYDIFF
     BUTTON ID_VIEW_SWITCHLEFT
@@ -327,9 +332,25 @@
     END
     POPUP "&Edit"
     BEGIN
+ MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO
+ MENUITEM SEPARATOR
         MENUITEM "&Copy", ID_EDIT_COPY
+ MENUITEM SEPARATOR
+ MENUITEM "Use text block from ""&Theirs""", ID_EDIT_USETHEIRBLOCK
+ MENUITEM "Use text block from ""&Mine""", ID_EDIT_USEMYBLOCK
+ MENUITEM "Use text block from ""T&heirs""before ""Mine""", ID_EDIT_USETHEIRTHENMYBLOCK
+ MENUITEM "Use text block from ""M&ine"" before ""Theirs""", ID_EDIT_USEMINETHENTHEIRBLOCK
+ MENUITEM SEPARATOR
         MENUITEM "&Find", ID_EDIT_FIND
+ MENUITEM "Mark as &resolved", ID_EDIT_MARKASRESOLVED
     END
+ POPUP "&Navigate"
+ BEGIN
+ MENUITEM "&Next Difference", ID_NAVIGATE_NEXTDIFFERENCE
+ MENUITEM "&Previous Difference", ID_NAVIGATE_PREVIOUSDIFFERENCE
+ MENUITEM "N&ext Conflict", ID_NAVIGATE_NEXTCONFLICT
+ MENUITEM "P&revious Conflict", ID_NAVIGATE_PREVIOUSCONFLICT
+ END
     POPUP "&View"
     BEGIN
         MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
@@ -343,17 +364,6 @@
         MENUITEM SEPARATOR
         MENUITEM "Show File List", ID_VIEW_SHOWFILELIST
     END
- POPUP "&Merge"
- BEGIN
- MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO
- MENUITEM SEPARATOR
- MENUITEM "&Next Difference", ID_MERGE_NEXTDIFFERENCE
- MENUITEM "&Previous Difference", ID_MERGE_PREVIOUSDIFFERENCE
- MENUITEM "N&ext Conflict", ID_MERGE_NEXTCONFLICT
- MENUITEM "P&revious Conflict", ID_MERGE_PREVIOUSCONFLICT
- MENUITEM SEPARATOR
- MENUITEM "&Mark as resolved", ID_MERGE_MARKASRESOLVED
- END
     POPUP "&Help"
     BEGIN
         MENUITEM "&Help Topics", ID_HELP
@@ -386,12 +396,12 @@
     "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
     "S", ID_FILE_SAVE_AS, VIRTKEY, SHIFT, CONTROL, NOINVERT
     VK_F1, ID_HELP, VIRTKEY, NOINVERT
- VK_RIGHT, ID_MERGE_NEXTCONFLICT, VIRTKEY, SHIFT, NOINVERT
- VK_F7, ID_MERGE_NEXTDIFFERENCE, VIRTKEY, NOINVERT
- VK_RIGHT, ID_MERGE_NEXTDIFFERENCE, VIRTKEY, NOINVERT
- VK_LEFT, ID_MERGE_PREVIOUSCONFLICT, VIRTKEY, SHIFT, NOINVERT
- VK_F7, ID_MERGE_PREVIOUSDIFFERENCE, VIRTKEY, SHIFT, NOINVERT
- VK_LEFT, ID_MERGE_PREVIOUSDIFFERENCE, VIRTKEY, NOINVERT
+// VK_RIGHT, ID_NAVIGATE_NEXTCONFLICT, VIRTKEY, SHIFT, NOINVERT
+ VK_F7, ID_NAVIGATE_NEXTDIFFERENCE, VIRTKEY, NOINVERT
+// VK_RIGHT, ID_NAVIGATE_NEXTDIFFERENCE, VIRTKEY, NOINVERT
+// VK_LEFT, ID_NAVIGATE_PREVIOUSCONFLICT, VIRTKEY, SHIFT, NOINVERT
+ VK_F7, ID_NAVIGATE_PREVIOUSDIFFERENCE, VIRTKEY, SHIFT, NOINVERT
+// VK_LEFT, ID_NAVIGATE_PREVIOUSDIFFERENCE, VIRTKEY, NOINVERT
     VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT
     VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT
     VK_DOWN, ID_VIEW_LINEDOWN, VIRTKEY, NOINVERT
@@ -402,9 +412,13 @@
     VK_UP, ID_VIEW_LINEUP, VIRTKEY, CONTROL, NOINVERT
     "D", ID_VIEW_ONEWAYDIFF, VIRTKEY, CONTROL, NOINVERT
     "T", ID_VIEW_WHITESPACES, VIRTKEY, CONTROL, NOINVERT
- VK_F8, ID_MERGE_NEXTCONFLICT, VIRTKEY, NOINVERT
- VK_F8, ID_MERGE_PREVIOUSCONFLICT, VIRTKEY, SHIFT, NOINVERT
+ VK_F8, ID_NAVIGATE_NEXTCONFLICT, VIRTKEY, NOINVERT
+ VK_F8, ID_NAVIGATE_PREVIOUSCONFLICT, VIRTKEY, SHIFT, NOINVERT
     VK_F3, ID_EDIT_FINDPREV, VIRTKEY, SHIFT, NOINVERT
+ VK_F9, ID_EDIT_USETHEIRBLOCK, VIRTKEY, CONTROL, NOINVERT
+ VK_F10, ID_EDIT_USEMYBLOCK, VIRTKEY, CONTROL, NOINVERT
+ VK_F9, ID_EDIT_USETHEIRTHENMYBLOCK, VIRTKEY, SHIFT, CONTROL, NOINVERT
+ VK_F10, ID_EDIT_USEMINETHENTHEIRBLOCK, VIRTKEY, SHIFT, CONTROL, NOINVERT
 END
 
 
@@ -504,8 +518,8 @@
 BEGIN
     ID_VIEW_WHITESPACES "Show special characters for whitespaces\nShow Whitespaces"
     ID_VIEW_ONEWAYDIFF "Switch between single and double pane view\nSwitch between single and double pane view"
- ID_MERGE_NEXTDIFFERENCE "Go to the next difference\nnext difference"
- ID_MERGE_PREVIOUSDIFFERENCE
+ ID_NAVIGATE_NEXTDIFFERENCE "Go to the next difference\nnext difference"
+ ID_NAVIGATE_PREVIOUSDIFFERENCE
                             "Go to the previous difference\nprevious difference"
     ID_VIEW_OPTIONS "Adjust the settings\nSettings"
 END
@@ -643,14 +657,22 @@
 
 STRINGTABLE
 BEGIN
- ID_MERGE_PREVIOUSCONFLICT "Go to the previous conflict\nprevious conflict"
- ID_MERGE_NEXTCONFLICT "Go to the next conflict\nnext conflict"
- ID_MERGE_MARKASRESOLVED "Marks a file as resolved in Subversion\nMark as resolved"
+ ID_NAVIGATE_PREVIOUSCONFLICT "Go to the previous conflict\nprevious conflict"
+ ID_NAVIGATE_NEXTCONFLICT "Go to the next conflict\nnext conflict"
+ ID_EDIT_MARKASRESOLVED "Marks a file as resolved in Subversion\nMark as resolved"
     ID_VIEW_SWITCHLEFT "Switch the contents of the left and right view\nSwitch left and right view"
 END
 
 STRINGTABLE
 BEGIN
+ ID_EDIT_USETHEIRBLOCK "Use text block from ""Theirs""\nUse ""Their"" text block"
+ ID_EDIT_USEMYBLOCK "Use text block from ""Mine""\nUse ""My"" text block"
+ ID_EDIT_USETHEIRTHENMYBLOCK "Use text block from ""Theirs"" before ""Mine""\n""Their"" text block then ""Mine"""
+ ID_EDIT_USEMINETHENTHEIRBLOCK "Use text block from ""Mine"" before ""Theirs""\n""My"" text block then ""Theirs"""
+END
+
+STRINGTABLE
+BEGIN
     IDS_WARNBETTERPATCHPATHFOUND
                             "The path\n<i>%s</i>\nseems not to match the paths in the patchfile.\nBut TortoiseMerge found the path\n<i>%s</i>\nmatches it better. Do you want to use the suggested path instead?"
     IDS_NOTFOUNDVIEWTITLEINDICATOR "(not found)"
Index: src/TortoiseMerge/BaseView.cpp
===================================================================
--- src/TortoiseMerge/BaseView.cpp (revision 7434)
+++ src/TortoiseMerge/BaseView.cpp (working copy)
@@ -139,16 +139,16 @@
         ON_WM_KILLFOCUS()
         ON_WM_SETFOCUS()
         ON_WM_CONTEXTMENU()
- ON_COMMAND(ID_MERGE_NEXTDIFFERENCE, OnMergeNextdifference)
- ON_COMMAND(ID_MERGE_PREVIOUSDIFFERENCE, OnMergePreviousdifference)
+ ON_COMMAND(ID_NAVIGATE_NEXTDIFFERENCE, OnMergeNextdifference)
+ ON_COMMAND(ID_NAVIGATE_PREVIOUSDIFFERENCE, OnMergePreviousdifference)
         ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
         ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
         ON_WM_KEYDOWN()
         ON_WM_LBUTTONUP()
         ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
         ON_WM_MOUSEMOVE()
- ON_COMMAND(ID_MERGE_PREVIOUSCONFLICT, OnMergePreviousconflict)
- ON_COMMAND(ID_MERGE_NEXTCONFLICT, OnMergeNextconflict)
+ ON_COMMAND(ID_NAVIGATE_PREVIOUSCONFLICT, OnMergePreviousconflict)
+ ON_COMMAND(ID_NAVIGATE_NEXTCONFLICT, OnMergeNextconflict)
         ON_WM_LBUTTONDBLCLK()
 END_MESSAGE_MAP()
 
@@ -1595,27 +1595,32 @@
                         OnContextMenu(point, nLine);
                         m_nSelBlockStart = -1;
                         m_nSelBlockEnd = -1;
- if (m_pwndLeft)
- {
- m_pwndLeft->UpdateStatusBar();
- m_pwndLeft->Invalidate();
- }
- if (m_pwndRight)
- {
- m_pwndRight->UpdateStatusBar();
- m_pwndRight->Invalidate();
- }
- if (m_pwndBottom)
- {
- m_pwndBottom->UpdateStatusBar();
- m_pwndBottom->Invalidate();
- }
- if (m_pwndLocator)
- m_pwndLocator->Invalidate();
+ RefreshViews();
                 } // if (ShallShowContextMenu(state, nLine))
         } // if (nLine <= m_arLineStates->GetCount())
 }
 
+void CBaseView::RefreshViews()
+{
+ if (m_pwndLeft)
+ {
+ m_pwndLeft->UpdateStatusBar();
+ m_pwndLeft->Invalidate();
+ }
+ if (m_pwndRight)
+ {
+ m_pwndRight->UpdateStatusBar();
+ m_pwndRight->Invalidate();
+ }
+ if (m_pwndBottom)
+ {
+ m_pwndBottom->UpdateStatusBar();
+ m_pwndBottom->Invalidate();
+ }
+ if (m_pwndLocator)
+ m_pwndLocator->Invalidate();
+}
+
 void CBaseView::GoToFirstDifference()
 {
         int nCenterPos = 0;
@@ -1659,6 +1664,28 @@
         }
 }
 
+void CBaseView::SetupSelection(int start, int end)
+{
+ if ((m_pwndBottom)&&(m_pwndBottom->IsWindowVisible()))
+ {
+ m_pwndBottom->m_nSelBlockStart = start;
+ m_pwndBottom->m_nSelBlockEnd = end;
+ m_pwndBottom->Invalidate();
+ }
+ if ((m_pwndLeft)&&(m_pwndLeft->IsWindowVisible()))
+ {
+ m_pwndLeft->m_nSelBlockStart = start;
+ m_pwndLeft->m_nSelBlockEnd = end;
+ m_pwndLeft->Invalidate();
+ }
+ if ((m_pwndRight)&&(m_pwndRight->IsWindowVisible()))
+ {
+ m_pwndRight->m_nSelBlockStart = start;
+ m_pwndRight->m_nSelBlockEnd = end;
+ m_pwndRight->Invalidate();
+ }
+}
+
 void CBaseView::OnMergePreviousconflict()
 {
         int nCenterPos = m_nTopLine + (GetScreenLines()/2);
@@ -1702,6 +1729,7 @@
                         nTopPos = 0;
                 ScrollAllToLine(nTopPos, FALSE);
                 RecalcAllVertScrollBars(TRUE);
+ SetupSelection(m_nSelBlockStart, m_nSelBlockEnd);
                 SetupDiffBars(m_nDiffBlockStart, m_nDiffBlockEnd);
                 ShowDiffLines(m_nDiffBlockStart);
         }
@@ -1750,6 +1778,7 @@
                         nTopPos = 0;
                 ScrollAllToLine(nTopPos, FALSE);
                 RecalcAllVertScrollBars(TRUE);
+ SetupSelection(m_nSelBlockStart, m_nSelBlockEnd);
                 SetupDiffBars(m_nDiffBlockStart, m_nDiffBlockEnd);
                 ShowDiffLines(m_nDiffBlockStart);
         } // if ((m_arLineStates)&&(nCenterPos < m_arLineStates->GetCount()))
@@ -1795,6 +1824,8 @@
                 int nTopPos = nCenterPos - (GetScreenLines()/2);
                 if (nTopPos < 0)
                         nTopPos = 0;
+
+ SetupSelection(m_nDiffBlockStart, m_nDiffBlockEnd);
                 ScrollAllToLine(nTopPos, FALSE);
                 RecalcAllVertScrollBars(TRUE);
                 SetupDiffBars(m_nDiffBlockStart, m_nDiffBlockEnd);
@@ -1842,6 +1873,7 @@
                 int nTopPos = nCenterPos - (GetScreenLines()/2);
                 if (nTopPos < 0)
                         nTopPos = 0;
+ SetupSelection(m_nDiffBlockStart, m_nDiffBlockEnd);
                 ScrollAllToLine(nTopPos, FALSE);
                 RecalcAllVertScrollBars(TRUE);
                 SetupDiffBars(m_nDiffBlockStart, m_nDiffBlockEnd);
@@ -2014,6 +2046,7 @@
                                 m_nSelBlockStart = m_nSelBlockEnd = nClickedLine;
                         }
                 }
+ SetupSelection(m_nSelBlockStart, m_nSelBlockEnd);
                 Invalidate();
         } // if ((nClickedLine <= 0)&&(nClickedLine <= nLineCount))
 
Index: src/TortoiseMerge/BaseView.h
===================================================================
--- src/TortoiseMerge/BaseView.h (revision 7434)
+++ src/TortoiseMerge/BaseView.h (working copy)
@@ -131,6 +131,7 @@
         void OnDoVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar, CBaseView * master);
 
         void SetupDiffBars(int start, int end);
+ void SetupSelection(int start, int end);
         void ShowDiffLines(int nLine);
         
         int GetTabSize() const {return m_nTabSize;}
@@ -154,6 +155,7 @@
         CFont * GetFont(BOOL bItalic = FALSE, BOOL bBold = FALSE, BOOL bStrikeOut = FALSE);
         int GetLineFromPoint(CPoint point);
         int GetMarginWidth();
+ void RefreshViews();
 
         virtual BOOL ShallShowContextMenu(CDiffData::DiffStates state, int nLine);
         virtual void OnContextMenu(CPoint point, int nLine);
Index: src/TortoiseMerge/BottomView.cpp
===================================================================
--- src/TortoiseMerge/BottomView.cpp (revision 7434)
+++ src/TortoiseMerge/BottomView.cpp (working copy)
@@ -32,6 +32,18 @@
 {
 }
 
+BOOL CBottomView::CanSelectTextBlocks()
+{
+BOOL bEnable = FALSE;
+
+ if (m_nSelBlockEnd >= 0)
+ {
+ CDiffData::DiffStates state = (CDiffData::DiffStates)m_arLineStates->GetAt(m_nSelBlockEnd);
+ bEnable = ShallShowContextMenu(state, 0);
+ }
+ return bEnable;
+}
+
 BOOL CBottomView::ShallShowContextMenu(CDiffData::DiffStates state, int /*nLine*/)
 {
         //The bottom view is not visible in one and two-way diff...
@@ -82,101 +94,117 @@
                 switch (cmd)
                 {
                 case ID_USETHEIRBLOCK:
- {
- for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- {
- m_arDiffLines->SetAt(i, m_pwndLeft->m_arDiffLines->GetAt(i));
- m_arLineStates->SetAt(i, m_pwndLeft->m_arLineStates->GetAt(i));
- } // for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- SetModified();
- }
+ UseTheirTextBlock();
                         break;
                 case ID_USEYOURBLOCK:
- {
- for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- {
- m_arDiffLines->SetAt(i, m_pwndRight->m_arDiffLines->GetAt(i));
- m_arLineStates->SetAt(i, m_pwndRight->m_arLineStates->GetAt(i));
- } // for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- SetModified();
- }
+ UseMyTextBlock();
                         break;
                 case ID_USEYOURANDTHEIRBLOCK:
- {
- for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- {
- m_arDiffLines->SetAt(i, m_pwndRight->m_arDiffLines->GetAt(i));
- m_arLineStates->SetAt(i, m_pwndRight->m_arLineStates->GetAt(i));
- m_pwndRight->m_arLineStates->SetAt(i, CDiffData::DIFFSTATE_YOURSADDED);
- }
-
- // your block is done, now insert their block
- int index = m_nSelBlockEnd+1;
- for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- {
- m_arDiffLines->InsertAt(index, m_pwndLeft->m_arDiffLines->GetAt(i));
- m_arLineLines->InsertAt(index, m_pwndLeft->m_arLineLines->GetAt(i));
- m_arLineStates->InsertAt(index++, m_pwndLeft->m_arLineStates->GetAt(i));
- m_pwndLeft->m_arLineStates->SetAt(i, CDiffData::DIFFSTATE_THEIRSADDED);
- }
- // adjust line numbers
- for (int i=m_nSelBlockEnd+1; i<GetLineCount(); ++i)
- {
- long oldline = (long)m_arLineLines->GetAt(i);
- if (oldline >= 0)
- m_arLineLines->SetAt(i, oldline+(index-m_nSelBlockEnd));
- }
-
- // now insert an empty block in both yours and theirs
- m_pwndLeft->m_arDiffLines->InsertAt(m_nSelBlockStart, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndLeft->m_arLineStates->InsertAt(m_nSelBlockStart, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndLeft->m_arLineLines->InsertAt(m_nSelBlockStart, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndRight->m_arDiffLines->InsertAt(m_nSelBlockEnd+1, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndRight->m_arLineStates->InsertAt(m_nSelBlockEnd+1, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndRight->m_arLineLines->InsertAt(m_nSelBlockEnd+1, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
- RecalcAllVertScrollBars();
- SetModified();
- m_pwndLeft->SetModified();
- m_pwndRight->SetModified();
- }
+ UseMyThenTheirTextBlock();
                         break;
                 case ID_USETHEIRANDYOURBLOCK:
- {
- for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- {
- m_arDiffLines->SetAt(i, m_pwndLeft->m_arDiffLines->GetAt(i));
- m_arLineStates->SetAt(i, m_pwndLeft->m_arLineStates->GetAt(i));
- }
-
- // your block is done, now insert their block
- int index = m_nSelBlockEnd+1;
- for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
- {
- m_arDiffLines->InsertAt(index, m_pwndRight->m_arDiffLines->GetAt(i));
- m_arLineLines->InsertAt(index, m_pwndLeft->m_arLineLines->GetAt(i));
- m_arLineStates->InsertAt(index++, m_pwndRight->m_arLineStates->GetAt(i));
- }
- // adjust line numbers
- for (int i=m_nSelBlockEnd+1; i<GetLineCount(); ++i)
- {
- long oldline = (long)m_arLineLines->GetAt(i);
- if (oldline >= 0)
- m_arLineLines->SetAt(i, oldline+(index-m_nSelBlockEnd));
- }
-
- // now insert an empty block in both yours and theirs
- m_pwndLeft->m_arDiffLines->InsertAt(m_nSelBlockStart, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndLeft->m_arLineStates->InsertAt(m_nSelBlockStart, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndLeft->m_arLineLines->InsertAt(m_nSelBlockStart, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndRight->m_arDiffLines->InsertAt(m_nSelBlockEnd+1, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndRight->m_arLineStates->InsertAt(m_nSelBlockEnd+1, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
- m_pwndRight->m_arLineLines->InsertAt(m_nSelBlockEnd+1, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
- RecalcAllVertScrollBars();
- SetModified();
- m_pwndLeft->SetModified();
- m_pwndRight->SetModified();
- }
+ UseTheirThenMyTextBlock();
                         break;
                 } // switch (cmd)
         } // if (popup.CreatePopupMenu())
 }
+
+void CBottomView::UseTheirTextBlock()
+{
+ for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ {
+ m_arDiffLines->SetAt(i, m_pwndLeft->m_arDiffLines->GetAt(i));
+ m_arLineStates->SetAt(i, m_pwndLeft->m_arLineStates->GetAt(i));
+ } // for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ SetModified();
+ RefreshViews();
+}
+
+void CBottomView::UseMyTextBlock()
+{
+ for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ {
+ m_arDiffLines->SetAt(i, m_pwndRight->m_arDiffLines->GetAt(i));
+ m_arLineStates->SetAt(i, m_pwndRight->m_arLineStates->GetAt(i));
+ } // for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ SetModified();
+ RefreshViews();
+}
+
+void CBottomView::UseTheirThenMyTextBlock()
+{
+ for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ {
+ m_arDiffLines->SetAt(i, m_pwndLeft->m_arDiffLines->GetAt(i));
+ m_arLineStates->SetAt(i, m_pwndLeft->m_arLineStates->GetAt(i));
+ }
+
+ // your block is done, now insert their block
+ int index = m_nSelBlockEnd+1;
+ for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ {
+ m_arDiffLines->InsertAt(index, m_pwndRight->m_arDiffLines->GetAt(i));
+ m_arLineLines->InsertAt(index, m_pwndLeft->m_arLineLines->GetAt(i));
+ m_arLineStates->InsertAt(index++, m_pwndRight->m_arLineStates->GetAt(i));
+ }
+ // adjust line numbers
+ for (int i=m_nSelBlockEnd+1; i<GetLineCount(); ++i)
+ {
+ long oldline = (long)m_arLineLines->GetAt(i);
+ if (oldline >= 0)
+ m_arLineLines->SetAt(i, oldline+(index-m_nSelBlockEnd));
+ }
+
+ // now insert an empty block in both yours and theirs
+ m_pwndLeft->m_arDiffLines->InsertAt(m_nSelBlockStart, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndLeft->m_arLineStates->InsertAt(m_nSelBlockStart, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndLeft->m_arLineLines->InsertAt(m_nSelBlockStart, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndRight->m_arDiffLines->InsertAt(m_nSelBlockEnd+1, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndRight->m_arLineStates->InsertAt(m_nSelBlockEnd+1, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndRight->m_arLineLines->InsertAt(m_nSelBlockEnd+1, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
+ RecalcAllVertScrollBars();
+ SetModified();
+ m_pwndLeft->SetModified();
+ m_pwndRight->SetModified();
+ RefreshViews();
+}
+
+void CBottomView::UseMyThenTheirTextBlock()
+{
+ for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ {
+ m_arDiffLines->SetAt(i, m_pwndRight->m_arDiffLines->GetAt(i));
+ m_arLineStates->SetAt(i, m_pwndRight->m_arLineStates->GetAt(i));
+ m_pwndRight->m_arLineStates->SetAt(i, CDiffData::DIFFSTATE_YOURSADDED);
+ }
+
+ // your block is done, now insert their block
+ int index = m_nSelBlockEnd+1;
+ for (int i=m_nSelBlockStart; i<=m_nSelBlockEnd; i++)
+ {
+ m_arDiffLines->InsertAt(index, m_pwndLeft->m_arDiffLines->GetAt(i));
+ m_arLineLines->InsertAt(index, m_pwndLeft->m_arLineLines->GetAt(i));
+ m_arLineStates->InsertAt(index++, m_pwndLeft->m_arLineStates->GetAt(i));
+ m_pwndLeft->m_arLineStates->SetAt(i, CDiffData::DIFFSTATE_THEIRSADDED);
+ }
+ // adjust line numbers
+ for (int i=m_nSelBlockEnd+1; i<GetLineCount(); ++i)
+ {
+ long oldline = (long)m_arLineLines->GetAt(i);
+ if (oldline >= 0)
+ m_arLineLines->SetAt(i, oldline+(index-m_nSelBlockEnd));
+ }
+
+ // now insert an empty block in both yours and theirs
+ m_pwndLeft->m_arDiffLines->InsertAt(m_nSelBlockStart, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndLeft->m_arLineStates->InsertAt(m_nSelBlockStart, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndLeft->m_arLineLines->InsertAt(m_nSelBlockStart, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndRight->m_arDiffLines->InsertAt(m_nSelBlockEnd+1, _T(""), m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndRight->m_arLineStates->InsertAt(m_nSelBlockEnd+1, CDiffData::DIFFSTATE_EMPTY, m_nSelBlockEnd-m_nSelBlockStart+1);
+ m_pwndRight->m_arLineLines->InsertAt(m_nSelBlockEnd+1, (DWORD)-1, m_nSelBlockEnd-m_nSelBlockStart+1);
+ RecalcAllVertScrollBars();
+ SetModified();
+ m_pwndLeft->SetModified();
+ m_pwndRight->SetModified();
+ RefreshViews();
+}
\ No newline at end of file
Index: src/TortoiseMerge/BottomView.h
===================================================================
--- src/TortoiseMerge/BottomView.h (revision 7434)
+++ src/TortoiseMerge/BottomView.h (working copy)
@@ -25,6 +25,13 @@
 public:
         CBottomView(void);
         ~CBottomView(void);
+
+ BOOL CanSelectTextBlocks();
+ void UseMyTextBlock();
+ void UseMyThenTheirTextBlock();
+ void UseTheirTextBlock();
+ void UseTheirThenMyTextBlock();
+
 protected:
         void OnContextMenu(CPoint point, int nLine);
         BOOL ShallShowContextMenu(CDiffData::DiffStates state, int nLine);
Index: src/TortoiseMerge/MainFrm.cpp
===================================================================
--- src/TortoiseMerge/MainFrm.cpp (revision 7434)
+++ src/TortoiseMerge/MainFrm.cpp (working copy)
@@ -67,10 +67,10 @@
         ON_COMMAND(ID_FILE_RELOAD, OnFileReload)
         ON_COMMAND(ID_VIEW_LINEDOWN, OnViewLinedown)
         ON_COMMAND(ID_VIEW_LINEUP, OnViewLineup)
- ON_UPDATE_COMMAND_UI(ID_MERGE_MARKASRESOLVED, OnUpdateMergeMarkasresolved)
- ON_COMMAND(ID_MERGE_MARKASRESOLVED, OnMergeMarkasresolved)
- ON_UPDATE_COMMAND_UI(ID_MERGE_NEXTCONFLICT, OnUpdateMergeNextconflict)
- ON_UPDATE_COMMAND_UI(ID_MERGE_PREVIOUSCONFLICT, OnUpdateMergePreviousconflict)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_MARKASRESOLVED, OnUpdateMergeMarkasresolved)
+ ON_COMMAND(ID_EDIT_MARKASRESOLVED, OnMergeMarkasresolved)
+ ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NEXTCONFLICT, OnUpdateMergeNextconflict)
+ ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PREVIOUSCONFLICT, OnUpdateMergePreviousconflict)
         ON_WM_MOVE()
         ON_WM_MOVING()
         ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
@@ -80,6 +80,14 @@
         ON_COMMAND(ID_VIEW_LINERIGHT, &CMainFrame::OnViewLineright)
         ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWFILELIST, &CMainFrame::OnUpdateViewShowfilelist)
         ON_COMMAND(ID_VIEW_SHOWFILELIST, &CMainFrame::OnViewShowfilelist)
+ ON_COMMAND(ID_EDIT_USETHEIRBLOCK, &CMainFrame::OnEditUseTheirs)
+ ON_COMMAND(ID_EDIT_USEMYBLOCK, &CMainFrame::OnEditUseMine)
+ ON_COMMAND(ID_EDIT_USETHEIRTHENMYBLOCK, &CMainFrame::OnEditUseTheirsThenMine)
+ ON_COMMAND(ID_EDIT_USEMINETHENTHEIRBLOCK, &CMainFrame::OnEditUseMineThenTheirs)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRBLOCK, &CMainFrame::OnUpdateTextBlockSelection)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_USEMYBLOCK, &CMainFrame::OnUpdateTextBlockSelection)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_USETHEIRTHENMYBLOCK, &CMainFrame::OnUpdateTextBlockSelection)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_USEMINETHENTHEIRBLOCK, &CMainFrame::OnUpdateTextBlockSelection)
 END_MESSAGE_MAP()
 
 static UINT indicators[] =
@@ -1248,6 +1256,39 @@
                 m_pwndBottomView->ScrollSide(1);
 }
 
+void CMainFrame::OnEditUseTheirs()
+{
+ if (m_pwndBottomView)
+ m_pwndBottomView->UseTheirTextBlock();
+}
+
+void CMainFrame::OnEditUseMine()
+{
+ if (m_pwndBottomView)
+ m_pwndBottomView->UseMyTextBlock();
+}
+
+void CMainFrame::OnEditUseTheirsThenMine()
+{
+ if (m_pwndBottomView)
+ m_pwndBottomView->UseTheirThenMyTextBlock();
+}
+
+void CMainFrame::OnEditUseMineThenTheirs()
+{
+ if (m_pwndBottomView)
+ m_pwndBottomView->UseMyThenTheirTextBlock();
+}
+
+void CMainFrame::OnUpdateTextBlockSelection(CCmdUI *pCmdUI)
+{
+ BOOL bEnable = FALSE;
+ if (m_pwndBottomView)
+ bEnable = m_pwndBottomView->CanSelectTextBlocks();
+
+ pCmdUI->Enable(bEnable);
+}
+
 void CMainFrame::OnFileReload()
 {
         if (((m_pwndBottomView)&&(m_pwndBottomView->IsModified())) ||
Index: src/TortoiseMerge/MainFrm.h
===================================================================
--- src/TortoiseMerge/MainFrm.h (revision 7434)
+++ src/TortoiseMerge/MainFrm.h (working copy)
@@ -73,6 +73,11 @@
         afx_msg void OnViewLineup();
         afx_msg void OnViewLineleft();
         afx_msg void OnViewLineright();
+ afx_msg void OnEditUseTheirs();
+ afx_msg void OnEditUseMine();
+ afx_msg void OnEditUseTheirsThenMine();
+ afx_msg void OnEditUseMineThenTheirs();
+ afx_msg void OnUpdateTextBlockSelection(CCmdUI *pCmdUI);
         afx_msg void OnUpdateMergeMarkasresolved(CCmdUI *pCmdUI);
         afx_msg void OnMergeMarkasresolved();
         afx_msg void OnUpdateMergeNextconflict(CCmdUI *pCmdUI);
Index: src/TortoiseMerge/resource.h
===================================================================
--- src/TortoiseMerge/resource.h (revision 7434)
+++ src/TortoiseMerge/resource.h (working copy)
@@ -176,8 +176,8 @@
 #define IDS_COLOURPICKER_DEFAULTTEXT 7001
 #define ID_VIEW_WHITESPACES 32774
 #define ID_VIEW_ONEWAYDIFF 32775
-#define ID_MERGE_NEXTDIFFERENCE 32779
-#define ID_MERGE_PREVIOUSDIFFERENCE 32780
+#define ID_NAVIGATE_NEXTDIFFERENCE 32779
+#define ID_NAVIGATE_PREVIOUSDIFFERENCE 32780
 #define ID_VIEW_ 32781
 #define ID_VIEW_OPTIONS 32782
 #define ID_BUTTON32783 32783
@@ -185,10 +185,10 @@
 #define ID_FILE_RELOAD 32794
 #define ID_BUTTON32797 32797
 #define ID_VIEW_LINEDOWN 32799
-#define ID_MERGE_PREVIOUSCONFLICT 32802
-#define ID_MERGE_NEXTCONFLICT 32804
+#define ID_NAVIGATE_PREVIOUSCONFLICT 32802
+#define ID_NAVIGATE_NEXTCONFLICT 32804
 #define ID_BUTTON32807 32807
-#define ID_MERGE_MARKASRESOLVED 32808
+#define ID_EDIT_MARKASRESOLVED 32808
 #define ID_VIEW_SWITCHLEFT 32811
 #define ID_BUTTON32812 32812
 #define ID_VIEW_LINELEFT 32813
@@ -196,13 +196,17 @@
 #define ID_BUTTON32816 32816
 #define ID_VIEW_SHOWFILELIST 32817
 #define ID_EDIT_FINDPREV 32818
+#define ID_EDIT_USETHEIRBLOCK 32819
+#define ID_EDIT_USEMYBLOCK 32820
+#define ID_EDIT_USETHEIRTHENMYBLOCK 32821
+#define ID_EDIT_USEMINETHENTHEIRBLOCK 32822
 
 // Next default values for new objects
 //
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE 141
-#define _APS_NEXT_COMMAND_VALUE 32819
+#define _APS_NEXT_COMMAND_VALUE 32823
 #define _APS_NEXT_CONTROL_VALUE 1071
 #define _APS_NEXT_SYMED_VALUE 101
 #endif

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tortoisesvn.tigris.org
For additional commands, e-mail: dev-help@tortoisesvn.tigris.org
Received on Sun Sep 10 22:09:53 2006

This is an archived mail posted to the TortoiseSVN Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.