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 syncGraphEditor():
    """Syncs the attributes selected in the channelBox to those in the
    graphEditor. I don't know of any way to select channelBox attributes, so I
    have not been able to implement the equivalent syncChannelBox."""

    # Get channelbox attributes
    attributes = selectedAttributes.getChannelBox(expandObjects=False)

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

    # Select channelbox attributes in graph editor
    for attr in attributes:
        cmd.selectionConnection(selectionConnection, edit=True, select=attr)
def clearGraphEditor(panel):
    """Deselects the attributes of the specified graphEditor panel by clearing
    the selectionConnection."""

    selectionConnection = selectedAttributes.getSelectionConnection(panel)
    cmd.selectionConnection(selectionConnection, e=1, clr=1)