BtInstallModuleChooserDialog::BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g,
                                                           QWidget *parent,
                                                           Qt::WindowFlags flags)
    : BtModuleChooserDialog(parent, flags), m_shown(false)
{
    resize(550, 340);

    // Read grouping order from settings or the default from argument:
    BtBookshelfTreeModel::Grouping groupingOrder(false);
    if (!groupingOrder.loadFrom(groupingOrderKey)) {
        groupingOrder = g;
    }

    BtInstallModuleChooserDialogModel *treeModel;
    treeModel = new BtInstallModuleChooserDialogModel(groupingOrder, this);
    connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)),
            this,      SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&)));

    m_bookshelfModel = new BtBookshelfModel(this);
    bookshelfWidget()->postFilterModel()->setShowShown(true);
    bookshelfWidget()->setTreeModel(treeModel);
    bookshelfWidget()->setSourceModel(m_bookshelfModel);
    bookshelfWidget()->showHideAction()->setVisible(false);
    bookshelfWidget()->showHideButton()->hide();
    bookshelfWidget()->treeView()->header()->show();

    retranslateUi();
}
BtOpenWorkActionMenu::BtOpenWorkActionMenu(QWidget *parent)
    : BtMenuView(parent), m_treeModel(0), m_postFilterModel(0)
{
    // Setup models:
    const BtBookshelfDockWidget *bookshelfDock(BtBookshelfDockWidget::getInstance());
    m_treeModel = new BtBookshelfTreeModel(bookshelfDock->groupingOrder(), this);
    m_postFilterModel = new BtBookshelfFilterModel(this);
    m_postFilterModel->setSourceModel(m_treeModel);
    setModel(m_postFilterModel);

    connect(this, SIGNAL(triggered(QModelIndex)),
            this, SLOT(slotIndexTriggered(QModelIndex)));
    connect(bookshelfDock, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)),
            m_treeModel,   SLOT(setGroupingOrder(BtBookshelfTreeModel::Grouping)));

}
BtSearchModuleChooserDialog::BtSearchModuleChooserDialog(QWidget *parent,
                                                         Qt::WindowFlags flags)
    : BtModuleChooserDialog(parent, flags)
{
    // Initialize the tree model:
    BtBookshelfTreeModel::Grouping grouping(groupingOrderKey);
    BtBookshelfTreeModel *treeModel = new BtBookshelfTreeModel(grouping, this);
    treeModel->setCheckable(true);
    BT_CONNECT(treeModel,
               SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)),
               this,
               SLOT(slotGroupingOrderChanged(
                            BtBookshelfTreeModel::Grouping const &)));

    // Initialize the bookshelf widget:
    bookshelfWidget()->showHideAction()->setVisible(false);
    bookshelfWidget()->showHideButton()->hide();
    bookshelfWidget()->setTreeModel(treeModel);
    bookshelfWidget()->setSourceModel(CSwordBackend::instance()->model());

    retranslateUi();
}
BtBookshelfDockWidget::BtBookshelfDockWidget(QWidget *parent, Qt::WindowFlags f)
        : QDockWidget(parent, f)
{
    BT_ASSERT(!m_instance);
    m_instance = this;

    setObjectName("BookshelfDock");


    // Setup actions and menus:
    initMenus();

    // Setup tree model:
    m_treeModel = new BtBookshelfTreeModel(groupingOrderKey, this);

    // Get backend model:
    BtBookshelfModel *bookshelfModel = CSwordBackend::instance()->model();

    // Setup bookshelf widgets:
    m_bookshelfWidget = new BtBookshelfWidget(this);
    m_bookshelfWidget->setTreeModel(m_treeModel);
    m_bookshelfWidget->setSourceModel(bookshelfModel);
    m_bookshelfWidget->setItemContextMenu(m_itemContextMenu);
    m_bookshelfWidget->treeView()->setMouseTracking(true); // required for moduleHovered
    /// \bug The correct grouping action is not selected on startup.

    // Setup welcome widgets:
    m_welcomeWidget = new QWidget(this);
    QVBoxLayout *welcomeLayout = new QVBoxLayout;
    m_installLabel = new QLabel(this);
    m_installLabel->setWordWrap(true);
    m_installLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
    welcomeLayout->addWidget(m_installLabel, 0, Qt::AlignHCenter | Qt::AlignBottom);
    m_installButton = new QPushButton(this);
    welcomeLayout->addWidget(m_installButton, 0, Qt::AlignHCenter | Qt::AlignTop);
    m_welcomeWidget->setLayout(welcomeLayout);

    // Setup stacked widget:
    m_stackedWidget = new QStackedWidget(this);
    m_stackedWidget->addWidget(m_bookshelfWidget);
    m_stackedWidget->addWidget(m_welcomeWidget);
    m_stackedWidget->setCurrentWidget(bookshelfModel->moduleList().empty()
                                      ? m_welcomeWidget
                                      : m_bookshelfWidget);
    setWidget(m_stackedWidget);

    // Connect signals:
    BT_CONNECT(m_bookshelfWidget->treeView(),
               SIGNAL(moduleActivated(CSwordModuleInfo *)),
               this, SLOT(slotModuleActivated(CSwordModuleInfo *)));
    BT_CONNECT(m_bookshelfWidget->treeView(),
               SIGNAL(moduleHovered(CSwordModuleInfo *)),
               this, SIGNAL(moduleHovered(CSwordModuleInfo *)));
    BT_CONNECT(m_treeModel, SIGNAL(moduleChecked(CSwordModuleInfo *, bool)),
               this,        SLOT(slotModuleChecked(CSwordModuleInfo *, bool)));
    BT_CONNECT(m_treeModel,
               SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)),
               this,
               SLOT(slotGroupingOrderChanged(
                            BtBookshelfTreeModel::Grouping const &)));
    BT_CONNECT(m_bookshelfWidget->showHideAction(), SIGNAL(toggled(bool)),
               m_treeModel,                         SLOT(setCheckable(bool)));
    BT_CONNECT(bookshelfModel,
               SIGNAL(rowsInserted(QModelIndex const &, int, int)),
               this, SLOT(slotModulesChanged()));
    BT_CONNECT(bookshelfModel,
               SIGNAL(rowsRemoved(QModelIndex const &, int, int)),
               this, SLOT(slotModulesChanged()));
    BT_CONNECT(m_installButton,       SIGNAL(clicked()),
               BibleTime::instance(), SLOT(slotBookshelfWizard()));

    retranslateUi();
}
void BtBookshelfDockWidget::slotGroupingOrderChanged(
        const BtBookshelfTreeModel::Grouping &g)
{
    g.saveTo(groupingOrderKey);
    emit groupingOrderChanged(g);
}