blob: 1307184c8e1604fc602439b578d62f90f34b8a2d [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 flashx.textLayout.operations
{
import flashx.textLayout.edit.SelectionState;
import flashx.textLayout.tlf_internal;
use namespace tlf_internal;
//
// Considered several ways of doing undo/redo
// 1 - object model level - stashing copies of all changed objects in the model and restoring them
// 2 - cookies - saving an audit trail of every modified property of the model objects
// 3 - operations - each operation creates an object that knows how to do/undo/redo itself
// going with # 3 for now
//
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.edit.IEditManager;
import flashx.undo.IOperation;
/**
* The FlowOperation class is the base class for all Text Layout Framework operations.
*
* <p>Operations are transformations of a text flow. An Operation class defines the
* logic for performing and undoing the transformation. Operations are executed by an
* edit manager. Most applications do not need to create or manage operations directly
* (unless implementing a custom edit manager).</p>
*
* <p>When an operation is performed, the edit manager dispatches an Operation object
* within the FlowOperationEvent object. You can query
* this Operation object to decide whether or not to allow the operation, to decide whether
* to perform some other operation as well, or to update related user-interface elements.</p>
*
* @see flashx.textLayout.events.FlowOperationEvent
* @see flashx.textLayout.edit.EditManager
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public class FlowOperation implements IOperation
{
/**
* Arbitrary data associated with an element.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public var userData:*;
// uint or null
private var _beginGeneration:uint;
private var _endGeneration:uint;
private var _textFlow:TextFlow; // target of the operation
/**
* Creates the FlowOperation object.
*
* @param textFlow The text flow to which this operation is applied.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function FlowOperation(textFlow:TextFlow)
{
_textFlow = textFlow;
}
/**
* The TextFlow object to which this operation is applied.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function get textFlow():TextFlow
{ return _textFlow; }
public function set textFlow(value:TextFlow):void
{ _textFlow = value; }
/**
* Executes the operation.
*
* <p>This method must be overridden in derived classes. The base class method does nothing.
* You should not call <code>doOperation()</code> directly. The edit manager
* calls the method when it executes the operation. </p>
*
* @return Boolean <code>true</code>, if the operation succeeded. Otherwise, <code>false</code>.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function doOperation():Boolean
{
return false;
}
/**
* Reverses the operation.
*
* <p>This method must be overridden in derived classes. The base class method does nothing.
* You should not call <code>undo()</code> directly. The edit manager
* calls the method when it reverses the operation. </p>
*
* @return The SelectionState object passed to the operation when it was performed. This
* SelectionState object can be the current selection or a selection created specifically
* for the operation.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function undo():SelectionState
{
return null;
}
/**
* Test if this operation be placed on the undo stack.
*
* @return true means to push the operation onto the undo stack. false means do not push this operation.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function canUndo():Boolean
{ return true; }
/**
* Re-executes the operation.
*
* <p>This method must be overridden in derived classes. The base class method does nothing.
* You should not call <code>redo()</code> directly. The edit manager
* calls the method when it re-executes the operation. </p>
*
* @return The SelectionState object passed to the operation when it was performed. This
* SelectionState object can be the current selection or a selection created specifically
* for the operation.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function redo():SelectionState
{
return null;
}
// Generation numbers
/**
* The text flow generation before the operation.
*
* <p>A generation of 0 indicates that the operation did not complete.</p>
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function get beginGeneration():uint
{ return _beginGeneration; }
/**
* The text flow generation after the operation.
*
* <p>A generation of 0 indicates that the operation did not complete.</p>
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function get endGeneration():uint
{ return _endGeneration; }
/** @private */
public function performUndo():void
{
var editManager:IEditManager = textFlow ? textFlow.interactionManager as IEditManager : null;
if (editManager != null)
{
editManager.performUndo(this);
}
}
/** @private */
public function performRedo():void
{
var editManager:IEditManager = textFlow ? textFlow.interactionManager as IEditManager : null;
if (editManager != null)
{
editManager.performRedo(this);
}
}
/** @private -- Sets the generation numbers into the operation. */
tlf_internal function setGenerations(beginGeneration:uint,endGeneration:uint):void
{
_beginGeneration = beginGeneration;
_endGeneration = endGeneration;
}
/**
* @private
*
* Combine this operation with another operation if the result can
* be represented as a single operation. In general, operations cannot be
* merged. But sequential inserts or deletes may be mergeable.
*
* Merging may occur through updating the properties of the operation
* on which this method is called, by creating a new operation.
*
* @param operation The FlowOperation to merge against
* @return A FlowOperation representing the combined operation if
* the merge was successful, null otherwise.
*/
tlf_internal function merge(operation:FlowOperation):FlowOperation // No PMD
{
return null;
}
}
}