Have icon for "reset" entry in reflog
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / preferences / GlobalConfigurationPreferencePage.java
blob046edaac7f9bb8b3ae42b2ace65c2daf2a1660c6
1 /*******************************************************************************
2 * Copyright (c) 2010, SAP AG.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License 2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-2.0/
8 * SPDX-License-Identifier: EPL-2.0
10 * Contributors:
11 * Mathias Kinzler (SAP AG) - initial implementation
12 *******************************************************************************/
13 package org.eclipse.egit.ui.internal.preferences;
15 import java.io.File;
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.Comparator;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
26 import org.eclipse.egit.core.RepositoryCache;
27 import org.eclipse.egit.ui.Activator;
28 import org.eclipse.egit.ui.internal.SWTUtils;
29 import org.eclipse.egit.ui.internal.UIText;
30 import org.eclipse.jface.dialogs.Dialog;
31 import org.eclipse.jface.layout.GridDataFactory;
32 import org.eclipse.jface.layout.GridLayoutFactory;
33 import org.eclipse.jface.preference.PreferencePage;
34 import org.eclipse.jgit.events.ConfigChangedEvent;
35 import org.eclipse.jgit.events.ConfigChangedListener;
36 import org.eclipse.jgit.lib.Repository;
37 import org.eclipse.jgit.lib.StoredConfig;
38 import org.eclipse.jgit.storage.file.FileBasedConfig;
39 import org.eclipse.jgit.util.FS;
40 import org.eclipse.jgit.util.SystemReader;
41 import org.eclipse.swt.SWT;
42 import org.eclipse.swt.custom.StackLayout;
43 import org.eclipse.swt.events.SelectionAdapter;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.layout.GridLayout;
46 import org.eclipse.swt.widgets.Combo;
47 import org.eclipse.swt.widgets.Composite;
48 import org.eclipse.swt.widgets.Control;
49 import org.eclipse.swt.widgets.Label;
50 import org.eclipse.swt.widgets.TabFolder;
51 import org.eclipse.swt.widgets.TabItem;
52 import org.eclipse.ui.IWorkbench;
53 import org.eclipse.ui.IWorkbenchPreferencePage;
55 /**
56 * Displays the global Git configuration and allows to edit it.
57 * <p>
58 * In EGit, this maps to the user configuration.
60 public class GlobalConfigurationPreferencePage extends PreferencePage implements
61 IWorkbenchPreferencePage {
62 /** The ID of this page */
63 public static final String ID = "org.eclipse.egit.ui.internal.preferences.GlobalConfigurationPreferencePage"; //$NON-NLS-1$
65 private FileBasedConfig userConfig;
67 private FileBasedConfig sysConfig;
69 private StackLayout repoConfigStackLayout;
71 private List<Repository> repositories;
73 private Map<Repository, ConfigurationEditorComponent> repoConfigEditors = new HashMap<>();
75 private Set<Repository> dirtyRepositories = new HashSet<>();
77 private boolean userIsDirty;
79 private boolean sysIsDirty;
81 private ConfigurationEditorComponent userConfigEditor;
83 private ConfigurationEditorComponent sysConfigEditor;
85 private Composite repoConfigComposite;
87 @Override
88 protected Control createContents(Composite parent) {
90 Composite composite = SWTUtils.createHVFillComposite(parent,
91 SWTUtils.MARGINS_NONE);
92 TabFolder tabFolder = new TabFolder(composite, SWT.NONE);
93 tabFolder.setLayoutData(SWTUtils.createHVFillGridData());
94 userConfigEditor = new ConfigurationEditorComponent(tabFolder,
95 userConfig, true, 5) {
96 @Override
97 protected void setErrorMessage(String message) {
98 GlobalConfigurationPreferencePage.this.setErrorMessage(message);
101 @Override
102 protected void setDirty(boolean dirty) {
103 userIsDirty = dirty;
104 updateApplyButton();
107 sysConfigEditor = new ConfigurationEditorComponent(tabFolder, sysConfig,
108 true, 5) {
109 @Override
110 protected void setErrorMessage(String message) {
111 GlobalConfigurationPreferencePage.this.setErrorMessage(message);
114 @Override
115 protected void setDirty(boolean dirty) {
116 sysIsDirty = dirty;
117 updateApplyButton();
120 Control result = userConfigEditor.createContents();
121 Dialog.applyDialogFont(result);
122 TabItem userTabItem = new TabItem(tabFolder, SWT.FILL);
123 userTabItem.setControl(result);
124 userTabItem.setText(UIText.GlobalConfigurationPreferencePage_userSettingTabTitle);
126 result = sysConfigEditor.createContents();
127 Dialog.applyDialogFont(result);
128 TabItem sysTabItem = new TabItem(tabFolder, SWT.FILL);
129 sysTabItem.setControl(result);
130 sysTabItem.setText(UIText.GlobalConfigurationPreferencePage_systemSettingTabTitle);
132 Composite repoTab = new Composite(tabFolder, SWT.NONE);
133 GridLayoutFactory.swtDefaults().margins(0, 0).applyTo(repoTab);
134 GridDataFactory.fillDefaults().grab(true, true).applyTo(repoTab);
135 Composite repositoryComposite = new Composite(repoTab, SWT.NONE);
136 repositoryComposite.setLayout(new GridLayout(2, false));
137 GridDataFactory.fillDefaults().grab(true, false).applyTo(
138 repositoryComposite);
139 Label repoLabel = new Label(repositoryComposite, SWT.NONE);
140 repoLabel
141 .setText(UIText.GlobalConfigurationPreferencePage_repositorySettingRepositoryLabel);
143 Combo repoCombo = new Combo(repositoryComposite, SWT.READ_ONLY);
144 repoCombo.addSelectionListener(new SelectionAdapter() {
145 @Override
146 public void widgetSelected(SelectionEvent e) {
147 Combo combo = (Combo) e.widget;
148 showRepositoryConfiguration(combo.getSelectionIndex());
151 repoCombo.setItems(getRepositoryComboItems());
153 repoConfigComposite = new Composite(repoTab, SWT.NONE);
154 GridDataFactory.fillDefaults().grab(true, true).applyTo(repoConfigComposite);
155 repoConfigStackLayout = new StackLayout();
156 repoConfigComposite.setLayout(repoConfigStackLayout);
158 TabItem repoTabItem = new TabItem(tabFolder, SWT.FILL);
159 repoTabItem.setControl(repoTab);
160 repoTabItem.setText(UIText.GlobalConfigurationPreferencePage_repositorySettingTabTitle);
162 if (repoCombo.getItemCount() > 0) {
163 repoCombo.select(0);
164 showRepositoryConfiguration(0);
165 } else {
166 repoCombo.setItems(new String[] {UIText.GlobalConfigurationPreferencePage_repositorySettingNoRepositories});
167 repoCombo.select(0);
168 repoCombo.setEnabled(false);
171 return composite;
174 @Override
175 public void setVisible(boolean visible) {
176 if (visible)
177 updateApplyButton();
178 super.setVisible(visible);
181 @Override
182 protected void updateApplyButton() {
183 if (getApplyButton() != null)
184 getApplyButton().setEnabled(userIsDirty || sysIsDirty || !dirtyRepositories.isEmpty());
187 @Override
188 public boolean performOk() {
189 boolean ok = true;
190 if (userIsDirty) {
191 try {
192 userConfigEditor.save();
193 } catch (IOException e) {
194 Activator.handleError(e.getMessage(), e, true);
195 ok = false;
198 if (sysIsDirty) {
199 try {
200 sysConfigEditor.save();
201 } catch (IOException e) {
202 Activator.handleError(e.getMessage(), e, true);
203 ok = false;
206 // Use array since calling save updates the dirty state which updates
207 // the set of dirty repositories that is being iterated over
208 final Repository[] repos = dirtyRepositories
209 .toArray(new Repository[0]);
210 for (Repository repository : repos) {
211 ConfigurationEditorComponent editor = repoConfigEditors.get(repository);
212 try {
213 editor.save();
214 } catch (IOException e) {
215 Activator.handleError(e.getMessage(), e, true);
216 ok = false;
219 return ok;
222 @Override
223 protected void performDefaults() {
224 try {
225 userConfigEditor.restore();
226 sysConfigEditor.restore();
227 for (ConfigurationEditorComponent editor : repoConfigEditors.values()) {
228 editor.restore();
231 } catch (IOException e) {
232 Activator.handleError(e.getMessage(), e, true);
234 super.performDefaults();
237 @Override
238 public void init(IWorkbench workbench) {
239 if (sysConfig == null)
240 sysConfig = SystemReader.getInstance().openSystemConfig(null, FS.DETECTED);
241 if (userConfig == null)
242 userConfig = SystemReader.getInstance().openUserConfig(null, FS.DETECTED); // no inherit here!
243 if (repositories == null) {
244 repositories = new ArrayList<>();
245 List<String> repoPaths = Activator.getDefault().getRepositoryUtil().getConfiguredRepositories();
246 RepositoryCache repositoryCache = org.eclipse.egit.core.Activator.getDefault().getRepositoryCache();
247 for (String repoPath : repoPaths) {
248 File gitDir = new File(repoPath);
249 if (!gitDir.exists())
250 continue;
251 try {
252 repositories.add(repositoryCache.lookupRepository(gitDir));
253 } catch (IOException e) {
254 continue;
257 sortRepositoriesByName();
261 private String getName(final Repository repo) {
262 return Activator.getDefault().getRepositoryUtil()
263 .getRepositoryName(repo);
266 private void sortRepositoriesByName() {
267 Collections.sort(repositories, new Comparator<Repository>() {
269 @Override
270 public int compare(Repository repo1, Repository repo2) {
271 return getName(repo1).compareTo(getName(repo2));
276 private String[] getRepositoryComboItems() {
277 List<String> items = new ArrayList<>();
278 for (Repository repository : repositories) {
279 String repoName = getName(repository);
280 if (repoName.length() > 0)
281 items.add(repoName);
283 return items.toArray(new String[0]);
286 private void showRepositoryConfiguration(int index) {
287 Repository repository = repositories.get(index);
288 ConfigurationEditorComponent editor = repoConfigEditors.get(repository);
289 if (editor == null) {
290 editor = createConfigurationEditor(repository);
291 repoConfigEditors.put(repository, editor);
293 repoConfigStackLayout.topControl = editor.getContents();
294 repoConfigComposite.layout();
297 private ConfigurationEditorComponent createConfigurationEditor(final Repository repository) {
298 StoredConfig repositoryConfig;
299 if (repository.getConfig() instanceof FileBasedConfig) {
300 File configFile = ((FileBasedConfig) repository.getConfig()).getFile();
301 repositoryConfig = new FileBasedConfig(configFile, repository
302 .getFS());
303 repositoryConfig.addChangeListener(new ConfigChangedListener() {
305 @Override
306 public void onConfigChanged(ConfigChangedEvent event) {
307 repository.getListenerList().dispatch(
308 new ConfigChangedEvent());
311 } else {
312 repositoryConfig = repository.getConfig();
314 ConfigurationEditorComponent editorComponent = new ConfigurationEditorComponent(
315 repoConfigComposite, repositoryConfig, true, 5) {
316 @Override
317 protected void setErrorMessage(String message) {
318 GlobalConfigurationPreferencePage.this.setErrorMessage(message);
321 @Override
322 protected void setDirty(boolean dirty) {
323 if (dirty)
324 dirtyRepositories.add(repository);
325 else
326 dirtyRepositories.remove(repository);
327 updateApplyButton();
330 editorComponent.createContents();
331 return editorComponent;