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
;
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
;
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
;
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
));
182 preview
= new Preview(composite
);
185 // TODO: Add help text for this preference page
187 themeListener
= new IPropertyChangeListener() {
188 public void propertyChange(PropertyChangeEvent event
) {
192 PlatformUI
.getWorkbench().getThemeManager().addPropertyChangeListener(
195 Dialog
.applyDialogFont(parent
);
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
);
218 private Scale
createLabeledScaleControl(Composite parent
) {
220 final int[] values
= new int[] { 0, 1, 2, 3, 5, 10, 15, 20, 50, 100,
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
]);
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.");
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);
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());
265 * Creates the controls for the first tab folder
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
279 UIText
.DecoratorPreferencesPage_projectFormatLabel
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
);
321 private TextPair
createFormatEditorControl(Composite composite
,
322 String title
, String buttonText
, final Map supportedBindings
,
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
) {
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
) {
392 showTracked
.addSelectionListener(selectionListener
);
393 showUntracked
.addSelectionListener(selectionListener
);
394 showStaged
.addSelectionListener(selectionListener
);
395 showConflicts
.addSelectionListener(selectionListener
);
396 showAssumeValid
.addSelectionListener(selectionListener
);
402 * @see IWorkbenchPreferencePage#init(IWorkbench)
404 public void init(IWorkbench workbench
) {
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));
425 * Store the preferences to the given preference 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
448 store
.setValue(UIPreferences
.DECORATOR_SHOW_UNTRACKED_ICON
,
449 showUntracked
.getSelection());
450 store
.setValue(UIPreferences
.DECORATOR_SHOW_STAGED_ICON
, showStaged
452 store
.setValue(UIPreferences
.DECORATOR_SHOW_CONFLICTS_ICON
,
453 showConflicts
.getSelection());
454 store
.setValue(UIPreferences
.DECORATOR_SHOW_ASSUME_VALID_ICON
,
455 showAssumeValid
.getSelection());
461 * Defaults was clicked. Restore the Git decoration preferences to their
464 protected void performDefaults() {
465 super.performDefaults();
466 IPreferenceStore store
= getPreferenceStore();
468 recomputeAncestorDecorations
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
));
478 .getDefaultString(UIPreferences
.DECORATOR_FOLDERTEXT_DECORATION
));
481 .getDefaultString(UIPreferences
.DECORATOR_PROJECTTEXT_DECORATION
));
483 showTracked
.setSelection(store
484 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_TRACKED_ICON
));
487 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_UNTRACKED_ICON
));
488 showStaged
.setSelection(store
489 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_STAGED_ICON
));
492 .getDefaultBoolean(UIPreferences
.DECORATOR_SHOW_CONFLICTS_ICON
));
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
504 * @return the preference store for this plugin
506 protected IPreferenceStore
doGetPreferenceStore() {
507 return Activator
.getDefault().getPreferenceStore();
513 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
515 public void dispose() {
516 PlatformUI
.getWorkbench().getThemeManager()
517 .removePropertyChangeListener(themeListener
);
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>
528 * the target to add the variable to
530 * the map of bindings
532 private void addVariables(Text target
, Map bindings
) {
534 final List
<StringPair
> variables
= new ArrayList
<StringPair
>(bindings
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() {
553 public void inputChanged(Viewer viewer
, Object oldInput
,
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
)
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$
587 TextPair(Text t1
, 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
);
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
);
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
);
650 private void updatePreview() {
656 * Preview control for showing how changes in the dialog will affect
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
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
);
682 fHelper
= new DecorationHelper(new PreferenceStore());
685 private void reloadDecorationHelper() {
686 PreferenceStore store
= new PreferenceStore();
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
) {
706 public Object
[] getChildren(Object parentElement
) {
707 return ((PreviewResource
) parentElement
).children
.toArray();
710 public Object
getParent(Object element
) {
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
) {
730 public String
getText(Object element
) {
731 final PreviewDecoration decoration
= getDecoration(element
);
732 final StringBuffer buffer
= new StringBuffer();
733 final String prefix
= decoration
.getPrefix();
735 buffer
.append(prefix
);
736 buffer
.append(((PreviewResource
) element
).getName());
737 final String suffix
= decoration
.getSuffix();
739 buffer
.append(suffix
);
740 return buffer
.toString();
743 public Image
getImage(Object element
) {
745 switch (((PreviewResource
) element
).type
) {
746 case IResource
.PROJECT
:
747 s
= SharedImages
.IMG_OBJ_PROJECT
;
749 case IResource
.FOLDER
:
750 s
= ISharedImages
.IMG_OBJ_FOLDER
;
753 s
= ISharedImages
.IMG_OBJ_FILE
;
756 final Image baseImage
= PlatformUI
.getWorkbench().getSharedImages()
758 final ImageDescriptor overlay
= getDecoration(element
).getOverlay();
762 return fImageCache
.createImage(new DecorationOverlayIcon(
763 baseImage
, overlay
, IDecoration
.BOTTOM_RIGHT
));
764 } catch (Exception e
) {
765 Activator
.logError(e
.getMessage(), e
);
771 private PreviewDecoration
getDecoration(Object element
) {
772 PreviewDecoration decoration
= new PreviewDecoration();
773 fHelper
.decorate(decoration
, (PreviewResource
) element
);
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
) {
804 this.branch
= branch
;
806 this.children
= Collections
.EMPTY_LIST
;
807 this.tracked
= tracked
;
808 this.ignored
= ignored
;
810 this.staged
= staged
;
811 this.conflicts
= conflicts
;
812 this.assumeValid
= assumeValid
;
815 public String
getName() {
819 public int getType() {
823 public String
getBranch() {
827 public boolean isTracked() {
831 public boolean isIgnored() {
835 public boolean isDirty() {
839 public Staged
staged() {
843 public boolean hasConflicts() {
847 public boolean isAssumeValid() {
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
863 * Copies the behavior of <code>DecorationBuilder</code> of only
864 * allowing the overlay to be set once.
866 public void addOverlay(ImageDescriptor overlayImage
) {
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() {
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();