How to indicate a file has changed after modifying it using IFile - eclipse

I've been able to successfully update the contents of a file via a popup menu extension I've created underneath the Source menu that comes up when right-clicking on a file.
I'd like to indicate that the file has been changed and needs to be saved. Right now, the file contents change and save automatically. I thought the IFile.touch method would cause the file to be in a state where it needed to be saved but I'm not seeing that happen.
Here's my code...
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
IEditorPart editorPart = HandlerUtil.getActiveEditor(event);
IEditorInput input = editorPart.getEditorInput();
InputStream is = null;
if (input instanceof FileEditorInput) {
IFile file = ((FileEditorInput) input).getFile();
try {
is = file.getContents();
String originalContents = convertStreamToString(is);
String newContents = originalContents + "testing changing the contents...";
InputStream newInput = new ByteArrayInputStream(newContents.getBytes());
file.setContents(newInput, false, true, null);
file.touch(null);
} catch (CoreException e) {
MessageDialog.openError(
window.getShell(),
"Generate Builder Error",
"An Exception has been thrown when interacting with file " + file.getName() +
": " + e.getMessage());
}
}
return null;
}

If you want the file's contents marked as needing to be saved, you need to be interacting with the in-memory representation you want to prompt as needing to be saved--the editor from which you're getting the input.

Based on help from nitind and this post - Replace selected code from eclipse editor thru plugin comand - I was able to update the text editor and the file shows up as modified. The key was to work with the ITextEditor and IDocumentProvider instead of a FileEditor.
Here's the updated code...
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
IEditorPart editorPart = HandlerUtil.getActiveEditor(event);
if (editorPart instanceof ITextEditor ) {
ITextEditor editor = (ITextEditor)editorPart;
IDocumentProvider prov = editor.getDocumentProvider();
IDocument doc = prov.getDocument( editor.getEditorInput() );
String className = getClassName(doc.get());
ISelection sel = editor.getSelectionProvider().getSelection();
if (sel instanceof TextSelection ) {
TextSelection textSel = (TextSelection)sel;
String newText = generateBuilderText(className, textSel.getText());
try {
doc.replace(textSel.getOffset(), textSel.getLength(), newText);
} catch (Exception e) {
MessageDialog.openError(
window.getShell(),
"Generate Builder Error",
"An Exception has been thrown when attempting to replace "
+ "text in editor " + editor.getTitle() +
": " + e.getMessage());
}
}
}
return null;
}

Related

How to pass argument in class that extends "EditorPart" from handler class to affect "createPartControl" UI creation

I have 2 problems.
1) Command handler not responding for EditorPart
2) How to pass argument to a class that extends "EditorPart" to affect "createPartControl" method for UI creation.
Please have a look below in my code for better understanding. I have created command handler for Editor but my handler is not responding as expected. I want to have the selected file path in the package explorer and pass this file path value to the class that extends EditorPart in order to create UI based on this selected file.
Handler.java
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
// get the page
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
IWorkbenchPage page = window.getActivePage();
// get the selection
ISelection selection = HandlerUtil.getCurrentSelection(event);
IStructuredSelection sel = (IStructuredSelection) selection;
Object selObj = sel.getFirstElement();
if (selObj instanceof IResource) {
resource = (IResource) selObj;
project = resource.getProject();
location = project.getLocation();
}else {
IAdaptable adaptable = (IAdaptable)selObj;
Object adapter = adaptable.getAdapter(IResource.class);
resource = (IResource) adapter;
project = resource.getProject();
location = project.getLocation();
}
TaskEditorInput input = new TaskEditorInput();
try {
page.openEditor(input, "launcher.ChartEditor");
} catch (PartInitException e) {
e.printStackTrace();
}
return null;
}
class that extends EditorPart
#Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
setSite(site);
setInput(input);
setPartName("ChartEditor");
}
public void createPartControl(Composite _parent) {
}
public void createChart(String filePath) {
dataset = chart1.createDataset(filePath);
try {
chart = chart1.createChart(dataset);
frame = new ChartComposite(parent, SWT.NONE, chart, true);
frame.pack();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I want pass the value of selected filepath in this createChart(String filePath) method from handler class. How can i do this? Please help me.
Add the value you want to pass to your class implementing IEditorInput (TaskEditorInput in your case). The editor input is given to the editor init method so you can get the value there:
#Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
if (input instanceof TaskEditorInout) {
TaskEditorInput taskInput = (TaskEditorInput)input;
// TODO save value for createPartControl
}
setSite(site);
setInput(input);
setPartName("ChartEditor");
}
To be sure to get the resource corresponding to a selection you need to use the platform adapter manager. On modern versions of Eclipse you can use
IStructuredSelection sel = HandlerUtil.getCurrentStructuredSelection(event);
IResource resource = Adapters.adapt(sel.getFirstElement(), IResource.class);

Printing to console removes hyperlinks created already

I was trying to create a feature to create hyperlinks in the console while the information is added.
While debugging, I noticed that the first hyperlink is succesfully created, but when the next line is printed to console, the hyperlink dissapears.
The code which I use to create the hyperlinks is:
String hyperLinkText = "test";
myConsole.printToConsole(test);
String myFile = new File("D:/Test/testFile.txt");
URI location = myFile.toURI();
IFile[] files = project.getWorkspace().getRoot().findFilesForLocationURI(location);
HyperlinkInformation hyperlinkInformation = new HyperlinkInformation(myConsole, myConsole.getDocument().get().length(), hyperLinkText.length());
FileHyperlink fileHyperlink = new FileHyperlink(hyperlinkInformation,
files[0], 1);
try {
hyperlinkInformation.getConsole().addHyperlink(fileHyperlink,
fileHyperlink.getOffset(), fileHyperlink.getLength());
} catch (BadLocationException e) {
//
}
The function addHyperlink:
public void addHyperlink(IHyperlink hyperlink, int offset, int length) throws BadLocationException {
IDocument document = getDocument();
ConsoleHyperlinkPosition hyperlinkPosition = new ConsoleHyperlinkPosition(hyperlink, offset, length);
try {
document.addPosition(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY, hyperlinkPosition);
fConsoleManager.refresh(this);
} catch (BadPositionCategoryException e) {
ConsolePlugin.log(e);
}
}
Is this the normal behaviour or am I missing something?

how to get drop down list by type respective alphabet in ComboBoxViewerCellEditor

In ComboBoxViewerCellEditor I want to write something and as a result I will get the matching dropdown value.
Can you suggest how to get this? Please find the code below:
public TCOperationColumnEditable(TableViewer viewer) {
super(viewer);
try
{
this.viewer = viewer;
//this.editor = new TextCellEditor(this.viewer.getTable());
OperationGSON[] allOperations = OperationAPIHandler.getInstance().getAllOperations();
ArrayList<String> opnName = new ArrayList<String>();
for(OperationGSON opn : allOperations)
{
opnName.add(opn.opnName);
}
this.editor = new ComboBoxViewerCellEditor(this.viewer.getTable(), SWT.FULL_SELECTION );
this.editor.setLabelProvider(new LabelProvider());
this.editor.setContentProvider(new ArrayContentProvide());
this.editor.setInput(opnName);
String[] stockArr = new String[opnName.size()];
stockArr = opnName.toArray(stockArr);
new AutoCompleteField(this.viewer.getControl(), new CComboContentAdapter(), stockArr);
}
catch(Exception e)
{
System.out.println("[" + getClass().getName() + " : TCOperationColumnEditable()] - Exception : " + e.getMessage());
e.printStackTrace();
}
}
enter image description here
Subclass TextCellEditor.
For a content proposal, use field assist API of JFace
(org.eclipse.jface.fieldassist). Content assist is enabled
when the cell editor is activated for the first time:
if (contentProposalAdapter == null) {
....
// enable content assist on the cell editor's text widget
contentProposalAdapter = new ContentProposalAdapter(text, new TextContentAdapter(), proposalProvider, activationKeyStroke, null);
} else {
contentProposalAdapter.setEnabled(true);
}
super.activate();
....
Make sure to also override method
TextCellEditor#dependsOnExternalFocusListener() to return false always.
Otherwise, you'll face some serious problems concerning focus.

e4 Application / Menu

i try to create an eclipse 4 application but i have a problem: "Menu/New" : when i try to create a new file i receive this error message :
Internal error org.eclipse.E4.core.di.InjectionException:
java.lang.NullPointerException
this's the code:
public class OpenHandler {
#Execute
public void execute(#Named(IServiceConstants.ACTIVE_SHELL) Shell shell, EPartService partService, MApplication application,
EModelService modelService) {
FileDialog dialog = new FileDialog(shell);
String fileName = dialog.open();
if (fileName != null) {
try {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
String text = scanner.useDelimiter("\\A").next();
scanner.close();
// create part
MPart part = MBasicFactory.INSTANCE.createPart();
part.setLabel(file.getName());
part.setCloseable(true);
part.getTags().add(EPartService.REMOVE_ON_HIDE_TAG);
part.setContributionURI("bundleclass://RCPTextEditor/RCPTextEditor.EditorPart");
// get part stack and show new part
List<MPartStack> stacks = modelService.findElements(application, null, MPartStack.class, null);
stacks.get(0).getChildren().add(part);
partService.showPart(part, PartState.ACTIVATE);
((EditorPart) part.getObject()).styledText.setText(text);
((EditorPart) part.getObject()).model = new EditorModel(text, text);
((EditorPart) part.getObject()).setFile(file);
part.setDirty(false);
} catch (IOException e) {
MessageDialog.openError(shell, "Error opening file", "File " + fileName + " could not be opened.");
}
}
}
}
Can someone help me ??? thanks in advance
Since you haven't show us the stack trace I am just guessing but the line
((EditorPart) part.getObject()).styledText.setText(text);
is probably accessing a styledText field before it has been created.
You need to do this in the #PostConstruct method of your EditorPart when you create the part controls.

Eclipse Plugin change Language programmatically

I am trying to change the language of my RCP plugin programmatically. I had no luck so far. The Approach below is not working for me. After restart the language does not change. I populate a Menu dynamically with listet Translation files in a specific folder. The method LanguageSelectedListener.widgetSelected when a MenuItem is selected. Tried this with an exported product and also running from eclipse.
private void setMenuLanguages(Menu menu){
File dir = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + language_directory);
String[] dirList = dir.list();
String currentLocale = System.getProperty("user.language");
Locale current = new Locale(currentLocale, "", "");
Locale[] locales = new Locale[dirList.length];
LanguageSelectedListener listener = new LanguageSelectedListener();
for(int i=0; i<dirList.length; i++){
String file = dirList[i].split(".properties")[0];
String locShort;
if(file.equals("messages"))locShort = "en"; //default english
else locShort = file.split("_")[1];
locales[i] = new Locale(locShort);
MenuItem menuItem = new MenuItem(menu, SWT.RADIO, i);
menuItem.setText(locales[i].getDisplayName());
menuItem.setData("locale", locales[i]);
menuItem.addSelectionListener(listener);
if(locales[i].getLanguage().equals(current.getLanguage()))
menuItem.setSelection(true);
}
return;
}
private class LanguageSelectedListener extends SelectionAdapter{
#Override
public void widgetSelected(SelectionEvent e) {
MenuItem item = (MenuItem) e.widget;
if(!item.getSelection() || !MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Info", "Programm wird neu gestartet. Möchten Sie fortfahren?")){
item.setSelection(false);
return;
}
Locale locale = (Locale) item.getData("locale");
StringBuffer arguments = new StringBuffer();
arguments.append("${eclipse.vm}\n"); //$NON-NLS-1$
arguments.append("-nl\n").append(locale.getLanguage()).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
System.setProperty("eclipse.exitcode", Integer.toString(IApplication.EXIT_RELAUNCH)); //$NON-NLS-1$
System.getProperties().setProperty(IApplicationContext.EXIT_DATA_PROPERTY, arguments.toString());
PlatformUI.getWorkbench().restart();
}
}
so I implemented the hacky solution by manipulating the ini file of the product (not the config.ini file). Works pretty well for me.
String installLoc = Platform.getInstallLocation().getURL().getPath();
String oldIniLocation = installLoc + "decoder.ini";
String content = null;
File oldIni = null;
try {
oldIni = new File(oldIniLocation);
content = FileUtils.readFileToString(oldIni, "UTF-8");
} catch (IOException e1) {
throw new RuntimeException("reading from file failed!", e1);
}
Locale locale = (Locale) item.getData("locale");
if(content.contains("-nl")){
content = content.replaceFirst("-nl\r\n..", "-nl\r\n" + locale.getLanguage());
}
else{
StringBuilder newContent = new StringBuilder("-nl\r\n" + locale.getLanguage() +"\r\n");
content = newContent.append(content).toString();
}
File newIni = new File(installLoc + "rename.ini");
try {
FileUtils.writeStringToFile(newIni, content, "UTF-8");
} catch (IOException e1) {
throw new RuntimeException("writing to file failed!", e1);
}
oldIni.delete();
//renaming newIni by moving it
oldIni = new File(installLoc + "decoder.ini");
try {
FileUtils.moveFile(newIni, oldIni);
} catch (IOException e1) {
throw new RuntimeException("renaming/moving file failed!", e1);
}
System.setProperty("eclipse.exitcode", Integer.toString(IApplication.EXIT_RESTART)); //$NON-NLS-1$
PlatformUI.getWorkbench().restart();