blob: 07661de6da6a17079f96fa06ab3a68f39371045b [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.debug.assert;
import flashx.textLayout.edit.ElementRange;
import flashx.textLayout.edit.ParaEdit;
import flashx.textLayout.edit.PointFormat;
import flashx.textLayout.edit.SelectionState;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.Category;
import flashx.textLayout.formats.ITextLayoutFormat;
import flashx.textLayout.formats.TextLayoutFormat;
import flashx.textLayout.property.Property;
import flashx.textLayout.tlf_internal;
use namespace tlf_internal;
/**
* The ClearFormatOperation class encapsulates a way to undefine formats.
*
* <p>An UndefineFormatOperation undefines properties set in the leaf format to the text in the
* specified range (no change is made if the specified range is a single point).
* It undefines properties set in the paragraph format to any paragraphs at least partially within the range
* (or a single paragraph if the range is a single point).
* And it undefines properties set in the container format to any containers at least partially within the range
* (or a single container if the range is a single point).</p>
*
* @see flashx.textLayout.edit.EditManager
* @see flashx.textLayout.events.FlowOperationEvent
*
* @includeExample examples\ApplyFormatOperation_example.as -noswf
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public class ClearFormatOperation extends FlowTextOperation
{
private var applyLeafFormat:ITextLayoutFormat;
private var applyParagraphFormat:ITextLayoutFormat;
private var applyContainerFormat:ITextLayoutFormat;
// helper array of styles to revert
// each entry has a begIdx, endIdx, ContainerFormat
private var undoLeafArray:Array;
private var undoParagraphArray:Array;
private var undoContainerArray:Array;
/**
* Creates an ClearFormatOperation object.
*
* @param operationState Defines the text range to which the format is applied.
* @param leafFormat The format whose set values indicate properties to undefine to LeafFlowElement objects in the selected range.
* @param paragraphFormat The format whose set values indicate properties to undefine to ParagraphElement objects in the selected range.
* @param containerFormat The format whose set values indicate properties to undefine to ContainerController objects in the selected range.
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function ClearFormatOperation(operationState:SelectionState, leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat = null)
{
super(operationState);
this.leafFormat = leafFormat;
this.paragraphFormat = paragraphFormat;
this.containerFormat = containerFormat;
}
/**
* The format properties to undefine on the leaf elements in the range.
*
* <p>If the range of this operation is a point, or if <code>leafFormat</code> is <code>null</code>,
* then no leaf element formats are changed.</p>
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function get leafFormat():ITextLayoutFormat
{
return applyLeafFormat;
}
public function set leafFormat(value:ITextLayoutFormat):void
{
applyLeafFormat = value ? new TextLayoutFormat(value) : null;
}
/**
* The format properties to undefine on the paragraphs in the range.
*
* <p>The formats of any paragraphs at least partially within the range are updated.
* If the range of this operation is a point, then a single paragraph is updated.
* If <code>paragraphFormat</code> is <code>null</code>, then no paragraph formats are changed.</p>
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function get paragraphFormat():ITextLayoutFormat
{
return applyParagraphFormat;
}
public function set paragraphFormat(value:ITextLayoutFormat):void
{
applyParagraphFormat = value ? new TextLayoutFormat(value) : null;
}
/**
* The format properties to undefine on the containers in the range.
*
* <p>The formats of any containers at least partially within the range are updated.
* If the range of this operation is a point, then a single container is updated.
* If <code>containerFormat</code> is <code>null</code>, then no container formats are changed.</p>
*
* @playerversion Flash 10
* @playerversion AIR 1.5
* @langversion 3.0
*/
public function get containerFormat():ITextLayoutFormat
{
return applyContainerFormat;
}
public function set containerFormat(value:ITextLayoutFormat):void
{
applyContainerFormat = value ? new TextLayoutFormat(value) : null;
}
private function doInternal():SelectionState
{
var anyNewSelectionState:SelectionState;
// Apply character format
if (applyLeafFormat)
{
if (absoluteStart != absoluteEnd)
{
var range:ElementRange = ElementRange.createElementRange(textFlow, absoluteStart,absoluteEnd);
var begSel:int = range.absoluteStart;
var endSel:int = range.absoluteEnd;
if(endSel == textFlow.textLength - 1)
++endSel;
// CONFIG::debug { if (begSel != absoluteStart || endSel != absoluteEnd) trace("found mismatch ApplyFormatOperation"); }
if (!undoLeafArray)
{
undoLeafArray = new Array();
ParaEdit.cacheStyleInformation(textFlow,begSel,endSel,undoLeafArray);
}
ParaEdit.applyTextStyleChange(textFlow,begSel,endSel,null,applyLeafFormat);
}
else if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
{
// on point selection remember pendling leaf formats for next char typed
anyNewSelectionState = originalSelectionState.clone();
// This is only a partial implementation - see watson bug
// here if the format is pending we can clear it
// The bug is that we don't remember any pending clear that's not set in pointFormat on the next character typed
var newFormat:PointFormat = new PointFormat(anyNewSelectionState.pointFormat);
for (var prop:String in TextLayoutFormat.description)
{
if (applyLeafFormat[prop] !== undefined)
newFormat[prop] = undefined;
}
anyNewSelectionState.pointFormat = newFormat;
}
}
if (applyParagraphFormat)
{
if (!undoParagraphArray)
{
undoParagraphArray = new Array();
ParaEdit.cacheParagraphStyleInformation(textFlow,absoluteStart, absoluteEnd,undoParagraphArray);
}
ParaEdit.applyParagraphStyleChange(textFlow,absoluteStart, absoluteEnd, null, applyParagraphFormat);
}
if (applyContainerFormat)
{
if (!undoContainerArray)
{
undoContainerArray = new Array();
ParaEdit.cacheContainerStyleInformation(textFlow,absoluteStart,absoluteEnd,undoContainerArray);
}
ParaEdit.applyContainerStyleChange(textFlow,absoluteStart,absoluteEnd, null, applyContainerFormat);
}
return anyNewSelectionState;
}
/** @private */
public override function doOperation():Boolean
{
var newSelectionState:SelectionState = doInternal();
if (newSelectionState && textFlow.interactionManager)
textFlow.interactionManager.setSelectionState(newSelectionState);
return true;
}
override public function redo():SelectionState
{
var newSelectionState:SelectionState = doInternal();
return newSelectionState? newSelectionState : originalSelectionState;
}
/** @private */
public override function undo():SelectionState
{
var obj:Object;
// Undo character format changes
for each (obj in undoLeafArray)
ParaEdit.setTextStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.style);
// Undo paragraph format changes
for each (obj in undoParagraphArray)
ParaEdit.setParagraphStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.attributes);
// Undo container format changes
for each (obj in undoContainerArray)
ParaEdit.setContainerStyleChange(obj);
return originalSelectionState;
}
}
}