Warn user before saving if source differs from destination store
[TortoiseGit.git] / src / TortoiseProc / Settings / GitSettings.h
blob1718be1e740ed5b67f4a4c51661a3c92b61aaef7
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013 - TortoiseGit
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 #pragma once
21 #include "../TortoiseProc.h"
22 #include "Git.h"
23 #include "Tooltip.h"
24 #include "../../Utils/UnicodeUtils.h"
26 class CSettings;
28 class CGitSettings
30 public:
31 CGitSettings()
32 : m_iConfigSource(0)
33 , m_bGlobal(false)
34 , m_bIsBareRepo(false)
35 , m_bHonorProjectConfig(false)
39 protected:
40 CComboBox m_cSaveTo;
41 int m_iConfigSource;
42 bool m_bGlobal;
43 bool m_bIsBareRepo;
44 bool m_bHonorProjectConfig;
46 void InitGitSettings(ISettingsPropPage *page, bool honorProjectConfig, CToolTips * tooltips)
48 m_bHonorProjectConfig = honorProjectConfig;
50 if (tooltips)
52 tooltips->AddTool(IDC_RADIO_SETTINGS_LOCAL, IDS_CONFIG_LOCAL_TT);
53 if (page->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT) != nullptr)
54 tooltips->AddTool(IDC_RADIO_SETTINGS_PROJECT, IDS_CONFIG_PROJECT_TT);
55 tooltips->AddTool(IDC_RADIO_SETTINGS_GLOBAL, IDS_CONFIG_GLOBAL_TT);
58 CString str = g_Git.m_CurrentDir;
59 m_bIsBareRepo = g_GitAdminDir.IsBareRepo(str);
60 CString proj;
61 if (g_GitAdminDir.HasAdminDir(str, &proj) || m_bIsBareRepo)
63 CString title;
64 page->GetWindowText(title);
65 page->SetWindowText(title + _T(" - ") + proj);
66 page->GetDlgItem(IDC_RADIO_SETTINGS_LOCAL)->EnableWindow(TRUE);
68 m_cSaveTo.AddString(CString(MAKEINTRESOURCE(IDS_CONFIG_LOCAL)));
70 if (page->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT) != nullptr)
72 page->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT)->EnableWindow(honorProjectConfig);
73 if (honorProjectConfig && !m_bIsBareRepo)
74 m_cSaveTo.AddString(CString(MAKEINTRESOURCE(IDS_CONFIG_PROJECT)));
77 else
79 m_bGlobal = true;
80 page->GetDlgItem(IDC_RADIO_SETTINGS_LOCAL)->EnableWindow(FALSE);
81 if (page->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT) != nullptr)
82 page->GetDlgItem(IDC_RADIO_SETTINGS_PROJECT)->EnableWindow(FALSE);
84 m_cSaveTo.AddString(CString(MAKEINTRESOURCE(IDS_CONFIG_GLOBAL)));
85 m_cSaveTo.SetCurSel(0);
87 page->CheckRadioButton(IDC_RADIO_SETTINGS_EFFECTIVE, IDC_RADIO_SETTINGS_SYSTEM, IDC_RADIO_SETTINGS_EFFECTIVE + m_iConfigSource);
89 LoadData();
92 bool Save(git_config * config, const CString &key, const CString &value, const bool askEmptyDelete = false, const CString def = _T(""))
94 CStringA keyA = CUnicodeUtils::GetUTF8(key);
95 int err = 0;
96 if (value.IsEmpty() || value == def)
98 const git_config_entry * entry = nullptr;
99 if (git_config_get_entry(&entry, config, keyA) == GIT_ENOTFOUND)
100 return true;
101 if (askEmptyDelete && CMessageBox::Show(nullptr, IDS_ASK_DELETE_EMPTY, IDS_APPNAME, 2, IDI_QUESTION, IDS_DELETEBUTTON, IDS_NO) == 2)
102 return true;
103 err = git_config_delete_entry(config, keyA);
105 else
107 CStringA valueA = CUnicodeUtils::GetMulti(value, CP_UTF8);
108 err = git_config_set_string(config, keyA, valueA);
110 if (err)
112 CString msg;
113 msg.Format(IDS_PROC_SAVECONFIGFAILED, key, value);
114 CMessageBox::Show(nullptr, g_Git.GetLibGit2LastErr(msg), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
115 return false;
117 return true;
120 void LoadData()
122 git_config * config;
123 git_config_new(&config);
124 if (!m_bGlobal && (m_iConfigSource == 0 || m_iConfigSource == 1))
126 if (git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.GetGitLocalConfig()), GIT_CONFIG_LEVEL_APP, FALSE)) // this needs to have the highest priority in order to override .tgitconfig settings
127 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
129 if ((m_iConfigSource == 0 && m_bHonorProjectConfig) || m_iConfigSource == 2)
131 if (!m_bIsBareRepo)
133 if (git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.m_CurrentDir) + "\\.tgitconfig", GIT_CONFIG_LEVEL_LOCAL, FALSE)) // this needs to have the second highest priority
134 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
136 else
138 CString tmpFile = GetTempFile();
139 CTGitPath path(_T(".tgitconfig"));
140 if (g_Git.GetOneFile(_T("HEAD"), path, tmpFile) == 0)
142 if (git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(tmpFile), GIT_CONFIG_LEVEL_LOCAL, FALSE)) // this needs to have the second highest priority
143 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
147 if (m_iConfigSource == 0 || m_iConfigSource == 3)
149 if (git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL, FALSE))
150 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
151 else
153 if (git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG, FALSE))
154 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
157 if (m_iConfigSource == 0 || m_iConfigSource == 4)
159 if (git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.GetGitSystemConfig()), GIT_CONFIG_LEVEL_SYSTEM, FALSE))
160 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
163 LoadDataImpl(config);
165 git_config_free(config);
168 bool WarnUserSafeToDifferentDestination(int storeTo)
170 if ((storeTo == IDS_CONFIG_GLOBAL && m_iConfigSource != 3) || (storeTo == IDS_CONFIG_PROJECT && m_iConfigSource != 2) || (storeTo == IDS_CONFIG_LOCAL && m_iConfigSource != 1))
172 CString dest;
173 dest.LoadString(storeTo);
174 CString msg;
175 msg.Format(IDS_WARNUSERSAFEDIFFERENT, dest);
176 if (CMessageBox::Show(nullptr, msg, _T("TortoiseGit"), 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_SAVEBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2)
177 return false;
179 return true;
182 BOOL SafeData()
184 git_config * config;
185 git_config_new(&config);
187 int err = 0;
188 if (m_bGlobal || (m_cSaveTo.GetCurSel() == 1 && (!m_bHonorProjectConfig || m_bIsBareRepo)) || m_cSaveTo.GetCurSel() == 2)
190 if (!WarnUserSafeToDifferentDestination(IDS_CONFIG_GLOBAL))
191 return FALSE;
192 if (PathIsDirectory(g_Git.GetGitGlobalXDGConfigPath()))
193 err = git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalXDGConfig()), GIT_CONFIG_LEVEL_XDG, FALSE);
194 else
195 err = git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.GetGitGlobalConfig()), GIT_CONFIG_LEVEL_GLOBAL, FALSE);
197 else if (m_cSaveTo.GetCurSel() == 1 && !m_bIsBareRepo && m_bHonorProjectConfig)
199 if (!WarnUserSafeToDifferentDestination(IDS_CONFIG_PROJECT))
200 return FALSE;
201 err = git_config_add_file_ondisk(config, CUnicodeUtils::GetUTF8(g_Git.m_CurrentDir) + "\\.tgitconfig", GIT_CONFIG_LEVEL_APP, FALSE);
203 else
205 if (!WarnUserSafeToDifferentDestination(IDS_CONFIG_PROJECT))
206 return FALSE;
207 err = git_config_add_file_ondisk(config, CUnicodeUtils::GetMulti(g_Git.GetGitLocalConfig(), CP_UTF8), GIT_CONFIG_LEVEL_LOCAL, FALSE);
209 if (err)
211 MessageBox(nullptr, g_Git.GetLibGit2LastErr(), _T("TortoiseGit"), MB_ICONEXCLAMATION);
212 return FALSE;
215 int ret = SafeDataImpl(config);
217 git_config_free(config);
219 return ret;
222 virtual void LoadDataImpl(git_config * config) = 0;
223 virtual BOOL SafeDataImpl(git_config * config) = 0;
225 static void AddTrueFalseToComboBox(CComboBox &combobox)
227 combobox.AddString(_T(""));
228 combobox.AddString(_T("true"));
229 combobox.AddString(_T("false"));
232 static void GetBoolConfigValueComboBox(git_config * config, const CString &key, CComboBox &combobox)
234 CStringA keyA = CUnicodeUtils::GetUTF8(key);
235 BOOL out = 0;
236 if (git_config_get_bool(&out, config, keyA) == GIT_ENOTFOUND)
237 combobox.SetCurSel(0);
238 else if (out)
239 combobox.SetCurSel(1);
240 else
241 combobox.SetCurSel(2);
244 static int GetConfigValue(git_config * config, const CString &key, CString &value)
246 CStringA keyA = CUnicodeUtils::GetUTF8(key);
247 const char *out = nullptr;
248 int retval = git_config_get_string(&out, config, keyA);
249 value = CUnicodeUtils::GetUnicode((CStringA)out);
250 return retval;
254 #define GITSETTINGS_DDX \
255 DDX_Control(pDX, IDC_COMBO_SETTINGS_SAFETO, m_cSaveTo);
257 #define GITSETTINGS_RADIO_EVENT \
258 ON_CBN_SELCHANGE(IDC_COMBO_SETTINGS_SAFETO, &OnChange) \
259 ON_BN_CLICKED(IDC_RADIO_SETTINGS_EFFECTIVE, &OnBnClickedChangedConfigSource) \
260 ON_BN_CLICKED(IDC_RADIO_SETTINGS_LOCAL, &OnBnClickedChangedConfigSource) \
261 ON_BN_CLICKED(IDC_RADIO_SETTINGS_PROJECT, &OnBnClickedChangedConfigSource) \
262 ON_BN_CLICKED(IDC_RADIO_SETTINGS_GLOBAL, &OnBnClickedChangedConfigSource) \
263 ON_BN_CLICKED(IDC_RADIO_SETTINGS_SYSTEM, &OnBnClickedChangedConfigSource)
265 #define GITSETTINGS_RADIO_EVENT_HANDLE \
266 afx_msg void OnBnClickedChangedConfigSource() \
268 m_iConfigSource = GetCheckedRadioButton(IDC_RADIO_SETTINGS_EFFECTIVE, IDC_RADIO_SETTINGS_SYSTEM) - IDC_RADIO_SETTINGS_EFFECTIVE; \
269 LoadData(); \