'Arrange the tabs in rows, in the order in which they were added.
If n_rows >= 1, this will be the number of rows used. Otherwise the
number of rows will be calculated according to the number of tabs and
max_tabs_per_row. In this case, the number of rows may change when
adding/removing tabs.'

def _arrange_tabs(self):

    while self._tabs:
        self._tabs.popitem()[1].destroy()
    self._reset_tab_rows()
    if (not self._tab_names):
        return
    if ((self.n_rows is not None) and (self.n_rows > 0)):
        n_rows = self.n_rows
    else:
        n_rows = (((len(self._tab_names) - 1) // self.max_tabs_per_row) + 1)
    expand_tabs = (self.expand_tabs or (n_rows > 1))
    i = 0
    for row_index in range(n_rows):
        n_tabs = ((((len(self._tab_names) - i) - 1) // (n_rows - row_index)) + 1)
        tab_names = self._tab_names[i:(i + n_tabs)]
        i += n_tabs
        self._add_tab_row(tab_names, expand_tabs)
    selected = self._selected_tab
    self.set_selected_tab(None)
    if (selected in self._tab_names):
        self.set_selected_tab(selected)
