/* * Copyright 2017 * Ubiquitous Knowledge Processing (UKP) Lab and FG Language Technology * Technische Universität Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.tudarmstadt.ukp.clarin.webanno.api.annotation.model; import static de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.selectByAddr; import java.io.Serializable; import java.util.List; import java.util.Map; import org.apache.uima.jcas.JCas; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil; import de.tudarmstadt.ukp.clarin.webanno.constraints.model.ParsedConstraints; import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature; import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer; import de.tudarmstadt.ukp.clarin.webanno.model.Mode; import de.tudarmstadt.ukp.clarin.webanno.model.Project; import de.tudarmstadt.ukp.clarin.webanno.model.ScriptDirection; import de.tudarmstadt.ukp.clarin.webanno.model.SourceDocument; import de.tudarmstadt.ukp.clarin.webanno.security.model.User; import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Sentence; /** * Covers information about the state of the annotation editor component that is relevant across * cycles. */ public interface AnnotatorState extends Serializable { void clearAllSelections(); // --------------------------------------------------------------------------------------------- // Window of visible annotations // --------------------------------------------------------------------------------------------- // REC: sentenceNumber/sentenceAddress can probably be dropped in favor of // firstSentenceNumber/firstSentenceAddress? /** * Get the number of the sentence in focus (curation view) */ int getFocusSentenceNumber(); /** * Set the number of the sentence in focus (curation view) */ void setFocusSentenceNumber(int sentenceNumber); void setFirstVisibleSentence(Sentence aSentence); int getFirstVisibleSentenceAddress(); int getFirstVisibleSentenceBegin(); int getFirstVisibleSentenceEnd(); int getFirstVisibleSentenceNumber(); int getLastVisibleSentenceNumber(); int getNumberOfSentences(); int getWindowBeginOffset(); int getWindowEndOffset(); // --------------------------------------------------------------------------------------------- // Annotation behavior // // Control which kinds of annotations are created when an annotation creation action is // triggered and also what happens after the annotation has been created (e.g. auto-forward) // --------------------------------------------------------------------------------------------- boolean isForwardAnnotation(); void setForwardAnnotation(boolean forwardAnnotation); AnnotationLayer getSelectedAnnotationLayer(); void setSelectedAnnotationLayer(AnnotationLayer selectedAnnotationLayer); AnnotationLayer getDefaultAnnotationLayer(); void setDefaultAnnotationLayer(AnnotationLayer defaultAnnotationLayer); // REC: would be very nice if we didn't need the mode - the behaviors specific to annotation, // curation, automation, correction, etc. should be local to the respective modules / pages Mode getMode(); // --------------------------------------------------------------------------------------------- // Remembered feature values // // These are optionally used when a new annotation is created to pre-fill feature values using // those of the last annotation of the same type. This can be useful when many annotations of // the same type with similar feature values need to be created. // --------------------------------------------------------------------------------------------- void rememberFeatures(); AnnotationLayer getRememberedSpanLayer(); AnnotationLayer getRememberedArcLayer(); Map<AnnotationFeature, Serializable> getRememberedSpanFeatures(); Map<AnnotationFeature, Serializable> getRememberedArcFeatures(); void clearRememberedFeatures(); // --------------------------------------------------------------------------------------------- // User // --------------------------------------------------------------------------------------------- // REC not sure if we need these really... we can fetch the user from the security context. // Might be interesting to have if we allow an admin to open another users annotation though. User getUser(); void setUser(User aUser); // --------------------------------------------------------------------------------------------- // Document // --------------------------------------------------------------------------------------------- SourceDocument getDocument(); void setDocument(SourceDocument aDocument, List<SourceDocument> aDocuments); int getDocumentIndex(); int getNumberOfDocuments(); // --------------------------------------------------------------------------------------------- // Project // --------------------------------------------------------------------------------------------- Project getProject(); void setProject(Project aProject); // REC: we cache the constraints when a document is opened because parsing them takes some time ParsedConstraints getConstraints(); void setConstraints(ParsedConstraints aConstraints); // --------------------------------------------------------------------------------------------- // Selection // --------------------------------------------------------------------------------------------- Selection getSelection(); void setArmedSlot(AnnotationFeature aName, int aIndex); boolean isArmedSlot(AnnotationFeature aName, int aIndex); void clearArmedSlot(); boolean isSlotArmed(); AnnotationFeature getArmedFeature(); int getArmedSlot(); // --------------------------------------------------------------------------------------------- // Rendering // - script direction can be changed by the user at will - it defaults to the direction // configured in the project // --------------------------------------------------------------------------------------------- ScriptDirection getScriptDirection(); void setScriptDirection(ScriptDirection aScriptDirection); void toggleScriptDirection(); // --------------------------------------------------------------------------------------------- // User preferences // --------------------------------------------------------------------------------------------- AnnotationPreference getPreferences(); void setPreferences(AnnotationPreference aPreferences); List<AnnotationLayer> getAnnotationLayers(); void setAnnotationLayers(List<AnnotationLayer> aAnnotationLayers); // --------------------------------------------------------------------------------------------- // Feature value models // --------------------------------------------------------------------------------------------- List<FeatureState> getFeatureStates(); FeatureState getFeatureState(AnnotationFeature aFeature); // --------------------------------------------------------------------------------------------- // Access to transient context // --------------------------------------------------------------------------------------------- TransientActionContext getAction(); // --------------------------------------------------------------------------------------------- // Navigation within or across a document // --------------------------------------------------------------------------------------------- default void moveToPreviousDocument(List<SourceDocument> aDocuments) { // Index of the current source document in the list int currentDocumentIndex = aDocuments.indexOf(getDocument()); // If the first the document if (currentDocumentIndex <= 0) { throw new IllegalStateException("This is the first document!"); } setDocument(aDocuments.get(currentDocumentIndex - 1), aDocuments); } default void moveToNextDocument(List<SourceDocument> aDocuments) { // Index of the current source document in the list int currentDocumentIndex = aDocuments.indexOf(getDocument()); // If the last document if (currentDocumentIndex >= aDocuments.size() - 1) { throw new IllegalStateException("This is the last document!"); } setDocument(aDocuments.get(currentDocumentIndex + 1), aDocuments); } default void moveToPreviousPage(JCas aJCas) { int firstSentenceAddress = WebAnnoCasUtil.getFirstSentenceAddress(aJCas); int previousSentenceAddress = WebAnnoCasUtil.getPreviousDisplayWindowSentenceBeginAddress( aJCas, getFirstVisibleSentenceAddress(), getPreferences().getWindowSize()); // Since BratAjaxCasUtil.getPreviousDisplayWindowSentenceBeginAddress returns same // address // if there are not much sentences to go back to as defined in windowSize if (previousSentenceAddress == getFirstVisibleSentenceAddress() && // Check whether it's not the beginning of document getFirstVisibleSentenceAddress() != firstSentenceAddress) { previousSentenceAddress = firstSentenceAddress; } if (getFirstVisibleSentenceAddress() == previousSentenceAddress) { throw new IllegalStateException("This is First Page!"); } Sentence sentence = selectByAddr(aJCas, Sentence.class, previousSentenceAddress); setFirstVisibleSentence(sentence); setFocusSentenceNumber(WebAnnoCasUtil.getSentenceNumber(aJCas, sentence.getBegin())); } default void moveToNextPage(JCas aJCas) { int nextSentenceAddress = WebAnnoCasUtil.getNextPageFirstSentenceAddress(aJCas, getFirstVisibleSentenceAddress(), getPreferences().getWindowSize()); if (getFirstVisibleSentenceAddress() == nextSentenceAddress) { throw new IllegalStateException("This is last page!"); } Sentence sentence = selectByAddr(aJCas, Sentence.class, nextSentenceAddress); setFirstVisibleSentence(sentence); setFocusSentenceNumber(WebAnnoCasUtil.getSentenceNumber(aJCas, sentence.getBegin())); } default void moveToFirstPage(JCas aJCas) { int firstSentenceAddress = WebAnnoCasUtil.getFirstSentenceAddress(aJCas); if (firstSentenceAddress == getFirstVisibleSentenceAddress()) { throw new IllegalStateException("This is first page!"); } Sentence sentence = selectByAddr(aJCas, Sentence.class, firstSentenceAddress); setFirstVisibleSentence(sentence); setFocusSentenceNumber(WebAnnoCasUtil.getSentenceNumber(aJCas, sentence.getBegin())); } default void moveToLastPage(JCas aJCas) { int lastDisplayWindowBeginingSentenceAddress = WebAnnoCasUtil .getLastDisplayWindowFirstSentenceAddress(aJCas, getPreferences().getWindowSize()); if (lastDisplayWindowBeginingSentenceAddress == getFirstVisibleSentenceAddress()) { throw new IllegalStateException("This is last page!"); } Sentence sentence = selectByAddr(aJCas, Sentence.class, lastDisplayWindowBeginingSentenceAddress); setFirstVisibleSentence(sentence); setFocusSentenceNumber(WebAnnoCasUtil.getSentenceNumber(aJCas, sentence.getBegin())); } }