How to populate undo/redo in an E3/E4 hybrid editor (DIEditorPart)? [message #1763648] |
Thu, 18 May 2017 11:02 |
Jens Rabe Messages: 81 Registered: September 2013 |
Member |
|
|
My application is hybrid E3/E4 because I want to use parts of the Eclipse Workbench, but also make my stuff (somewhat) ready for later pure E4 based applications.
In this application I have an editor which uses a custom editor input (not file-based, but based on data pulled from a database; when the user saves the changes, they are written back to the database). My local in-memory representation of the data is managed by EMF / Xcore and the editor uses a manually-designed GUI that works via EMF Edit Databinding, i.e., I am using an EditingDomain (that is, a basic AdapterFactoryEditingDomain with a BasicCommandStack) to track all the changes.
To plug my E4 editor into an E3 editor, I use the compatibility layer, and here especially the DIEditorPart.
While this works fine so far, I have not yet been able to get undo/redo to work.
My code looks like this (I am using Scala with Scala-IDE):
The E3 editor bridge:
final class CustomEditorPartE3Bridge extends DIEditorPart(classOf[CustomEditorPart])
The "real" part:
final class CustomEditorPart {
@Inject private var _ctx: IEclipseContext = _
private var _view: Option[MyCustomEditorView] = None
@Inject private var _dirty: MDirtyable = _
@Inject @Optional private var _dirtyE3: IDirtyProviderService = _
private var doPersist: () => Unit = () => {}
@PostConstruct
def init(input: IEditorInput): Unit = input match {
case i: MyCustomEditorInput => initPart(i)
case _ =>
throw new IllegalStateException("Required a %s but got a %s".
format(classOf[MyCustomEditorInput].getName, input.getClass.getName))
}
private def initPart(input: MyCustomEditorInput): Unit = {
val cc = _ctx.createChild()
// Now we need an adapter factory and a respective editing domain
// to enable Undo and Redo
val adapterFactory = new ModelAdapterFactory // generated with Xcore
val cs = new BasicCommandStack
val domain = new AdapterFactoryEditingDomain(adapterFactory, cs)
// We need the editing domain in the control for Databinding
cc.set(classOf[EditingDomain], domain)
// Now we setup the view
_view = Some(ContextInjectionFactory.make(classOf[MyCustomEditorView], cc))
// And we handle dirtying of our part
object csl extends CommandStackListener {
def commandStackChanged(eo: EventObject): Unit = {
val dirty = cs.isSaveNeeded()
if (_dirtyE3 == null) {
_dirty.setDirty(dirty)
} else {
Display.getDefault.asyncExec(() => _dirtyE3.setDirtyState(dirty))
}
}
}
cs.addCommandStackListener(csl)
// Finally, we setup our saving routine.
doPersist = () => { /* not relevant here */ }
}
@Focus
def setFocus(): Unit = _view.foreach(_.setFocus)
@PersistState
def persistState(): Unit = {}
@Persist
def commit(): Unit = doPersist()
}
So, how do I contribute undo/redo so that E3's undo/redo mechanism kicks in? Do I somehow have to propagate my EditingDomain back to my E3 bridge and set up some action bar contributor or can I inject something that sets up the undo/redo for me?
|
|
|
Powered by
FUDForum. Page generated in 0.02683 seconds