1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2007-2008 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "TortoiseProc.h"
21 #include "ConflictResolveDlg.h"
23 #include "UnicodeUtils.h"
24 #include "PathUtils.h"
28 IMPLEMENT_DYNAMIC(CConflictResolveDlg
, CResizableStandAloneDialog
)
30 CConflictResolveDlg::CConflictResolveDlg(CWnd
* pParent
/*=NULL*/)
31 : CResizableStandAloneDialog(CConflictResolveDlg::IDD
, pParent
)
32 , m_pConflictDescription(NULL
)
33 , m_choice(svn_wc_conflict_choose_postpone
)
39 CConflictResolveDlg::~CConflictResolveDlg()
43 void CConflictResolveDlg::DoDataExchange(CDataExchange
* pDX
)
45 CResizableStandAloneDialog::DoDataExchange(pDX
);
49 BEGIN_MESSAGE_MAP(CConflictResolveDlg
, CResizableStandAloneDialog
)
50 ON_BN_CLICKED(IDC_USELOCAL
, &CConflictResolveDlg::OnBnClickedUselocal
)
51 ON_BN_CLICKED(IDC_USEREPO
, &CConflictResolveDlg::OnBnClickedUserepo
)
52 ON_BN_CLICKED(IDC_EDITCONFLICT
, &CConflictResolveDlg::OnBnClickedEditconflict
)
53 ON_BN_CLICKED(IDC_RESOLVED
, &CConflictResolveDlg::OnBnClickedResolved
)
54 ON_BN_CLICKED(IDC_RESOLVEALLLATER
, &CConflictResolveDlg::OnBnClickedResolvealllater
)
55 ON_BN_CLICKED(IDHELP
, &CConflictResolveDlg::OnBnClickedHelp
)
56 ON_BN_CLICKED(IDC_ABORT
, &CConflictResolveDlg::OnBnClickedAbort
)
60 // CConflictResolveDlg message handlers
62 BOOL
CConflictResolveDlg::OnInitDialog()
64 CResizableStandAloneDialog::OnInitDialog();
66 // without a conflict description, this dialog is useless.
67 ASSERT(m_pConflictDescription
);
69 CString filename
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->path
);
70 filename
= CPathUtils::GetFileNameFromPath(filename
);
75 switch (m_pConflictDescription
->action
)
77 case svn_wc_conflict_action_edit
:
78 if (m_pConflictDescription
->property_name
)
79 sActionText
.Format(IDS_EDITCONFLICT_PROP_ACTIONINFO_MODIFY
,
80 (LPCTSTR
)CUnicodeUtils::GetUnicode(m_pConflictDescription
->property_name
),
83 sActionText
.Format(IDS_EDITCONFLICT_ACTIONINFO_MODIFY
, (LPCTSTR
)filename
);
85 case svn_wc_conflict_action_add
:
86 if (m_pConflictDescription
->property_name
)
87 sActionText
.Format(IDS_EDITCONFLICT_PROP_ACTIONINFO_ADD
,
88 (LPCTSTR
)CUnicodeUtils::GetUnicode(m_pConflictDescription
->property_name
),
91 sActionText
.Format(IDS_EDITCONFLICT_ACTIONINFO_ADD
, (LPCTSTR
)filename
);
93 case svn_wc_conflict_action_delete
:
94 if (m_pConflictDescription
->property_name
)
95 sActionText
.Format(IDS_EDITCONFLICT_PROP_ACTIONINFO_DELETE
,
96 (LPCTSTR
)CUnicodeUtils::GetUnicode(m_pConflictDescription
->property_name
),
99 sActionText
.Format(IDS_EDITCONFLICT_ACTIONINFO_DELETE
, (LPCTSTR
)filename
);
105 switch (m_pConflictDescription
->reason
)
107 case svn_wc_conflict_reason_edited
:
108 sReasonText
.LoadString(IDS_EDITCONFLICT_REASONINFO_EDITED
);
110 case svn_wc_conflict_reason_obstructed
:
111 sReasonText
.LoadString(IDS_EDITCONFLICT_REASONINFO_OBSTRUCTED
);
113 case svn_wc_conflict_reason_deleted
:
114 sReasonText
.LoadString(IDS_EDITCONFLICT_REASONINFO_DELETED
);
116 case svn_wc_conflict_reason_missing
:
117 sReasonText
.LoadString(IDS_EDITCONFLICT_REASONINFO_MISSING
);
119 case svn_wc_conflict_reason_unversioned
:
120 sReasonText
.LoadString(IDS_EDITCONFLICT_REASONINFO_UNVERSIONED
);
126 sInfoText
= sActionText
+ _T(" ") + sReasonText
;
127 SetDlgItemText(IDC_INFOLABEL
, sInfoText
);
129 // if we deal with a binary file, editing the conflict isn't possible
130 // because the 'merged_file' is not used and Subversion therefore can't
131 // use it as the result of the edit.
132 if (m_pConflictDescription
->is_binary
)
134 GetDlgItem(IDC_RESOLVELABEL
)->EnableWindow(FALSE
);
135 GetDlgItem(IDC_EDITCONFLICT
)->EnableWindow(FALSE
);
136 GetDlgItem(IDC_RESOLVED
)->EnableWindow(FALSE
);
139 // the "resolved" button must not be enabled as long as the user hasn't used
140 // the "edit" button.
141 GetDlgItem(IDC_RESOLVED
)->EnableWindow(FALSE
);
143 m_bCancelled
= false;
145 AddAnchor(IDC_INFOLABEL
, TOP_LEFT
, BOTTOM_RIGHT
);
146 AddAnchor(IDC_GROUP
, BOTTOM_LEFT
, BOTTOM_RIGHT
);
147 AddAnchor(IDC_CHOOSELABEL
, BOTTOM_LEFT
);
148 AddAnchor(IDC_USELOCAL
, BOTTOM_LEFT
);
149 AddAnchor(IDC_USEREPO
, BOTTOM_RIGHT
);
150 AddAnchor(IDC_ORLABEL
, BOTTOM_LEFT
);
151 AddAnchor(IDC_RESOLVELABEL
, BOTTOM_LEFT
);
152 AddAnchor(IDC_EDITCONFLICT
, BOTTOM_LEFT
);
153 AddAnchor(IDC_RESOLVED
, BOTTOM_RIGHT
);
154 AddAnchor(IDC_ORLABEL2
, BOTTOM_LEFT
);
155 AddAnchor(IDC_LEAVELABEL
, BOTTOM_LEFT
);
156 AddAnchor(IDCANCEL
, BOTTOM_LEFT
);
157 AddAnchor(IDC_RESOLVEALLLATER
, BOTTOM_RIGHT
);
158 AddAnchor(IDC_ABORT
, BOTTOM_RIGHT
);
159 AddAnchor(IDHELP
, BOTTOM_RIGHT
);
164 void CConflictResolveDlg::OnBnClickedUselocal()
166 m_choice
= svn_wc_conflict_choose_mine_full
;
170 void CConflictResolveDlg::OnBnClickedUserepo()
172 m_choice
= svn_wc_conflict_choose_theirs_full
;
176 void CConflictResolveDlg::OnBnClickedEditconflict()
178 CString filename
, n1
, n2
, n3
;
179 if (m_pConflictDescription
->property_name
)
181 filename
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->property_name
);
182 n1
.Format(IDS_DIFF_PROP_WCNAME
, (LPCTSTR
)filename
);
183 n2
.Format(IDS_DIFF_PROP_BASENAME
, (LPCTSTR
)filename
);
184 n3
.Format(IDS_DIFF_PROP_REMOTENAME
, (LPCTSTR
)filename
);
188 filename
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->path
);
189 filename
= CPathUtils::GetFileNameFromPath(filename
);
190 n1
.Format(IDS_DIFF_WCNAME
, (LPCTSTR
)filename
);
191 n2
.Format(IDS_DIFF_BASENAME
, (LPCTSTR
)filename
);
192 n3
.Format(IDS_DIFF_REMOTENAME
, (LPCTSTR
)filename
);
195 if (m_pConflictDescription
->base_file
== NULL
)
197 CAppUtils::DiffFlags flags
;
198 // no base file, start TortoiseMerge in Two-way diff mode
199 CAppUtils::StartExtDiff(CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->their_file
)),
200 CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->my_file
)),
205 // Subversion segfaults (1.5.1) if the path of the merged file is not a child of the
206 // folder where the conflict occurs. That's why we try to use the provided file path first...
207 if (m_pConflictDescription
->merged_file
)
208 m_mergedfile
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->merged_file
);
210 m_mergedfile
= CTempFiles::Instance().GetTempFilePath(false, CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->path
))).GetWinPath();
211 CAppUtils::StartExtMerge(CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->base_file
)),
212 CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->their_file
)),
213 CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->my_file
)),
214 CTSVNPath(m_mergedfile
),
215 n2
, n3
, n1
, CString(), false);
218 GetDlgItem(IDC_RESOLVED
)->EnableWindow(TRUE
);
221 void CConflictResolveDlg::OnBnClickedResolved()
223 m_choice
= svn_wc_conflict_choose_merged
;
224 if (m_mergedfile
.IsEmpty())
225 m_mergedfile
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->my_file
);
229 void CConflictResolveDlg::OnBnClickedResolvealllater()
231 m_choice
= svn_wc_conflict_choose_postpone
;
235 void CConflictResolveDlg::OnCancel()
237 m_choice
= svn_wc_conflict_choose_postpone
;
239 CResizableStandAloneDialog::OnCancel();
242 void CConflictResolveDlg::OnBnClickedHelp()
247 void CConflictResolveDlg::OnBnClickedAbort()
250 m_choice
= svn_wc_conflict_choose_postpone
;
251 CResizableStandAloneDialog::OnCancel();