Skip to content

Commit 2bc5d37

Browse files
committed
Show dedicated indicator in tabs of dirty parts
Tabs render dirty parts by showing a `*` in front of the tab name (e.g., in front of the file name. This information is hard to see by developers. This change introduces a graphical indicator on the close button to highlight dirty (unsaved) changes. Furthermore, introduction of a new preference "Indicate unsaved changes by overlaying the close button" in section "Appearance". If preference "Indicate unsaved changes by overlaying the close button" is set and there are unsaved changes in the editor, the "dirty" indicator overlays the close button. If the preference is not set (which is the default), the old behavior is in place which indicates unsaved changes by character `*`.
1 parent 61cca8f commit 2bc5d37

File tree

10 files changed

+58
-7
lines changed

10 files changed

+58
-7
lines changed

bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/internal/workbench/renderers/swt/BasicPartList.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public Font getFont(Object element) {
7272
public String getText(Object element) {
7373
if (element instanceof MDirtyable
7474
&& ((MDirtyable) element).isDirty()) {
75-
return "*" + ((MUILabel) element).getLocalizedLabel(); //$NON-NLS-1$
75+
return ((MUILabel) element).getLocalizedLabel() + " ●"; //$NON-NLS-1$
7676
}
7777
return ((MUILabel) element).getLocalizedLabel();
7878
}

bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java

+17
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,21 @@ public class CTabRendering extends CTabFolderRenderer implements ICTabRendering,
9090
*/
9191
public static final boolean SHOW_FULL_TEXT_FOR_VIEW_TABS_DEFAULT = false;
9292

93+
/**
94+
* A named preference for setting CTabFolder's to be rendered with dirty
95+
* indicator overlay on close button
96+
* <p>
97+
* The default value for this preference is: <code>false</code> (render
98+
* CTabFolder's with icons)
99+
* </p>
100+
*/
101+
public static final String SHOW_DIRTY_INDICATOR_ON_TABS = "SHOW_DIRTY_INDICATOR_ON_TABS"; //$NON-NLS-1$
102+
103+
/**
104+
* Default value for "dirty indicator" preference for tabs
105+
*/
106+
public static final boolean SHOW_DIRTY_INDICATOR_ON_TABS_DEFAULT = false;
107+
93108
private static int MIN_VIEW_CHARS = 1;
94109
private static int MAX_VIEW_CHARS = Integer.MAX_VALUE;
95110

@@ -616,6 +631,7 @@ void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds) {
616631
}
617632

618633
if (selectedTabHighlightColor != null) {
634+
Color originalBackground = gc.getBackground();
619635
gc.setBackground(selectedTabHighlightColor);
620636
boolean highlightOnTop = drawTabHighlightOnTop;
621637
if (onBottom) {
@@ -627,6 +643,7 @@ void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds) {
627643
int widthAdjustment = cornerSize == SQUARE_CORNER ? 0 : 1;
628644
gc.fillRectangle(bounds.x + horizontalOffset, bounds.y + verticalOffset, bounds.width - widthAdjustment,
629645
highlightHeight);
646+
gc.setBackground(originalBackground);
630647
}
631648

632649
if (backgroundPattern != null) {

bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ protected void updateTab(CTabItem cti, MPart part, String attName, Object newVal
647647
break;
648648
case UIEvents.Dirtyable.DIRTY:
649649
cti.setText(getLabel(part, part.getLocalizedLabel()));
650+
cti.setShowDirty(part.isDirty() && getShowDirtyIndicatorForTabsFromPreferences());
650651
break;
651652
case UIEvents.UILabel.ICONURI:
652653
changePartTabImage(part, cti);
@@ -683,7 +684,8 @@ private String getLabel(MUILabel itemPart, String newName) {
683684
newName = LegacyActionTools.escapeMnemonics(newName);
684685
}
685686

686-
if (itemPart instanceof MDirtyable && ((MDirtyable) itemPart).isDirty()) {
687+
if (itemPart instanceof MDirtyable && ((MDirtyable) itemPart).isDirty()
688+
&& !getShowDirtyIndicatorForTabsFromPreferences()) {
687689
newName = '*' + newName;
688690
}
689691
return newName;
@@ -822,6 +824,11 @@ private boolean getMRUValueFromPreferences() {
822824
return preferences.getBoolean(MRU_KEY, initialMRUValue);
823825
}
824826

827+
private boolean getShowDirtyIndicatorForTabsFromPreferences() {
828+
return preferences.getBoolean(CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS,
829+
CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS_DEFAULT);
830+
}
831+
825832
private void updateMRUValue(CTabFolder tabFolder) {
826833
boolean actualMRUValue = getMRUValue();
827834
tabFolder.setMRUVisible(actualMRUValue);

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/FilteredTableBaseHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ private PerspectiveLabelProvider getPerspectiveLabelProvider() {
815815
/** Returns the text for the given {@link WorkbenchPartReference} */
816816
protected String getWorkbenchPartReferenceText(WorkbenchPartReference ref) {
817817
if (ref.isDirty()) {
818-
return "*" + ref.getTitle(); //$NON-NLS-1$
818+
return ref.getTitle() + " ●"; //$NON-NLS-1$
819819
}
820820
return ref.getTitle();
821821
}

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java

+2
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ public class WorkbenchMessages extends NLS {
477477
public static String ViewsPreference_viewTabs_icons_and_titles_label;
478478
public static String ViewsPreference_showFullTextForViewTabs;
479479
public static String ViewsPreference_hideIconsForViewTabs;
480+
public static String ViewsPreference_viewTabs_preferences_label;
481+
public static String ViewsPreference_showDirtyIndicatorForTabs;
480482
public static String ToggleFullScreenMode_ActivationPopup_Description;
481483
public static String ToggleFullScreenMode_ActivationPopup_Description_NoKeybinding;
482484
public static String ToggleFullScreenMode_ActivationPopup_DoNotShowAgain;

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbookEditorsHandler.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ public class WorkbookEditorsHandler extends FilteredTableBaseHandler {
8282
*/
8383
private static final String DIRTY_PREFIX = "*"; //$NON-NLS-1$
8484

85+
/**
86+
* Prefix used to mark Editors that are dirty (unsaved changes).
87+
*/
88+
private static final String DIRTY_INDICATOR = " ●"; //$NON-NLS-1$
89+
8590
/**
8691
* Used to signify that matching path segments have been omitted from modified
8792
* file paths.
@@ -298,7 +303,7 @@ private Path getPathSegment(Integer segmentIndex, java.nio.file.Path path) {
298303
*/
299304
private String prependDirtyIndicationIfDirty(EditorReference editorReference, String labelText) {
300305
if (editorReference.isDirty()) {
301-
return DIRTY_PREFIX + labelText;
306+
return labelText + DIRTY_INDICATOR; // DIRTY_PREFIX + labelText;
302307
}
303308
return labelText;
304309
}

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java

+16
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ public class ViewsPreferencePage extends PreferencePage implements IWorkbenchPre
122122
private Button hideIconsForViewTabs;
123123
private Button showFullTextForViewTabs;
124124

125+
private Button showDirtyIndicatorForTabs;
126+
125127
@Override
126128
protected Control createContents(Composite parent) {
127129
initializeDialogUnits(parent);
@@ -185,6 +187,8 @@ protected Control createContents(Composite parent) {
185187
createHideIconsForViewTabs(comp);
186188
createDependency(showFullTextForViewTabs, hideIconsForViewTabs);
187189

190+
createShowDiryIndicatorForTabs(comp);
191+
188192
createHiDPISettingsGroup(comp);
189193

190194
if (currentTheme != null) {
@@ -245,6 +249,15 @@ protected void createHideIconsForViewTabs(Composite composite) {
245249
actualValue);
246250
}
247251

252+
protected void createShowDiryIndicatorForTabs(Composite composite) {
253+
boolean actualValue = getSwtRendererPreference(CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS,
254+
CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS_DEFAULT);
255+
createLabel(composite, ""); //$NON-NLS-1$
256+
createLabel(composite, WorkbenchMessages.ViewsPreference_viewTabs_preferences_label);
257+
showDirtyIndicatorForTabs = createCheckButton(composite,
258+
WorkbenchMessages.ViewsPreference_showDirtyIndicatorForTabs, actualValue);
259+
}
260+
248261
private boolean getSwtRendererPreference(String prefName, boolean defaultValue) {
249262
return Platform.getPreferencesService().getBoolean(PREF_QUALIFIER_ECLIPSE_E4_UI_WORKBENCH_RENDERERS_SWT,
250263
prefName, defaultValue, null);
@@ -361,6 +374,7 @@ public boolean performOk() {
361374
}
362375
prefs.putBoolean(CTabRendering.HIDE_ICONS_FOR_VIEW_TABS, hideIconsForViewTabs.getSelection());
363376
prefs.putBoolean(CTabRendering.SHOW_FULL_TEXT_FOR_VIEW_TABS, showFullTextForViewTabs.getSelection());
377+
prefs.putBoolean(CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS, showDirtyIndicatorForTabs.getSelection());
364378
}
365379

366380
IPreferenceStore apiStore = PrefUtil.getAPIPreferenceStore();
@@ -450,6 +464,8 @@ protected void performDefaults() {
450464
showFullTextForViewTabs.setSelection(defaultPrefs.getBoolean(CTabRendering.SHOW_FULL_TEXT_FOR_VIEW_TABS,
451465
CTabRendering.SHOW_FULL_TEXT_FOR_VIEW_TABS_DEFAULT));
452466
showFullTextForViewTabs.notifyListeners(SWT.Selection, null);
467+
showDirtyIndicatorForTabs.setSelection(defaultPrefs.getBoolean(CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS,
468+
CTabRendering.SHOW_DIRTY_INDICATOR_ON_TABS_DEFAULT));
453469
}
454470
IPreferenceStore apiStore = PrefUtil.getAPIPreferenceStore();
455471
useColoredLabels.setSelection(apiStore.getDefaultBoolean(IWorkbenchPreferenceConstants.USE_COLORED_LABELS));

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/WorkbenchEditorsDialog.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ String[] getText() {
682682
text = new String[2];
683683
if (editorRef != null) {
684684
if (editorRef.isDirty()) {
685-
text[0] = "*" + editorRef.getTitle(); //$NON-NLS-1$
685+
text[0] = editorRef.getTitle() + " ●"; //$NON-NLS-1$
686686
} else {
687687
text[0] = editorRef.getTitle();
688688
}

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties

+2
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ ViewsPreference_enableMRU = Show &most recently used tabs
435435
ViewsPreference_showFullTextForViewTabs = Always show full titles
436436
ViewsPreference_hideIconsForViewTabs = Hide icons
437437
ViewsPreference_viewTabs_icons_and_titles_label = Tab icons and titles in view areas:
438+
ViewsPreference_showDirtyIndicatorForTabs = Indicate unsaved changes by overlaying the close button
439+
ViewsPreference_viewTabs_preferences_label = Tab preferences:
438440
ToggleFullScreenMode_ActivationPopup_Description=You have gone full screen. Use the Toggle Full Screen command ({0}) to deactivate.
439441
ToggleFullScreenMode_ActivationPopup_Description_NoKeybinding=You have gone full screen. Use the Toggle Full Screen command to deactivate.
440442
ToggleFullScreenMode_ActivationPopup_DoNotShowAgain=Do not show again

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/providers/EditorElement.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
*/
2929
public class EditorElement extends QuickAccessElement {
3030

31-
private static final String DIRTY_MARK = "*"; //$NON-NLS-1$
31+
// private static final String DIRTY_PREFIX = "*"; //$NON-NLS-1$
32+
private static final String DIRTY_INDICATOR = " ●"; //$NON-NLS-1$
3233

3334
private IEditorReference editorReference;
3435
private boolean dirty;
@@ -65,7 +66,8 @@ public ImageDescriptor getImageDescriptor() {
6566

6667
@Override
6768
public String getLabel() {
68-
return (dirty ? DIRTY_MARK : "") + editorReference.getTitle() + separator + editorReference.getTitleToolTip(); //$NON-NLS-1$
69+
return editorReference.getTitle() + (dirty ? DIRTY_INDICATOR : "") + separator //$NON-NLS-1$
70+
+ editorReference.getTitleToolTip();
6971
}
7072

7173
@Override

0 commit comments

Comments
 (0)