Skip to main content

Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » How to populate undo/redo in an E3/E4 hybrid editor (DIEditorPart)?
How to populate undo/redo in an E3/E4 hybrid editor (DIEditorPart)? [message #1763648] Thu, 18 May 2017 11:02
Jens Rabe is currently offline Jens RabeFriend
Messages: 81
Registered: September 2013
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 = () => {}

  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) {
        } else {
          Display.getDefault.asyncExec(() => _dirtyE3.setDirtyState(dirty))
    // Finally, we setup our saving routine.
    doPersist = () => { /* not relevant here */ }

  def setFocus(): Unit = _view.foreach(_.setFocus)

  def persistState(): Unit = {}

  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?
Previous Topic:How to use 'BeanProperties' without warnings
Next Topic:Product Configuration Wizard
Goto Forum:

Current Time: Thu Nov 15 04:41:25 GMT 2018

Powered by FUDForum. Page generated in 0.46912 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top