1 // TortoiseSVN - 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
);
165 void CConflictResolveDlg::OnBnClickedUselocal()
167 m_choice
= svn_wc_conflict_choose_mine_full
;
171 void CConflictResolveDlg::OnBnClickedUserepo()
173 m_choice
= svn_wc_conflict_choose_theirs_full
;
177 void CConflictResolveDlg::OnBnClickedEditconflict()
179 CString filename
, n1
, n2
, n3
;
180 if (m_pConflictDescription
->property_name
)
182 filename
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->property_name
);
183 n1
.Format(IDS_DIFF_PROP_WCNAME
, (LPCTSTR
)filename
);
184 n2
.Format(IDS_DIFF_PROP_BASENAME
, (LPCTSTR
)filename
);
185 n3
.Format(IDS_DIFF_PROP_REMOTENAME
, (LPCTSTR
)filename
);
189 filename
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->path
);
190 filename
= CPathUtils::GetFileNameFromPath(filename
);
191 n1
.Format(IDS_DIFF_WCNAME
, (LPCTSTR
)filename
);
192 n2
.Format(IDS_DIFF_BASENAME
, (LPCTSTR
)filename
);
193 n3
.Format(IDS_DIFF_REMOTENAME
, (LPCTSTR
)filename
);
196 if (m_pConflictDescription
->base_file
== NULL
)
198 CAppUtils::DiffFlags flags
;
199 // no base file, start TortoiseMerge in Two-way diff mode
200 CAppUtils::StartExtDiff(CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->their_file
)),
201 CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->my_file
)),
206 // Subversion segfaults (1.5.1) if the path of the merged file is not a child of the
207 // folder where the conflict occurs. That's why we try to use the provided file path first...
208 if (m_pConflictDescription
->merged_file
)
209 m_mergedfile
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->merged_file
);
211 m_mergedfile
= CTempFiles::Instance().GetTempFilePath(false, CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->path
))).GetWinPath();
212 CAppUtils::StartExtMerge(CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->base_file
)),
213 CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->their_file
)),
214 CTSVNPath(CUnicodeUtils::GetUnicode(m_pConflictDescription
->my_file
)),
215 CTSVNPath(m_mergedfile
),
216 n2
, n3
, n1
, CString(), false);
219 GetDlgItem(IDC_RESOLVED
)->EnableWindow(TRUE
);
222 void CConflictResolveDlg::OnBnClickedResolved()
224 m_choice
= svn_wc_conflict_choose_merged
;
225 if (m_mergedfile
.IsEmpty())
226 m_mergedfile
= CUnicodeUtils::GetUnicode(m_pConflictDescription
->my_file
);
230 void CConflictResolveDlg::OnBnClickedResolvealllater()
232 m_choice
= svn_wc_conflict_choose_postpone
;
236 void CConflictResolveDlg::OnCancel()
238 m_choice
= svn_wc_conflict_choose_postpone
;
240 CResizableStandAloneDialog::OnCancel();
243 void CConflictResolveDlg::OnBnClickedHelp()
248 void CConflictResolveDlg::OnBnClickedAbort()
251 m_choice
= svn_wc_conflict_choose_postpone
;
252 CResizableStandAloneDialog::OnCancel();