Initial EGit contribution to eclipse.org
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / preferences / GitDecoratorPreferencePage.java
blobec3aaa138bfd23a1eda1ef168cca3084692fd44a
1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
3 * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
9 *******************************************************************************/
10 package org.eclipse.egit.ui.internal.preferences;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Observable;
20 import java.util.Observer;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.egit.ui.Activator;
24 import org.eclipse.egit.ui.UIPreferences;
25 import org.eclipse.egit.ui.UIText;
26 import org.eclipse.egit.ui.internal.SWTUtils;
27 import org.eclipse.egit.ui.internal.decorators.IDecoratableResource;
28 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator.DecorationHelper;
29 import org.eclipse.egit.ui.internal.decorators.IDecoratableResource.Staged;
30 import org.eclipse.jface.dialogs.Dialog;
31 import org.eclipse.jface.preference.IPreferenceStore;
32 import org.eclipse.jface.preference.PreferencePage;
33 import org.eclipse.jface.preference.PreferenceStore;
34 import org.eclipse.jface.resource.ImageDescriptor;
35 import org.eclipse.jface.resource.JFaceResources;
36 import org.eclipse.jface.resource.LocalResourceManager;
37 import org.eclipse.jface.resource.ResourceManager;
38 import org.eclipse.jface.util.IPropertyChangeListener;
39 import org.eclipse.jface.util.PropertyChangeEvent;
40 import org.eclipse.jface.viewers.DecorationContext;
41 import org.eclipse.jface.viewers.DecorationOverlayIcon;
42 import org.eclipse.jface.viewers.IDecoration;
43 import org.eclipse.jface.viewers.IDecorationContext;
44 import org.eclipse.jface.viewers.ILabelProvider;
45 import org.eclipse.jface.viewers.IStructuredContentProvider;
46 import org.eclipse.jface.viewers.ITreeContentProvider;
47 import org.eclipse.jface.viewers.LabelProvider;
48 import org.eclipse.jface.viewers.TreeViewer;
49 import org.eclipse.jface.viewers.Viewer;
50 import org.eclipse.jface.window.Window;
51 import org.eclipse.swt.SWT;
52 import org.eclipse.swt.events.ModifyEvent;
53 import org.eclipse.swt.events.ModifyListener;
54 import org.eclipse.swt.events.SelectionAdapter;
55 import org.eclipse.swt.events.SelectionEvent;
56 import org.eclipse.swt.events.SelectionListener;
57 import org.eclipse.swt.graphics.Color;
58 import org.eclipse.swt.graphics.Font;
59 import org.eclipse.swt.graphics.Image;
60 import org.eclipse.swt.layout.GridData;
61 import org.eclipse.swt.layout.GridLayout;
62 import org.eclipse.swt.widgets.Button;
63 import org.eclipse.swt.widgets.Composite;
64 import org.eclipse.swt.widgets.Control;
65 import org.eclipse.swt.widgets.Event;
66 import org.eclipse.swt.widgets.Label;
67 import org.eclipse.swt.widgets.Listener;
68 import org.eclipse.swt.widgets.Scale;
69 import org.eclipse.swt.widgets.TabFolder;
70 import org.eclipse.swt.widgets.TabItem;
71 import org.eclipse.swt.widgets.Text;
72 import org.eclipse.swt.widgets.TreeItem;
73 import org.eclipse.ui.ISharedImages;
74 import org.eclipse.ui.IWorkbench;
75 import org.eclipse.ui.IWorkbenchPreferencePage;
76 import org.eclipse.ui.PlatformUI;
77 import org.eclipse.ui.dialogs.ListSelectionDialog;
78 import org.eclipse.ui.ide.IDE.SharedImages;
79 import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
81 /**
82 * Preference page for customizing Git label decorations
84 public class GitDecoratorPreferencePage extends PreferencePage implements
85 IWorkbenchPreferencePage {
87 private GeneralTab generalTab;
89 private TextDecorationTab textDecorationTab;
91 private IconDecorationTab iconDecorationTab;
93 private Preview preview;
95 private static final Collection PREVIEW_FILESYSTEM_ROOT;
97 private static final Map<String, String> FILE_AND_FOLDER_BINDINGS;
99 private static final Map<String, String> PROJECT_BINDINGS;
101 private static IPropertyChangeListener themeListener;
103 static {
104 final PreviewResource project = new PreviewResource(
105 "Project", IResource.PROJECT, "master", true, false, true, Staged.NOT_STAGED, false, false); //$NON-NLS-1$ //$NON-NLS-2$1
106 final ArrayList<PreviewResource> children = new ArrayList<PreviewResource>();
108 children
109 .add(new PreviewResource(
110 "folder", IResource.FOLDER, null, true, false, true, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
111 children
112 .add(new PreviewResource(
113 "tracked.txt", IResource.FILE, null, true, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
114 children
115 .add(new PreviewResource(
116 "untracked.txt", IResource.FILE, null, false, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
117 children
118 .add(new PreviewResource(
119 "ignored.txt", IResource.FILE, null, false, true, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
120 children
121 .add(new PreviewResource(
122 "dirty.txt", IResource.FILE, null, true, false, true, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
123 children
124 .add(new PreviewResource(
125 "staged.txt", IResource.FILE, null, true, false, false, Staged.MODIFIED, false, false)); //$NON-NLS-1$
126 children
127 .add(new PreviewResource(
128 "partially-staged.txt", IResource.FILE, null, true, false, true, Staged.MODIFIED, false, false)); //$NON-NLS-1$
129 children
130 .add(new PreviewResource(
131 "added.txt", IResource.FILE, null, true, false, false, Staged.ADDED, false, false)); //$NON-NLS-1$
132 children
133 .add(new PreviewResource(
134 "removed.txt", IResource.FILE, null, true, false, false, Staged.REMOVED, false, false)); //$NON-NLS-1$
135 children
136 .add(new PreviewResource(
137 "conflict.txt", IResource.FILE, null, true, false, true, Staged.NOT_STAGED, true, false)); //$NON-NLS-1$
138 children
139 .add(new PreviewResource(
140 "assume-valid.txt", IResource.FILE, null, true, false, false, Staged.NOT_STAGED, false, true)); //$NON-NLS-1$
141 project.children = children;
142 PREVIEW_FILESYSTEM_ROOT = Collections.singleton(project);
144 FILE_AND_FOLDER_BINDINGS = new HashMap<String, String>();
145 FILE_AND_FOLDER_BINDINGS.put(DecorationHelper.BINDING_RESOURCE_NAME,
146 UIText.DecoratorPreferencesPage_bindingResourceName);
147 FILE_AND_FOLDER_BINDINGS.put(DecorationHelper.BINDING_DIRTY_FLAG,
148 UIText.DecoratorPreferencesPage_bindingDirtyFlag);
149 FILE_AND_FOLDER_BINDINGS.put(DecorationHelper.BINDING_STAGED_FLAG,
150 UIText.DecoratorPreferencesPage_bindingStagedFlag);
152 PROJECT_BINDINGS = new HashMap<String, String>();
153 PROJECT_BINDINGS.put(DecorationHelper.BINDING_RESOURCE_NAME,
154 UIText.DecoratorPreferencesPage_bindingResourceName);
155 PROJECT_BINDINGS.put(DecorationHelper.BINDING_DIRTY_FLAG,
156 UIText.DecoratorPreferencesPage_bindingDirtyFlag);
157 PROJECT_BINDINGS.put(DecorationHelper.BINDING_STAGED_FLAG,
158 UIText.DecoratorPreferencesPage_bindingStagedFlag);
159 PROJECT_BINDINGS.put(DecorationHelper.BINDING_BRANCH_NAME,
160 UIText.DecoratorPreferencesPage_bindingBranchName);
164 * Constructs a decorator preference page
166 public GitDecoratorPreferencePage() {
167 setDescription(UIText.DecoratorPreferencesPage_description);
171 * @see PreferencePage#createContents(Composite)
173 protected Control createContents(Composite parent) {
175 Composite composite = SWTUtils.createHVFillComposite(parent,
176 SWTUtils.MARGINS_NONE);
178 SWTUtils.createPreferenceLink(
179 (IWorkbenchPreferenceContainer) getContainer(), composite,
180 "org.eclipse.ui.preferencePages.Decorators", //$NON-NLS-1$
181 UIText.DecoratorPreferencesPage_labelDecorationsLink);
183 TabFolder tabFolder = new TabFolder(composite, SWT.NONE);
184 tabFolder.setLayoutData(SWTUtils.createHVFillGridData());
186 generalTab = new GeneralTab(tabFolder);
187 textDecorationTab = new TextDecorationTab(tabFolder);
188 iconDecorationTab = new IconDecorationTab(tabFolder);
190 initializeValues();
192 preview = new Preview(composite);
193 preview.refresh();
195 generalTab.addObserver(preview);
196 textDecorationTab.addObserver(preview);
197 iconDecorationTab.addObserver(preview);
199 // TODO: Add help text for this preference page
201 themeListener = new IPropertyChangeListener() {
202 public void propertyChange(PropertyChangeEvent event) {
203 preview.refresh();
206 PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(
207 themeListener);
209 Dialog.applyDialogFont(parent);
211 return composite;
215 * Wrapper class for TabItems used in the preference page TabFolder
217 * The reason for this wrapper is mainly that the class TabItem is not
218 * supposed to be subclassed.
220 * When controls in the tab change it will emit update() to any registered
221 * observers. This is currently used for updating the decoration preview.
223 private abstract class Tab extends Observable {
224 public abstract void initializeValues(IPreferenceStore store);
226 public abstract void performDefaults(IPreferenceStore store);
228 public abstract void performOk(IPreferenceStore store);
232 * Tab page for general preferences related to decoration
234 private class GeneralTab extends Tab implements SelectionListener {
236 private Button recomputeAncestorDecorations;
238 private Scale containerRecurseLimit;
240 public GeneralTab(TabFolder parent) {
241 Composite composite = SWTUtils.createHVFillComposite(parent,
242 SWTUtils.MARGINS_DEFAULT, 1);
244 recomputeAncestorDecorations = SWTUtils
245 .createCheckBox(
246 composite,
247 UIText.DecoratorPreferencesPage_recomputeAncestorDecorations);
248 recomputeAncestorDecorations
249 .setToolTipText(UIText.DecoratorPreferencesPage_recomputeAncestorDecorationsTooltip);
251 SWTUtils.createLabel(composite,
252 UIText.DecoratorPreferencesPage_computeRecursiveLimit);
253 containerRecurseLimit = createLabeledScaleControl(composite);
254 containerRecurseLimit
255 .setToolTipText(UIText.DecoratorPreferencesPage_computeRecursiveLimitTooltip);
257 recomputeAncestorDecorations.addSelectionListener(this);
258 containerRecurseLimit.addSelectionListener(this);
260 final TabItem tabItem = new TabItem(parent, SWT.NONE);
261 tabItem.setText(UIText.DecoratorPreferencesPage_generalTabFolder);
262 tabItem.setControl(composite);
265 public void initializeValues(IPreferenceStore store) {
266 recomputeAncestorDecorations.setSelection(store
267 .getBoolean(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS));
268 containerRecurseLimit.setSelection(store
269 .getInt(UIPreferences.DECORATOR_RECURSIVE_LIMIT));
272 public void performDefaults(IPreferenceStore store) {
273 recomputeAncestorDecorations
274 .setSelection(store
275 .getDefaultBoolean(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS));
276 containerRecurseLimit.setSelection(store
277 .getDefaultInt(UIPreferences.DECORATOR_RECURSIVE_LIMIT));
280 public void performOk(IPreferenceStore store) {
281 store.setValue(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS,
282 recomputeAncestorDecorations.getSelection());
283 store.setValue(UIPreferences.DECORATOR_RECURSIVE_LIMIT,
284 containerRecurseLimit.getSelection());
287 public void widgetSelected(SelectionEvent e) {
288 setChanged();
289 notifyObservers();
292 public void widgetDefaultSelected(SelectionEvent e) {
293 // Not interesting for us
296 private Scale createLabeledScaleControl(Composite parent) {
298 final int[] values = new int[] { 0, 1, 2, 3, 5, 10, 15, 20, 50,
299 100, Integer.MAX_VALUE };
301 Composite composite = SWTUtils.createHVFillComposite(parent,
302 SWTUtils.MARGINS_DEFAULT);
304 Composite labels = SWTUtils.createHVFillComposite(composite,
305 SWTUtils.MARGINS_NONE, values.length);
306 GridLayout labelsLayout = (GridLayout) labels.getLayout();
307 labelsLayout.makeColumnsEqualWidth = true;
308 labelsLayout.horizontalSpacing = 0;
309 labels.setLayoutData(SWTUtils.createGridData(-1, -1, SWT.FILL,
310 SWT.FILL, false, false));
312 for (int i = 0; i < values.length; ++i) {
313 Label label = SWTUtils.createLabel(labels, "" + values[i]); //$NON-NLS-1$
314 if (i == 0) {
315 label.setAlignment(SWT.LEFT);
316 label.setText("Off"); //$NON-NLS-1$
317 } else if (i == values.length - 1) {
318 label.setAlignment(SWT.RIGHT);
319 label.setText("Inf."); //$NON-NLS-1$
320 } else {
321 label.setAlignment(SWT.CENTER);
325 final Scale scale = new Scale(composite, SWT.HORIZONTAL);
326 scale.setLayoutData(SWTUtils.createHVFillGridData());
327 scale.setMaximum(values.length - 1);
328 scale.setMinimum(0);
329 scale.setIncrement(1);
330 scale.setPageIncrement(1);
332 scale.addListener(SWT.Selection, new Listener() {
333 public void handleEvent(Event event) {
334 // Workaround for GTK treating the slider as stepless
335 scale.setSelection(scale.getSelection());
339 return scale;
344 * The tab page for text-decoration preferences
346 private class TextDecorationTab extends Tab implements ModifyListener {
348 private final FormatEditor fileTextFormat;
350 private final FormatEditor folderTextFormat;
352 private final FormatEditor projectTextFormat;
354 public TextDecorationTab(TabFolder parent) {
355 Composite composite = SWTUtils.createHVFillComposite(parent,
356 SWTUtils.MARGINS_DEFAULT, 3);
358 fileTextFormat = new FormatEditor(composite,
359 UIText.DecoratorPreferencesPage_fileFormatLabel,
360 UIText.DecoratorPreferencesPage_addVariablesAction,
361 FILE_AND_FOLDER_BINDINGS,
362 UIPreferences.DECORATOR_FILETEXT_DECORATION);
363 folderTextFormat = new FormatEditor(composite,
364 UIText.DecoratorPreferencesPage_folderFormatLabel,
365 UIText.DecoratorPreferencesPage_addVariablesAction,
366 FILE_AND_FOLDER_BINDINGS,
367 UIPreferences.DECORATOR_FOLDERTEXT_DECORATION);
368 projectTextFormat = new FormatEditor(composite,
369 UIText.DecoratorPreferencesPage_projectFormatLabel,
370 UIText.DecoratorPreferencesPage_addVariablesAction,
371 PROJECT_BINDINGS,
372 UIPreferences.DECORATOR_PROJECTTEXT_DECORATION);
374 fileTextFormat.addModifyListener(this);
375 folderTextFormat.addModifyListener(this);
376 projectTextFormat.addModifyListener(this);
378 final TabItem tabItem = new TabItem(parent, SWT.NONE);
379 tabItem.setText(UIText.DecoratorPreferencesPage_textLabel);
380 tabItem.setControl(composite);
383 public void initializeValues(IPreferenceStore store) {
384 fileTextFormat.initializeValue(store);
385 folderTextFormat.initializeValue(store);
386 projectTextFormat.initializeValue(store);
389 public void performDefaults(IPreferenceStore store) {
390 fileTextFormat.performDefaults(store);
391 folderTextFormat.performDefaults(store);
392 projectTextFormat.performDefaults(store);
395 public void performOk(IPreferenceStore store) {
396 fileTextFormat.performOk(store);
397 folderTextFormat.performOk(store);
398 projectTextFormat.performOk(store);
401 public void modifyText(ModifyEvent e) {
402 setChanged();
403 notifyObservers();
406 private class FormatEditor extends SelectionAdapter {
407 private final Text text;
409 private final Map bindings;
411 private final String key;
413 public FormatEditor(Composite composite, String title,
414 String buttonText, Map bindings, String key) {
416 this.key = key;
417 this.bindings = bindings;
419 final Label label = SWTUtils.createLabel(composite, title);
420 label.setLayoutData(SWTUtils.createGridData(SWT.DEFAULT,
421 SWT.DEFAULT, false, false));
423 text = SWTUtils.createText(composite);
425 final Button button = new Button(composite, SWT.NONE);
426 button.setText(buttonText);
427 button.setLayoutData(new GridData());
429 button.addSelectionListener(this);
432 public void addModifyListener(ModifyListener listener) {
433 text.addModifyListener(listener);
436 public void widgetSelected(SelectionEvent e) {
437 final ILabelProvider labelProvider = new LabelProvider() {
438 public String getText(Object element) {
439 return ((Map.Entry) element).getKey()
440 + " - " + ((Map.Entry) element).getValue(); //$NON-NLS-1$
444 final IStructuredContentProvider contentsProvider = new IStructuredContentProvider() {
445 public Object[] getElements(Object inputElement) {
446 return ((Collection) inputElement).toArray();
449 public void dispose() {
450 // No-op
453 public void inputChanged(Viewer viewer, Object oldInput,
454 Object newInput) {
455 // No-op
459 final ListSelectionDialog dialog = new ListSelectionDialog(text
460 .getShell(), bindings.entrySet(), contentsProvider,
461 labelProvider,
462 UIText.DecoratorPreferencesPage_selectVariablesToAdd);
463 dialog.setHelpAvailable(false);
464 dialog
465 .setTitle(UIText.DecoratorPreferencesPage_addVariablesTitle);
466 if (dialog.open() != Window.OK)
467 return;
469 Object[] result = dialog.getResult();
471 for (int i = 0; i < result.length; i++) {
472 text.insert("{" + ((Map.Entry) result[i]).getKey() + "}"); //$NON-NLS-1$ //$NON-NLS-2$
476 public void performOk(IPreferenceStore store) {
477 store.setValue(key, text.getText());
480 public void performDefaults(IPreferenceStore store) {
481 store.setToDefault(key);
482 text.setText(store.getDefaultString(key));
485 public void initializeValue(IPreferenceStore store) {
486 text.setText(store.getString(key));
492 * Tab page for icon-related preferences
494 private class IconDecorationTab extends Tab implements SelectionListener {
496 private Button showTracked;
498 private Button showUntracked;
500 private Button showStaged;
502 private Button showConflicts;
504 private Button showAssumeValid;
506 public IconDecorationTab(TabFolder parent) {
507 Composite composite = SWTUtils.createHVFillComposite(parent,
508 SWTUtils.MARGINS_DEFAULT, 2);
510 showTracked = SWTUtils.createCheckBox(composite,
511 UIText.DecoratorPreferencesPage_iconsShowTracked);
512 showUntracked = SWTUtils.createCheckBox(composite,
513 UIText.DecoratorPreferencesPage_iconsShowUntracked);
514 showStaged = SWTUtils.createCheckBox(composite,
515 UIText.DecoratorPreferencesPage_iconsShowStaged);
516 showConflicts = SWTUtils.createCheckBox(composite,
517 UIText.DecoratorPreferencesPage_iconsShowConflicts);
518 showAssumeValid = SWTUtils.createCheckBox(composite,
519 UIText.DecoratorPreferencesPage_iconsShowAssumeValid);
521 showTracked.addSelectionListener(this);
522 showUntracked.addSelectionListener(this);
523 showStaged.addSelectionListener(this);
524 showConflicts.addSelectionListener(this);
525 showAssumeValid.addSelectionListener(this);
527 final TabItem tabItem = new TabItem(parent, SWT.NONE);
528 tabItem.setText(UIText.DecoratorPreferencesPage_iconLabel);
529 tabItem.setControl(composite);
532 public void initializeValues(IPreferenceStore store) {
533 showTracked.setSelection(store
534 .getBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
535 showUntracked.setSelection(store
536 .getBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
537 showStaged.setSelection(store
538 .getBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
539 showConflicts.setSelection(store
540 .getBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
541 showAssumeValid
542 .setSelection(store
543 .getBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
546 public void performDefaults(IPreferenceStore store) {
547 showTracked
548 .setSelection(store
549 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
550 showUntracked
551 .setSelection(store
552 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
553 showStaged
554 .setSelection(store
555 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
556 showConflicts
557 .setSelection(store
558 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
559 showAssumeValid
560 .setSelection(store
561 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
564 public void performOk(IPreferenceStore store) {
565 store.setValue(UIPreferences.DECORATOR_SHOW_TRACKED_ICON,
566 showTracked.getSelection());
567 store.setValue(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON,
568 showUntracked.getSelection());
569 store.setValue(UIPreferences.DECORATOR_SHOW_STAGED_ICON, showStaged
570 .getSelection());
571 store.setValue(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON,
572 showConflicts.getSelection());
573 store.setValue(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON,
574 showAssumeValid.getSelection());
577 public void widgetSelected(SelectionEvent e) {
578 setChanged();
579 notifyObservers();
582 public void widgetDefaultSelected(SelectionEvent e) {
583 // Not interesting for us
588 * Initializes states of the controls from the preference store.
590 private void initializeValues() {
591 final IPreferenceStore store = getPreferenceStore();
592 generalTab.initializeValues(store);
593 textDecorationTab.initializeValues(store);
594 iconDecorationTab.initializeValues(store);
595 setValid(true);
599 * @see IWorkbenchPreferencePage#init(IWorkbench)
601 public void init(IWorkbench workbench) {
602 // No-op
606 * OK was clicked. Store the preferences to the plugin store
608 * @return whether it is okay to close the preference page
610 public boolean performOk() {
611 IPreferenceStore store = getPreferenceStore();
612 final boolean okToClose = performOk(store);
613 if (store.needsSaving()) {
614 Activator.getDefault().savePluginPreferences();
615 Activator.broadcastPropertyChange(new PropertyChangeEvent(this,
616 Activator.DECORATORS_CHANGED, null, null));
618 return okToClose;
622 * Store the preferences to the given preference store
624 * @param store
625 * the preference store to store the preferences to
627 * @return whether it operation succeeded
629 private boolean performOk(IPreferenceStore store) {
630 generalTab.performOk(store);
631 textDecorationTab.performOk(store);
632 iconDecorationTab.performOk(store);
633 return true;
637 * Defaults was clicked. Restore the Git decoration preferences to their
638 * default values
640 protected void performDefaults() {
641 IPreferenceStore store = getPreferenceStore();
642 generalTab.performDefaults(store);
643 textDecorationTab.performDefaults(store);
644 iconDecorationTab.performDefaults(store);
645 super.performDefaults();
646 preview.refresh();
650 * Returns the preference store that belongs to the our plugin.
652 * This is important because we want to store our preferences separately
653 * from the desktop.
655 * @return the preference store for this plugin
657 protected IPreferenceStore doGetPreferenceStore() {
658 return Activator.getDefault().getPreferenceStore();
662 * (non-Javadoc)
664 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
666 public void dispose() {
667 PlatformUI.getWorkbench().getThemeManager()
668 .removePropertyChangeListener(themeListener);
669 super.dispose();
673 * Preview control for showing how changes in the dialog will affect
674 * decoration
676 private class Preview extends LabelProvider implements Observer,
677 ITreeContentProvider {
679 private final ResourceManager fImageCache;
681 private final TreeViewer fViewer;
683 private DecorationHelper fHelper;
685 public Preview(Composite composite) {
686 // Has to happen before the tree control is constructed
687 reloadDecorationHelper();
688 SWTUtils.createLabel(composite,
689 UIText.DecoratorPreferencesPage_preview);
690 fImageCache = new LocalResourceManager(JFaceResources
691 .getResources());
693 fViewer = new TreeViewer(composite);
694 fViewer.getControl().setLayoutData(SWTUtils.createHVFillGridData());
695 fViewer.setContentProvider(this);
696 fViewer.setLabelProvider(this);
697 fViewer.setInput(PREVIEW_FILESYSTEM_ROOT);
698 fViewer.expandAll();
699 fHelper = new DecorationHelper(new PreferenceStore());
702 private void reloadDecorationHelper() {
703 PreferenceStore store = new PreferenceStore();
704 performOk(store);
705 fHelper = new DecorationHelper(store);
708 public void refresh() {
709 reloadDecorationHelper();
710 fViewer.refresh(true);
711 setColorsAndFonts(fViewer.getTree().getItems());
714 @SuppressWarnings("unused")
715 private void setColorsAndFonts(TreeItem[] items) {
716 // TODO: Implement colors and fonts
719 public void update(Observable o, Object arg) {
720 refresh();
723 public Object[] getChildren(Object parentElement) {
724 return ((PreviewResource) parentElement).children.toArray();
727 public Object getParent(Object element) {
728 return null;
731 public boolean hasChildren(Object element) {
732 return !((PreviewResource) element).children.isEmpty();
735 public Object[] getElements(Object inputElement) {
736 return ((Collection) inputElement).toArray();
739 public void dispose() {
740 fImageCache.dispose();
743 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
744 // No-op
747 public String getText(Object element) {
748 final PreviewDecoration decoration = getDecoration(element);
749 final StringBuffer buffer = new StringBuffer();
750 final String prefix = decoration.getPrefix();
751 if (prefix != null)
752 buffer.append(prefix);
753 buffer.append(((PreviewResource) element).getName());
754 final String suffix = decoration.getSuffix();
755 if (suffix != null)
756 buffer.append(suffix);
757 return buffer.toString();
760 public Image getImage(Object element) {
761 final String s;
762 switch (((PreviewResource) element).type) {
763 case IResource.PROJECT:
764 s = SharedImages.IMG_OBJ_PROJECT;
765 break;
766 case IResource.FOLDER:
767 s = ISharedImages.IMG_OBJ_FOLDER;
768 break;
769 default:
770 s = ISharedImages.IMG_OBJ_FILE;
771 break;
773 final Image baseImage = PlatformUI.getWorkbench().getSharedImages()
774 .getImage(s);
775 final ImageDescriptor overlay = getDecoration(element).getOverlay();
776 if (overlay == null)
777 return baseImage;
778 try {
779 return fImageCache.createImage(new DecorationOverlayIcon(
780 baseImage, overlay, IDecoration.BOTTOM_RIGHT));
781 } catch (Exception e) {
782 Activator.logError(e.getMessage(), e);
785 return null;
788 private PreviewDecoration getDecoration(Object element) {
789 PreviewDecoration decoration = new PreviewDecoration();
790 fHelper.decorate(decoration, (PreviewResource) element);
791 return decoration;
795 private static class PreviewResource implements IDecoratableResource {
796 private final String name;
798 private final String branch;
800 private final int type;
802 private Collection children;
804 private boolean tracked;
806 private boolean ignored;
808 private boolean dirty;
810 private boolean conflicts;
812 private Staged staged;
814 private boolean assumeValid;
816 public PreviewResource(String name, int type, String branch,
817 boolean tracked, boolean ignored, boolean dirty, Staged staged,
818 boolean conflicts, boolean assumeValid) {
820 this.name = name;
821 this.branch = branch;
822 this.type = type;
823 this.children = Collections.EMPTY_LIST;
824 this.tracked = tracked;
825 this.ignored = ignored;
826 this.dirty = dirty;
827 this.staged = staged;
828 this.conflicts = conflicts;
829 this.assumeValid = assumeValid;
832 public String getName() {
833 return name;
836 public int getType() {
837 return type;
840 public String getBranch() {
841 return branch;
844 public boolean isTracked() {
845 return tracked;
848 public boolean isIgnored() {
849 return ignored;
852 public boolean isDirty() {
853 return dirty;
856 public Staged staged() {
857 return staged;
860 public boolean hasConflicts() {
861 return conflicts;
864 public boolean isAssumeValid() {
865 return assumeValid;
869 private class PreviewDecoration implements IDecoration {
871 private List<String> prefixes = new ArrayList<String>();
873 private List<String> suffixes = new ArrayList<String>();
875 private ImageDescriptor overlay = null;
878 * Adds an icon overlay to the decoration
879 * <p>
880 * Copies the behavior of <code>DecorationBuilder</code> of only
881 * allowing the overlay to be set once.
883 public void addOverlay(ImageDescriptor overlayImage) {
884 if (overlay == null)
885 overlay = overlayImage;
888 public void addOverlay(ImageDescriptor overlayImage, int quadrant) {
889 addOverlay(overlayImage);
892 public void addPrefix(String prefix) {
893 prefixes.add(prefix);
896 public void addSuffix(String suffix) {
897 suffixes.add(suffix);
900 public IDecorationContext getDecorationContext() {
901 return new DecorationContext();
904 public void setBackgroundColor(Color color) {
905 // TODO: Add support for color
908 public void setForegroundColor(Color color) {
909 // TODO: Add support for color
912 public void setFont(Font font) {
913 // TODO: Add support for fonts
916 public ImageDescriptor getOverlay() {
917 return overlay;
920 public String getPrefix() {
921 StringBuffer sb = new StringBuffer();
922 for (Iterator<String> iter = prefixes.iterator(); iter.hasNext();) {
923 sb.append(iter.next());
925 return sb.toString();
928 public String getSuffix() {
929 StringBuffer sb = new StringBuffer();
930 for (Iterator<String> iter = suffixes.iterator(); iter.hasNext();) {
931 sb.append(iter.next());
933 return sb.toString();