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
11 * Mathias Kinzler (SAP AG) - initial implementation
12 *******************************************************************************/
13 package org
.eclipse
.egit
.ui
.internal
.preferences
;
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
;
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
;
56 * Displays the global Git configuration and allows to edit it.
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
;
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) {
97 protected void setErrorMessage(String message
) {
98 GlobalConfigurationPreferencePage
.this.setErrorMessage(message
);
102 protected void setDirty(boolean dirty
) {
107 sysConfigEditor
= new ConfigurationEditorComponent(tabFolder
, sysConfig
,
110 protected void setErrorMessage(String message
) {
111 GlobalConfigurationPreferencePage
.this.setErrorMessage(message
);
115 protected void setDirty(boolean dirty
) {
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
);
141 .setText(UIText
.GlobalConfigurationPreferencePage_repositorySettingRepositoryLabel
);
143 Combo repoCombo
= new Combo(repositoryComposite
, SWT
.READ_ONLY
);
144 repoCombo
.addSelectionListener(new SelectionAdapter() {
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) {
164 showRepositoryConfiguration(0);
166 repoCombo
.setItems(new String
[] {UIText
.GlobalConfigurationPreferencePage_repositorySettingNoRepositories
});
168 repoCombo
.setEnabled(false);
175 public void setVisible(boolean visible
) {
178 super.setVisible(visible
);
182 protected void updateApplyButton() {
183 if (getApplyButton() != null)
184 getApplyButton().setEnabled(userIsDirty
|| sysIsDirty
|| !dirtyRepositories
.isEmpty());
188 public boolean performOk() {
192 userConfigEditor
.save();
193 } catch (IOException e
) {
194 Activator
.handleError(e
.getMessage(), e
, true);
200 sysConfigEditor
.save();
201 } catch (IOException e
) {
202 Activator
.handleError(e
.getMessage(), e
, true);
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
);
214 } catch (IOException e
) {
215 Activator
.handleError(e
.getMessage(), e
, true);
223 protected void performDefaults() {
225 userConfigEditor
.restore();
226 sysConfigEditor
.restore();
227 for (ConfigurationEditorComponent editor
: repoConfigEditors
.values()) {
231 } catch (IOException e
) {
232 Activator
.handleError(e
.getMessage(), e
, true);
234 super.performDefaults();
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())
252 repositories
.add(repositoryCache
.lookupRepository(gitDir
));
253 } catch (IOException e
) {
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
>() {
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)
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
303 repositoryConfig
.addChangeListener(new ConfigChangedListener() {
306 public void onConfigChanged(ConfigChangedEvent event
) {
307 repository
.getListenerList().dispatch(
308 new ConfigChangedEvent());
312 repositoryConfig
= repository
.getConfig();
314 ConfigurationEditorComponent editorComponent
= new ConfigurationEditorComponent(
315 repoConfigComposite
, repositoryConfig
, true, 5) {
317 protected void setErrorMessage(String message
) {
318 GlobalConfigurationPreferencePage
.this.setErrorMessage(message
);
322 protected void setDirty(boolean dirty
) {
324 dirtyRepositories
.add(repository
);
326 dirtyRepositories
.remove(repository
);
330 editorComponent
.createContents();
331 return editorComponent
;