1/* 2 * This file is part of gitg 3 * 4 * Copyright (C) 2013 - Sindhu S 5 * 6 * gitg is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * gitg 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. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with gitg. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20namespace Gitg 21{ 22 [GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-author-details-dialog.ui")] 23 public class AuthorDetailsDialog : Gtk.Dialog 24 { 25 //Do this to pull in config.h before glib.h (for gettext) 26 private const string version = Gitg.Config.VERSION; 27 28 [GtkChild (name = "entry_name")] 29 private Gtk.Entry d_entry_name; 30 31 [GtkChild (name = "entry_email")] 32 private Gtk.Entry d_entry_email; 33 34 [GtkChild (name = "label_info")] 35 private Gtk.Label d_label_info; 36 37 [GtkChild (name = "checkbutton_override_global")] 38 private Gtk.CheckButton d_checkbutton_override_global; 39 40 private string? d_repository_name; 41 42 private Ggit.Config d_config; 43 44 public AuthorDetailsDialog (Gtk.Window? parent, Ggit.Config config, string? repository_name) 45 { 46 Object (use_header_bar: 1); 47 48 if (parent != null) 49 { 50 set_transient_for (parent); 51 } 52 53 d_repository_name = repository_name; 54 d_config = config; 55 } 56 57 public static AuthorDetailsDialog? show_global(Window window) 58 { 59 var xdg_config_path = Path.build_filename(Environment.get_user_config_dir(), "git", "config"); 60 var config_path = Path.build_filename(Environment.get_home_dir(), ".gitconfig"); 61 62 // If neither exists yet, create default empty one 63 if (!FileUtils.test(xdg_config_path, FileTest.EXISTS) && !FileUtils.test(config_path, FileTest.EXISTS)) 64 { 65 try 66 { 67 FileUtils.set_contents(config_path, ""); 68 } catch {} 69 } 70 71 var global_config_file = Ggit.Config.find_global(); 72 73 if (global_config_file == null) 74 { 75 return null; 76 } 77 78 Ggit.Config? global_config; 79 80 try 81 { 82 global_config = new Ggit.Config.from_file(global_config_file); 83 } 84 catch 85 { 86 return null; 87 } 88 89 var author_details = new AuthorDetailsDialog(window, global_config, null); 90 author_details.show(); 91 92 return author_details; 93 } 94 95 private void build_global() 96 { 97 title = _("Author Details"); 98 d_label_info.label = _("Enter default details used for all repositories:"); 99 d_label_info.show(); 100 } 101 102 private bool config_is_local(string name) 103 { 104 try 105 { 106 var entry = d_config.get_entry(name); 107 return entry.get_level() == Ggit.ConfigLevel.LOCAL; 108 } 109 catch 110 { 111 return false; 112 } 113 } 114 115 private void build_repository() 116 { 117 title = "%s — %s".printf(d_repository_name, _("Author Details")); 118 119 // Translators: %s is the repository name 120 d_checkbutton_override_global.label = _("Override global details for repository “%s”:").printf(d_repository_name); 121 d_checkbutton_override_global.active = (config_is_local("user.name") || config_is_local("user.email")); 122 123 d_checkbutton_override_global.notify["active"].connect(update_sensitivity); 124 d_checkbutton_override_global.show(); 125 126 update_sensitivity(); 127 } 128 129 private void update_sensitivity() 130 { 131 d_entry_name.sensitive = d_checkbutton_override_global.active; 132 d_entry_email.sensitive = d_checkbutton_override_global.active; 133 134 Ggit.Config? config = null; 135 136 try 137 { 138 if (!d_checkbutton_override_global.active) 139 { 140 config = d_config.open_level(Ggit.ConfigLevel.GLOBAL); 141 } 142 else 143 { 144 config = d_config; 145 } 146 } catch {} 147 148 if (config != null) 149 { 150 update_entries(config); 151 } 152 } 153 154 public override void show() 155 { 156 base.show(); 157 158 if (d_repository_name == null) 159 { 160 build_global(); 161 } 162 else 163 { 164 build_repository(); 165 } 166 167 update_entries(d_config); 168 } 169 170 private string read_config_string(Ggit.Config config, string name, string defval = "") 171 { 172 string? ret = null; 173 174 try 175 { 176 ret = config.snapshot().get_string(name); 177 } catch {} 178 179 return ret != null ? ret : defval; 180 } 181 182 private void update_entries(Ggit.Config config) 183 { 184 d_entry_name.set_text(read_config_string(config, "user.name").chomp()); 185 d_entry_email.set_text(read_config_string(config, "user.email").chomp()); 186 } 187 188 private void delete_local_entries() 189 { 190 try 191 { 192 if (d_config.get_entry("user.name").get_level() == Ggit.ConfigLevel.LOCAL) 193 { 194 d_config.delete_entry("user.name"); 195 } 196 } catch {} 197 198 try 199 { 200 if (d_config.get_entry("user.email").get_level() == Ggit.ConfigLevel.LOCAL) 201 { 202 d_config.delete_entry("user.email"); 203 } 204 } catch {} 205 } 206 207 public override void response(int id) { 208 if (id == Gtk.ResponseType.OK) 209 { 210 try 211 { 212 if (d_repository_name != null) 213 { 214 if (d_checkbutton_override_global.active) 215 { 216 d_config.set_string("user.name", d_entry_name.get_text()); 217 d_config.set_string("user.email", d_entry_email.get_text()); 218 } 219 else 220 { 221 delete_local_entries(); 222 } 223 } 224 else 225 { 226 d_config.set_string("user.name", d_entry_name.get_text()); 227 d_config.set_string("user.email", d_entry_email.get_text()); 228 } 229 } 230 catch (Error e) 231 { 232 show_config_error(_("Failed to set Git user config."), e.message); 233 destroy(); 234 return; 235 } 236 } 237 238 destroy(); 239 } 240 241 private void show_config_error(string primary_message, string secondary_message) 242 { 243 var error_dialog = new Gtk.MessageDialog(this, 244 Gtk.DialogFlags.DESTROY_WITH_PARENT, 245 Gtk.MessageType.ERROR, 246 Gtk.ButtonsType.OK, 247 "%s", 248 primary_message); 249 250 error_dialog.secondary_text = secondary_message; 251 error_dialog.response.connect((d, id) => { 252 error_dialog.destroy(); 253 }); 254 255 error_dialog.show(); 256 } 257 } 258} 259 260/* vi:ts=4 */ 261