Activating find/replace for jface TextViewer eclipse worbench action - eclipse-plugin

I have made an eclipse plugin with TextViewer interface for displaying a text document but the standard find/replace stay in gray mode.

I assume you are using the TextViewer in a view rather than an editor. In this case:
Your view in which the TextViewer is used must "adapt" to org.eclipse.jface.text.IFindReplaceTarget i.e. its getAdapter() must return the target from viewer.
You need to explicitly register a handler for "org.eclipse.ui.edit.findReplace" command (which can be org.eclipse.ui.texteditorFindReplaceAction). Check out Platform Command Framework to get started.

I've used Martii Käärik's pointers for finding the answer to this question. I've got it working with the following code, which however uses an internal string identifier from TextEditor. Still, here it goes.
getAdapter() in the view must be implemented like this (viewer is an instance of TextViewer)
public Object getAdapter(Class adapter) {
if (IFindReplaceTarget.class.equals(adapter)) {
if (viewer != null) {
return viewer.getFindReplaceTarget();
}
}
return super.getAdapter(adapter);
}
In createPartControl() of your view, add this code:
FindReplaceAction findAction= new FindReplaceAction(ResourceBundle.getBundle("org.eclipse.ui.texteditor.ConstructedTextEditorMessages"), null, this);
IHandlerService handlerService= (IHandlerService) getSite().getService(IHandlerService.class);
IHandler handler= new AbstractHandler() {
public Object execute(ExecutionEvent event) throws ExecutionException {
if (viewer != null && viewer.getDocument() != null)
findAction.run();
return null;
}
};
handlerService.activateHandler("org.eclipse.ui.edit.findReplace", handler);
No XML required.

Related

Deactivate all Codan Checkers programmatically

How can I deactivate all Codan Checkers for my content type or inside my editor programmatically?
I know I can turn off the Checkers in Window -> Preferences -> C/C++ -> Code Analysis. But I need to do that programmatically.
One way to achieve that is to modify the methods runInEditor() and processResource() in org.eclipse.cdt.codan.internal.core.CodanRunner.
public static void runInEditor(Object model, IResource resource, IProgressMonitor monitor) {
if (resource != null && !resource.toString().endsWith("blub)) {
processResource(resource, model, CheckerLaunchMode.RUN_AS_YOU_TYPE, monitor);
}
}
public static void processResource(IResource resource, CheckerLaunchMode checkerLaunchMode, IProgressMonitor monitor) {
if (resource != null && !resource.toString().endsWith("blub")) {
processResource(resource, null, checkerLaunchMode, monitor);
}
}
For the Unresolved Inclusion warning I can overwrite CPreprocessor and return do nothing in the overriden handleProblem() method.
Is there a way to suppress the Codan Checkers without modifying CDT code?
You should be able to do this using the org.eclipse.cdt.codan.core.checkerEnablement extension point.
I can't find generated documentation for it, but you can see the schema for it here.
The extension point allows you to specify a class inheriting from org.eclipse.cdt.codan.internal.core.ICheckerEnablementVerifier and provide a method boolean isCheckerEnabled(IChecker, IResource, CheckerLaunchMode) which determines if the given checker can run on the given resource in the given launch mode. If any enablement verifier returns false, the checker is not run.
Register your own implementation of ICheckerEnablementVerifier in your Plugin's plugin.xml:
<extension
point="org.eclipse.cdt.codan.core.checkerEnablement">
<verifier class="path.to.MyCheckerEnablementVerifier" />
</extension>
The following implementation checks the content type:
public class MyCheckerEnablementVerifier implements ICheckerEnablementVerifier {
#Override
public boolean isCheckerEnabled(IChecker checker, IResource resource, CheckerLaunchMode mode) {
IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
IContentType contentType = contentTypeManager.findContentTypeFor(resource.getLocation().toOSString());
if (contentType.getId().equals("contenttypeid")) {
return false;
} else {
return true;
}
}
}

Disable copy/paste on Xamarin forms input field i.e. Entry

I am working on disabling copy/paste option menus on xamarin forms Entry, I am able to disable copy option using IsPassword=true attribute but this attribute also converts the normal input field to password field, which is not a requirement.
<Entry IsPassword="true" Placeholder="Password" TextColor="Green" BackgroundColor="#2c3e50" />
Thanks in advance.
This has to do with how Forms functions. Using iOS as the example here, the CanPerform override referred to in the other answer's Bugzilla issue is using the UIMenuController as the withSender and not the UITextField itself that might otherwise be expected. This is because the EntryRenderer class is a ViewRenderer<TView, TNativeView> type and subsequently is using whatever TNativeView (in this case, the UITextView) has in its CanPerform. Because nothing is going to be overridden by default, one still sees all of the cut/copy/paste options in the UIMenuController.
As a result, there would be a couple options. You could first make the modification where if you don't want copy/paste but are fine with getting rid of everything else, you can use UIMenuController.SharedMenuController.SetMenuVisible(false, false) in a custom renderer inheriting from EntryRenderer. If you look around on SO, there are similar questions where this is a possible route.
Alternatively, you can create a "true" custom renderer inheriting from ViewRenderer<TView, TNativeView> as ViewRenderer<Entry, YourNoCopyPasteUITextFieldClassName>. The class inheriting from UITextField can then override CanPerform as something like follows:
public override bool CanPerform(Selector action, NSObject withSender)
{
if(action.Name == "paste:" || action.Name == "copy:" || action.Name == "cut:")
return false;
return base.CanPerform(action, withSender);
}
This will require more effort because the custom renderer will not have the same behavior as the EntryRenderer, but as Xamarin.Forms is now open source, you could look to it for some ideas as to how the EntryRenderer functions normally. Something similar would likely have to be done for Android.
Edit: For Android, you can probably use this SO answer as a starting point: How to disable copy/paste from/to EditText
Another custom renderer, this time inheriting from ViewRenderer<Entry, EditText>, and create a class inside of it like this (in the most basic form):
class Callback : Java.Lang.Object, ActionMode.ICallback
{
public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
{
return false;
}
public bool OnCreateActionMode(ActionMode mode, IMenu menu)
{
return false;
}
public void OnDestroyActionMode(ActionMode mode)
{
}
public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
{
return false;
}
}
Then, in your OnElementChanged method, you can set the native control and the CustomSelectionActionModeCallback value:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.CustomSelectionActionModeCallback = new Callback();
}
}
Doing something like the following appears to disable all of the copy/paste/cut functionality on the custom entry as far as the toolbar goes. However, you can still long click to show the paste button, to which I've poked around a bit hadn't found an answer yet beyond setting LongClickable to false. If I do find anything else in that regard, I'd make sure to update this.

Eclipse Plugin Dev- Extracting IStackFrame object from selection in Debug View

So, I am developing an Eclipse plugin and trying to build a View similiar to the Variables View. Now, to get the selected StackFrame from the Debug View, I have registered an IDebugContextListener, which ultimately calls the method listed below in case of a selection.
The problem is that I ma unable to get a IStackFrame object from IStructuredSelection.getFirstElement().
I also tried to get an adapter for the IStackframe class. That too didn't work.
I would really appreciate if someone can point me the method of getting a IStackFrame object from a selection.
private void contextActivated(ISelection context) {
if (context instanceof StructuredSelection) {
System.out.println("a");
Object data = ((StructuredSelection) context).getFirstElement();
if (data instanceof IStackFrame) {
System.out.println("yes");
} else {
System.out.println("no" + data.getClass().getName());
}
}
}
The issue with this is that it always execute the else part (even when the selection is a StackFrame in the debug view). Also, the adapter approach didn't work.

Rename "params" parameter in Java Bindings Library with Mono for Android?

I'm trying to create a Java Binding Library for BugSense, but one of the methods has a parameter named "params" which is a reserved word in C#. I've tried to use the Metadata.xml file to rename it, but I can't figure out how to access the class, let alone the method or it's parameter.
Here is the problem code it's generating:
namespace Com.Bugsense.Trace {
[global::Android.Runtime.Register ("com/bugsense/trace/ActivityAsyncTask", DoNotGenerateAcw=true)]
internal partial class ActivityAsyncTaskInvoker : ActivityAsyncTask {
static IntPtr id_doInBackground_arrayLjava_lang_Object_;
[Register ("doInBackground", "([Ljava/lang/Object;)Ljava/lang/Object;", "GetDoInBackground_arrayLjava_lang_Object_Handler")]
protected override global::Java.Lang.Object DoInBackground (global::Java.Lang.Object[] params)
{
if (id_doInBackground_arrayLjava_lang_Object_ == IntPtr.Zero)
id_doInBackground_arrayLjava_lang_Object_ = JNIEnv.GetMethodID (class_ref, "doInBackground", "([Ljava/lang/Object;)Ljava/lang/Object;");
IntPtr native_params = JNIEnv.NewArray (params);
global::Java.Lang.Object __ret = Java.Lang.Object.GetObject<global::Java.Lang.Object> (JNIEnv.CallObjectMethod (Handle, id_doInBackground_arrayLjava_lang_Object_, new JValue (native_params)), JniHandleOwnership.TransferLocalRef);
if (params != null) {
JNIEnv.CopyArray (native_params, params);
JNIEnv.DeleteLocalRef (native_params);
}
return __ret;
}
}
}
Here is my mapping, which I feel should work, but just refuses to.
<attr path="/api/package[#name='com.bugsense.trace']/class[#name='ActivityAsyncTaskInvoker']/method[#name='doInBackground']/parameter[#name='params']" name="managedName">#params</attr>
I've tried everything I can think of. Please, HELP!
So, turns out it's just a bug in the current version of Mono for Android. If you update to the 4.2.4 build, which is in beta, everything compiles fine.

Unsubscribe from IObservableElementEnumerable.EnumerableChanged doesn't work?

Parts of our UI uses IObservableElementEnumerable.EnumerableChanged in order to update if the user e.g. deletes a domain object from a folder.
When the UI is disposed, we unsubscribe from the event... or so we thought. It turns out that the unsubscribe doesn't have any effect, and our event handler is still called. This caused a number of odd bugs, but also leads to memory leaks.
The only time unsubscription works, is if we store the IObservableElementEnumerable reference instead of calling IObservableElementEnumerableFactory.GetEnumerable(obj) again. But this, in turn, is likely to keep a live reference to the folder object, which will break if the folder itself is deleted by the user.
This is particularly puzzling as the GetEnumerable() documentation clearly states: "It is expected that subsequent calls with the same domain object will yield the same instance of IObservableElementEnumerable." Is this not to be interpreted as a guarantee?
Should there be any reason for unsubscription not working?
The following code replicates the issue on Petrel 2011 (add to a simple plugin with a menu extension, or get the full solution here (DropBox)):
using System;
using System.Linq;
using System.Windows.Forms;
using Slb.Ocean.Core;
using Slb.Ocean.Petrel;
using Slb.Ocean.Petrel.Basics;
using Slb.Ocean.Petrel.UI;
namespace ObservableElementEnumerable
{
public class OEEForm : Form
{
private Droid _droid;
private bool _disposed;
public OEEForm()
{
IInput input = PetrelProject.Inputs;
IIdentifiable selected = input.GetSelected<object>().FirstOrDefault() as IIdentifiable;
if (selected == null)
{
PetrelLogger.InfoOutputWindow("Select a folder first");
return;
}
_droid = selected.Droid;
GetEnumerable().EnumerableChanged += enumerable_EnumerableChanged;
PetrelLogger.InfoOutputWindow("Enumerable subscribed");
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && !_disposed)
{
GetEnumerable().EnumerableChanged -= enumerable_EnumerableChanged;
PetrelLogger.InfoOutputWindow("Enumerable unsubscribed (?)");
_droid = null;
_disposed = true;
}
}
IObservableElementEnumerable GetEnumerable()
{
if (_disposed)
throw new ObjectDisposedException("OEEForm");
object obj = DataManager.Resolve(_droid);
IObservableElementEnumerableFactory factory = CoreSystem.GetService<IObservableElementEnumerableFactory>(obj);
IObservableElementEnumerable enumerable = factory.GetEnumerable(obj);
return enumerable;
}
void enumerable_EnumerableChanged(object sender, ElementEnumerableChangeEventArgs e)
{
PetrelLogger.InfoOutputWindow("Enumerable changed");
if (_disposed)
PetrelLogger.InfoOutputWindow("... but I am disposed and unsubscribed!");
}
}
public static class Menu1
{
public static void OEEBegin1_ToolClick(object sender, System.EventArgs e)
{
OEEForm f = new OEEForm();
f.Show();
}
}
}
To replicate:
Run Petrel with the plugin
Load a project with a folder with objects
Select the folder
Activate the plugin menu item
With the popup open, delete an object in the folder
Close the Form popping up
Delete an object in the folder
The message log should clearly show that the event handler is still called after the form is disposed.
You already keep a reference to the underlying enumerable by connecting the event. Events are references as well. Just keep a reference to the enumerable and unsubscribe from the same instance as the one you subscribe to.
To deal with the issue of objects that are deleted by the user you need to listen to the delete event.