Skip to content

Commit

Permalink
Add extension point for configuring ITextDoubleClickStrategy.
Browse files Browse the repository at this point in the history
Provide extension point so that the double click strategy used by the
Generic Editor can be configured by content type.

See #113
  • Loading branch information
andrewL-avlq committed Nov 22, 2022
1 parent ecfc0d0 commit 9488194
Show file tree
Hide file tree
Showing 9 changed files with 433 additions and 1 deletion.
13 changes: 13 additions & 0 deletions org.eclipse.ui.genericeditor.tests/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -286,4 +286,17 @@
contentType="org.eclipse.ui.genericeditor.tests.content-type">
</quickAssistProcessor>
</extension>
<extension
point="org.eclipse.ui.genericeditor.textDoubleClickStrategies">
<textDoubleClickStrategy
class="org.eclipse.ui.genericeditor.tests.contributions.WideDoubleClickStrategy"
contentType="org.eclipse.ui.genericeditor.tests.enabled-when-content-type">
<enabledWhen>
<test
forcePluginActivation="true"
property="org.eclipse.ui.genericeditor.tests.contributions.enabled">
</test>
</enabledWhen>
</textDoubleClickStrategy>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*******************************************************************************
* Copyright (c) 2022 Avaloq Group AG (http://www.avaloq.com).
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Andrew Lamb (Avaloq Group AG) - initial implementation
*******************************************************************************/
package org.eclipse.ui.genericeditor.tests;

import org.junit.Assert;
import org.junit.Test;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;

import org.eclipse.jface.text.tests.util.DisplayHelper;

import org.eclipse.ui.genericeditor.tests.contributions.EnabledPropertyTester;

public class DoubleClickTest extends AbstratGenericEditorTest {
private static final String EDITOR_TEXT= "one two three\n" +
"four five six\n" +
"seven eight nine";

@Override
protected void createAndOpenFile() throws Exception {
createAndOpenFile("foo.txt", EDITOR_TEXT);
}

@Test
public void testDefaultDoubleClick() throws Exception {
checkDoubleClickSelectionForCaretOffset(EDITOR_TEXT.indexOf("five") + 1, "five");
}

@Test
public void testEnabledWhenDoubleClick() throws Exception {
EnabledPropertyTester.setEnabled(true);
createAndOpenFile("enabledWhen.txt", EDITOR_TEXT);

checkDoubleClickSelectionForCaretOffset(EDITOR_TEXT.indexOf("five") + 1, "four five six");

EnabledPropertyTester.setEnabled(false);
}

private void checkDoubleClickSelectionForCaretOffset(int pos, String expectedSelection) throws Exception {
editor.selectAndReveal(pos, 0);
final StyledText editorTextWidget= (StyledText) editor.getAdapter(Control.class);
DisplayHelper.driveEventQueue(editorTextWidget.getDisplay());
new DisplayHelper() {
@Override
protected boolean condition() {
return editorTextWidget.isFocusControl() && editorTextWidget.getSelection().x == pos;
}
}.waitForCondition(editorTextWidget.getDisplay(), 3000);
editorTextWidget.getShell().forceActive();
editorTextWidget.getShell().setActive();
editorTextWidget.getShell().setFocus();
editorTextWidget.getShell().getDisplay().wake();
Rectangle target = editorTextWidget.getCaret().getBounds();
doubleClick(editorTextWidget, target.x + 5, target.y + 5);
Assert.assertEquals(expectedSelection, editorTextWidget.getSelectionText());
}

private void doubleClick(StyledText widget, int x, int y) {
widget.getDisplay().setCursorLocation(widget.toDisplay(x, y));
DisplayHelper.driveEventQueue(widget.getDisplay());

Event mouseDownEvent= new Event();
mouseDownEvent.button = 1;
mouseDownEvent.count = 1;
mouseDownEvent.display = widget.getDisplay();
mouseDownEvent.doit = true;
mouseDownEvent.time = (int) System.currentTimeMillis();
mouseDownEvent.type = SWT.MouseDown;
mouseDownEvent.widget = widget;
mouseDownEvent.x = x;
mouseDownEvent.y = y;
widget.getDisplay().post(mouseDownEvent);
DisplayHelper.driveEventQueue(widget.getDisplay());

Event mouseUpEvent= new Event();
mouseUpEvent.button = 1;
mouseUpEvent.display = widget.getDisplay();
mouseUpEvent.doit = true;
mouseUpEvent.time = (int) System.currentTimeMillis();
mouseUpEvent.type = SWT.MouseUp;
mouseUpEvent.widget = widget;
mouseUpEvent.x = x;
mouseUpEvent.y = y;
widget.getDisplay().post(mouseUpEvent);
DisplayHelper.driveEventQueue(widget.getDisplay());

mouseDownEvent.count = 2;
mouseDownEvent.time = (int) System.currentTimeMillis();
widget.getDisplay().post(mouseDownEvent);
DisplayHelper.driveEventQueue(widget.getDisplay());

mouseUpEvent.time = (int) System.currentTimeMillis();
widget.getDisplay().post(mouseUpEvent);
DisplayHelper.driveEventQueue(widget.getDisplay());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
ReconcilerTest.class,
HighlightTest.class,
IconsTest.class,
TestQuickAssist.class
TestQuickAssist.class,
DoubleClickTest.class
})
public class GenericEditorTestSuite {
// see @SuiteClasses
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2022 Avaloq Group AG (http://www.avaloq.com).
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Andrew Lamb (Avaloq Group AG) - initial implementation
*******************************************************************************/
package org.eclipse.ui.genericeditor.tests.contributions;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextViewer;

public class WideDoubleClickStrategy implements ITextDoubleClickStrategy {

@Override
public void doubleClicked(ITextViewer viewer) {
int offset = viewer.getSelectedRange().x;
IDocument document = viewer.getDocument();
try {
IRegion region = document.getLineInformationOfOffset(offset);
viewer.setSelectedRange(region.getOffset(), region.getLength());
} catch (BadLocationException e) {
// do nothing
}
}

}
1 change: 1 addition & 0 deletions org.eclipse.ui.genericeditor/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<extension-point id="contentAssistProcessors" name="%ExtPoint.contentAssistProcessors" schema="schema/contentAssistProcessors.exsd"/>
<extension-point id="hoverProviders" name="%ExtPoint.hoverProviders" schema="schema/hoverProviders.exsd"/>
<extension-point id="autoEditStrategies" name="%ExtPoint.autoEditStrategies" schema="schema/autoEditStrategies.exsd"/>
<extension-point id="textDoubleClickStrategies" name="%ExtPoint.textDoubleClickStrategies" schema="schema/textDoubleClickStrategies.exsd"/>
<extension-point id="highlightReconcilers" name="%ExtPoint.highlightReconcilers" schema="schema/highlightReconcilers.exsd"/>
<extension-point id="foldingReconcilers" name="%ExtPoint.foldingReconcilers" schema="schema/foldingReconcilers.exsd"/>
<extension-point id="characterPairMatchers" name="%ExtPoint.characterPairMatchers" schema="schema/characterPairMatchers.exsd"/>
Expand Down
158 changes: 158 additions & 0 deletions org.eclipse.ui.genericeditor/schema/textDoubleClickStrategies.exsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.ui.genericeditor" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.ui.genericeditor" id="textDoubleClickStrategies" name="Text double-click strategies"/>
</appinfo>
<documentation>
This extension point is used to contribute text double-click strategies for a given content type.
</documentation>
</annotation>

<include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>

<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence minOccurs="1" maxOccurs="unbounded">
<element ref="textDoubleClickStrategy"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
a fully qualified identifier of the target extension point
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
an optional identifier of the extension instance
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
an optional name of the extension instance
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>

<element name="textDoubleClickStrategy">
<complexType>
<sequence>
<element ref="enabledWhen" minOccurs="0" maxOccurs="1"/>
</sequence>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
The fully qualified class name implementing the interface &lt;code&gt;org.eclipse.jface.text.ITextDoubleClickStrategy&lt;/code&gt;
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.jface.text.ITextDoubleClickStrategy"/>
</appinfo>
</annotation>
</attribute>
<attribute name="contentType" type="string" use="required">
<annotation>
<documentation>
The target content-type for this extension. Content-types are defined as extension to the org.eclipse.core.contenttype.contentTypes extension point.
</documentation>
<appinfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.core.contenttype.contentTypes/content-type/@id"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>

<element name="enabledWhen">
<annotation>
<documentation>
A core Expression that controls the enabled of the given text double-click strategies. The viewer, editor, and editor input are registered in the evaluation context as variable:

* &lt;with variable=&quot;viewer&quot;/&gt; : use it if your expression requires the viewer.
* &lt;with variable=&quot;document&quot;/&gt; : use it if your expression requires the document.
* &lt;with variable=&quot;editor&quot;/&gt; : use it if your expression requires the editor (deprecated, not always set).
* &lt;with variable=&quot;editorInput&quot;/&gt; : use it if your expression requires the editor input (deprecated, not always set).
</documentation>
</annotation>
<complexType>
<choice minOccurs="0" maxOccurs="1">
<element ref="not"/>
<element ref="or"/>
<element ref="and"/>
<element ref="instanceof"/>
<element ref="test"/>
<element ref="systemTest"/>
<element ref="equals"/>
<element ref="count"/>
<element ref="with"/>
<element ref="resolve"/>
<element ref="adapt"/>
<element ref="iterate"/>
<element ref="reference"/>
</choice>
</complexType>
</element>

<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
1.2
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
This is an example of a strategy being registered for a target definition file type:

&lt;pre&gt;
&lt;extension point=&quot;org.eclipse.ui.genericeditor.textDoubleClickStrategies&quot;&gt;
&lt;textDoubleClickStrategy
class=&quot;org.eclipse.ui.genericeditor.examples.TargetDefinitionTextDoubleClickStrategy&quot;
contentType=&quot;org.eclipse.pde.targetFile&quot;&gt;
&lt;enabledWhen&gt;
&lt;with variable=&quot;editor&quot;&gt;
&lt;test property=&quot;org.eclipse.ui.genericeditor.examples.TargetDefinitionPropertyTester&quot;&gt;
&lt;/test&gt;
&lt;/with&gt;
&lt;/enabledWhen&gt;
&lt;/textDoubleClickStrategy&gt;
&lt;/extension&gt;
&lt;/pre&gt;
</documentation>
</annotation>



<annotation>
<appinfo>
<meta.section type="copyright"/>
</appinfo>
<documentation>
Copyright (c) 2022 Avaloq Group AG (http://www.avaloq.com) and others

This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at &lt;a href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/

SPDX-License-Identifier: EPL-2.0
</documentation>
</annotation>

</schema>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Simon Scholz <[email protected]> - Bug 527830
* Angelo Zerr <[email protected]> - [generic editor] Default Code folding for generic editor should use IndentFoldingStrategy - Bug 520659
* Christoph Läubrich - Bug 570459 - [genericeditor] Support ContentAssistProcessors to be registered as OSGi-Services
* Andrew Lamb - Issue #113 - Extension point for ITextDoubleClickStrategy
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;

Expand All @@ -26,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -48,6 +50,7 @@
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextHoverExtension;
import org.eclipse.jface.text.ITextHoverExtension2;
Expand Down Expand Up @@ -401,4 +404,16 @@ protected IInformationControl doCreateInformationControl(Shell parent) {
public void setFallbackContentTypes(Set<IContentType> contentTypes) {
this.fallbackContentTypes = (contentTypes == null ? Set.of() : contentTypes);
}

@Override
public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
TextDoubleClickStrategyRegistry registry = GenericEditorPlugin.getDefault()
.getTextDoubleClickStrategyRegistry();
Optional<ITextDoubleClickStrategy> doubleClickStrategies = registry.getTextDoubleClickStrategy(sourceViewer,
editor, getContentTypes(sourceViewer.getDocument()));
if (!doubleClickStrategies.isEmpty()) {
return doubleClickStrategies.get();
}
return super.getDoubleClickStrategy(sourceViewer, contentType);
}
}
Loading

0 comments on commit 9488194

Please sign in to comment.