package fi.utu.ville.exercises.model; import java.io.Serializable; import com.vaadin.ui.Component; import fi.utu.ville.standardutils.Localizer; import fi.utu.ville.standardutils.TempFilesManager; /** * <p> * An implementor of {@link EditorHelper} collects together many environment-dependent functionalities potentially required by an {@link Editor} and provides a * clean interface for accessing these functionalities. * </p> * <p> * {@link Editor}-implementors receive an implementor of this class through {@link Editor #initialize(Localizer, ExerciseData, EditorHelper) initialize()} * -method. * </p> * <p> * {@link EditorHelper} contains methods helping testing, saving and canceling exercise-editing. There is also a default implementation that can be used for * implementing these functionalities ( {@link #getControlbar(EditedExerciseGiver) getControlbar()}). {@link EditorHelper} also contains a method for fetching * {@link TempFilesManager}. {@link EditorHelper} handles all {@link ExerciseSaveListener}s; listeners can be informed with * {@link #informSaveListeners(ExerciseData) informSaveListeners()}-method when the exercise instance should be saved. * </p> * <p> * The general-info-editor-view ({@link #getInfoEditorView()}) must be shown at some point to the user of an {@link Editor}-implementor to allow editing of * general attributes of an exercise-instance. * </p> * * @author Riku Haavisto * */ public interface EditorHelper<E extends ExerciseData> extends Serializable { /** * <p> * Set exercise name for {@link GeneralExerciseInfo} * </p> * * @param name * New value for name */ void setExerciseName(String name); /** * <p> * Set exercise description for {@link GeneralExerciseInfo} * </p> * * @param description * New value for description */ void setExerciseDescription(String description); /** * @return {@link GeneralExerciseInfo} parsed from the current state of the general-info-editor */ GeneralExerciseInfo getExerciseInfo(); /** * @return The GUI through which the user can edit general attributes of an exercise instance (eg. name and description) */ Component getInfoEditorView(); /** * <p> * Exit the editor without informing the {@link ExerciseSaveListener}s, ie. cancel. * </p> * <p> * If you use default-toolbar ({@link #getControlbar(EditedExerciseGiver) getControlbar()}) you don't need to call this directly. * </p> */ void goBack(); /** * <p> * Registers a new {@link ExerciseSaveListener} to be informed when editing of an exercise instance is done, and it should be saved. * </p> * <p> * The only situation where this method would be required to be called directly by an {@link Editor}-instance would be when the editor nests some other * editor. Normal exercise-types can ignore this method as appropriate listeners will be registered by ViLLE-system. * </p> * * @param saveListener * {@link ExerciseSaveListener} to register */ void registerExerSaveListener(ExerciseSaveListener<E> saveListener); /** * <p> * Informs all the registered {@link ExerciseSaveListener}s that the exercise with {@link ExerciseData} dataToSave should be saved. * </p> * <p> * If you use default-toolbar ({@link #getControlbar(EditedExerciseGiver) getControlbar()}) you don't need to call this directly unless you want to provide * an alternate way to initiate 'save'-action. * </p> * * @param dataToSave * {@link ExerciseData}-instance that should be saved */ void informSaveListeners(E dataToSave); /** * <p> * A means for fetching a testing-view for an {@link Executor}-instance typically loaded with {@link ExerciseData}-instance currently under edit. * </p> * <p> * If you use default-toolbar ({@link #getControlbar(EditedExerciseGiver) getControlbar()}) you don't need to call this directly. * </p> * * @param toTest * {@link Executor}-loaded with parameters to be tested * @return {@link Component} that includes ViLLE-exercise-view suitable for testing */ Component getTestingExerciseView(Executor<?, ?> toTest); /** * A component that includes buttons to preview and save current exercise instance, and to cancel editing. * * @param toRegister * {@link EditedExerciseGiver} that returns {@link ExerciseData} -instances of the current state of the editor; used to generate test and save * -actions * @return {@link Component} containing default buttons for test, save and cancel */ Component getControlbar(EditedExerciseGiver<E> toRegister); /** * Enables and disables the default test-button. Should be used if the exercise is not always in a state that can be tested (and when default control-bar is * used). * * @param enabled * true if should be enabled */ void setTestEnabled(boolean enabled); /** * Enables and disables the default save-button. Should be used if the exercise is not always in a state that can be saved (and when default control-bar is * used). * * @param enabled * true if should be enabled */ void setSaveEnabled(boolean enabled); /** * @return current {@link TempFilesManager} */ TempFilesManager getTempManager(); /** * The return value of this method is used in showing a warning to a teacher who is trying to leave an editor without saving changes made to it. Usually it * is enough to err on the side of caution, ie. to return true from this method after the user has used for example some text-field regardless whether the * value of the field was actually changed or not. * * @return true if the user made changes to the editor's state since last save or the loading of the exercise */ boolean hasUnsubmittedChanges(); void clearUnSubmChangesFlag(); void setUnSubmChangesFlag(); /** * Implementor of this exercise knows how to return {@link ExerciseData} -instance corresponding to the current state of an {@link Editor}. That * {@link ExerciseData}-instance can then be used to test and save the exercise under editing. * * @author rahaav * * @param <F> * {@link ExerciseData}-type */ interface EditedExerciseGiver<F extends ExerciseData> { /** * <p> * Returns an {@link ExerciseData}-instance corresponding to the current state of the {@link Editor}. * </p> * <p> * Returning null is allowed, this is handled as a prompt to do nothing. Showing appropriate error messages to the user is the responsibility of the * implementor. Generally speaking it might be better to disable test and save, when they are not allowed (and maybe even show some status message in * the UI telling the user why the exercise is not currently ready for testing or saving). * </p> * * @param forSaving * if this is true data is wanted for saving, if false it is wanted only for testing (in most cases this does not matter) * @return {@link ExerciseData}-instance or null if {@link Editor} represents invalid exercise-state (eg. no questions in a question-based exercise) */ F getCurrExerData(boolean forSaving); } }