Refactor the class GitDecoratorPreferencePage
[egit/chris.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / preferences / GitDecoratorPreferencePage.java
blob9cd1424cd0815038a49a8b7797c2d72b464ab4db
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 String getText() {
437 return text.getText();
440 public void widgetSelected(SelectionEvent e) {
441 final ILabelProvider labelProvider = new LabelProvider() {
442 public String getText(Object element) {
443 return ((Map.Entry) element).getKey()
444 + " - " + ((Map.Entry) element).getValue(); //$NON-NLS-1$
448 final IStructuredContentProvider contentsProvider = new IStructuredContentProvider() {
449 public Object[] getElements(Object inputElement) {
450 return ((Collection) inputElement).toArray();
453 public void dispose() {
454 // No-op
457 public void inputChanged(Viewer viewer, Object oldInput,
458 Object newInput) {
459 // No-op
463 final ListSelectionDialog dialog = new ListSelectionDialog(text
464 .getShell(), bindings.entrySet(), contentsProvider,
465 labelProvider,
466 UIText.DecoratorPreferencesPage_selectVariablesToAdd);
467 dialog.setHelpAvailable(false);
468 dialog
469 .setTitle(UIText.DecoratorPreferencesPage_addVariablesTitle);
470 if (dialog.open() != Window.OK)
471 return;
473 Object[] result = dialog.getResult();
475 for (int i = 0; i < result.length; i++) {
476 text.insert("{" + ((Map.Entry) result[i]).getKey() + "}"); //$NON-NLS-1$ //$NON-NLS-2$
480 public void performOk(IPreferenceStore store) {
481 store.setValue(key, text.getText());
484 public void performDefaults(IPreferenceStore store) {
485 store.setToDefault(key);
486 text.setText(store.getDefaultString(key));
489 public void initializeValue(IPreferenceStore store) {
490 text.setText(store.getString(key));
496 * Tab page for icon-related preferences
498 private class IconDecorationTab extends Tab implements SelectionListener {
500 private Button showTracked;
502 private Button showUntracked;
504 private Button showStaged;
506 private Button showConflicts;
508 private Button showAssumeValid;
510 public IconDecorationTab(TabFolder parent) {
511 Composite composite = SWTUtils.createHVFillComposite(parent,
512 SWTUtils.MARGINS_DEFAULT, 2);
514 showTracked = SWTUtils.createCheckBox(composite,
515 UIText.DecoratorPreferencesPage_iconsShowTracked);
516 showUntracked = SWTUtils.createCheckBox(composite,
517 UIText.DecoratorPreferencesPage_iconsShowUntracked);
518 showStaged = SWTUtils.createCheckBox(composite,
519 UIText.DecoratorPreferencesPage_iconsShowStaged);
520 showConflicts = SWTUtils.createCheckBox(composite,
521 UIText.DecoratorPreferencesPage_iconsShowConflicts);
522 showAssumeValid = SWTUtils.createCheckBox(composite,
523 UIText.DecoratorPreferencesPage_iconsShowAssumeValid);
525 showTracked.addSelectionListener(this);
526 showUntracked.addSelectionListener(this);
527 showStaged.addSelectionListener(this);
528 showConflicts.addSelectionListener(this);
529 showAssumeValid.addSelectionListener(this);
531 final TabItem tabItem = new TabItem(parent, SWT.NONE);
532 tabItem.setText(UIText.DecoratorPreferencesPage_iconLabel);
533 tabItem.setControl(composite);
536 public void initializeValues(IPreferenceStore store) {
537 showTracked.setSelection(store
538 .getBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
539 showUntracked.setSelection(store
540 .getBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
541 showStaged.setSelection(store
542 .getBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
543 showConflicts.setSelection(store
544 .getBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
545 showAssumeValid
546 .setSelection(store
547 .getBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
550 public void performDefaults(IPreferenceStore store) {
551 showTracked
552 .setSelection(store
553 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
554 showUntracked
555 .setSelection(store
556 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
557 showStaged
558 .setSelection(store
559 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
560 showConflicts
561 .setSelection(store
562 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
563 showAssumeValid
564 .setSelection(store
565 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
568 public void performOk(IPreferenceStore store) {
569 store.setValue(UIPreferences.DECORATOR_SHOW_TRACKED_ICON,
570 showTracked.getSelection());
571 store.setValue(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON,
572 showUntracked.getSelection());
573 store.setValue(UIPreferences.DECORATOR_SHOW_STAGED_ICON, showStaged
574 .getSelection());
575 store.setValue(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON,
576 showConflicts.getSelection());
577 store.setValue(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON,
578 showAssumeValid.getSelection());
581 public void widgetSelected(SelectionEvent e) {
582 setChanged();
583 notifyObservers();
586 public void widgetDefaultSelected(SelectionEvent e) {
587 // Not interesting for us
592 * Initializes states of the controls from the preference store.
594 private void initializeValues() {
595 final IPreferenceStore store = getPreferenceStore();
596 generalTab.initializeValues(store);
597 textDecorationTab.initializeValues(store);
598 iconDecorationTab.initializeValues(store);
599 setValid(true);
603 * @see IWorkbenchPreferencePage#init(IWorkbench)
605 public void init(IWorkbench workbench) {
606 // No-op
610 * OK was clicked. Store the preferences to the plugin store
612 * @return whether it is okay to close the preference page
614 public boolean performOk() {
615 IPreferenceStore store = getPreferenceStore();
616 final boolean okToClose = performOk(store);
617 if (store.needsSaving()) {
618 Activator.getDefault().savePluginPreferences();
619 Activator.broadcastPropertyChange(new PropertyChangeEvent(this,
620 Activator.DECORATORS_CHANGED, null, null));
622 return okToClose;
626 * Store the preferences to the given preference store
628 * @param store
629 * the preference store to store the preferences to
631 * @return whether it operation succeeded
633 private boolean performOk(IPreferenceStore store) {
634 generalTab.performOk(store);
635 textDecorationTab.performOk(store);
636 iconDecorationTab.performOk(store);
637 return true;
641 * Defaults was clicked. Restore the Git decoration preferences to their
642 * default values
644 protected void performDefaults() {
645 IPreferenceStore store = getPreferenceStore();
646 generalTab.performDefaults(store);
647 textDecorationTab.performDefaults(store);
648 iconDecorationTab.performDefaults(store);
649 super.performDefaults();
650 preview.refresh();
654 * Returns the preference store that belongs to the our plugin.
656 * This is important because we want to store our preferences separately
657 * from the desktop.
659 * @return the preference store for this plugin
661 protected IPreferenceStore doGetPreferenceStore() {
662 return Activator.getDefault().getPreferenceStore();
666 * (non-Javadoc)
668 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
670 public void dispose() {
671 PlatformUI.getWorkbench().getThemeManager()
672 .removePropertyChangeListener(themeListener);
673 super.dispose();
677 * Preview control for showing how changes in the dialog will affect
678 * decoration
680 private class Preview extends LabelProvider implements Observer,
681 ITreeContentProvider {
683 private final ResourceManager fImageCache;
685 private final TreeViewer fViewer;
687 private DecorationHelper fHelper;
689 public Preview(Composite composite) {
690 // Has to happen before the tree control is constructed
691 reloadDecorationHelper();
692 SWTUtils.createLabel(composite,
693 UIText.DecoratorPreferencesPage_preview);
694 fImageCache = new LocalResourceManager(JFaceResources
695 .getResources());
697 fViewer = new TreeViewer(composite);
698 fViewer.getControl().setLayoutData(SWTUtils.createHVFillGridData());
699 fViewer.setContentProvider(this);
700 fViewer.setLabelProvider(this);
701 fViewer.setInput(PREVIEW_FILESYSTEM_ROOT);
702 fViewer.expandAll();
703 fHelper = new DecorationHelper(new PreferenceStore());
706 private void reloadDecorationHelper() {
707 PreferenceStore store = new PreferenceStore();
708 performOk(store);
709 fHelper = new DecorationHelper(store);
712 public void refresh() {
713 reloadDecorationHelper();
714 fViewer.refresh(true);
715 setColorsAndFonts(fViewer.getTree().getItems());
718 @SuppressWarnings("unused")
719 private void setColorsAndFonts(TreeItem[] items) {
720 // TODO: Implement colors and fonts
723 public void update(Observable o, Object arg) {
724 refresh();
727 public Object[] getChildren(Object parentElement) {
728 return ((PreviewResource) parentElement).children.toArray();
731 public Object getParent(Object element) {
732 return null;
735 public boolean hasChildren(Object element) {
736 return !((PreviewResource) element).children.isEmpty();
739 public Object[] getElements(Object inputElement) {
740 return ((Collection) inputElement).toArray();
743 public void dispose() {
744 fImageCache.dispose();
747 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
748 // No-op
751 public String getText(Object element) {
752 final PreviewDecoration decoration = getDecoration(element);
753 final StringBuffer buffer = new StringBuffer();
754 final String prefix = decoration.getPrefix();
755 if (prefix != null)
756 buffer.append(prefix);
757 buffer.append(((PreviewResource) element).getName());
758 final String suffix = decoration.getSuffix();
759 if (suffix != null)
760 buffer.append(suffix);
761 return buffer.toString();
764 public Image getImage(Object element) {
765 final String s;
766 switch (((PreviewResource) element).type) {
767 case IResource.PROJECT:
768 s = SharedImages.IMG_OBJ_PROJECT;
769 break;
770 case IResource.FOLDER:
771 s = ISharedImages.IMG_OBJ_FOLDER;
772 break;
773 default:
774 s = ISharedImages.IMG_OBJ_FILE;
775 break;
777 final Image baseImage = PlatformUI.getWorkbench().getSharedImages()
778 .getImage(s);
779 final ImageDescriptor overlay = getDecoration(element).getOverlay();
780 if (overlay == null)
781 return baseImage;
782 try {
783 return fImageCache.createImage(new DecorationOverlayIcon(
784 baseImage, overlay, IDecoration.BOTTOM_RIGHT));
785 } catch (Exception e) {
786 Activator.logError(e.getMessage(), e);
789 return null;
792 private PreviewDecoration getDecoration(Object element) {
793 PreviewDecoration decoration = new PreviewDecoration();
794 fHelper.decorate(decoration, (PreviewResource) element);
795 return decoration;
799 private static class PreviewResource implements IDecoratableResource {
800 private final String name;
802 private final String branch;
804 private final int type;
806 private Collection children;
808 private boolean tracked;
810 private boolean ignored;
812 private boolean dirty;
814 private boolean conflicts;
816 private Staged staged;
818 private boolean assumeValid;
820 public PreviewResource(String name, int type, String branch,
821 boolean tracked, boolean ignored, boolean dirty, Staged staged,
822 boolean conflicts, boolean assumeValid) {
824 this.name = name;
825 this.branch = branch;
826 this.type = type;
827 this.children = Collections.EMPTY_LIST;
828 this.tracked = tracked;
829 this.ignored = ignored;
830 this.dirty = dirty;
831 this.staged = staged;
832 this.conflicts = conflicts;
833 this.assumeValid = assumeValid;
836 public String getName() {
837 return name;
840 public int getType() {
841 return type;
844 public String getBranch() {
845 return branch;
848 public boolean isTracked() {
849 return tracked;
852 public boolean isIgnored() {
853 return ignored;
856 public boolean isDirty() {
857 return dirty;
860 public Staged staged() {
861 return staged;
864 public boolean hasConflicts() {
865 return conflicts;
868 public boolean isAssumeValid() {
869 return assumeValid;
873 private class PreviewDecoration implements IDecoration {
875 private List<String> prefixes = new ArrayList<String>();
877 private List<String> suffixes = new ArrayList<String>();
879 private ImageDescriptor overlay = null;
882 * Adds an icon overlay to the decoration
883 * <p>
884 * Copies the behavior of <code>DecorationBuilder</code> of only
885 * allowing the overlay to be set once.
887 public void addOverlay(ImageDescriptor overlayImage) {
888 if (overlay == null)
889 overlay = overlayImage;
892 public void addOverlay(ImageDescriptor overlayImage, int quadrant) {
893 addOverlay(overlayImage);
896 public void addPrefix(String prefix) {
897 prefixes.add(prefix);
900 public void addSuffix(String suffix) {
901 suffixes.add(suffix);
904 public IDecorationContext getDecorationContext() {
905 return new DecorationContext();
908 public void setBackgroundColor(Color color) {
909 // TODO: Add support for color
912 public void setForegroundColor(Color color) {
913 // TODO: Add support for color
916 public void setFont(Font font) {
917 // TODO: Add support for fonts
920 public ImageDescriptor getOverlay() {
921 return overlay;
924 public String getPrefix() {
925 StringBuffer sb = new StringBuffer();
926 for (Iterator<String> iter = prefixes.iterator(); iter.hasNext();) {
927 sb.append(iter.next());
929 return sb.toString();
932 public String getSuffix() {
933 StringBuffer sb = new StringBuffer();
934 for (Iterator<String> iter = suffixes.iterator(); iter.hasNext();) {
935 sb.append(iter.next());
937 return sb.toString();