/******************************************************************************* * Copyright (C) 2003-2007, 2013, Guillaume Brocker * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Guillaume Brocker - Initial API and implementation * ******************************************************************************/ package eclox.ui.editor.basic; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import eclox.core.doxyfiles.Setting; import eclox.ui.editor.editors.AbstractEditor; /** * Base implementation of for multi editors. * * @author Guillaume Brocker */ public abstract class MultiEditor extends AbstractEditor { /** * symbolic constant value for yes */ private static final String YES = "YES"; /** * symbolic constant value for no */ private static final String NO = "NO"; protected class State { private String name; private Set<Setting> selectedSettings = new HashSet<Setting>(); private Set<Setting> deselectedSettings = new HashSet<Setting>(); State( String name ) { this.name = name; } void addSettingToSelect( Setting setting ) { selectedSettings.add( setting ); deselectedSettings.remove( setting ); } void addSettingToDeselect( Setting setting ) { if( selectedSettings.contains(setting) == false ) { deselectedSettings.add( setting ); } } String getName() { return name; } boolean wantsSelection() { boolean wanted = true; Iterator<Setting> i; // Updates the selection according to the value of settings owned by the state. i = selectedSettings.iterator(); while( i.hasNext() ) { Setting setting = (Setting) i.next(); wanted = wanted && setting.getValue().equals(YES); } // Updates the selection according to the value of settings owned by the state. i = deselectedSettings.iterator(); while( i.hasNext() ) { Setting setting = (Setting) i.next(); wanted = wanted && setting.getValue().equals(NO); } // Job's done. return wanted; } void commit() { Iterator<Setting> i; i = selectedSettings.iterator(); while( i.hasNext() ) { Setting setting = (Setting) i.next(); setting.setValue(YES); } i = deselectedSettings.iterator(); while( i.hasNext() ) { Setting setting = (Setting) i.next(); setting.setValue(NO); } } } /** * the collection of managed states */ protected State [] states; /** * the state being selected */ private State selection; /** * a boolean telling if the editor is dirty */ private boolean dirty = false; /** * Creates a new multi editor instance * * @param states an array containing the name of the states to create */ public MultiEditor( String [] states ) { this.states = new State[states.length]; for( int i = 0; i != states.length; ++i ) { this.states[i] = new State(states[i]); } } /** * Adds the given setting to a given state * * @param state the name of a state * @param setting the setting to add to the given state */ public void addSetting( String state, Setting setting ) { if( setting != null ) { for( int i = 0; i != states.length; ++i ) { if( states[i].name.equals(state) ) { states[i].addSettingToSelect(setting); } else { states[i].addSettingToDeselect(setting); } } } } /** * @see eclox.ui.editor.editors.IEditor#commit() */ public void commit() { // Commits the selected state. if( selection != null ) { selection.commit(); } dirty = false; fireEditorChanged(); } /** * Retrieves the selected state of the editor * * @return a string representing the selected state, or null if none */ public String getSelection() { return (selection != null) ? selection.getName() : null; } /** * @see eclox.ui.editor.editors.IEditor#isDirty() */ public boolean isDirty() { return dirty; } /** * @see eclox.ui.editor.editors.IEditor#isStale() */ public boolean isStale() { // Looks for the state that wants the selection. State wantedSelection = null; for( int i = 0; i != states.length; ++i ) { if( states[i].wantsSelection() ) { wantedSelection = states[i]; break; } } return wantedSelection != selection; } /** * Sub-classes must call this method first, in order to refresh the current state * and then refresh the user interface controls, according to the current state. * * @see eclox.ui.editor.editors.IEditor#refresh() */ public void refresh() { selection = null; dirty = false; // Searches the states that wants to be selected for( int i = 0; i != states.length; ++i ) { if( states[i].wantsSelection() ) { selection = states[i]; break; } } fireEditorChanged(); } /** * Retrieves the selected state of the multi editor. * * @return a state or null when none */ protected State getSelectionAsState() { return selection; } /** * Retrieves the state for the given name * * @name a string containing a state name * * @return the matching state or null when none */ protected State getState( String name ) { State found = null; for( int i = 0; i != states.length; ++i ) { if( states[i].getName() .equals(name) ) { found = states[i]; break; } } return found; } /** * Selectes the given state * * @param state a string containing a state name */ protected void selectState( String state ) { State candidate = getState(state); if( candidate != null ) { selection = candidate; dirty = true; fireEditorChanged(); } } }