package LinGUIne.parts.advanced; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CaretEvent; import org.eclipse.swt.custom.CaretListener; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import LinGUIne.extensions.IEditorSettings; import LinGUIne.extensions.IProjectDataEditor; import LinGUIne.model.AnnotationSet; import LinGUIne.model.AnnotationSetContents; import LinGUIne.model.IProjectData; import LinGUIne.model.Project; import LinGUIne.model.TextData; import LinGUIne.model.TextDataContents; import LinGUIne.model.annotations.IAnnotation; import LinGUIne.model.annotations.MetaAnnotation; import LinGUIne.model.annotations.Tag; import LinGUIne.model.annotations.TextAnnotation; /** * ProjectDataEditor for TextAnnotations in an AnnotationSet for TextData. * * @author Kyle Mullins */ public class TextAnnotationSetEditor implements IProjectDataEditor { private StyledText textArea; private Project parentProject; private TextData projectData; private TextDataContents projectDataContents; private AnnotationSet annotationSet; private AnnotationSetContents annotationSetContents; private TextAnnotationSetSettings editorSettings; private DirtyStateChangedListener dirtyListener; private boolean isDirty; private boolean updatingTextArea; @Override public boolean canOpenData(IProjectData data, Project proj) { if(data instanceof AnnotationSet){ AnnotationSet annotations = (AnnotationSet)data; return proj.getDataForAnnotation(annotations) instanceof TextData; } return false; } @Override public boolean hasEditorSettings() { return true; } @Override public IEditorSettings getEditorSettings() { return editorSettings; } @Override public void createComposite(Composite parent) { Composite container = new Composite(parent, SWT.NONE); container.setLayout(new GridLayout(1, false)); textArea = new StyledText(container, SWT.V_SCROLL | SWT.H_SCROLL); textArea.setLayoutData(new GridData(GridData.FILL_BOTH)); textArea.setAlwaysShowScrollBars(true); textArea.addModifyListener(new ModifyListener(){ @Override public void modifyText(ModifyEvent e) { if(!updatingTextArea){ if(!projectDataContents.getText().equals(textArea.getText())){ projectDataContents.setText(textArea.getText()); setDirty(true); //TODO: Intelligently update annotationSetContents } } } }); /* * Set up listeners to keep the settings updated properly. */ textArea.addCaretListener(new CaretListener(){ @Override public void caretMoved(CaretEvent event) { editorSettings.caretMoved(event.caretOffset); } }); textArea.addSelectionListener(new SelectionListener(){ @Override public void widgetSelected(SelectionEvent e) { editorSettings.selectionChanged(new Point(e.x, e.y)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); updateTextArea(); createContextMenu(textArea); } @Override public void setInputData(IProjectData data, Project parentProj) { if(canOpenData(data, parentProj)){ annotationSet = (AnnotationSet)data; annotationSetContents = annotationSet.getContents(); projectData = (TextData)parentProj.getDataForAnnotation(annotationSet); projectDataContents = projectData.getContents(); parentProject = parentProj; editorSettings = new TextAnnotationSetSettings(this, projectDataContents, annotationSetContents); } else{ throw new IllegalArgumentException("This class only supports " + "TextData objects with Annotations!"); } } @Override public IProjectData getInputProjectData(){ return projectData; } @Override public Project getInputParentProject(){ return parentProject; } @Override public void registerDirtyStateListener(DirtyStateChangedListener listener) { dirtyListener = listener; } @Override public boolean saveChanges() { if(projectData.updateContents(projectDataContents)){ if(annotationSet.updateContents(annotationSetContents)){ setDirty(false); return true; } } return false; } @Override public String getPartLabel() { return projectData.getName() + " (Annotations)"; } @Override public String getPartIconURI(){ return null; } /** * Sets the dirty state of the editor. * * @param dirty */ public void setDirty(boolean dirty){ if(isDirty != dirty){ isDirty = dirty; dirtyListener.dirtyChanged(isDirty); } } /** * Updates the text area to reflect changes to the Annotations from the * settings view. */ public void annotationsChanged(){ int caretOffset = textArea.getCaretOffset(); updateTextArea(); textArea.setCaretOffset(caretOffset); } /** * Updates the text area to reflect the current state of the AnnotationSet's * contents. */ private void updateTextArea() { //Silly flagging to keep update calls from triggering the ModifyListener updatingTextArea = true;{ textArea.setText(projectDataContents.getText()); } updatingTextArea = false; for(Tag tag: annotationSetContents.getTags()){ if(tag.getEnabled()){ for(IAnnotation annotation: annotationSetContents.getAnnotations(tag)){ if(annotation instanceof TextAnnotation){ TextAnnotation textAnnotation = ((TextAnnotation)annotation); StyleRange style = new StyleRange( textAnnotation.getStartIndex(), textAnnotation.getLength(), tag.getColor(), textArea.getBackground(), SWT.BOLD); textArea.setStyleRange(style); } else if(annotation instanceof MetaAnnotation){ //TODO: Handle annotations of other annotations } } } } } /** * Creates the context menu. */ private void createContextMenu(Composite container){ Menu contextMenu = new Menu(container); container.setMenu(contextMenu); MenuItem selectAllItem = new MenuItem(contextMenu, SWT.NONE); selectAllItem.setText("Select All"); selectAllItem.addSelectionListener(new SelectionListener(){ @Override public void widgetSelected(SelectionEvent e) { textArea.setSelection(0, textArea.getText().length()); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); } }