def selectSimilarAttributes(detectCursor=True):
    """Selects the same attributes already selected on every node in the Graph
    Editor.

    When detectCursor is true, if your cursor is not over the Graph Editor, the
    Channel Box attributes are synced to the Graph Editor using the method
    syncGraphEditor().
    """

    # Where is the cursor?
    useGraphEditor, panel = selectedAttributes.isGraphEditorActive()

    # Select similar attributes.
    if useGraphEditor or not detectCursor:
        # Get selected nodes and attributes
        attributes = selectedAttributes.getGraphEditor(panel, expandObjects=False)
        nodes = cmd.ls(sl=1, l=1)

        # Clear graph editor attributes
        selectionConnection = selectedAttributes.getSelectionConnection(panel)
        cmd.selectionConnection(selectionConnection, e=1, clr=1)

        # Process attributes
        # Get the attribute part of node.attribute and separate out
        # selected objects.
        objs = []
        for x in reversed(range(len(attributes))):
            if "." in attributes[x]:
                # This works for compound attributes too.  Trust me.
                null, attributes[x] = selectedAttributes.splitAttr(attributes[x])
            else:
                objs.append(attributes.pop(x))
        attributes = list(set(attributes))

        # Select the attributes on every node selected
        for attr in attributes:
            for node in nodes:
                try:
                    cmd.selectionConnection(selectionConnection, edit=True, select="%s.%s" % (node, attr))
                except RuntimeError:
                    # That attribute probably didn't exist on that node.
                    pass

        # reselect objects
        for obj in objs:
            cmd.selectionConnection(selectionConnection, edit=True, select=obj)

    else:
        syncGraphEditor()
def clearAttributes(graphEditor=None, channelBox=None):
    """Clears any attributes selected in the graphEditor and/or channelBox.

    If nothing is passed it will clear the graphEditor if it is under the
    cursor, otherwise it will clear the channelBox. If graphEditor and/or
    channelBox is specified it will clear those no matter where the cursor
    is."""
    if graphEditor is None and channelBox is None:
        graphEditorActive, panel = selectedAttributes.isGraphEditorActive()
        if graphEditorActive:
            clearGraphEditor(panel)
        else:
            clearChannelBox()
    else:
        if graphEditor:
            clearGraphEditor("graphEditor1")
        if channelBox:
            clearChannelBox()