From 362c51d688e46651b584f48e3cce212c7efad91a Mon Sep 17 00:00:00 2001 From: Gesa HENTSCHKE Date: Wed, 17 Apr 2024 16:25:13 +0200 Subject: [PATCH 1/2] [#866] add generic text editor property page fixes #866 --- .../plugin.properties | 1 + .../org.eclipse.ui.genericeditor/plugin.xml | 9 + .../GenericEditorContentAssistant.java | 33 ++- .../ui/internal/genericeditor/Messages.java | 10 + .../genericeditor/messages.properties | 10 + .../GenericEditorPreferenceConstants.java | 4 +- .../GenericEditorPreferencePage.java | 237 ++++++++++++++++++ 7 files changed, 294 insertions(+), 10 deletions(-) create mode 100644 bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java diff --git a/bundles/org.eclipse.ui.genericeditor/plugin.properties b/bundles/org.eclipse.ui.genericeditor/plugin.properties index 9e89bdac80c..490be35fa35 100644 --- a/bundles/org.eclipse.ui.genericeditor/plugin.properties +++ b/bundles/org.eclipse.ui.genericeditor/plugin.properties @@ -39,3 +39,4 @@ gotoMatchingBracketCommand_name = Go to Matching Bracket gotoMatchingBracketCommand_description = Moves the cursor to the matching bracket systemEditorOrGenericEditorStrategy=System Editor; if none: Advanced Text Editor genericEditorStrategy=Advanced Text Editor +PreferencePages.GenericTextEditors=Generic Text Editors diff --git a/bundles/org.eclipse.ui.genericeditor/plugin.xml b/bundles/org.eclipse.ui.genericeditor/plugin.xml index 22c389664d9..107f075c39e 100644 --- a/bundles/org.eclipse.ui.genericeditor/plugin.xml +++ b/bundles/org.eclipse.ui.genericeditor/plugin.xml @@ -276,4 +276,13 @@ label="%genericEditorStrategy"> + + + + diff --git a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java index e6403a38055..ef0d7b84862 100644 --- a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java +++ b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java @@ -28,6 +28,8 @@ import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.internal.genericeditor.preferences.GenericEditorPreferenceConstants; @@ -43,11 +45,12 @@ * * @author christoph */ -public class GenericEditorContentAssistant extends ContentAssistant { +public class GenericEditorContentAssistant extends ContentAssistant implements IPropertyChangeListener { private static final DefaultContentAssistProcessor DEFAULT_CONTENT_ASSIST_PROCESSOR = new DefaultContentAssistProcessor(); private ContentTypeRelatedExtensionTracker contentAssistProcessorTracker; private Set types; private List processors; + private final IPreferenceStore preferenceStore; /** * Creates a new GenericEditorContentAssistant instance for the given content @@ -90,20 +93,17 @@ public GenericEditorContentAssistant( this.contentAssistProcessorTracker = contentAssistProcessorTracker; this.processors = Objects.requireNonNullElseGet(processors, () -> Collections.emptyList()); this.types = types; + this.preferenceStore = preferenceStore; setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW); setProposalPopupOrientation(IContentAssistant.PROPOSAL_REMOVE); enableColoredLabels(true); if (preferenceStore != null) { - enableAutoActivation( - preferenceStore.getBoolean(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION)); - setAutoActivationDelay( - preferenceStore.getInt(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY)); - enableAutoActivateCompletionOnType(preferenceStore - .getBoolean(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE)); + updateAutoActivationPreferences(); + preferenceStore.addPropertyChangeListener(this); } else { enableAutoActivation(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DEFAULT); - setAutoActivationDelay(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFUALT); + setAutoActivationDelay(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFAULT); enableAutoActivateCompletionOnType( GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE_DEFAULT); } @@ -150,9 +150,21 @@ private void updateProcessorToken(IContentAssistProcessor processor, IDocument d } } + private void updateAutoActivationPreferences() { + enableAutoActivation( + preferenceStore.getBoolean(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION)); + setAutoActivationDelay( + preferenceStore.getInt(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY)); + enableAutoActivateCompletionOnType( + preferenceStore.getBoolean(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE)); + } + @Override public void uninstall() { contentAssistProcessorTracker.stopTracking(); + if (preferenceStore != null) { + preferenceStore.removePropertyChangeListener(this); + } super.uninstall(); } @@ -175,4 +187,9 @@ public void install(ITextViewer textViewer) { }); contentAssistProcessorTracker.startTracking(); } + + @Override + public void propertyChange(PropertyChangeEvent event) { + updateAutoActivationPreferences(); + } } diff --git a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/Messages.java b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/Messages.java index 9586e006c81..c442d52481d 100644 --- a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/Messages.java +++ b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/Messages.java @@ -26,6 +26,16 @@ public class Messages extends NLS { public static String GotoMatchingBracket_error_bracketOutsideSelectedElement; public static String GenericEditorMergeViewer_title; + public static String ContentAssistant; + public static String ContentAssistant_autoActivation; + public static String ContentAssistant_autoActivation_Tooltip; + public static String ContentAssistant_autoActivationDelay; + public static String ContentAssistant_autoActivationDelay_Tooltip; + public static String ContentAssistant_autoActivationOnType; + public static String ContentAssistant_autoActivationOnType_Tooltip; + public static String ContentAssistant_autoActivationDelay_InvalidInput; + public static String ContentAssistant_autoActivationDelay_EmptyInput; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/messages.properties b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/messages.properties index 290689c51dc..5fb48e83632 100644 --- a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/messages.properties +++ b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/messages.properties @@ -19,4 +19,14 @@ TextViewer_open_hyperlink_error_message=The operation is not applicable to the c GotoMatchingBracket_error_noMatchingBracket=No matching bracket found GotoMatchingBracket_error_bracketOutsideSelectedElement=Matching bracket is outside the selected element +ContentAssistant=Content Assist +ContentAssistant_autoActivation=Enable auto activation +ContentAssistant_autoActivation_Tooltip=The content assist will be activated on typing or on trigger characters if auto activation is enabled. +ContentAssistant_autoActivationDelay=Auto activation delay (ms): +ContentAssistant_autoActivationDelay_Tooltip=Activation delay in milliseconds for content assist. +ContentAssistant_autoActivationOnType=Enable auto activation on typing +ContentAssistant_autoActivationOnType_Tooltip=Controls whether auto activation on typing is enabled. If disabled, content assist will be activated by trigger characters only. +ContentAssistant_autoActivationDelay_InvalidInput=''{0}'' is not a valid input. +ContentAssistant_autoActivationDelay_EmptyInput=Empty input. + GenericEditorMergeViewer_title={0} Compare \ No newline at end of file diff --git a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferenceConstants.java b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferenceConstants.java index ba56c7a7995..33ea47dfd72 100644 --- a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferenceConstants.java +++ b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferenceConstants.java @@ -101,7 +101,7 @@ private GenericEditorPreferenceConstants() { * @since 1.3 */ public final static String CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY = "contentAssistant.autoActivationDelay"; //$NON-NLS-1$ - public final static int CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFUALT = 10; + public final static int CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFAULT = 10; /** * A named preference that controls whether auto activation on typing is enabled @@ -138,7 +138,7 @@ public static void initializeDefaultValues(IPreferenceStore store) { store.setDefault(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION, CONTENT_ASSISTANT_AUTO_ACTIVATION_DEFAULT); store.setDefault(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY, - CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFUALT); + CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFAULT); store.setDefault(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE, CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE_DEFAULT); // Colors that are set by the current theme diff --git a/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java new file mode 100644 index 00000000000..b76f2b5e360 --- /dev/null +++ b/bundles/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/preferences/GenericEditorPreferencePage.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * See git history + *******************************************************************************/ +package org.eclipse.ui.internal.genericeditor.preferences; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.PreferenceMetadata; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.internal.genericeditor.Messages; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +public class GenericEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + private final ArrayList leadFollowerListeners = new ArrayList<>(); + private final Map, Button> buttons = new HashMap<>(); + private final Map, Text> textFields = new HashMap<>(); + private static final int columns = 2; + private final IPreferenceStore store; + + public GenericEditorPreferencePage() { + this.store = GenericEditorPreferenceConstants.getPreferenceStore(); + } + + @Override + public void init(IWorkbench workbench) { + // nothing to do + } + + @Override + protected Control createContents(Composite parent) { + var control = createAppearancePage(parent); + Dialog.applyDialogFont(control); + initialize(); + return control; + } + + @Override + public boolean performOk() { + if (store instanceof ScopedPreferenceStore scopedStore) { + buttons.entrySet().forEach(e -> scopedStore.setValue(e.getKey().identifer(), e.getValue().getSelection())); + textFields.entrySet().forEach(e -> scopedStore.setValue(e.getKey().identifer(), e.getValue().getText())); + try { + scopedStore.save(); + } catch (IOException e) { + Platform.getLog(getClass()).error("Cannot to save preferences.", e); //$NON-NLS-1$ + return false; + } + } + return true; + } + + @Override + protected void performDefaults() { + buttons.entrySet().forEach(e -> e.getValue().setSelection(store.getDefaultBoolean(e.getKey().identifer()))); + textFields.entrySet().forEach(e -> e.getValue().setText(store.getDefaultString(e.getKey().identifer()))); + updateFollower(); + super.performDefaults(); + } + + private Control createAppearancePage(Composite parent) { + + Composite appearanceComposite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = columns; + layout.marginHeight = 0; + layout.marginWidth = 0; + + final var contetAssistGroup = createGroup(appearanceComposite, Messages.ContentAssistant); + + final var autoActivationMetadata = new PreferenceMetadata<>(Boolean.class, // + GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION, // + GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DEFAULT, // + Messages.ContentAssistant_autoActivation, // + Messages.ContentAssistant_autoActivation_Tooltip); + final var autoActivation = createButton(autoActivationMetadata, contetAssistGroup, SWT.CHECK, 0); + + final var activationDelay = new PreferenceMetadata<>(String.class, // + GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY, // + Integer.toString(GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_DELAY_DEFAULT), // + Messages.ContentAssistant_autoActivationDelay, // + Messages.ContentAssistant_autoActivationDelay_Tooltip); + final var activationDelayControl = createTextField(activationDelay, contetAssistGroup, 4, 20); + + final var autoActivationOnTypeMetada = new PreferenceMetadata<>(Boolean.class, // + GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE, // + GenericEditorPreferenceConstants.CONTENT_ASSISTANT_AUTO_ACTIVATION_ON_TYPE_DEFAULT, // + Messages.ContentAssistant_autoActivationOnType, // + Messages.ContentAssistant_autoActivationOnType_Tooltip); // + final var autoActivationOnType = createButton(autoActivationOnTypeMetada, contetAssistGroup, SWT.CHECK, 20); + List follower = new ArrayList<>(3); + Collections.addAll(follower, activationDelayControl); + follower.add(autoActivationOnType); + + createDependency(autoActivation, autoActivationMetadata.identifer(), follower.toArray(new Control[0])); + + appearanceComposite.setLayout(layout); + return appearanceComposite; + } + + private void initialize() { + buttons.entrySet().forEach(e -> e.getValue().setSelection(store.getBoolean(e.getKey().identifer()))); + textFields.entrySet().forEach(e -> e.getValue().setText(store.getString(e.getKey().identifer()))); + } + + private static Group createGroup(Composite parent, String label) { + Group group = new Group(parent, SWT.NONE); + group.setFont(parent.getFont()); + group.setText(label); + GridLayout layout = new GridLayout(); + layout.numColumns = columns; + group.setLayout(layout); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + return group; + } + + private Button createButton(final PreferenceMetadata meta, Composite composite, int style, + int horizontalIndent) { + Button button = new Button(composite, style); + button.setLayoutData(GridDataFactory.fillDefaults().span(columns, 1).indent(horizontalIndent, 0).create()); + button.setData(meta); + button.setText(meta.name()); + button.setToolTipText(meta.description()); + buttons.put(meta, button); + return button; + } + + private Control[] createTextField(final PreferenceMetadata meta, Composite composite, int textLimit, + int horizontalIndent) { + Label labelControl = new Label(composite, SWT.NONE); + labelControl.setText(meta.name()); + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalIndent = horizontalIndent; + labelControl.setLayoutData(gd); + + final Text textControl = new Text(composite, SWT.BORDER | SWT.SINGLE); + gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.widthHint = convertWidthInCharsToPixels(textLimit + 1); + textControl.setLayoutData(gd); + textControl.setTextLimit(textLimit); + textControl.setToolTipText(meta.description()); + + textControl.addModifyListener(e -> { + updateStatus(validateDelay(textControl.getText())); + }); + textFields.put(meta, textControl); + return new Control[] { labelControl, textControl }; + } + + private static String validateDelay(String value) { + if (value.isEmpty()) { + return Messages.ContentAssistant_autoActivationDelay_EmptyInput; + } + try { + int integer = parseInteger(value); + if (integer < 0) + return NLS.bind(Messages.ContentAssistant_autoActivationDelay_InvalidInput, integer); + } catch (NumberFormatException e) { + return NLS.bind(Messages.ContentAssistant_autoActivationDelay_InvalidInput, value); + } + return null; + } + + private void updateStatus(String errorMessage) { + setValid(errorMessage == null); + var messageType = errorMessage == null ? IMessageProvider.NONE : IMessageProvider.ERROR; + setMessage(errorMessage, messageType); + setErrorMessage(errorMessage); + } + + private static int parseInteger(Object value) throws NumberFormatException { + if (value instanceof Integer) { + return ((Integer) value).intValue(); + } + if (value instanceof String) { + return Integer.parseInt((String) value); + } + throw new NumberFormatException(NLS.bind(Messages.ContentAssistant_autoActivationDelay_InvalidInput, value)); + } + + private void createDependency(final Button lead, String leadKey, final Control[] follower) { + var leadState = store.getBoolean(leadKey); + for (Control f : follower) { + f.setEnabled(leadState); + } + + SelectionListener listener = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + boolean state = lead.getSelection(); + for (Control f : follower) { + f.setEnabled(state); + } + } + }; + leadFollowerListeners.add(listener); + lead.addSelectionListener(listener); + } + + private void updateFollower() { + for (var listener : leadFollowerListeners) { + listener.widgetSelected(null); + } + } +} From 316aec2cd102e71dd9284ea91445af9c27aa3f32 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 10 Apr 2024 10:23:26 +0200 Subject: [PATCH 2/2] Centralize functionality for creating and identifying editor stacks The functionality for creating and identifying editor stacks based on the "EditorStack" tag is scattered across several code places. This change centralizes the according functionality in the recently introduced PartStackUtil. This utility class currently contains functionality related to the primary data stack, which also relies on being an editor stack. In addition, this change reverts the preliminary fix for visible names of open editors being to short (#1712) as this became obsolete with the recent improvements of handling primary data stacks and editor stacks (#1775, #1778). Contributes to https://github.com/eclipse-platform/eclipse.platform.ui/issues/1570 Contributes to https://github.com/eclipse-platform/eclipse.platform.ui/issues/1773 --- .../renderers/swt/CTabRendering.java | 15 ++--------- .../renderers/swt/StackRenderer.java | 10 +++---- .../ui/internal/workbench/PartStackUtil.java | 26 ++++++++++++++++--- .../e4/compatibility/ModeledPageLayout.java | 1 - .../renderers/swt/StackRendererTest.java | 11 ++++---- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java index afc4e9b25da..f562024aaff 100644 --- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java +++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java @@ -25,12 +25,9 @@ import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.e4.ui.internal.css.swt.ICTabRendering; +import org.eclipse.e4.ui.internal.workbench.PartStackUtil; import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; -import org.eclipse.e4.ui.model.application.ui.MContext; import org.eclipse.e4.ui.model.application.ui.MUIElement; -import org.eclipse.e4.ui.workbench.modeling.EModelService; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabFolderRenderer; @@ -1329,15 +1326,7 @@ private void hideIconsForViewTabsPreferenceChanged() { private boolean isPartOfEditorStack() { MUIElement element = (MUIElement) parent.getData(AbstractPartRenderer.OWNING_ME); - EObject root = EcoreUtil.getRootContainer((EObject) element, true); - if (root instanceof MContext context) { - EModelService eModelService = context.getContext().get(EModelService.class); - if (eModelService != null) { - int location = eModelService.getElementLocation(element); - return (location & EModelService.IN_SHARED_AREA) != 0; - } - } - return false; + return PartStackUtil.isEditorStack(element); } private boolean getSwtRendererPreference(String prefName, boolean defaultValue) { diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java index e46a4a29c39..9d5eb842923 100644 --- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java +++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java @@ -43,6 +43,7 @@ import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.e4.ui.di.UISynchronize; import org.eclipse.e4.ui.internal.workbench.OpaqueElementUtil; +import org.eclipse.e4.ui.internal.workbench.PartStackUtil; import org.eclipse.e4.ui.internal.workbench.renderers.swt.BasicPartList; import org.eclipse.e4.ui.internal.workbench.renderers.swt.SWTRenderersMessages; import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; @@ -128,8 +129,6 @@ public class StackRenderer extends LazyStackRenderer { private static final String ONBOARDING_IMAGE = "EditorStack.OnboardingImage"; //$NON-NLS-1$ private static final String ONBOARDING_TEXT = "EditorStack.OnboardingText"; //$NON-NLS-1$ - private static final String EDITOR_STACK_ID = "EditorStack"; //$NON-NLS-1$ - /** * Id of a a control. */ @@ -703,7 +702,7 @@ public Object createWidget(MUIElement element, Object parent) { int location = modelService.getElementLocation(element); boolean isInSharedArea = (location & EModelService.IN_SHARED_AREA) != 0; if (isInSharedArea) { - pStack.getTags().add(EDITOR_STACK_ID); + PartStackUtil.makeEditorStack(pStack); } Composite parentComposite = (Composite) parent; @@ -717,7 +716,7 @@ public Object createWidget(MUIElement element, Object parent) { int styleOverride = getStyleOverride(pStack); int style = styleOverride == -1 ? SWT.BORDER : styleOverride; CTabFolder tabFolder = new CTabFolder(parentComposite, style); - if (pStack.getTags().contains("EditorStack")) { //$NON-NLS-1$ + if (PartStackUtil.isEditorStack(element)) { createOnboardingControls(tabFolder); initializeOnboardingInformationInEditorStack(tabFolder); } @@ -1926,7 +1925,8 @@ private Stream getEditorTabFolders(MPerspective perspective) { Predicate tabFolders = CTabFolder.class::isInstance; Function toTabFolder = CTabFolder.class::cast; - List elements = modelService.findElements(perspective, null, MPartStack.class, List.of(EDITOR_STACK_ID)); + List elements = modelService.findElements(perspective, null, MPartStack.class, + List.of(PartStackUtil.EDITOR_STACK_TAG)); return elements.stream().map(MUIElement::getWidget).filter(tabFolders).map(toTabFolder); } diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartStackUtil.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartStackUtil.java index 49064edd6f8..c9df5991875 100644 --- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartStackUtil.java +++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartStackUtil.java @@ -28,10 +28,8 @@ private PartStackUtil() { * @param partStack the part stack to make the primary data stack */ public static void initializeAsPrimaryDataStack(MPartStack partStack) { + makeEditorStack(partStack); partStack.getTags().add(PRIMARY_DATA_STACK_ID); - if (!partStack.getTags().contains(EDITOR_STACK_TAG)) { - partStack.getTags().add(EDITOR_STACK_TAG); - } partStack.setElementId(PRIMARY_DATA_STACK_ID); } @@ -42,4 +40,26 @@ public static void initializeAsPrimaryDataStack(MPartStack partStack) { public static boolean isPrimaryDataStack(MApplicationElement element) { return element instanceof MPartStack && PRIMARY_DATA_STACK_ID.equals(element.getElementId()); } + + /** + * @param element the element to check for being an editor stack + * @return whether the given element is marked as an editor stack + */ + public static boolean isEditorStack(MApplicationElement element) { + return element instanceof MPartStack && element.getTags().contains(EDITOR_STACK_TAG); + } + + /** + * Marks the given part stack as an editor stack. In consequence calling + * {{@link #isEditorStack(MApplicationElement)} for the element will return + * {@code true}. + * + * @param partStack the part stack to mark as an editor stack + */ + public static void makeEditorStack(MPartStack partStack) { + if (!partStack.getTags().contains(EDITOR_STACK_TAG)) { + partStack.getTags().add(EDITOR_STACK_TAG); + } + } + } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java index e9f827dd1a6..b472abd82b5 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java @@ -74,7 +74,6 @@ public class ModeledPageLayout implements IPageLayout { public static final String PERSP_SHORTCUT_TAG = "persp.perspSC:"; //$NON-NLS-1$ public static final String SHOW_IN_PART_TAG = "persp.showIn:"; //$NON-NLS-1$ public static final String SHOW_VIEW_TAG = "persp.viewSC:"; //$NON-NLS-1$ - public static final String EDITOR_STACK_TAG = "EditorStack"; //$NON-NLS-1$ public static final String HIDDEN_MENU_PREFIX = "persp.hideMenuSC:"; //$NON-NLS-1$ public static final String HIDDEN_TOOLBAR_PREFIX = "persp.hideToolbarSC:"; //$NON-NLS-1$ public static final String HIDDEN_ACTIONSET_PREFIX = "persp.hideActionSetSC:"; //$NON-NLS-1$ diff --git a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRendererTest.java b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRendererTest.java index ab1fe15ce1f..6cc804ce8eb 100644 --- a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRendererTest.java +++ b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRendererTest.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.List; import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.internal.workbench.PartStackUtil; import org.eclipse.e4.ui.internal.workbench.swt.CSSConstants; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; @@ -411,7 +412,7 @@ public void testBug573518_SharedPartToolbarShown2() { @Test public void testOnboardingRenderedWithCorrectSizeForEditorStack() { - partStack.getTags().add("EditorStack"); + PartStackUtil.makeEditorStack(partStack); contextRule.createAndRunWorkbench(window); @@ -445,7 +446,7 @@ public void testOnboardingNotRenderedForNonEditorStack() { @Test public void testOnboardingIsFilled() { MPerspective perspective = createPerspective(); - partStack.getTags().add("EditorStack"); + PartStackUtil.makeEditorStack(partStack); contextRule.createAndRunWorkbench(window); switchToPerspective(perspective); @@ -500,13 +501,13 @@ private void assertFilledOnboardingInformation(CTabFolder tabFolder) { @Test public void testOnboardingIsFilledForEveryEditorStack() { MPerspective perspective = createPerspective(); - partStack.getTags().add("EditorStack"); + PartStackUtil.makeEditorStack(partStack); contextRule.createAndRunWorkbench(window); // Create second editor stack MPartStack secondPartStack = ems.createModelElement(MPartStack.class); - secondPartStack.getTags().add("EditorStack"); + PartStackUtil.makeEditorStack(secondPartStack); MPlaceholder placeholder = ems.createModelElement(MPlaceholder.class); placeholder.setRef(secondPartStack); perspective.getChildren().add(placeholder); @@ -520,7 +521,7 @@ public void testOnboardingIsFilledForEveryEditorStack() { @Test public void testOnboardingIsHiddenWhenEditorOpened() { - partStack.getTags().add("EditorStack"); + PartStackUtil.makeEditorStack(partStack); contextRule.createAndRunWorkbench(window);