Custom Clipboard Formats

Ever wished you could copy and paste using more clipboard formats? We do too. We haven’t had the time to add new converters for this release, but we did the next best thing. We added the ability for an application to add its own text converters, which can then be used to either paste data that was posted to the clipboard, or copy data from TLF to the clipboard. This allows you to add new formats — for instance, RTF or HTML — and have them work in copy/paste with other applications.

The first step is to create the converters. For copying, you will need an exporter to convert the TextFlow into data to add to the clipboard. For pasting, you need an importer to take the data from the clipboard and convert it to a TextFlow that can be pasted into TLF. We have a new base class you can extend to make this easier, ConverterBase.

Next step is to tell the TextConverter class about the new converters, so it can make them available to the copy & paste operations that need them. You do this by calling TextConverter.addFormatAt. The formats are ordered in the TextConverter, and this is significant when we are pasting and there may be multiple formats that are capable of handling the data on the clipboard. The formats will be considered in the order in which they appear in the TextConverter. An individual converter can register early in the chain to get a first pick at doing the conversion, and pass (by returning null for the TextFlow) to allow formats later in the chain to handle it.

addFormatAt takes a format name, importer and exporter classes, and a clipboard format. The format name can be anything you choose to call your format, but preferably will be unique. The importer and exporter classes are the ones you write. The clipboard format is like a mime-type, it specifies how the data will be tagged on the clipboard. There’s a predefined list of these in flash.desktop.ClipboardFormats, or you can choose to make a new one.

Another thing to consider when adding a format for use with the clipboard is how to handle elements that were only partially copied. In TLF, when an element is completely selected and copied, then when it is pasted it appears in entirety. But if the final terminator or newline is not copied, then when it is pasted it may be merged into the neighboring element. For instance, when a part of a list is copied and pasted into another list TLF merges the pasted list into the existing list instead of treating the pasted list as a nested list. Same for paragraphs. If the entire paragraph is copied (including the trailing newline) then we want to paste an entire paragraph. But if only part of the paragraph is copied, then when you paste it should merge into the destination paragraph.

To support this, TLF adds a special format property to the element if it wasn’t copied all the way through to its end. These properties should only appear on TextFlows that are in the scrap. Importers that convert from a clipboard format are called with the useClipboardAnnotations flag set to true, and should generate these ConverterBase.MERGE_TO_NEXT_ON_PASTE properties for any elements that weren’t copied in entirety (e.g., mergeToNextOnPaste = “true”).

You can remove an existing format by calling TextConverter.removeFormat. This is useful if there is a format that you never want to use at all. If you want to remove the format for clipboard operations, but preserve its use in other situations,  you can remove it and then add it back in with a null clipboardFormat. If you want to replace an existing converter with one of your own, that works fine too. If you are replacing one of the formats we supply, look to see if it supports any additional interfaces; if so, your replacement should support the same interfaces. For instance, there are additional parameters that apply to importing HTML or TLF data, as well as for exporting plain text. TLF will expect these interfaces to be supported on any converter registered with the same format name.

I’ve posted a simple example application that registers a new clipboard format: CustomClipboardFormat

Please let us know how this works for you!