/******************************************************************************* * Copyright (c) 2012 Google, Inc. * 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: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.recorder.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.jface.action.IAction; import com.windowtester.ui.core.model.IEvent; import com.windowtester.ui.core.model.IEventGroup; import com.windowtester.ui.core.model.IEventSequence; import com.windowtester.ui.core.model.ISemanticEvent; import com.windowtester.ui.internal.corel.model.EventSequence; import com.windowtester.ui.util.ActionProvider; import com.windowtester.ui.util.CommandStack; import com.windowtester.ui.util.ICommand; import com.windowtester.ui.util.ICommandStack; /** * A wrapper for a sequence that adds change event notification. */ public class EventSequenceModel implements IEventSequenceModel { private static final ISemanticEvent[] EMPTY_SELECTION = new ISemanticEvent[]{}; private final IEventSequence _sequence = new EventSequence(); private final List _listeners = new ArrayList(); //initialized lazily since we need a reference to 'this' private IEventSequenceCommandFactory _commandFactory; private ActionProvider _actionProvider; private ISemanticEvent[] _selection = EMPTY_SELECTION; protected final IEventSequence getSequence() { return _sequence; } private List getListeners() { return _listeners; } protected final ActionProvider getActionProvider() { if (_actionProvider == null) _actionProvider = createActionProvider(); return _actionProvider; } /** * Override to inject. */ protected ActionProvider createActionProvider() { return new ActionProvider(getCommandFactory(), createSequenceLabelProvider(), new CommandStack()); } /** * Override to inject. */ protected SequenceCommandLabelProvider createSequenceLabelProvider() { return new SequenceCommandLabelProvider(); } protected final IEventSequenceCommandFactory getCommandFactory() { if (_commandFactory == null) _commandFactory = createCommandFactory(); return _commandFactory; } /** * Override to inject. */ protected EventSequenceCommandFactory createCommandFactory() { return new EventSequenceCommandFactory(getSequence()); } private ICommandStack getCommandStack() { return getActionProvider().getCommandStack(); } /* (non-Javadoc) * @see com.windowtester.ui.core.model.IEventSequence#getEvents() */ public ISemanticEvent[] getEvents() { return getSequence().getEvents(); } /* (non-Javadoc) * @see com.windowtester.ui.core.model.IEventSequence#removeAll() */ public IEventSequence removeAll() { exec(getCommandFactory().removeEvery()); return this; } private void exec(ICommand cmd) { getCommandStack().exec(cmd); changed(); } /* (non-Javadoc) * @see com.windowtester.ui.core.model.IEventSequence#removeAll(com.windowtester.ui.core.model.ISemanticEvent[]) */ public IEventSequence removeAll(ISemanticEvent[] events) { exec(getCommandFactory().removeAll(events)); return this; } /* (non-Javadoc) * @see com.windowtester.ui.core.model.IEventSequence#remove(com.windowtester.ui.core.model.ISemanticEvent) */ public IEventSequence remove(ISemanticEvent event) { exec(getCommandFactory().remove(event)); return this; } /* (non-Javadoc) * @see com.windowtester.ui.core.model.IEventSequence#add(com.windowtester.ui.core.model.ISemanticEvent) */ public IEventSequence add(ISemanticEvent event) { exec(getCommandFactory().add(event)); select(new ISemanticEvent[]{event}); return this; } //note: this is not undoable... public IEventSequence addAll(ISemanticEvent[] events) { _sequence.addAll(events); select(events); return this; } /* (non-Javadoc) * @see com.windowtester.ui.core.model.IEventSequence#add(int, com.windowtester.ui.core.model.ISemanticEvent) */ public IEventSequence add(int index, ISemanticEvent event) { //... TODO! throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#addListener(com.windowtester.recorder.ui.IEventSequenceModel.ISequenceListener) */ public void addListener(ISequenceListener listener) { getListeners().add(listener); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#removeListener(com.windowtester.recorder.ui.IEventSequenceModel.ISequenceListener) */ public void removeListener(ISequenceListener listener) { getListeners().remove(listener); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#undo() */ public void undo() { getCommandStack().undo(); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#canUndo() */ public boolean canUndo() { return !getCommandStack().isEmpty(); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#isEmpty() */ public boolean isEmpty() { return getEvents().length == 0; } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#sessionStarted() */ public void sessionStarted() { //NOTICE: this is NOT undoable getSequence().removeAll(); changed(); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#sessionEnded() */ public void sessionEnded() { // no-op } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#select(com.windowtester.ui.core.model.ISemanticEvent[]) */ public void select(ISemanticEvent[] events) { setSelection(events); changed(); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#getSelection() */ public ISemanticEvent[] getSelection() { return _selection; } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#hasSelection() */ public boolean hasSelection() { return getSelection().length > 0; } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#getActions() */ public IAction[] getActions() { return getActionProvider().getActions(getSelection()); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#clickDelete() */ public void clickDelete() { removeAll(getSelection()); } /* (non-Javadoc) * @see com.windowtester.recorder.ui.IEventSequenceModel#group(com.windowtester.ui.core.model.ISemanticEvent[]) */ public IEventGroup group(IEvent[] events) { return _sequence.group(events); } private void setSelection(ISemanticEvent[] selection) { _selection = (selection == null) ? EMPTY_SELECTION : selection; } private void changed() { for (Iterator iterator = getListeners().iterator(); iterator.hasNext();) { ISequenceListener listener = (ISequenceListener) iterator.next(); listener.sequenceChanged(); } } }