Add support for "project" config level
[TortoiseGit.git] / src / TortoiseProc / SubmoduleUpdateDlg.cpp
blob2dcb7a9cb381e781460b178d97a2ae32627ed0f9
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2012 Sven Strickroth, <email@cs-ware.de>
4 // Copyright (C) 2013 - TortoiseGit
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.
21 #include "stdafx.h"
22 #include "TortoiseProc.h"
23 #include "SubmoduleUpdateDlg.h"
24 #include "AppUtils.h"
25 #include "UnicodeUtils.h"
26 #include "MessageBox.h"
28 IMPLEMENT_DYNAMIC(CSubmoduleUpdateDlg, CStandAloneDialog)
30 CSubmoduleUpdateDlg::CSubmoduleUpdateDlg(CWnd* pParent /*=NULL*/)
31 : CStandAloneDialog(CSubmoduleUpdateDlg::IDD, pParent)
32 , m_bInit(true)
33 , m_bRecursive(FALSE)
34 , m_bForce(FALSE)
35 , m_bNoFetch(FALSE)
36 , m_bMerge(FALSE)
37 , m_bRebase(FALSE)
38 , m_bRemote(FALSE)
42 CSubmoduleUpdateDlg::~CSubmoduleUpdateDlg()
46 void CSubmoduleUpdateDlg::DoDataExchange(CDataExchange* pDX)
48 CStandAloneDialog::DoDataExchange(pDX);
49 DDX_Control(pDX, IDC_LIST_PATH, m_PathListBox);
50 DDX_Control(pDX, IDC_SELECTALL, m_SelectAll);
51 DDX_Check(pDX, IDC_CHECK_SUBMODULE_INIT, m_bInit);
52 DDX_Check(pDX, IDC_CHECK_SUBMODULE_RECURSIVE, m_bRecursive);
53 DDX_Check(pDX, IDC_FORCE, m_bForce);
54 DDX_Check(pDX, IDC_CHECK_SUBMODULE_NOFETCH, m_bNoFetch);
55 DDX_Check(pDX, IDC_CHECK_SUBMODULE_MERGE, m_bMerge);
56 DDX_Check(pDX, IDC_CHECK_SUBMODULE_REBASE, m_bRebase);
57 DDX_Check(pDX, IDC_CHECK_SUBMODULE_REMOTE, m_bRemote);
61 BEGIN_MESSAGE_MAP(CSubmoduleUpdateDlg, CStandAloneDialog)
62 ON_BN_CLICKED(IDC_SELECTALL, OnBnClickedSelectall)
63 ON_BN_CLICKED(IDOK, &CSubmoduleUpdateDlg::OnBnClickedOk)
64 ON_LBN_SELCHANGE(IDC_LIST_PATH, &CSubmoduleUpdateDlg::OnLbnSelchangeListPath)
65 END_MESSAGE_MAP()
67 static int SubmoduleCallback(git_submodule *sm, const char * /*name*/, void *payload)
69 STRING_VECTOR *list = *(STRING_VECTOR **)payload;
70 STRING_VECTOR *prefixList = *((STRING_VECTOR **)payload + 1);
71 CString path = CUnicodeUtils::GetUnicode(git_submodule_path(sm));
72 if (prefixList->empty())
74 list->push_back(path);
76 else
78 for (size_t i = 0; i < prefixList->size(); ++i)
80 CString prefix = prefixList->at(i) + _T("/");
81 if (path.Left(prefix.GetLength()) == prefix)
82 list->push_back(path);
85 return 0;
88 static void GetSubmodulePathList(STRING_VECTOR &list, STRING_VECTOR &prefixList)
90 git_repository *repo;
91 if (git_repository_open(&repo, CUnicodeUtils::GetUTF8(g_Git.m_CurrentDir)))
93 MessageBox(NULL, CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR);
94 return;
97 STRING_VECTOR *listParams[] = { &list, &prefixList };
98 if (git_submodule_foreach(repo, SubmoduleCallback, &listParams))
100 MessageBox(NULL, CGit::GetLibGit2LastErr(_T("Could not get submodule list.")), _T("TortoiseGit"), MB_ICONERROR);
101 return;
104 git_repository_free(repo);
105 std::sort(list.begin(), list.end());
108 BOOL CSubmoduleUpdateDlg::OnInitDialog()
110 CStandAloneDialog::OnInitDialog();
111 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
113 CString sWindowTitle;
114 GetWindowText(sWindowTitle);
115 CAppUtils::SetWindowTitle(m_hWnd, g_Git.m_CurrentDir, sWindowTitle);
117 AdjustControlSize(IDC_CHECK_SUBMODULE_INIT);
118 AdjustControlSize(IDC_CHECK_SUBMODULE_RECURSIVE);
119 AdjustControlSize(IDC_CHECK_SUBMODULE_NOFETCH);
120 AdjustControlSize(IDC_CHECK_SUBMODULE_MERGE);
121 AdjustControlSize(IDC_CHECK_SUBMODULE_REBASE);
123 CString WorkingDir = g_Git.m_CurrentDir;
124 WorkingDir.Replace(_T(':'), _T('_'));
126 m_regPath = CRegString(CString(_T("Software\\TortoiseGit\\History\\SubmoduleUpdatePath\\") + WorkingDir));
127 CString path = m_regPath;
128 STRING_VECTOR list;
129 GetSubmodulePathList(list, m_PathFilterList);
130 STRING_VECTOR selected;
131 if (m_PathList.empty())
133 int pos = 0;
134 while (pos >= 0)
136 CString part = path.Tokenize(_T("|"), pos);
137 if (!part.IsEmpty())
138 selected.push_back(part);
141 else
143 for (size_t i = 0; i < m_PathList.size(); ++i)
144 selected.push_back(m_PathList[i]);
147 for (size_t i = 0; i < list.size(); ++i)
149 m_PathListBox.AddString(list[i]);
150 if (selected.size() == 0)
151 m_PathListBox.SetSel((int)i);
152 else
154 for (int j = 0; j < selected.size(); ++j)
156 if (selected[j] == list[i])
157 m_PathListBox.SetSel((int)i);
162 OnLbnSelchangeListPath();
163 UpdateData(FALSE);
165 return TRUE;
168 void CSubmoduleUpdateDlg::OnBnClickedOk()
170 CStandAloneDialog::UpdateData(TRUE);
171 m_PathList.clear();
172 if (m_bRemote && CAppUtils::GetMsysgitVersion() < 0x01080200)
174 CString gitver;
175 gitver.Format(IDS_GITVER_REQUIRED, _T("--remote"), _T("1.8.2"));
176 CMessageBox::Show(m_hWnd, gitver, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
177 return;
180 CString selected;
181 for (int i = 0; i < m_PathListBox.GetCount(); ++i)
183 if (m_PathListBox.GetSel(i))
185 if (!selected.IsEmpty())
186 selected.Append(_T("|"));
187 CString text;
188 m_PathListBox.GetText(i, text);
189 m_PathList.push_back(text);
190 selected.Append(text);
193 m_regPath = selected;
195 CStandAloneDialog::OnOK();
198 void CSubmoduleUpdateDlg::OnLbnSelchangeListPath()
200 GetDlgItem(IDOK)->EnableWindow(m_PathListBox.GetSelCount() > 0 ? TRUE : FALSE);
201 if (m_PathListBox.GetSelCount() == 0)
202 m_SelectAll.SetCheck(BST_UNCHECKED);
203 else if ((int)m_PathListBox.GetSelCount() < m_PathListBox.GetCount())
204 m_SelectAll.SetCheck(BST_INDETERMINATE);
205 else
206 m_SelectAll.SetCheck(BST_CHECKED);
209 void CSubmoduleUpdateDlg::OnBnClickedSelectall()
211 UINT state = (m_SelectAll.GetState() & 0x0003);
212 if (state == BST_INDETERMINATE)
214 // It is not at all useful to manually place the checkbox into the indeterminate state...
215 // We will force this on to the unchecked state
216 state = BST_UNCHECKED;
217 m_SelectAll.SetCheck(state);
219 if (state == BST_UNCHECKED)
221 for (int i = 0; i < m_PathListBox.GetCount(); ++i)
222 m_PathListBox.SetSel(i, FALSE);
224 else
226 for (int i = 0; i < m_PathListBox.GetCount(); ++i)
227 m_PathListBox.SetSel(i, TRUE);