Menu commands and keystrokes for copy and paste



Copy and paste functionality is commonly triggered through menu commands and keyboard shortcuts. On OS X, an edit menu with the copy and paste commands is automatically created by the operating system, but you must add listeners to these menu commands to hook up your own copy and paste functions. On Windows, you can add a native edit menu to any window that uses system chrome. (You can also create non-native menus with Flex and ActionScript, or, in HTML content, you can use DHTML, but that is beyond the scope of this discussion.)

To trigger copy and paste commands in response to keyboard shortcuts, you can either assign key equivalents to the appropriate command items in a native application or window menu, or you can listen for the keystrokes directly.

Starting a copy or paste operation with a menu command

To trigger a copy or paste operation with a menu command, you must add listeners for the select event on the menu items that call your handler functions.

When your handler function is called, you can find the object to be copied from or pasted into using the focus property of the stage. You can then call the appropriate method of the focused object (or a general fallback method, if no object has focus) to carry out the copy, cut, or paste logic. For example, the following copy event handler checks whether the focused object is of the correct type, in this case, a class named Scrap, and then calls the object’s doCopy() method.

function copyCommand(event:Event):void{ 
    if(NativeApplication.nativeApplication.activeWindow.stage.focus is Scrap){ 
        Scrap(NativeApplication.nativeApplication.activeWindow.stage.focus).doCopy(); 
    } else { 
        NativeApplication.nativeApplication.copy(); 
    } 
}

If copyCommand() in the example does not recognize the class of the focused object, it calls the NativeApplication copy() method. The NativeApplication copy() method sends an internal copy command to the focused object. If the object is a built-in class that implements copy and paste internally, than the object will perform the command. The Textfield and HTMLLoader classes are currently the only such built-in classes. Other interactive objects will dispatch the copy event. Similar commands are available for cut, paste, select all, and for the TextArea only, clear, undo, and redo.

In HTML content, the default copy and paste behavior can be triggered using the NativeApplication edit commands. The following example creates an edit menu for an editable HTML document:

<html> 
<head> 
    <title>Edit Menu</title>         
    <script src="AIRAliases.js" type="text/javascript"></script>     
    <script language="javascript" type="text/javascript">     
        function init(){ 
            document.designMode = "On"; 
            addEditMenu(); 
        }     
         
        function addEditMenu(){ 
            var menu = new air.NativeMenu 
            var edit = menu.addSubmenu(new air.NativeMenu(), "Edit"); 
             
            var copy = edit.submenu.addItem(new air.NativeMenuItem("Copy")); 
            var cut = edit.submenu.addItem(new air.NativeMenuItem("Cut")); 
            var paste = edit.submenu.addItem(new air.NativeMenuItem("Paste")); 
            var selectAll = edit.submenu.addItem(new air.NativeMenuItem("Select All")); 
 
             
            copy.addEventListener(air.Event.SELECT, function(){ 
                air.NativeApplication.nativeApplication.copy(); 
            }); 
            cut.addEventListener(air.Event.SELECT, function(){ 
                air.NativeApplication.nativeApplication.cut(); 
            }); 
            paste.addEventListener(air.Event.SELECT, function(){ 
                air.NativeApplication.nativeApplication.paste(); 
            }); 
 
            selectAll.addEventListener(air.Event.SELECT, function(){ 
                air.NativeApplication.nativeApplication.selectAll(); 
            }); 
             
            copy.keyEquivalent = "c"; 
            cut.keyEquivalent = "x"; 
            paste.keyEquivalent = "v"; 
            selectAll.keyEquivalent = "a"; 
             
            if(air.NativeWindow.supportsMenu){ 
                window.nativeWindow.menu = menu; 
            } else if (air.NativeApplication.supportsMenu){ 
                air.NativeApplication.nativeApplication.menu = menu; 
            } 
        }     
    </script> 
</head> 
<body onLoad="init()"> 
    <p>Neque porro quisquam est qui dolorem ipsum  
    quia dolor sit amet, consectetur, adipisci velit.</p> 
</body> 
</html>

The previous example replaces the application menu on Mac OS X, but you can also make use of the default Edit menu by finding the existing items and adding event listeners to them.

If you use a context menu to invoke a copy or paste command, you can use the contextMenuOwner property of the ContextMenuEvent object dispatched when the menu is opened or an item is selected to determine which object is the proper target of the copy or paste command.

Finding default menu items on Mac OS X

To find the default edit menu and the specific copy, cut, and paste command items in the application menu on Mac OS X, you can search through the menu hierarchy using the label property of the NativeMenuItem objects. For example, the following function takes a name and finds the item with the matching label in the menu:

private function findItemByName(menu:NativeMenu,  
                     name:String,  
                     recurse:Boolean = false):NativeMenuItem{ 
    var searchItem:NativeMenuItem = null; 
    for each (var item:NativeMenuItem in menu.items){ 
        if(item.label == name){ 
            searchItem = item; 
            break; 
        } 
        if((item.submenu != null) && recurse){ 
             searchItem = findItemByName(item.submenu, name); 
        } 
    } 
    return searchItem; 
} 

You can set the recurse parameter to true to include submenus in the search, or false to include only the passed-in menu.

Starting a copy or paste command with a keystroke

If your application uses native window or application menus for copy and paste, you can add key equivalents to the menu items to implement keyboard shortcuts. Otherwise, you can listen for the relevant keystrokes yourself, as demonstrated in the following example:

private function init():void{ 
    stage.addEventListener(KeyboardEvent.KEY_DOWN, keyListener); 
} 
private function keyListener(event:KeyboardEvent):void{ 
    if(event.ctrlKey){ 
        event.preventDefault(); 
        switch(String.fromCharCode(event.charCode)){ 
            case "c": 
                NativeApplication.nativeApplication.copy(); 
                break; 
            case "x": 
                NativeApplication.nativeApplication.cut(); 
                break; 
            case "v": 
                NativeApplication.nativeApplication.paste(); 
                break; 
            case "a": 
                NativeApplication.nativeApplication.selectAll(); 
                break; 
            case "z": 
                NativeApplication.nativeApplication.undo(); 
                break; 
            case "y": 
                NativeApplication.nativeApplication.redo(); 
                break; 
        } 
    } 
}

In HTML content, the keyboard shortcuts for copy and paste commands are implemented by default. It is not possible to trap all of the keystrokes commonly used for copy and paste using a key event listener. If you need to override the default behavior, a better strategy is to listen for the copy and paste events themselves.