Remove System.out.println from RevWalkFilterTest
[jgit.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / internal / preferences / GitDecoratorPreferencePage.java
blob8e0ac4e5f04db96dd2a3608770ba9302b86b09b0
1 /*******************************************************************************
2 * Copyright (C) 2003, 2006 Subclipse project and others.
3 * Copyright (C) 2008, 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 * See LICENSE for the full license text, also available.
8 *******************************************************************************/
9 package org.spearce.egit.ui.internal.preferences;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Observable;
19 import java.util.Observer;
21 import org.eclipse.core.resources.IResource;
22 import org.eclipse.jface.dialogs.Dialog;
23 import org.eclipse.jface.dialogs.IDialogConstants;
24 import org.eclipse.jface.preference.IPreferenceStore;
25 import org.eclipse.jface.preference.PreferencePage;
26 import org.eclipse.jface.preference.PreferenceStore;
27 import org.eclipse.jface.resource.ImageDescriptor;
28 import org.eclipse.jface.resource.JFaceResources;
29 import org.eclipse.jface.resource.LocalResourceManager;
30 import org.eclipse.jface.resource.ResourceManager;
31 import org.eclipse.jface.util.IPropertyChangeListener;
32 import org.eclipse.jface.util.PropertyChangeEvent;
33 import org.eclipse.jface.viewers.DecorationContext;
34 import org.eclipse.jface.viewers.DecorationOverlayIcon;
35 import org.eclipse.jface.viewers.IDecoration;
36 import org.eclipse.jface.viewers.IDecorationContext;
37 import org.eclipse.jface.viewers.ILabelProvider;
38 import org.eclipse.jface.viewers.IStructuredContentProvider;
39 import org.eclipse.jface.viewers.ITreeContentProvider;
40 import org.eclipse.jface.viewers.LabelProvider;
41 import org.eclipse.jface.viewers.TreeViewer;
42 import org.eclipse.jface.viewers.Viewer;
43 import org.eclipse.jface.window.Window;
44 import org.eclipse.swt.SWT;
45 import org.eclipse.swt.events.ModifyEvent;
46 import org.eclipse.swt.events.ModifyListener;
47 import org.eclipse.swt.events.SelectionAdapter;
48 import org.eclipse.swt.events.SelectionEvent;
49 import org.eclipse.swt.events.SelectionListener;
50 import org.eclipse.swt.graphics.Color;
51 import org.eclipse.swt.graphics.Font;
52 import org.eclipse.swt.graphics.Image;
53 import org.eclipse.swt.layout.GridData;
54 import org.eclipse.swt.layout.GridLayout;
55 import org.eclipse.swt.widgets.Button;
56 import org.eclipse.swt.widgets.Composite;
57 import org.eclipse.swt.widgets.Control;
58 import org.eclipse.swt.widgets.Event;
59 import org.eclipse.swt.widgets.Label;
60 import org.eclipse.swt.widgets.Listener;
61 import org.eclipse.swt.widgets.Scale;
62 import org.eclipse.swt.widgets.TabFolder;
63 import org.eclipse.swt.widgets.TabItem;
64 import org.eclipse.swt.widgets.Text;
65 import org.eclipse.swt.widgets.TreeItem;
66 import org.eclipse.ui.ISharedImages;
67 import org.eclipse.ui.IWorkbench;
68 import org.eclipse.ui.IWorkbenchPreferencePage;
69 import org.eclipse.ui.PlatformUI;
70 import org.eclipse.ui.dialogs.ListSelectionDialog;
71 import org.eclipse.ui.ide.IDE.SharedImages;
72 import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
73 import org.spearce.egit.ui.Activator;
74 import org.spearce.egit.ui.UIPreferences;
75 import org.spearce.egit.ui.UIText;
76 import org.spearce.egit.ui.internal.SWTUtils;
77 import org.spearce.egit.ui.internal.decorators.IDecoratableResource;
78 import org.spearce.egit.ui.internal.decorators.GitLightweightDecorator.DecorationHelper;
79 import org.spearce.egit.ui.internal.decorators.IDecoratableResource.Staged;
82 /**
83 * Preference page for customizing Git label decorations
85 public class GitDecoratorPreferencePage extends PreferencePage implements
86 IWorkbenchPreferencePage {
88 private Text fileTextFormat;
90 private Text folderTextFormat;
92 private Text projectTextFormat;
94 private Button recomputeAncestorDecorations;
96 private Scale containerRecurseLimit;
98 private Button showTracked;
100 private Button showUntracked;
102 private Preview preview;
104 private Button showStaged;
106 private Button showConflicts;
108 private Button showAssumeValid;
110 private static final Collection PREVIEW_FILESYSTEM_ROOT;
112 private static IPropertyChangeListener themeListener;
114 static {
115 final PreviewResource project = new PreviewResource(
116 "Project", IResource.PROJECT, "master", true, false, true, Staged.NOT_STAGED, false, false); //$NON-NLS-1$1
117 final ArrayList<PreviewResource> children = new ArrayList<PreviewResource>();
119 children.add(new PreviewResource(
120 "folder", IResource.FOLDER, null, true, false, true, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
121 children.add(new PreviewResource(
122 "tracked.txt", IResource.FILE, null, true, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
123 children.add(new PreviewResource(
124 "untracked.txt", IResource.FILE, null, false, false, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
125 children.add(new PreviewResource(
126 "ignored.txt", IResource.FILE, null, false, true, false, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
127 children.add(new PreviewResource(
128 "dirty.txt", IResource.FILE, null, true, false, true, Staged.NOT_STAGED, false, false)); //$NON-NLS-1$
129 children.add(new PreviewResource(
130 "staged.txt", IResource.FILE, null, true, false, false, Staged.MODIFIED, false, false)); //$NON-NLS-1$
131 children.add(new PreviewResource(
132 "partially-staged.txt", IResource.FILE, null, true, false, true, Staged.MODIFIED, false, false)); //$NON-NLS-1$
133 children.add(new PreviewResource(
134 "added.txt", IResource.FILE, null, true, false, false, Staged.ADDED, false, false)); //$NON-NLS-1$
135 children.add(new PreviewResource(
136 "removed.txt", IResource.FILE, null, true, false, false, Staged.REMOVED, false, false)); //$NON-NLS-1$
137 children.add(new PreviewResource(
138 "conflict.txt", IResource.FILE, null, true, false, true, Staged.NOT_STAGED, true, false)); //$NON-NLS-1$
139 children.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);
146 * Constructs a decorator preference page
148 public GitDecoratorPreferencePage() {
149 setDescription(UIText.DecoratorPreferencesPage_description);
153 * @see PreferencePage#createContents(Composite)
155 protected Control createContents(Composite parent) {
157 Composite composite = SWTUtils.createHVFillComposite(parent,
158 SWTUtils.MARGINS_NONE);
160 SWTUtils.createPreferenceLink(
161 (IWorkbenchPreferenceContainer) getContainer(), composite,
162 "org.eclipse.ui.preferencePages.Decorators", //$NON-NLS-1$
163 UIText.DecoratorPreferencesPage_labelDecorationsLink);
165 TabFolder tabFolder = new TabFolder(composite, SWT.NONE);
166 tabFolder.setLayoutData(SWTUtils.createHVFillGridData());
168 TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
169 tabItem.setText(UIText.DecoratorPreferencesPage_generalTabFolder);
170 tabItem.setControl(createGeneralDecoratorPage(tabFolder));
172 tabItem = new TabItem(tabFolder, SWT.NONE);
173 tabItem.setText(UIText.DecoratorPreferencesPage_textLabel);
174 tabItem.setControl(createTextDecoratorPage(tabFolder));
176 tabItem = new TabItem(tabFolder, SWT.NONE);
177 tabItem.setText(UIText.DecoratorPreferencesPage_iconLabel);
178 tabItem.setControl(createIconDecoratorPage(tabFolder));
180 initializeValues();
182 preview = new Preview(composite);
183 preview.refresh();
185 // TODO: Add help text for this preference page
187 themeListener = new IPropertyChangeListener() {
188 public void propertyChange(PropertyChangeEvent event) {
189 preview.refresh();
192 PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(
193 themeListener);
195 Dialog.applyDialogFont(parent);
197 return composite;
200 private Control createGeneralDecoratorPage(Composite parent) {
201 Composite composite = SWTUtils.createHVFillComposite(parent,
202 SWTUtils.MARGINS_DEFAULT, 1);
204 recomputeAncestorDecorations = SWTUtils.createCheckBox(composite,
205 UIText.DecoratorPreferencesPage_recomputeAncestorDecorations);
206 recomputeAncestorDecorations
207 .setToolTipText(UIText.DecoratorPreferencesPage_recomputeAncestorDecorationsTooltip);
209 SWTUtils.createLabel(composite,
210 UIText.DecoratorPreferencesPage_computeRecursiveLimit);
211 containerRecurseLimit = createLabeledScaleControl(composite);
212 containerRecurseLimit
213 .setToolTipText(UIText.DecoratorPreferencesPage_computeRecursiveLimitTooltip);
215 return composite;
218 private Scale createLabeledScaleControl(Composite parent) {
220 final int[] values = new int[] { 0, 1, 2, 3, 5, 10, 15, 20, 50, 100,
221 Integer.MAX_VALUE };
223 Composite composite = SWTUtils.createHVFillComposite(parent,
224 SWTUtils.MARGINS_DEFAULT);
226 Composite labels = SWTUtils.createHVFillComposite(composite,
227 SWTUtils.MARGINS_NONE, values.length);
228 GridLayout labelsLayout = (GridLayout) labels.getLayout();
229 labelsLayout.makeColumnsEqualWidth = true;
230 labelsLayout.horizontalSpacing = 0;
231 labels.setLayoutData(SWTUtils.createGridData(-1, -1, SWT.FILL,
232 SWT.FILL, false, false));
234 for (int i = 0; i < values.length; ++i) {
235 Label label = SWTUtils.createLabel(labels, "" + values[i]);
236 if (i == 0) {
237 label.setAlignment(SWT.LEFT);
238 label.setText("Off");
239 } else if (i == values.length - 1) {
240 label.setAlignment(SWT.RIGHT);
241 label.setText("Inf.");
242 } else {
243 label.setAlignment(SWT.CENTER);
247 final Scale scale = new Scale(composite, SWT.HORIZONTAL);
248 scale.setLayoutData(SWTUtils.createHVFillGridData());
249 scale.setMaximum(values.length - 1);
250 scale.setMinimum(0);
251 scale.setIncrement(1);
252 scale.setPageIncrement(1);
254 scale.addListener(SWT.Selection, new Listener() {
255 public void handleEvent(Event event) {
256 // Workaround for GTK treating the slider as stepless
257 scale.setSelection(scale.getSelection());
261 return scale;
265 * Creates the controls for the first tab folder
267 * @param parent
269 * @return the control
271 private Control createTextDecoratorPage(Composite parent) {
272 Composite fileTextGroup = SWTUtils.createHVFillComposite(parent,
273 SWTUtils.MARGINS_DEFAULT, 3);
275 int labelWidth = convertWidthInCharsToPixels(Math.max(
276 UIText.DecoratorPreferencesPage_fileFormatLabel.length(),
277 Math.max(UIText.DecoratorPreferencesPage_folderFormatLabel
278 .length(),
279 UIText.DecoratorPreferencesPage_projectFormatLabel
280 .length())));
282 TextPair format = createFormatEditorControl(fileTextGroup,
283 UIText.DecoratorPreferencesPage_fileFormatLabel,
284 UIText.DecoratorPreferencesPage_addVariablesAction,
285 getFileBindingDescriptions(), labelWidth);
286 fileTextFormat = format.t1;
288 format = createFormatEditorControl(fileTextGroup,
289 UIText.DecoratorPreferencesPage_folderFormatLabel,
290 UIText.DecoratorPreferencesPage_addVariablesAction,
291 getFolderBindingDescriptions(), labelWidth);
292 folderTextFormat = format.t1;
294 format = createFormatEditorControl(fileTextGroup,
295 UIText.DecoratorPreferencesPage_projectFormatLabel,
296 UIText.DecoratorPreferencesPage_addVariablesAction,
297 getProjectBindingDescriptions(), labelWidth);
298 projectTextFormat = format.t1;
300 return fileTextGroup;
303 private Control createIconDecoratorPage(Composite parent) {
304 Composite imageGroup = SWTUtils.createHVFillComposite(parent,
305 SWTUtils.MARGINS_DEFAULT, 2);
307 showTracked = SWTUtils.createCheckBox(imageGroup,
308 UIText.DecoratorPreferencesPage_iconsShowTracked);
309 showUntracked = SWTUtils.createCheckBox(imageGroup,
310 UIText.DecoratorPreferencesPage_iconsShowUntracked);
311 showStaged = SWTUtils.createCheckBox(imageGroup,
312 UIText.DecoratorPreferencesPage_iconsShowStaged);
313 showConflicts = SWTUtils.createCheckBox(imageGroup,
314 UIText.DecoratorPreferencesPage_iconsShowConflicts);
315 showAssumeValid = SWTUtils.createCheckBox(imageGroup,
316 UIText.DecoratorPreferencesPage_iconsShowAssumeValid);
318 return imageGroup;
321 private TextPair createFormatEditorControl(Composite composite,
322 String title, String buttonText, final Map supportedBindings,
323 int labelWidth) {
325 Label label = SWTUtils.createLabel(composite, title);
326 GridData labelGridData = new GridData();
327 labelGridData.widthHint = labelWidth;
328 label.setLayoutData(labelGridData);
330 Text format = new Text(composite, SWT.BORDER);
331 GridData textGridData = new GridData(GridData.FILL_HORIZONTAL);
332 textGridData.widthHint = 200;
333 format.setLayoutData(textGridData);
334 format.addModifyListener(new ModifyListener() {
335 public void modifyText(ModifyEvent e) {
336 updatePreview();
339 Button b = new Button(composite, SWT.NONE);
340 b.setText(buttonText);
341 GridData data = new GridData();
342 data.horizontalAlignment = GridData.FILL;
343 int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
344 data.widthHint = Math.max(widthHint, b.computeSize(SWT.DEFAULT,
345 SWT.DEFAULT, true).x);
346 b.setLayoutData(data);
347 final Text formatToInsert = format;
348 b.addListener(SWT.Selection, new Listener() {
349 public void handleEvent(Event event) {
350 addVariables(formatToInsert, supportedBindings);
354 return new TextPair(format, null);
358 * Initializes states of the controls from the preference store.
360 private void initializeValues() {
361 final IPreferenceStore store = getPreferenceStore();
363 recomputeAncestorDecorations.setSelection(store
364 .getBoolean(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS));
365 containerRecurseLimit.setSelection(store
366 .getInt(UIPreferences.DECORATOR_RECURSIVE_LIMIT));
368 fileTextFormat.setText(store
369 .getString(UIPreferences.DECORATOR_FILETEXT_DECORATION));
370 folderTextFormat.setText(store
371 .getString(UIPreferences.DECORATOR_FOLDERTEXT_DECORATION));
372 projectTextFormat.setText(store
373 .getString(UIPreferences.DECORATOR_PROJECTTEXT_DECORATION));
375 showTracked.setSelection(store
376 .getBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
377 showUntracked.setSelection(store
378 .getBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
379 showStaged.setSelection(store
380 .getBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
381 showConflicts.setSelection(store
382 .getBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
383 showAssumeValid.setSelection(store
384 .getBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
386 SelectionListener selectionListener = new SelectionAdapter() {
387 public void widgetSelected(SelectionEvent e) {
388 preview.refresh();
392 showTracked.addSelectionListener(selectionListener);
393 showUntracked.addSelectionListener(selectionListener);
394 showStaged.addSelectionListener(selectionListener);
395 showConflicts.addSelectionListener(selectionListener);
396 showAssumeValid.addSelectionListener(selectionListener);
398 setValid(true);
402 * @see IWorkbenchPreferencePage#init(IWorkbench)
404 public void init(IWorkbench workbench) {
405 // No-op
409 * OK was clicked. Store the preferences to the plugin store
411 * @return whether it is okay to close the preference page
413 public boolean performOk() {
414 IPreferenceStore store = getPreferenceStore();
415 final boolean okToClose = performOk(store);
416 if (store.needsSaving()) {
417 Activator.getDefault().savePluginPreferences();
418 Activator.broadcastPropertyChange(new PropertyChangeEvent(this,
419 Activator.DECORATORS_CHANGED, null, null));
421 return okToClose;
425 * Store the preferences to the given preference store
427 * @param store
428 * the preference store to store the preferences to
430 * @return whether it operation succeeded
432 private boolean performOk(IPreferenceStore store) {
434 store.setValue(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS,
435 recomputeAncestorDecorations.getSelection());
436 store.setValue(UIPreferences.DECORATOR_RECURSIVE_LIMIT,
437 containerRecurseLimit.getSelection());
439 store.setValue(UIPreferences.DECORATOR_FILETEXT_DECORATION,
440 fileTextFormat.getText());
441 store.setValue(UIPreferences.DECORATOR_FOLDERTEXT_DECORATION,
442 folderTextFormat.getText());
443 store.setValue(UIPreferences.DECORATOR_PROJECTTEXT_DECORATION,
444 projectTextFormat.getText());
446 store.setValue(UIPreferences.DECORATOR_SHOW_TRACKED_ICON, showTracked
447 .getSelection());
448 store.setValue(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON,
449 showUntracked.getSelection());
450 store.setValue(UIPreferences.DECORATOR_SHOW_STAGED_ICON, showStaged
451 .getSelection());
452 store.setValue(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON,
453 showConflicts.getSelection());
454 store.setValue(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON,
455 showAssumeValid.getSelection());
457 return true;
461 * Defaults was clicked. Restore the Git decoration preferences to their
462 * default values
464 protected void performDefaults() {
465 super.performDefaults();
466 IPreferenceStore store = getPreferenceStore();
468 recomputeAncestorDecorations
469 .setSelection(store
470 .getDefaultBoolean(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS));
471 containerRecurseLimit.setSelection(store
472 .getDefaultInt(UIPreferences.DECORATOR_RECURSIVE_LIMIT));
474 fileTextFormat.setText(store
475 .getDefaultString(UIPreferences.DECORATOR_FILETEXT_DECORATION));
476 folderTextFormat
477 .setText(store
478 .getDefaultString(UIPreferences.DECORATOR_FOLDERTEXT_DECORATION));
479 projectTextFormat
480 .setText(store
481 .getDefaultString(UIPreferences.DECORATOR_PROJECTTEXT_DECORATION));
483 showTracked.setSelection(store
484 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_TRACKED_ICON));
485 showUntracked
486 .setSelection(store
487 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON));
488 showStaged.setSelection(store
489 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_STAGED_ICON));
490 showConflicts
491 .setSelection(store
492 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON));
493 showAssumeValid
494 .setSelection(store
495 .getDefaultBoolean(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON));
499 * Returns the preference store that belongs to the our plugin.
501 * This is important because we want to store our preferences separately
502 * from the desktop.
504 * @return the preference store for this plugin
506 protected IPreferenceStore doGetPreferenceStore() {
507 return Activator.getDefault().getPreferenceStore();
511 * (non-Javadoc)
513 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
515 public void dispose() {
516 PlatformUI.getWorkbench().getThemeManager()
517 .removePropertyChangeListener(themeListener);
518 super.dispose();
522 * Adds another variable to the given target text
524 * A ListSelectionDialog pops up and allow the user to choose the variable,
525 * which is then inserted at current position in <code>text</code>
527 * @param target
528 * the target to add the variable to
529 * @param bindings
530 * the map of bindings
532 private void addVariables(Text target, Map bindings) {
534 final List<StringPair> variables = new ArrayList<StringPair>(bindings
535 .size());
537 ILabelProvider labelProvider = new LabelProvider() {
538 public String getText(Object element) {
539 return ((StringPair) element).s1
540 + " - " + ((StringPair) element).s2; //$NON-NLS-1$
544 IStructuredContentProvider contentsProvider = new IStructuredContentProvider() {
545 public Object[] getElements(Object inputElement) {
546 return variables.toArray(new StringPair[variables.size()]);
549 public void dispose() {
550 // No-op
553 public void inputChanged(Viewer viewer, Object oldInput,
554 Object newInput) {
555 // No-op
559 for (Iterator it = bindings.keySet().iterator(); it.hasNext();) {
560 StringPair variable = new StringPair();
561 variable.s1 = (String) it.next(); // variable
562 variable.s2 = (String) bindings.get(variable.s1); // description
563 variables.add(variable);
566 ListSelectionDialog dialog = new ListSelectionDialog(this.getShell(),
567 this, contentsProvider, labelProvider,
568 UIText.DecoratorPreferencesPage_selectVariablesToAdd);
569 dialog.setTitle(UIText.DecoratorPreferencesPage_addVariablesTitle);
570 if (dialog.open() != Window.OK)
571 return;
573 Object[] result = dialog.getResult();
575 for (int i = 0; i < result.length; i++) {
576 target.insert("{" + ((StringPair) result[i]).s1 + "}"); //$NON-NLS-1$ //$NON-NLS-2$
580 class StringPair {
581 String s1;
583 String s2;
586 class TextPair {
587 TextPair(Text t1, Text t2) {
588 this.t1 = t1;
589 this.t2 = t2;
592 Text t1;
594 Text t2;
598 * Gets the map of bindings between variables and description, to use for
599 * the format editors for files
601 * @return the bindings
603 private Map getFileBindingDescriptions() {
604 Map<String, String> bindings = new HashMap<String, String>();
605 bindings.put(DecorationHelper.BINDING_RESOURCE_NAME,
606 UIText.DecoratorPreferencesPage_bindingResourceName);
607 bindings.put(DecorationHelper.BINDING_DIRTY_FLAG,
608 UIText.DecoratorPreferencesPage_bindingDirtyFlag);
609 bindings.put(DecorationHelper.BINDING_STAGED_FLAG,
610 UIText.DecoratorPreferencesPage_bindingStagedFlag);
611 return bindings;
615 * Gets the map of bindings between variables and description, to use for
616 * the format editors for folders
618 * @return the bindings
620 private Map getFolderBindingDescriptions() {
621 Map<String, String> bindings = new HashMap<String, String>();
622 bindings.put(DecorationHelper.BINDING_RESOURCE_NAME,
623 UIText.DecoratorPreferencesPage_bindingResourceName);
624 bindings.put(DecorationHelper.BINDING_DIRTY_FLAG,
625 UIText.DecoratorPreferencesPage_bindingDirtyFlag);
626 bindings.put(DecorationHelper.BINDING_STAGED_FLAG,
627 UIText.DecoratorPreferencesPage_bindingStagedFlag);
628 return bindings;
632 * Gets the map of bindings between variables and description, to use for
633 * the format editors for projects
635 * @return the bindings
637 private Map getProjectBindingDescriptions() {
638 Map<String, String> bindings = new HashMap<String, String>();
639 bindings.put(DecorationHelper.BINDING_RESOURCE_NAME,
640 UIText.DecoratorPreferencesPage_bindingResourceName);
641 bindings.put(DecorationHelper.BINDING_DIRTY_FLAG,
642 UIText.DecoratorPreferencesPage_bindingDirtyFlag);
643 bindings.put(DecorationHelper.BINDING_STAGED_FLAG,
644 UIText.DecoratorPreferencesPage_bindingStagedFlag);
645 bindings.put(DecorationHelper.BINDING_BRANCH_NAME,
646 UIText.DecoratorPreferencesPage_bindingBranchName);
647 return bindings;
650 private void updatePreview() {
651 if (preview != null)
652 preview.refresh();
656 * Preview control for showing how changes in the dialog will affect
657 * decoration
659 private class Preview extends LabelProvider implements Observer,
660 ITreeContentProvider {
662 private final ResourceManager fImageCache;
664 private final TreeViewer fViewer;
666 private DecorationHelper fHelper;
668 public Preview(Composite composite) {
669 // Has to happen before the tree control is constructed
670 reloadDecorationHelper();
671 SWTUtils.createLabel(composite,
672 UIText.DecoratorPreferencesPage_preview);
673 fImageCache = new LocalResourceManager(JFaceResources
674 .getResources());
676 fViewer = new TreeViewer(composite);
677 fViewer.getControl().setLayoutData(SWTUtils.createHVFillGridData());
678 fViewer.setContentProvider(this);
679 fViewer.setLabelProvider(this);
680 fViewer.setInput(PREVIEW_FILESYSTEM_ROOT);
681 fViewer.expandAll();
682 fHelper = new DecorationHelper(new PreferenceStore());
685 private void reloadDecorationHelper() {
686 PreferenceStore store = new PreferenceStore();
687 performOk(store);
688 fHelper = new DecorationHelper(store);
691 public void refresh() {
692 reloadDecorationHelper();
693 fViewer.refresh(true);
694 setColorsAndFonts(fViewer.getTree().getItems());
697 @SuppressWarnings("unused")
698 private void setColorsAndFonts(TreeItem[] items) {
699 // TODO: Implement colors and fonts
702 public void update(Observable o, Object arg) {
703 refresh();
706 public Object[] getChildren(Object parentElement) {
707 return ((PreviewResource) parentElement).children.toArray();
710 public Object getParent(Object element) {
711 return null;
714 public boolean hasChildren(Object element) {
715 return !((PreviewResource) element).children.isEmpty();
718 public Object[] getElements(Object inputElement) {
719 return ((Collection) inputElement).toArray();
722 public void dispose() {
723 fImageCache.dispose();
726 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
727 // No-op
730 public String getText(Object element) {
731 final PreviewDecoration decoration = getDecoration(element);
732 final StringBuffer buffer = new StringBuffer();
733 final String prefix = decoration.getPrefix();
734 if (prefix != null)
735 buffer.append(prefix);
736 buffer.append(((PreviewResource) element).getName());
737 final String suffix = decoration.getSuffix();
738 if (suffix != null)
739 buffer.append(suffix);
740 return buffer.toString();
743 public Image getImage(Object element) {
744 final String s;
745 switch (((PreviewResource) element).type) {
746 case IResource.PROJECT:
747 s = SharedImages.IMG_OBJ_PROJECT;
748 break;
749 case IResource.FOLDER:
750 s = ISharedImages.IMG_OBJ_FOLDER;
751 break;
752 default:
753 s = ISharedImages.IMG_OBJ_FILE;
754 break;
756 final Image baseImage = PlatformUI.getWorkbench().getSharedImages()
757 .getImage(s);
758 final ImageDescriptor overlay = getDecoration(element).getOverlay();
759 if (overlay == null)
760 return baseImage;
761 try {
762 return fImageCache.createImage(new DecorationOverlayIcon(
763 baseImage, overlay, IDecoration.BOTTOM_RIGHT));
764 } catch (Exception e) {
765 Activator.logError(e.getMessage(), e);
768 return null;
771 private PreviewDecoration getDecoration(Object element) {
772 PreviewDecoration decoration = new PreviewDecoration();
773 fHelper.decorate(decoration, (PreviewResource) element);
774 return decoration;
778 private static class PreviewResource implements IDecoratableResource {
779 private final String name;
781 private final String branch;
783 private final int type;
785 private Collection children;
787 private boolean tracked;
789 private boolean ignored;
791 private boolean dirty;
793 private boolean conflicts;
795 private Staged staged;
797 private boolean assumeValid;
799 public PreviewResource(String name, int type, String branch,
800 boolean tracked, boolean ignored, boolean dirty, Staged staged,
801 boolean conflicts, boolean assumeValid) {
803 this.name = name;
804 this.branch = branch;
805 this.type = type;
806 this.children = Collections.EMPTY_LIST;
807 this.tracked = tracked;
808 this.ignored = ignored;
809 this.dirty = dirty;
810 this.staged = staged;
811 this.conflicts = conflicts;
812 this.assumeValid = assumeValid;
815 public String getName() {
816 return name;
819 public int getType() {
820 return type;
823 public String getBranch() {
824 return branch;
827 public boolean isTracked() {
828 return tracked;
831 public boolean isIgnored() {
832 return ignored;
835 public boolean isDirty() {
836 return dirty;
839 public Staged staged() {
840 return staged;
843 public boolean hasConflicts() {
844 return conflicts;
847 public boolean isAssumeValid() {
848 return assumeValid;
852 private class PreviewDecoration implements IDecoration {
854 private List<String> prefixes = new ArrayList<String>();
856 private List<String> suffixes = new ArrayList<String>();
858 private ImageDescriptor overlay = null;
861 * Adds an icon overlay to the decoration
862 * <p>
863 * Copies the behavior of <code>DecorationBuilder</code> of only
864 * allowing the overlay to be set once.
866 public void addOverlay(ImageDescriptor overlayImage) {
867 if (overlay == null)
868 overlay = overlayImage;
871 public void addOverlay(ImageDescriptor overlayImage, int quadrant) {
872 addOverlay(overlayImage);
875 public void addPrefix(String prefix) {
876 prefixes.add(prefix);
879 public void addSuffix(String suffix) {
880 suffixes.add(suffix);
883 public IDecorationContext getDecorationContext() {
884 return new DecorationContext();
887 public void setBackgroundColor(Color color) {
890 public void setForegroundColor(Color color) {
893 public void setFont(Font font) {
896 public ImageDescriptor getOverlay() {
897 return overlay;
900 public String getPrefix() {
901 StringBuffer sb = new StringBuffer();
902 for (Iterator<String> iter = prefixes.iterator(); iter.hasNext();) {
903 sb.append(iter.next());
905 return sb.toString();
908 public String getSuffix() {
909 StringBuffer sb = new StringBuffer();
910 for (Iterator<String> iter = suffixes.iterator(); iter.hasNext();) {
911 sb.append(iter.next());
913 return sb.toString();