2017-05-18 8 views
0

이클립스 워크 벤치의 일부를 사용하고 싶기 때문에 내 응용 프로그램이 하이브리드 E3/E4이지만 나중에 순수한 E4 기반 응용 프로그램을 사용할 준비가되었습니다.Eclipse3/Eclipse4 하이브리드 편집기 (DIEditorPart)에서 실행 취소/다시 실행을 채우는 방법은 무엇입니까?

이 응용 프로그램에서는 파일 기반이 아닌 데이터베이스에서 가져온 데이터를 기반으로 사용자 정의 편집기 입력을 사용하는 편집기가 있는데, 사용자가 변경 사항을 저장하면 데이터베이스에 다시 기록됩니다. 데이터의 내 로컬 메모리 내 표현은 EMF/Xcore에서 관리하며 편집기는 EMF 편집 데이터 바인딩을 통해 작동하는 수동으로 설계된 GUI를 사용합니다. 즉 EditingDomain (즉 AdapterFactoryEditingDomainBasicCommandStack)을 사용합니다. 모든 변경 사항을 추적하십시오.

내 E4 편집기를 E3 편집기에 연결하려면 호환성 레이어를 사용하고 특히 여기서는 DIEditorPart입니다.

아직까지는 제대로 작동하지만 아직 실행 취소/다시 실행을 수행 할 수는 없습니다.

내 코드는 다음과 같습니다

(I 스칼라-IDE와 스칼라를 사용하고 있습니다) :

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 용도의 다양한 예를 주위 하구 및 검색 후 나는이 함께했다 :

나는 내가 IWorkbenchPart를 삽입 할 수 DIEditorPart을 사용하고합니다. 부품이 순수 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) 
     } 
    } 

UndoActionRedoAction보기 :

는 그래서 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) 

,하지만 작동 .