'Provide the usual action buttons in list views.
Allow customizing the urls, since this overwrites anything
that would be inserted by CRUD/select via linkto. The resource
id should be represented by "[id]".
@param r: the S3Request
@param deletable: records can be deleted
@param editable: records can be modified
@param copyable: record data can be copied into new record
@param read_url: URL to read a record
@param delete_url: URL to delete a record
@param update_url: URL to update a record
@param copy_url: URL to copy record data
@note: If custom actions are already configured at this point,
they will appear AFTER the standard action buttons'

@classmethod
def action_buttons(cls, r, deletable=True, editable=True, copyable=False, read_url=None, delete_url=None, update_url=None, copy_url=None):

    s3crud = S3CRUD
    s3 = current.response.s3
    labels = s3.crud_labels
    custom_actions = s3.actions
    s3.actions = None
    auth = current.auth
    has_permission = auth.s3_has_permission
    ownership_required = auth.permission.ownership_required
    if r.component:
        table = r.component.table
        args = [r.id, r.component.alias, '[id]']
    else:
        table = r.table
        args = ['[id]']
    get_vars = cls._linkto_vars(r)
    if (r.representation == 'iframe'):
        if current.deployment_settings.get_ui_iframe_opens_full():
            iframe_safe = (lambda url: url)
            target = dict(_target='_blank')
        else:
            iframe_safe = (lambda url: s3_set_extension(url, 'iframe'))
            target = {}
    else:
        iframe_safe = (lambda url: url)
        target = {}
    if (editable and has_permission('update', table) and (not ownership_required('update', table))):
        if (not update_url):
            update_url = iframe_safe(URL(args=(args + ['update']), vars=get_vars))
        s3crud.action_button(labels.UPDATE, update_url, _class='action-btn    edit', icon='edit', **target)
    else:
        if (not read_url):
            read_url = iframe_safe(URL(args=args, vars=get_vars))
        s3crud.action_button(labels.READ, read_url, _class='action-btn    read', icon='file', **target)
    if (deletable and has_permission('delete', table)):
        icon = 'delete'
        if (not delete_url):
            delete_url = iframe_safe(URL(args=(args + ['delete']), vars=get_vars))
        if ownership_required('delete', table):
            query = auth.s3_accessible_query('delete', table)
            rows = current.db(query).select(table._id)
            restrict = []
            rappend = restrict.append
            for row in rows:
                row_id = row.get('id', None)
                if row_id:
                    rappend(str(row_id))
            s3crud.action_button(labels.DELETE, delete_url, _class='delete-btn', icon=icon, restrict=restrict, **target)
        else:
            s3crud.action_button(labels.DELETE, delete_url, _class='delete-btn', icon=icon, **target)
    if (copyable and has_permission('create', table)):
        if (not copy_url):
            copy_url = iframe_safe(URL(args=(args + ['copy'])))
        s3crud.action_button(labels.COPY, copy_url, icon='icon-copy', **target)
    if custom_actions:
        s3.actions = (s3.actions + custom_actions)
