wiki:Entry_MS_Migration

Version 5 (modified by sena, 4 years ago) (diff)

--

Migrating the multi-page viewer

Each of the MS plugins have a multi-page viewer that extends from CancelableMultiPageEditor (core plugin). For this specific plugin the class is MassSpecMultiPageViewer. One of the major changes for this editor and all the pages (tabs) of the editor is the removal of the reference to ViewInput (core plugin - uses IEditorInput). All pages to be added to a multi-page editor now implement an interface IEntryEditorPart which will give them access to the Entry.

public interface IEntryEditorPart {
	Entry getEntry();
	void setEntry (Entry entry);
	
	void createPartControl(Composite parent);

	void setDirty(boolean b);
	boolean isDirty();
}

Multi-page editor requires a CTabFolder to hold the pages and each page needs to be added as a CTabItem to this folder. CancelableMultiPageEditor handles the interactions such as adding pages so MassSpecMultiPageViewer does not need to change much to handle the addition of pages (tabs). One major change is that all the pages need to be created with ContextInjectionFactory.make(...) method to be able access injected objects later. The following code shows the required changes:

        protected MassSpecScansView getNewScansView( Entry entry, MassSpecEntityProperty entityProperty) {
		MassSpecEntityProperty msProp = (MassSpecEntityProperty) entityProperty.clone();
		msProp.setParentScanNum( entityProperty.getScanNum() );
		msProp.setScanNum(null);
		getPart().getContext().set(MIN_MS_LEVEL_CONTEXT, getMinMSLevel());
		getPart().getContext().set(Property.class, msProp);
		getPart().getContext().set(Entry.class, entry);
		MassSpecScansView view = ContextInjectionFactory.make(MassSpecScansView.class, getPart().getContext());
		
		return view;
	}

Previously, MassSpecScansView object was being created by calling its constructor directly (see below). However, now all the necessary objects for the MassSpecScanView need to be set into the context before initializing it through ContextInjectionFactory.

       protected MassSpecScansView getNewScansView( Entry entry, MassSpecEntityProperty entityProperty) {
		MassSpecEntityProperty msProp = (MassSpecEntityProperty) entityProperty.clone();
		msProp.setParentScanNum( entityProperty.getScanNum() );
		msProp.setScanNum(null);
                return new MassSpecScansView(this.getContainer(), entry, msProp, getMinMSLevel());
       }

Updating the pages

One important aspect of the multi-page editor is to react to the changes in any of the pages (tabs) so that the editor gets marked dirty. In order to handle this behavior, the MassSpecMultiPageViewer needs to subscribe to the changes in the tabs. This is done by publishing EntryEditorPart.EVENT_TOPIC_CONTENT_MODIFIED event every time a page gets dirty as shown below:

public abstract class EntryEditorPart implements IEntryEditorPart {
	
	public static final String EVENT_TOPIC_CONTENT_MODIFIED = "content_modified_in_a_tab";
	
	protected Entry entry = null;
	protected Font boldFont = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
	protected String errMsg = null;
	
	boolean dirty = false;
	@Inject protected IEclipseContext context;
	@Inject IEventBroker eventBroker;
	
	public IEclipseContext getContext() {
		return context;
	}
	
	@Override
	public Entry getEntry() {
		return entry;
	}

	@Override
	public void setEntry(Entry entry) {
		this.entry = entry;
	}
	
	@Override
	public void setDirty(boolean d) {
		this.dirty = d;
		eventBroker.post(EVENT_TOPIC_CONTENT_MODIFIED, this);
	}
...

The multi-page editor then listens to this event.

public class MassSpecMultiPageViewer extends CancelableMultiPageEditor implements IPropertyChangeListener {

     ...

        /** 
	 * this method is called whenever a page (tab) is updated 
	 * However we have to check to make sure the modified page is one of the pages of this
	 * multi-page editor
	 *  
	 * @param the part that gets dirty
	 */
	@Optional @Inject
	public void tabContentModified (@UIEventTopic
			(EntryEditorPart.EVENT_TOPIC_CONTENT_MODIFIED) IEntryEditorPart part) {
		if (part.equals(propertyView) || part.equals(scansView) || this.alPeaksViews.contains(part))
			setDirty(part.isDirty());
	} 
    ...
}

Each specific multi-page viewer needs to react to the changes in its own pages, not any other component that gets modified.