Formatos de datos para Clipboard

Flash Player 10 y posterior, Adobe AIR 1.0 y posterior

Los formatos para Clipboard describen los datos que se colocan en un objeto Clipboard. Flash Player o AIR convierten automáticamente los formatos de datos estándar entre tipos de datos de ActionScript y formatos del portapapeles del sistema. Además, los objetos de la aplicación se pueden transferir entre aplicaciones basadas en ActionScript mediante formatos definidos por la aplicación.

Un objeto Clipboard puede contener representaciones de la misma información en distintos formatos. Por ejemplo, un objeto Clipboard que representa a un elemento Sprite puede incluir un formato de referencia para utilizarse dentro de la misma aplicación, un formato serializado para utilizarlo con otra aplicación que se ejecute en Flash Player o AIR, un formato de mapa de bits para utilizarse en un editor de imágenes y un formato de lista de archivos (posiblemente con representación aplazada para codificar un archivo PNG) para copiar o arrastrar una representación del elemento Sprite al sistema de archivos.

Formatos de datos estándar

Las constantes que definen los nombres de formatos estándar se proporcionan en la clase ClipboardFormats:

Constante

Descripción

TEXT_FORMAT

Los datos en formato de texto se traducen a y de la clase String de ActionScript.

HTML_FORMAT

Texto con marcado HTML.

RICH_TEXT_FORMAT

Los datos en formato de texto enriquecido se traducen a y de la clase ByteArray de ActionScript. El marcado RTF no se interpreta ni traduce de forma alguna.

BITMAP_FORMAT

(Solo AIR) Los datos con formato de mapa de bits se convierten con la clase BitmapData de ActionScript.

FILE_LIST_FORMAT

(Solo AIR) Los datos con formato de lista de archivos se convierten en un conjunto de objetos File de ActionScript.

URL_FORMAT

(Solo AIR) Los datos con formato URL se convierten con la clase String de ActionScript.

Al copiar y pegar datos como respuesta a un evento copy , cut , o paste en contenido HTML alojado en una aplicación de AIR, es necesario usar tipos MIME en lugar de cadenas ClipboardFormat. Los tipos de datos MIME válidos son:

Tipo MIME

Descripción

Texto

"text/plain"

URL

"text/uri-list"

Mapa de bits

"image/x-vnd.adobe.air.bitmap"

Lista de archivos

"application/x-vnd.adobe.air.file-list"

Nota: los datos en formato de texto enriquecido no están disponibles en la propiedad clipboardData del objeto de evento distribuido como resultado de un evento paste en contenido HTML.

Formatos de datos personalizados

Se pueden utilizar formatos personalizados definidos por la aplicación para transferir objetos como referencias o como copias serializadas. Las referencias solo son válidas en la misma aplicación. Los objetos serializados se pueden transferir entre aplicaciones, pero solo pueden utilizarse con objetos que permanecen válidos al serializarse y deserializarse. Los objetos suelen poder serializarse si sus propiedades son tipos sencillos u objetos serializables.

Para añadir un objeto serializado a un objeto Clipboard, establezca el parámetro serializable en true al llamar al método Clipboard.setData() . El nombre del formato puede ser el de uno de los formatos estándar o una cadena arbitraria definida por la aplicación.

Modos de transferencia

Cuando un objeto se escribe en el portapapeles con un formato de datos personalizado, los datos del objeto se pueden leer en el portapapeles, bien como una referencia o como una copia serializada del objeto original. Existen cuatro modos de transferencia que determinan si los objetos se transfieren como referencias o como copias serializadas:

Modo de transferencia

Descripción

ClipboardTransferModes.ORIGINAL_ONLY

Solo se devuelve una referencia. Si no se dispone de ninguna referencia, se devuelve un valor nulo.

ClipboardTransferModes.ORIGINAL_PREFFERED

Se devuelve una referencia, si hay una disponible. En caso contrario, se devuelve una copia serializada.

ClipboardTransferModes.CLONE_ONLY

Solo se devuelve una copia serializada. Si no hay ninguna disponible, se devuelve un valor null.

ClipboardTransferModes.CLONE_PREFFERED

Se devuelve una copia serializada, si hay una disponible. En caso contrario, se devuelve una referencia.

Lectura y escritura de formatos de datos personalizados

Al escribir un objeto en el portapapeles, puede utilizar cualquier cadena que no comience con los prefijos reservados air: o flash: para el parámetro format . Utilice la misma cadena que el formato para leer el objeto. Los ejemplos siguientes ilustran cómo se leen y escriben objetos en el portapapeles:

public function createClipboardObject(object:Object):Clipboard{ 
    var transfer:Clipboard = Clipboard.generalClipboard; 
    transfer.setData("object", object, true); 
} 

Para extraer un objeto serializado del objeto Clipboard (tras una operación de soltar y pegar), utilice el mismo nombre de formato y los modos de transferencia CLONE_ONLY o CLONE_PREFFERED .

var transfer:Object = clipboard.getData("object", ClipboardTransferMode.CLONE_ONLY); 

Siempre se añade una referencia al objeto Clipboard. Para extraer la referencia del objeto portapapeles (tras una operación de colocar o pegar), en lugar de la copia serializada utilice los modos de transferencia ORIGINAL_ONLY o ORIGINAL_PREFFERED :

var transferredObject:Object =  
    clipboard.getData("object", ClipboardTransferMode.ORIGINAL_ONLY); 

Las referencias solo son válidas si el objeto Clipboard viene de la aplicación de actual. Utilice el modo de transferencia ORIGINAL_PREFFERED para tener acceso a la referencia cuando está disponible, y la copia serializada cuando la referencia no está disponible.

Representación aplazada

Si la creación de un formato de datos requiere mucho procesamiento, puede utilizar la representación aplazada si suministra una función que proporcione los datos a petición. Solo se llama a la función si el receptor de la operación de colocar o pegar solicita datos en el formato diferido.

La función de representación se añade a un objeto Clipboard utilizando el método setDataHandler() . La función debe devolver los datos en el formato adecuado. Por ejemplo: si llamó a setDataHandler(ClipboardFormat.TEXT_FORMAT, writeText) , la función writeText() debe devolver una cadena.

Si se añade un formato de datos del mismo tipo a un objeto Clipboard con el método setData() , esos datos tendrán prioridad sobre la versión aplazada (no se llama nunca a la función de representación). La función de representación puede o no volver a llamarse si se solicita acceso una segunda vez a los mismos datos del portapapeles.

Nota: en Mac OS X, la representación aplazada funciona solo con formatos de datos personalizados. En los formatos de datos estándar, se llama a la función de representación inmediatamente.

Pegar texto con una función de representación aplazada

El ejemplo siguiente ilustra cómo se implementa una función de representación aplazada.

Cuando el usuario pulsa el botón Copiar, la aplicación borra el portapapeles del sistema para garantizar que no queda contenido de operaciones anteriores con el portapapeles. El método setDataHandler() establece entonces la función renderData() como procesador del portapapeles.

Cuando el usuario selecciona el comando Pegar en el menú contextual del campo de texto de destino, la aplicación accede al portapapeles y establece el texto de destino. Dado que el formato de los datos de texto del portapapeles se ha establecido con una función y no con una cadena, el portapapeles llama a la función renderData() . La función renderData() devuelve el texto que estaba en el texto de origen, que se asigna entonces al texto de destino.

Tenga en cuenta que si se modifica el texto de origen antes de pulsar el botón Pegar, la modificación se reflejará en el texto pegado, incluso cuando se produce después de haber pulsado el botón de copiar. Esto se debe a que la función de representación no copia el texto de origen sino hasta pulsar el botón de pegar. (Al utilizar la representación aplazada en una aplicación real, puede ser conveniente guardar o proteger de alguna manera los datos de origen para evitar que suceda este problema).

Ejemplo de Flash

 package {  
    import flash.desktop.Clipboard; 
    import flash.desktop.ClipboardFormats; 
    import flash.desktop.ClipboardTransferMode; 
    import flash.display.Sprite; 
    import flash.text.TextField; 
    import flash.text.TextFormat; 
    import flash.text.TextFieldType; 
    import flash.events.MouseEvent; 
    import flash.events.Event; 
    public class DeferredRenderingExample extends Sprite  
    {  
         private var sourceTextField:TextField; 
        private var destination:TextField; 
        private var copyText:TextField; 
        public function DeferredRenderingExample():void 
        { 
            sourceTextField = createTextField(10, 10, 380, 90); 
            sourceTextField.text = "Neque porro quisquam est qui dolorem " 
                + "ipsum quia dolor sit amet, consectetur, adipisci velit."; 
                 
            copyText = createTextField(10, 110, 35, 20); 
            copyText.htmlText = "<a href='#'>Copy</a>"; 
            copyText.addEventListener(MouseEvent.CLICK, onCopy); 
 
            destination = createTextField(10, 145, 380, 90); 
            destination.addEventListener(Event.PASTE, onPaste); 
        } 
        private function createTextField(x:Number, y:Number, width:Number, 
                        height:Number):TextField 
        { 
            var newTxt:TextField = new TextField(); 
            newTxt.x = x; 
            newTxt.y = y; 
            newTxt.height = height; 
            newTxt.width = width; 
            newTxt.border = true; 
            newTxt.multiline = true; 
            newTxt.wordWrap = true; 
            newTxt.type = TextFieldType.INPUT; 
            addChild(newTxt); 
            return newTxt; 
        } 
        public function onCopy(event:MouseEvent):void 
        { 
            Clipboard.generalClipboard.clear(); 
            Clipboard.generalClipboard.setDataHandler(ClipboardFormats.TEXT_FORMAT, 
                            renderData); 
        } 
        public function onPaste(event:Event):void 
        { 
            sourceTextField.text = 
            Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT).toString; 
        } 
        public function renderData():String 
        { 
            trace("Rendering data"); 
            var sourceStr:String = sourceTextField.text; 
            if (sourceTextField.selectionEndIndex > 
                     sourceTextField.selectionBeginIndex) 
            { 
                return sourceStr.substring(sourceTextField.selectionBeginIndex, 
                                    sourceTextField.selectionEndIndex); 
            } 
            else 
            { 
                return sourceStr; 
            } 
        } 
    } 
}

Ejemplo de Flex

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="326" height="330" applicationComplete="init()"> 
    <mx:Script> 
    <![CDATA[ 
    import flash.desktop.Clipboard; 
    import flash.desktop.ClipboardFormats; 
     
    public function init():void 
    { 
        destination.addEventListener("paste", doPaste); 
    } 
 
    public function doCopy():void 
    { 
        Clipboard.generalClipboard.clear(); 
        Clipboard.generalClipboard.setDataHandler(ClipboardFormats.TEXT_FORMAT, renderData); 
    } 
    public function doPaste(event:Event):void 
    { 
        destination.text = Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT).toString; 
    } 
     
    public function renderData():String{ 
        trace("Rendering data"); 
        return source.text; 
    } 
    ]]> 
    </mx:Script> 
    <mx:Label x="10" y="10" text="Source"/> 
    <mx:TextArea id="source" x="10" y="36" width="300" height="100"> 
        <mx:text>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.</mx:text> 
    </mx:TextArea> 
    <mx:Label x="10" y="181" text="Destination"/> 
    <mx:TextArea id="destination"  x="12" y="207" width="300" height="100"/> 
    <mx:Button click="doCopy();" x="91" y="156" label="Copy"/> 
</mx:Application>