1
// TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2019, 2023 - TortoiseGit
4 // Copyright (C) 2006-2013 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "BottomView.h"
26 IMPLEMENT_DYNCREATE(CBottomView
, CBaseView
)
28 CBottomView::CBottomView()
31 m_pState
= &m_AllState
.bottom
;
32 m_nStatusBarID
= ID_INDICATOR_BOTTOMVIEW
;
35 CBottomView::~CBottomView()
40 void CBottomView::AddContextItems(CIconMenu
& popup
, DiffState state
)
42 const bool bShow
= HasSelection() && (state
!= DiffState::Unknown
);
46 popup
.AppendMenuIcon(POPUPCOMMAND_USETHEIRBLOCK
, IDS_VIEWCONTEXTMENU_USETHEIRBLOCK
);
47 popup
.AppendMenuIcon(POPUPCOMMAND_USEYOURBLOCK
, IDS_VIEWCONTEXTMENU_USEYOURBLOCK
);
48 popup
.AppendMenuIcon(POPUPCOMMAND_USEYOURANDTHEIRBLOCK
, IDS_VIEWCONTEXTMENU_USEYOURANDTHEIRBLOCK
);
49 popup
.AppendMenuIcon(POPUPCOMMAND_USETHEIRANDYOURBLOCK
, IDS_VIEWCONTEXTMENU_USETHEIRANDYOURBLOCK
);
51 CBaseView::AddContextItems(popup
, state
);
55 void CBottomView::UseBlock(CBaseView
* pwndView
, int nFirstViewLine
, int nLastViewLine
)
57 if (!IsViewGood(pwndView
))
59 CUndo::GetInstance().BeginGrouping(); // start group undo
61 for (int viewLine
= nFirstViewLine
; viewLine
<= nLastViewLine
; viewLine
++)
63 viewdata lineData
= pwndView
->GetViewData(viewLine
);
64 if ((lineData
.ending
!= EOL::NoEnding
) || (viewLine
< (GetViewCount() - 1) && lineData
.state
!= DiffState::ConflictEmpty
&& lineData
.state
!= DiffState::IdenticalRemoved
))
65 lineData
.ending
= m_lineendings
;
66 lineData
.state
= ResolveState(lineData
.state
);
67 SetViewData(viewLine
, lineData
);
71 // make sure previous (non empty) line have EOL set
72 for (int nCheckViewLine
= nFirstViewLine
-1; nCheckViewLine
> 0; nCheckViewLine
--)
74 if (!IsViewLineEmpty(nCheckViewLine
) && GetViewState(nCheckViewLine
) != DiffState::IdenticalRemoved
)
76 if (GetViewLineEnding(nCheckViewLine
) == EOL::NoEnding
)
78 SetViewLineEnding(nCheckViewLine
, m_lineendings
);
85 int nRemovedLines
= CleanEmptyLines();
87 UpdateViewLineNumbers();
90 CUndo::GetInstance().EndGrouping();
94 SetupAllViewSelection(nFirstViewLine
, nLastViewLine
- nRemovedLines
);
95 BuildAllScreen2ViewVector();
99 void CBottomView::UseBothBlocks(CBaseView
* pwndFirst
, CBaseView
* pwndLast
)
101 if (!IsViewGood(pwndFirst
) || !IsViewGood(pwndLast
))
103 int nFirstViewLine
= 0; // first view line in selection
104 int nLastViewLine
= 0; // last view line in selection
106 if (!GetViewSelection(nFirstViewLine
, nLastViewLine
))
109 int nNextViewLine
= nLastViewLine
+ 1; // first view line after selected block
111 CUndo::GetInstance().BeginGrouping(); // start group undo
113 // use (copy) first block
114 for (int viewLine
= nFirstViewLine
; viewLine
<= nLastViewLine
; viewLine
++)
116 viewdata lineData
= pwndFirst
->GetViewData(viewLine
);
117 if ((lineData
.ending
!= EOL::NoEnding
) || (viewLine
< (GetViewCount() - 1) && lineData
.state
!= DiffState::ConflictEmpty
&& lineData
.state
!= DiffState::IdenticalRemoved
))
118 lineData
.ending
= m_lineendings
;
119 lineData
.state
= ResolveState(lineData
.state
);
120 SetViewData(viewLine
, lineData
);
121 if (!IsStateEmpty(pwndFirst
->GetViewState(viewLine
)))
123 pwndFirst
->SetViewState(viewLine
, DiffState::YoursAdded
); // this is improper (may be DiffState::TheirsAdded) but seems not to produce any visible bug
126 // make sure previous (non empty) line have EOL set
127 for (int nCheckViewLine
= nFirstViewLine
-1; nCheckViewLine
> 0; nCheckViewLine
--)
129 if (!IsViewLineEmpty(nCheckViewLine
))
131 if (GetViewLineEnding(nCheckViewLine
) == EOL::NoEnding
)
133 SetViewLineEnding(nCheckViewLine
, m_lineendings
);
141 // use (insert) last block
142 int nViewIndex
= nNextViewLine
;
143 for (int viewLine
= nFirstViewLine
; viewLine
<= nLastViewLine
; viewLine
++, nViewIndex
++)
145 viewdata lineData
= pwndLast
->GetViewData(viewLine
);
146 lineData
.state
= ResolveState(lineData
.state
);
147 InsertViewData(nViewIndex
, lineData
);
148 if (!IsStateEmpty(pwndLast
->GetViewState(viewLine
)))
150 pwndLast
->SetViewState(viewLine
, DiffState::TheirsAdded
); // this is improper but seems not to produce any visible bug
155 // adjust line numbers in target
156 // we fix all line numbers to handle exotic cases
157 UpdateViewLineNumbers();
160 // now insert an empty block in both first and last
161 int nCount
= nLastViewLine
- nFirstViewLine
+ 1;
162 pwndLast
->InsertViewEmptyLines(nFirstViewLine
, nCount
);
163 pwndFirst
->InsertViewEmptyLines(nNextViewLine
, nCount
);
166 int nRemovedLines
= CleanEmptyLines();
169 CUndo::GetInstance().EndGrouping();
173 SetupAllViewSelection(nFirstViewLine
, 2*nLastViewLine
- nFirstViewLine
- nRemovedLines
+ 1);
174 BuildAllScreen2ViewVector();
179 void CBottomView::UseViewBlock(CBaseView
* pwndView
)
181 if (!IsViewGood(pwndView
))
183 int nFirstViewLine
= 0; // first view line in selection
184 int nLastViewLine
= 0; // last view line in selection
186 if (!GetViewSelection(nFirstViewLine
, nLastViewLine
))
189 return UseBlock(pwndView
, nFirstViewLine
, nLastViewLine
);
192 void CBottomView::UseViewFile(CBaseView
* pwndView
)
194 if (!IsViewGood(pwndView
))
196 int nFirstViewLine
= 0;
197 int nLastViewLine
= GetViewCount()-1;
199 return UseBlock(pwndView
, nFirstViewLine
, nLastViewLine
);