Showing link inside custom hover (Eclipse plugin development) - eclipse-plugin

I have a custom hover inside CDT editor (see the linked SO question) and now I want to show link inside my IAnnotationHover hover:
public class MyAwesomeHover implements IAnnotationHover {
#Override
public String getHoverInfo(ISourceViewer sw, int ln) {
return "<a href='www.stackoverflow.com'>so</a>"
}
}
Unfortunately the link is not shown - the hover window shows only simple text (i.e "so"). Other HTML elements I tried work OK (ul, li, p, font ...). Can anyone help me please?

As was mentioned in the comments, the RevisionHover was a good starting point. The magic is in implementing the IAnnotationHoverExtension and creation of a custom AbstractReusableInformationControlCreator. I am posting a code snippet with solution that worked for me.
public class MyHover implements IAnnotationHover, IAnnotationHoverExtension {
...
#Override
public IInformationControlCreator getHoverControlCreator() {
return new MyCreator();
}
...
#Override
public Object getHoverInfo(ISourceViewer sv, ILineRange lr, int vnl) {
return "<a href='www.stackoverflow.com'>so</a>";
}
...
private final class MyCreator extends AbstractReusableInformationControlCreator {
protected IInformationControl doCreateInformationControl(Shell parent) {
BrowserInformationControl control =
new BrowserInformationControl(
parent,
JFaceResources.DIALOG_FONT,
false);
control.addLocationListener(
new LocationAdapter() {
#Override
public void changing(LocationEvent ev) {
if (ev.location.startsWith("file:")) {
// !This opens the link!
openUrl(ev.location)
}
}
});
return control;
}
}
}

Related

How do I make the "user operation is waiting" dialog invisible in Eclipse RCP?

I'm creating a web development framework with Eclipse RCP.
The wizard is creating a feature that creates a project when you press Finish.
I want to show Process Monitor at the bottom of the wizard
I wrote the code as below.
public abstract class CreateProjectWizard extends Wizard {
public CreateProjectWizard () {
...
setNeedsProgressMonitor(true);
}
...
#Override
public boolean performFinish() {
IRunnableWithProgress runnable= new IRunnableWithProgress() {
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
...
IStatus status = createProject(input, monitor);
...
}
};
try {
getContainer().run(true, true, runnable);
}
...
return true;
}
}
How do I make the "user operation is waiting" dialog invisible?
I will let you know if you need additional information.
It looks like you should be able to call Dialog.setBlockedHandler with something that implements IDialogBlockedHandler to change this dialog (both in org.eclipse.jface.dialogs).
The blocked handler does not have to display a dialog, the default JFace handler is just:
new IDialogBlockedHandler() {
#Override
public void clearBlocked() {
// No default behavior
}
#Override
public void showBlocked(IProgressMonitor blocking,
IStatus blockingStatus, String blockedName) {
// No default behavior
}
#Override
public void showBlocked(Shell parentShell, IProgressMonitor blocking,
IStatus blockingStatus, String blockedName) {
// No default behavior
}
};
Eclipse normally replaces this with org.eclipse.ui.internal.dialogs.WorkbenchDialogBlockedHandler which shows the dialog you see (BlockedJobsDialog).
Note that this will not stop the operation waiting for the blocking jobs to finish it will just stop the dialog appearing.

Eclipse Plugin: How can I tell the plugin to open a new Editor every time instead of switching the focus to an existing Editor?

In my Plugin there is an action to open an Editor (extends EditorPart). When I try to open it a second time, its init method isn't called. Instead the focus is shifted to the editor that is already open.
The Editor is associated with a filetype. Here is the excerpt from the plugin.xml:
<extension point="org.eclipse.ui.editors">
<editor
class="de.blub.tool.ide.editors.GRASPEditor"
default="true"
extensions="grasp"
filenames="*.grasp"
icon="icons/newGraspFile.png"
id="de.blub.tool.ide.editors.GRASPEditor"
name="GRASP File Editor">
</editor>
</extension>
I have an Action to open a new Editor. When I try to click that Action twice it reuses the first Editor. I also tried to use an EditorMatcher that implements IEditorMatchingStrategy and always returns false in its matches() method. Even that doesn't change the behavior.
This seems to be a desired/default behavior in eclipse. How can I change that so that the user can initialize a new Editor each time?
Eclipse looks for the equals method of the IEditorInput instance. The Editor somewhere in its code (in my case in the doSave method) uses a setInput method like this:
#Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
// Initialize the editor input
this.input = new MyInputClass(resource);
...
}
#Override
public void doSave(IProgressMonitor monitor) {
...
setInput(input);
}
MyInputClass is the class that extends IEditorInput. The logic for eclipse to reuse an Editor or create a new one is in its equals method. The following example checks the path of an IResource field:
public class MyInputClass implements IEditorInput {
private IResource resource;
public MyInputClass(IResource resource) {
this.resource = resource;
}
public IResource getResource() {
return resource;
}
public void setResource(IResource resource) {
this.resource = resource;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof MyEditorClass) {
MyEditorClass other = (MyEditorClass) obj;
if (getResource().getFullPath().equals(other.getResource().getFullPath())) {
return true;
}
}
return false;
}
}
Of course one can define another logic inside the equals method. Make sure to not create a chaos, which is very well possible, as greg-449 pointed out in a comment.

Scrollable Layout in Vaadin Flow

In Vaadin Flow, there exists no Component that is essentially a Scrollable Layout.
In Vaadin 8, this was done by the Panel.
Is there a way to achieve a scrollable Component in Vaadin Flow?
Edit: I have now published an add-on here that provides the class VerticalScrollLayout, and also the class HorizontalScrollLayout. If there are suggestions for improvements, feel free to contact me or comment here.
Yes it is possible, although there is no existing Component that does it automatically.
The way to go is placing a VerticalLayout (for a vertical scroll bar) inside another component, and setting the display property of that VerticalLayout from flex to block. (credits to Diego Sanz Villafruela in the vaadin forum)
I have made my own VerticalScrollLayout class that does it all for you, so that using it in a view is as easy as using a simple VerticalLayout
public class VerticalScrollLayout extends VerticalLayout {
private VerticalLayout content;
public VerticalScrollLayout(){
preparePanel();
}
public VerticalScrollLayout(Component... children){
preparePanel();
this.add(children);
}
private void preparePanel() {
setWidth("100%");
setHeight("100%");
getStyle().set("overflow", "auto");
content = new VerticalLayout();
content.getStyle().set("display", "block");
content.setWidth("100%");
content.setPadding(false);
super.add(content);
}
public VerticalLayout getContent(){
return content;
}
#Override
public void add(Component... components){
content.add(components);
}
#Override
public void remove(Component... components){
content.remove(components);
}
#Override
public void removeAll(){
content.removeAll();
}
#Override
public void addComponentAsFirst(Component component) {
content.addComponentAtIndex(0, component);
}
}
There is now an official component for scrolling:
https://vaadin.com/docs/latest/components/scroller

How to delegate third-party components in react-native ios

I have following react native component in android.
parent class contains some common settings,
and some template code (eg. setData).
android version
parent component
public abstract class ParentComponent<T extends Chart, U extends Entry> extends SimpleViewManager {
#ReactProp(name = "commonSettings")
public void setCommonSettings(T chart, ReadableMap propMap) {
// do common settings
}
abstract U createEntry(ReadableMap value);
#ReactProp(name = "data")
public void setData(Chart chart, ReadableArray values) {
for (int i = 0; i < values(); i++) {
chart.addEntry(values.getMap(i));
}
}
}
child component A
public class FooComponent extends ParentComponent<FooChart, FooEntry> {
#Override
public String getName() {
return "FooChart";
}
#Override
protected View createViewInstance(ThemedReactContext reactContext) {
return new FooChart(reactContext);
}
#ReactProp(name = "fooSettings")
public void setFooSettings(FooChart chart, ReadableMap propMap) {
// do foo settings
}
#Override
FooEntry createEntry(ReadableMap value) {
return xxxxx;
}
}
child component B
public class BarComponent extends ParentComponent<BarChart, BarEntry> {
#Override
public String getName() {
return "BarChart";
}
#Override
protected View createViewInstance(ThemedReactContext reactContext) {
return new BarChart(reactContext);
}
#ReactProp(name = "barSettings")
public void setBarSettings(FooChart chart, ReadableMap propMap) {
// do foo settings
}
#Override
BarEntry createEntry(ReadableMap value) {
return xxxxx;
}
}
But How should I implement these in ios?
I am quite new to oc & swift developing, here are my doubts.
In ios, there need a RCTViewManager that return a UIView instance.
what shoud be the UIView instance?
I don't want to inherit FooChart & BarChart, delegate is what I need.
So should I create a custom UIView, initialize a fooChart and holds its reference, then self.addSubView(fooChart) ?
How to share the common settings and template code? Extension ?
Do I have to duplicate RCT_EXPORT_VIEW_PROPERTY(commonSettings, NSDictionary) in both FooChartViewManager and BarChartViewManager?
I tried to define class ParentComponentManagerSwift: RCTViewManager,
and declare RCT_EXPORT_VIEW_PROPERTY(commonSettings, NSDictionary) there,
and class FooComponentManagerSwift: ParentComponentManager, but it doesn't work.
But our components do inherit bunch of exports like backgroundColor/width/height which declared in RCTViewManager?
1) If FooChart & BarChart is a subclass of UIView, then you can initialize FooChart & BarChart, set delegate and return it directly
- (UIView *)view {
FooChart *chart = [FooChart new];
chart.delegate = self;
return chart;
}
2) You can share common settings and template code using inheritance
3) You can either duplicate exports or create some macros that will combine common exports.
Components actually do not inherit exports. All components have RCTViewManager exports + own exports, but its done without using inheritance.

Dynamically update title of Design Support TabLayout

is there a way to dynamically update the title of a tab in a Design Support TabLayout? I tried adding a method in the Adapter which changes the contents of the ArrayList which holds the titles of the tabs and notify the adapter but the tab titles don't change to the new title.
Adapter:
public class TabAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments = new ArrayList<>();
private final List<String> fragmentTiles = new ArrayList<>();
public TabAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
fragments.add(fragment);
fragmentTiles.add(title);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentTiles.get(position);
}
public void setFragmentTiles(int index, String title) {
fragmentTiles.set(index, title);
Log.e("ARRAY", fragmentTiles.toString());
}
}
I am changing the content of the title ArrayList like this:
adapter.setFragmentTiles("New title 1");
adapter.setFragmentTiles("New title 2");
adapter.notifyDataSetChanged();
But this doesn't work. Do I have to update the ViewPager or the TabLayout as well?
What's worked for me is to use the setText method on the Tab:
i.e. tab.setText(...); // where ... is CharSequence or resId
Looking at the methods available to the TabLayout you can get the desired Tab instance of an index/position:
e.g. tabLayout.getTabAt(...); // where ... is int.
As far as I can tell, calling notifyDataSetChanged() on the adapter just calls the getCount() of the adapter as opposed to what one might expect of refreshing the title.
Hopefully that helps or at least points you in the right direction.