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
;
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
;
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
;
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
>();
109 .add(new PreviewResource(
110 "folder", IResource
.FOLDER
, null, true, false, true, Staged
.NOT_STAGED
, false, false)); //$NON-NLS-1$
112 .add(new PreviewResource(
113 "tracked.txt", IResource
.FILE
, null, true, false, false, Staged
.NOT_STAGED
, false, false)); //$NON-NLS-1$
115 .add(new PreviewResource(
116 "untracked.txt", IResource
.FILE
, null, false, false, false, Staged
.NOT_STAGED
, false, false)); //$NON-NLS-1$
118 .add(new PreviewResource(
119 "ignored.txt", IResource
.FILE
, null, false, true, false, Staged
.NOT_STAGED
, false, false)); //$NON-NLS-1$
121 .add(new PreviewResource(
122 "dirty.txt", IResource
.FILE
, null, true, false, true, Staged
.NOT_STAGED
, false, false)); //$NON-NLS-1$
124 .add(new PreviewResource(
125 "staged.txt", IResource
.FILE
, null, true, false, false, Staged
.MODIFIED
, false, false)); //$NON-NLS-1$
127 .add(new PreviewResource(
128 "partially-staged.txt", IResource
.FILE
, null, true, false, true, Staged
.MODIFIED
, false, false)); //$NON-NLS-1$
130 .add(new PreviewResource(
131 "added.txt", IResource
.FILE
, null, true, false, false, Staged
.ADDED
, false, false)); //$NON-NLS-1$
133 .add(new PreviewResource(
134 "removed.txt", IResource
.FILE
, null, true, false, false, Staged
.REMOVED
, false, false)); //$NON-NLS-1$
136 .add(new PreviewResource(
137 "conflict.txt", IResource
.FILE
, null, true, false, true, Staged
.NOT_STAGED
, true, false)); //$NON-NLS-1$
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
);
192 preview
= new Preview(composite
);
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
) {
206 PlatformUI
.getWorkbench().getThemeManager().addPropertyChangeListener(
209 Dialog
.applyDialogFont(parent
);
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
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
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
) {
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$
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$
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);
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());
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
,
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
) {
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
) {
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() {
457 public void inputChanged(Viewer viewer
, Object oldInput
,
463 final ListSelectionDialog dialog
= new ListSelectionDialog(text
464 .getShell(), bindings
.entrySet(), contentsProvider
,
466 UIText
.DecoratorPreferencesPage_selectVariablesToAdd
);
467 dialog
.setHelpAvailable(false);
469 .setTitle(UIText
.DecoratorPreferencesPage_addVariablesTitle
);
470 if (dialog
.open() != Window
.OK
)
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
));
547 .getBoolean(UIPreferences
.DECORATOR_SHOW_ASSUME_VALID_ICON
));
550 public void performDefaults(IPreferenceStore store
) {
553 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_TRACKED_ICON
));
556 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_UNTRACKED_ICON
));
559 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_STAGED_ICON
));
562 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_CONFLICTS_ICON
));
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
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
) {
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
);
603 * @see IWorkbenchPreferencePage#init(IWorkbench)
605 public void init(IWorkbench workbench
) {
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));
626 * Store the preferences to the given preference 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
);
641 * Defaults was clicked. Restore the Git decoration preferences to their
644 protected void performDefaults() {
645 IPreferenceStore store
= getPreferenceStore();
646 generalTab
.performDefaults(store
);
647 textDecorationTab
.performDefaults(store
);
648 iconDecorationTab
.performDefaults(store
);
649 super.performDefaults();
654 * Returns the preference store that belongs to the our plugin.
656 * This is important because we want to store our preferences separately
659 * @return the preference store for this plugin
661 protected IPreferenceStore
doGetPreferenceStore() {
662 return Activator
.getDefault().getPreferenceStore();
668 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
670 public void dispose() {
671 PlatformUI
.getWorkbench().getThemeManager()
672 .removePropertyChangeListener(themeListener
);
677 * Preview control for showing how changes in the dialog will affect
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
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
);
703 fHelper
= new DecorationHelper(new PreferenceStore());
706 private void reloadDecorationHelper() {
707 PreferenceStore store
= new PreferenceStore();
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
) {
727 public Object
[] getChildren(Object parentElement
) {
728 return ((PreviewResource
) parentElement
).children
.toArray();
731 public Object
getParent(Object element
) {
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
) {
751 public String
getText(Object element
) {
752 final PreviewDecoration decoration
= getDecoration(element
);
753 final StringBuffer buffer
= new StringBuffer();
754 final String prefix
= decoration
.getPrefix();
756 buffer
.append(prefix
);
757 buffer
.append(((PreviewResource
) element
).getName());
758 final String suffix
= decoration
.getSuffix();
760 buffer
.append(suffix
);
761 return buffer
.toString();
764 public Image
getImage(Object element
) {
766 switch (((PreviewResource
) element
).type
) {
767 case IResource
.PROJECT
:
768 s
= SharedImages
.IMG_OBJ_PROJECT
;
770 case IResource
.FOLDER
:
771 s
= ISharedImages
.IMG_OBJ_FOLDER
;
774 s
= ISharedImages
.IMG_OBJ_FILE
;
777 final Image baseImage
= PlatformUI
.getWorkbench().getSharedImages()
779 final ImageDescriptor overlay
= getDecoration(element
).getOverlay();
783 return fImageCache
.createImage(new DecorationOverlayIcon(
784 baseImage
, overlay
, IDecoration
.BOTTOM_RIGHT
));
785 } catch (Exception e
) {
786 Activator
.logError(e
.getMessage(), e
);
792 private PreviewDecoration
getDecoration(Object element
) {
793 PreviewDecoration decoration
= new PreviewDecoration();
794 fHelper
.decorate(decoration
, (PreviewResource
) element
);
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
) {
825 this.branch
= branch
;
827 this.children
= Collections
.EMPTY_LIST
;
828 this.tracked
= tracked
;
829 this.ignored
= ignored
;
831 this.staged
= staged
;
832 this.conflicts
= conflicts
;
833 this.assumeValid
= assumeValid
;
836 public String
getName() {
840 public int getType() {
844 public String
getBranch() {
848 public boolean isTracked() {
852 public boolean isIgnored() {
856 public boolean isDirty() {
860 public Staged
staged() {
864 public boolean hasConflicts() {
868 public boolean isAssumeValid() {
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
884 * Copies the behavior of <code>DecorationBuilder</code> of only
885 * allowing the overlay to be set once.
887 public void addOverlay(ImageDescriptor overlayImage
) {
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() {
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();