2017-05-18 6 views
0

私のアプリケーションはEclipse Workbenchの一部を使用したいので、ハイブリッドE3/E4ですが、後で純粋なE4ベースのアプリケーションのために私のもの(いくらか)を用意しています。Eclipse3/Eclipse4ハイブリッドエディタ(DIEditorPart)で元に戻す/やり直しを行う方法

このアプリケーションでは、ファイルベースではなく、データベースから取得したデータに基づいて、カスタムエディタ入力を使用するエディタを使用します。ユーザーが変更を保存すると、データベースに書き戻されます。データのローカルメモリ内表現はEMF/Xcoreによって管理され、エディタはEMF編集データバインディングを使用して手動で設計されたGUIを使用します。つまり、EditingDomain(すなわちAdapterFactoryEditingDomainBasicCommandStack)を使用しています。すべての変更を追跡します。

E4エディタをE3エディタに接続するには、互換レイヤーを使用します。ここでは特にDIEditorPartです。

これまでのところうまく動作しますが、私はまだ元に戻す/やり直しを行うことができませんでした。

私のコードは次のようになり

(私はスカラ座-IDEでのScalaを使用しています):

E3エディタブリッジ:

final class CustomEditorPartE3Bridge extends DIEditorPart(classOf[CustomEditorPart]) 

そして "本物" の一部:

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() 
} 

では、元に戻す/やり直しを行って、E3の元に戻す/やり直しの仕組みが始まるようにするにはどうすればいいですか?どういうわけか私のEditingDomainを私のE3ブリッジに戻して、いくつかのアクションバーコントリビュータを設定しなければならないのですか、私のために元に戻す/やり直しを設定するものを注入できますか?

+0

コマンドスタック上で操作できるアンドゥ/リドゥハンドラ(デフォルトコマンドにバインドされています)を登録しましたか(EHandlerServiceまたはアプリケーションモデル経由)ですか? –

+0

これを実行し、私のundo/redoハンドラを次のように追加しました: '_handlerService.activateHandler(" org.eclipse.ui.edit.undo "、undo)' - 'undo'は、メソッドがアノテーションされたクラスのオブジェクトです'@CanExecute'と' @Execute'を使用します。ただし、取り消し/やり直しはまだ行われません。 – rabejens

答えて

0

私はこれを回答として投稿していますので、解決策としてマークすることができます。周りいじると私はこれを思い付いたEHandlerServiceの用途の様々な例を検索した後

私はDIEditorPartを使用していたとき、私はIWorkbenchPartを注入することができます。後で純粋なE4ベースのアプリケーションでこのパーツを使用すると、これが存在しない可能性があるので、@Optionalとして注入し、後でnullをテストします。このような

@Inject @Optional private var _workbenchPart: IWorkbenchPart = _ 

    // In my method 
    val cc: IEclipseContext = ... 
    val domain: EditingDomain = ... 
    cc.set(classOf[EditingDomain], domain) 
    if (_workbenchPart != null) { 
     val undoAction = ContextInjectionFactory.make(classOf[UndoAction], cc) 
     val redoAction = ContextInjectionFactory.make(classOf[RedoAction], cc) 
     val site = _workbenchPart.getSite.asInstanceOf[{ 
     def getActionBars(): org.eclipse.ui.IActionBars 
     }] 
     val targetActionBars = site.getActionBars 
     if (targetActionBars != null) { 
     targetActionBars.setGlobalActionHandler(ActionFactory.UNDO.getId, undoAction) 
     targetActionBars.setGlobalActionHandler(ActionFactory.REDO.getId, redoAction) 
     } 
    } 

マイ​​とRedoAction外観:

だからE4の方法に加えて、私は次のよう持っている。これは、ハッキングのビットです

abstract class UndoRedoAction(canExecute: CommandStack => Boolean, 
           execute: CommandStack => Unit) extends Action { 

    @Inject private var _domain: EditingDomain = _ 

    @PostConstruct 
    private def init(): Unit = { 
    setEnabled(canExecute(_domain.getCommandStack)) 
    object csl extends CommandStackListener { 
     def commandStackChanged(eo: EventObject): Unit = setEnabled(canExecute(_domain.getCommandStack)) 
    } 
    _domain.getCommandStack.addCommandStackListener(csl) 
    } 

    override final def run(): Unit = execute(_domain.getCommandStack) 
} 

final class UndoAction extends UndoRedoAction(_.canUndo, _.undo) 
final class RedoAction extends UndoRedoAction(_.canRedo, _.redo) 

が、それは動作します。

関連する問題