'Merge selected books in library.'

def merge_books(self, safe_merge=False, merge_only_formats=False):

    from calibre.gui2.dialogs.confirm_merge import confirm_merge
    if (self.gui.stack.currentIndex() != 0):
        return
    rows = self.gui.library_view.selectionModel().selectedRows()
    if ((not rows) or (len(rows) == 0)):
        return error_dialog(self.gui, _('Cannot    merge    books'), _('No    books    selected'), show=True)
    if (len(rows) < 2):
        return error_dialog(self.gui, _('Cannot    merge    books'), _('At    least    two    books    must    be    selected    for    merging'), show=True)
    if (len(rows) > 5):
        if (not confirm((('<p>' + _('You    are    about    to    merge    more    than    5    books.        Are    you    <b>sure</b>    you    want    to    proceed?')) + '</p>'), 'merge_too_many_books', self.gui)):
            return
    (dest_id, src_ids) = self.books_to_merge(rows)
    mi = self.gui.current_db.new_api.get_proxy_metadata(dest_id)
    title = mi.title
    hpos = self.gui.library_view.horizontalScrollBar().value()
    if safe_merge:
        if (not confirm_merge((('<p>' + (_('Book    formats    and    metadata    from    the    selected    books    will    be    added    to    the    <b>first    selected    book</b>    (%s).<br>    The    second    and    subsequently    selected    books    will    not    be    deleted    or    changed.<br><br>Please    confirm    you    want    to    proceed.') % title)) + '</p>'), 'merge_books_safe', self.gui, mi)):
            return
        self.add_formats(dest_id, self.formats_for_books(rows))
        self.merge_metadata(dest_id, src_ids)
    elif merge_only_formats:
        if (not confirm_merge((('<p>' + (_('Book    formats    from    the    selected    books    will    be    merged    into    the    <b>first    selected    book</b>    (%s).    Metadata    in    the    first    selected    book    will    not    be    changed.    Author,    Title    and    all    other    metadata    will    <i>not</i>    be    merged.<br><br>After    being    merged,    the    second    and    subsequently    selected    books,    with    any    metadata    they    have    will    be    <b>deleted</b>.    <br><br>All    book    formats    of    the    first    selected    book    will    be    kept    and    any    duplicate    formats    in    the    second    and    subsequently    selected    books    will    be    permanently    <b>deleted</b>    from    your    calibre    library.<br><br>        Are    you    <b>sure</b>    you    want    to    proceed?') % title)) + '</p>'), 'merge_only_formats', self.gui, mi)):
            return
        self.add_formats(dest_id, self.formats_for_books(rows))
        self.delete_books_after_merge(src_ids)
    else:
        if (not confirm_merge((('<p>' + (_('Book    formats    and    metadata    from    the    selected    books    will    be    merged    into    the    <b>first    selected    book</b>    (%s).<br><br>After    being    merged,    the    second    and    subsequently    selected    books    will    be    <b>deleted</b>.    <br><br>All    book    formats    of    the    first    selected    book    will    be    kept    and    any    duplicate    formats    in    the    second    and    subsequently    selected    books    will    be    permanently    <b>deleted</b>    from    your    calibre    library.<br><br>        Are    you    <b>sure</b>    you    want    to    proceed?') % title)) + '</p>'), 'merge_books', self.gui, mi)):
            return
        self.add_formats(dest_id, self.formats_for_books(rows))
        self.merge_metadata(dest_id, src_ids)
        self.delete_books_after_merge(src_ids)
        dest_row = rows[0].row()
        for row in rows:
            if (row.row() < rows[0].row()):
                dest_row -= 1
        self.gui.library_view.set_current_row(dest_row)
    cr = self.gui.library_view.currentIndex().row()
    self.gui.library_view.model().refresh_ids((dest_id,), cr)
    self.gui.library_view.horizontalScrollBar().setValue(hpos)
