i have the following problem and am grateful for any help.
I start a batch processing for a file in my plugin and unfortunately I have to make sure that the file is closed in the text editor.
I also have to make sure that other editor references for the same file are closed.
Examples:
"Menu => Window => new Window
"Menu => Editor => Toggle Split Horizontal/Vertical and Clone.
This I have also hopefully managed to do
Here's my code:
IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
for (IWorkbenchWindow window : windows) {
IWorkbenchPage page = window.getActivePage();
IEditorReference[] editorReferences = page.getEditorReferences();
for (IEditorReference editorReference : editorReferences) {
String name = editorReference.getName();
IEditorPart editorPart = editorReference.getEditor(false);
if (editorPart instanceof ITextEditor && name != null) {
// Here I note down various attributes, e.g. split
if (name.equals(memberName)) {
MPart mPart = editorPart.getSite().getService(MPart.class);
if (mPart != null) {
List<String> tags = mPart.getTags();
if (tags.contains(IPresentationEngine.SPLIT_HORIZONTAL)) {
openConfiguration.setSplitHorizontal();
} else if (tags.contains(IPresentationEngine.SPLIT_VERTICAL)) {
openConfiguration.setSplitVertical();
}
}
... // another attributes
// close Editor
page.closeEditor(editorPart, false);
}
}
}
}
Now I have the problem that the file is restored in the same state after the batch processing is finished. For example, if the user has done a "horizontal split" or a "clone" on the previously closed file, this should now be displayed exactly as before. When splitting, for example, also with the same ratio as before.
My solution is that I remember the relevant data before (when closing, see code above) and set it again after opening.
Question: Is this the right approach or is there a more elegant way?
Question: How do I determine the ratio for a split?
Question: How do I recognize a clone reference? ("Menu => Editor => Clone")
The plugin must run in an RCA that is still based on Eclipse 4.8 and supports the Eclipse 3.x API.
Related
I am working in an RCP application similar to Eclipse where the user can navigate in Project Explorer tree and opens any file in the Editor
i am Setting the RCP application title in a class which extends "WorkbenchWindowAdvisor" as the following:
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
configurer.setTitle("My RCP Application title");
But what i need to show up in title bar the perspective name and the opened file path like in normal eclipse:
any suggestions
Thanks
This is requires listening to a lot of events in your WorkbenchWindowAdvisor.
In the preWindowOpen method you need to add listeners for:
Page activation and closing using configurer.getWindow().addPageListener(listener) The pageActivated and pageClosed listener methods need to update the title.
Perspective changes using configurer.getWindow().addPerspectiveListener(listener). The perspectiveActivated, perspectiveSavedAs, perspectiveDeactivated methods need to update the title.
Part activations using configurer.getWindow().getPartService().addPartListener(listener). This need to use an IPartListener2. The partActivated, partBroughtToTop, partClosed, partHidden, partVisible methods need to update the title.
You get the open file path from the active editor:
IWorkbenchPage currentPage = configurer.getWindow().getActivePage();
IEditorPart activeEditor = currentPage.getActiveEditor();
if (activeEditor != null) {
path = activeEditor.getTitleToolTip();
}
and the perspective name:
IPerspectiveDescriptor persp = currentPage.getPerspective();
if (persp != null) {
label = persp.getLabel();
}
The full, even more complex, code for this is in org.eclipse.ui.internal.ide.application.IDEWorkbenchWindowAdvisor
I have a plugin which work with special json config files,and it can be runned by the Run button.
I make changes to the config without saving the file.
If I the hit the run button to try it out, plugin will use the config as it is on disk...
It would be nice if the tool would either save all files before running -
or at least give a warning message that tells me that some files are not saved..
How can i detect modified files and get a list of this files?
How can i save changes in this files?
You can look at all the editors which are marked 'dirty' (have modified data) using something like:
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
for (IWorkbenchWindow window : windows)
{
IWorkbenchPage[] pages = window.getPages();
for (IWorkbenchPage page : pages)
{
IEditorPart[] editors = page.getDirtyEditors();
for (IEditorPart editor : editors)
{
IEditorInput input = editor.getEditorInput();
if (input instanceof FileEditorInput)
{
IFile file = ((FileEditorInput)input).getFile();
// TODO ... deal with file
}
}
}
}
Note: Not all editors use FileEditorInput so you might need more code if the editor is using a different input.
When you have an IEditorPart you can call the
public void doSave(IProgressMonitor monitor);
method to get the editor to save its data - but you should confirm with the user first that they want to do this.
I have eclipse rcp application, editor with ctabfolder in certain scenerio i am having editor instance further ctabfolder page those are showing file content. My problem is that if i opened same file in first editor and afer change made at file i opened another editor at application, now it showing the previous opened file not the updated one while i have made avaliable changed file for all process for opening another ediotr.
I am using this for creating editor input, I think this is culprit as it is in a singleton pattern and returning the already invoked instance of ctab page.
IFileStore fileStore = EFS.getLocalFileSystem().getStore("filepath");
if yes then tell me the appropriate replacement for this.
To make an editor be aware that the file it is editing has been changed by another editor you need to make the editor track resource changes using an IResourceChangeListener. Set this up with something like:
IResourceChangeListener resourceChange = new ResourceChange();
ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChange, IResourceChangeEvent.POST_CHANGE);
The ResourceChange class would be:
private class ResourceChange implements IResourceChangeListener
{
#Override
public void resourceChanged(final IResourceChangeEvent event)
{
final IResourceDelta eventDelta = event.getDelta();
final IResourceDelta trackDelta = eventDelta.findMember(editFile);
if (trackDelta != null)
{
if ((trackDelta.getKind() & IResourceDelta.CHANGED) != 0 &&
(trackDelta.getFlags() & IResourceDelta.CONTENT) != 0)
{
// TODO handle change
}
}
}
}
editFile is the IFile the editor is working with.
You need to be careful how to handle the change because this will be invoked during the Save operation for the editor.
I'm working on an Eclipse RCP project and need to let the user select some file.
For convenience, based on some conditions, the initial directory of the file choosing dialog should be set prior to opening it.
As I'm bound to Eclipse RCP / SWT, I am working with the org.eclipse.swt.widgets.FileDialog.
The documentation of this FileDialog points out to use the setFilterPath(String string)-method which should do exactly what I need (see documentation).
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setFilterExtensions(new String [] {"*.html"});
dialog.setFilterPath("c:\\temp");
String result = dialog.open();
Unfortunately it is not working, at least not "every time".
I have currently no installation to check on it, but I'm quite sure that the feature would work totally fine on a Windows 200/XP/Vista machine.
I am working with a Windows 7 machine and I think I am suffering from the behaviour described here for lpstrInitialDir.
At least, this is exactly the behaviour I am facing: The path is good the first time I open the dialog, but the second time, the path is initially set to the last chosen path.
This seems to be convenient in most cases, but it is not in mine.
Can this be right?
If so, have I any chance on changing the behaviour according to my needs?
Thanks for any helping answer!
I ran into the same problem on Windows 10 and found a solution that seems to be working for me. A code snippet from the DirectoryDialog led to the right direction:
if (filterPath != null && filterPath.length() > 0) {
String path = filterPath.replace('/', '\\');
char[] buffer = new char[path.length() + 1];
path.getChars(0, path.length(), buffer, 0);
if (COM.SHCreateItemFromParsingName(buffer, 0, COM.IID_IShellItem, ppv) == OS.S_OK) {
IShellItem psi = new IShellItem(ppv[0]);
/*
* SetDefaultDirectory does not work if the dialog has
* persisted recently used folder. The fix is to clear the
* persisted data.
*/
fileDialog.ClearClientData();
fileDialog.SetDefaultFolder(psi);
psi.Release();
}
}
The FileDialog misses this statement 'fileDialog.ClearClientData()'. My solution is to execute the following code before setting the path and open the dialog:
long [] ppv = new long [1];
if (COM.CoCreateInstance(COM.CLSID_FileOpenDialog, 0, COM.CLSCTX_INPROC_SERVER, COM.IID_IFileOpenDialog, ppv) == OS.S_OK) {
IFileDialog fileDialog = new IFileDialog(ppv[0]);
fileDialog.ClearClientData();
fileDialog.Release();
}
Now you can set the filterpath without Windows messing things up.
I found a simple Solution for the Problem you described (I had the exact same Problem).
Just rearrange the your code like this:
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setFilterPath("c:\\temp"); // This line is switched with the following line
dialog.setFilterExtensions(new String [] {"*.html"});
String result = dialog.open();
Somehow the Order of the methods called is relevant.
Are you using the same FileDialog object when you re-open it?
I ran a few quick tests and found that, if you re-set the filterPath, the dialog opens in the correct location.
If I open the same object again, it starts in the previously selected location.
All,
I am creating a palette less eclipse plugin where am adding figures to the custom editor through the contextual menu, but am not finding a way to do it. Can anyone please guide me as to how to go about adding figures to editor dynamically through context menu i.e. adding actions/commands.
Since Eclipse GEF plugin development finds so less examples to look at, I am adding my solution so others find it useful. This code helps to render a node to the editor.
Source code for Action class to render figures to the editor:
public class AddNodeAction extends EditorPartAction
{
public static final String ADD_NODE = "ADDNODE";
public AddNodeAction(IEditorPart editor) {
super(editor);
setText("Add a Node");
setId(ADD_NODE); // Important to set ID
}
public void run()
{
<ParentModelClass> parent= (<ParentModelClass>)getEditorPart().getAdapter(<ParentModelClass>.class);
if (parent== null)
return;
CommandStack command = (CommandStack)getEditorPart().getAdapter(CommandStack.class);
if (command != null)
{
CompoundCommand totalCmd = new CompoundCommand();
<ChildModelToRenderFigureCommand>cmd = new <ChildModelToRenderFigureCommand>(parent);
cmd.setParent(parent);
<ChildModelClass> newNode = new <ChildModelClass>();
cmd.setNode(newNode);
cmd.setLocation(getLocation()); // Any location you wish to set to
totalCmd.add(cmd);
command.execute(totalCmd);
}
}
#Override
protected boolean calculateEnabled()
{
return true;
}
}
I think you need multiple different things here. Please remember that GEF would like you to have proper MVC pattern, where you have your own model, Figures as View and EditParts as controllers.
From the top of my head I would say that you need at least these things:
CreateCommand
contains all model level modifications that you need to
perform to add your new data to your
data model (undoable and transactional)
CreateAction
makes that CreateCommand instance, initializes it with current selection and executes that command in editdomain
ContextMenuProvider
Provides that CreateAction to context menu
If you happen to be using GMF the canonical mechanism will generate the editparts for you automatically when you make the model modifications inside a command, but if you are not using GMF, you must make sure that your own models and editparts are handling and refreshing the new item adding properly.
EDIT:
Ok, here is some code suggestion with playing around with requests.
public void run() {
// Fetch viewer from editor part (might not work, if not, try some other way)
EditPartViewer viewer = (EditPartViewer) part.getAdapter(EditPartViewer.class);
// get Target EditPart that is under the mouse
EditPart targetEditPart = viewer.findObjectAt(getLocation());
// If nothing under mouse, set root item as target (just playing safe)
if(targetEditPart == null)
targetEditPart = viewer.getContents();
// Make and initialize create request with proper information
CreateRequest createReq = new CreateRequest();
createReq.setLocation(getLocation());
createReq.setFactory(new OwnFactoryImplementation());
// Ask from target editpart command for this request
Command command = targetEditPart.getCommand(createReq);
// If command is ok, and it can be executed, go and execute it on commandstack
if(command != null && command.canExecute()) {
viewer.getEditDomain().getCommandStack().execute(command);
}
}
Now what happens is that editpart will be requested for creation, so the action itself doesn't know how the command works, what makes it objective agaist the command.
So to make things work, you need to install new EditPolicy to your EditPart. EditPolicies can be installed on EditParts createDefaultEditPolicies() function. This EditPolicy must react and return command when there is CreateRequest. This way any child can provide own kind of command for creating children for itself.
Here is a good image how it works (controller is EditPart):
Please ask if I can help you some more. I know that this looks bit more complex, but this makes your own life much more easier, and after you have done that, you actually understand Command-Request Pattern quite well, and it can be reused in many different places.