#include "PacksPage.h" #include "FieldsListModel.h" #include "PacksListModel.h" #include "PackFieldsListModel.h" #include "PackFieldsView.h" #include "UnusedFieldsListModel.h" #include "../dictionary/Dictionary.h" #include "../study/CardSideView.h" #include "../dictionary/CardPack.h" #include "../field-styles/FieldStyleFactory.h" #include #include #include #include PacksPage::PacksPage( DictionaryOptionsDialog* aParent ): QWidget( aParent ), m_parent( aParent ) { createPacksList(); createPackFieldsList(); createUnusedFieldsList(); createPackPreview(); QGridLayout* mainLt = new QGridLayout; mainLt->addLayout( m_packsListLt, 0, 0, 2, 1 ); mainLt->addLayout( m_fieldsListLt, 0, 1 ); mainLt->addLayout( m_unusedFieldsListLt, 1, 1 ); mainLt->addLayout( m_previewLt, 0, 2, 2, 1 ); setLayout( mainLt ); // Select first pack m_packsListView->selectionModel()->setCurrentIndex( m_packFieldsListModel->index(0, 0), QItemSelectionModel::Select ); } PacksPage::~PacksPage() { } void PacksPage::createPacksList() { m_packsListModel = new PacksListModel( m_parent ); m_packsListView = new PackFieldsView( this ); m_packsListView->setModel( m_packsListModel ); m_packsListView->setDropIndicatorShown(true); m_packsListView->setMinimumWidth( 200 ); QPushButton* addPackBtn = new QPushButton( QPixmap(":/images/add.png"), tr("Add") ); QPushButton* removePackBtn = new QPushButton( QPixmap(":/images/delete.png"), tr("Remove") ); QHBoxLayout* packBtnLt = new QHBoxLayout; packBtnLt->addWidget( addPackBtn ); packBtnLt->addWidget( removePackBtn ); connect( addPackBtn, SIGNAL(clicked()), this, SLOT(addPack()) ); connect( removePackBtn, SIGNAL(clicked()), this, SLOT(removePacks()) ); QToolButton* packMoveUpBtn = new QToolButton; packMoveUpBtn->setObjectName("pack-up"); packMoveUpBtn->setIcon(QIcon(":/images/1uparrow.png")); packMoveUpBtn->setToolTip(tr("Move pack up")); QToolButton* packMoveDownBtn = new QToolButton; packMoveDownBtn->setObjectName("pack-down"); packMoveDownBtn->setIcon(QIcon(":/images/1downarrow.png")); packMoveDownBtn->setToolTip(tr("Move pack down")); QVBoxLayout* packMoveBtnsLt = new QVBoxLayout; packMoveBtnsLt->addWidget( packMoveUpBtn ); packMoveBtnsLt->addWidget( packMoveDownBtn ); packMoveBtnsLt->addStretch( 1 ); connect( packMoveUpBtn, SIGNAL(clicked()), this, SLOT(moveItemsUpDown()) ); connect( packMoveDownBtn, SIGNAL(clicked()), this, SLOT(moveItemsUpDown()) ); m_packsListLt = new QGridLayout; m_packsListLt->addWidget( new QLabel(""+tr("Card packs")+""), 0, 0, 1, 2 ); m_packsListLt->addWidget( m_packsListView, 1, 0 ); m_packsListLt->addLayout( packMoveBtnsLt, 1, 1 ); m_packsListLt->addLayout( packBtnLt, 2, 0, 1, 2 ); } void PacksPage::createPackFieldsList() { m_packFieldsListModel = new PackFieldsListModel( m_parent ); m_fieldsListView = new PackFieldsView( this ); m_fieldsListView->setModel( m_packFieldsListModel ); m_fieldsListView->setDropIndicatorShown(true); connect( m_packsListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), m_packFieldsListModel, SLOT(changeParentRow(const QModelIndex&)) ); connect( m_packsListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), SLOT(updateUsesExactAnswer(const QModelIndex&)) ); connect( m_packFieldsListModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), m_packsListView, SLOT(updateCurrent()) ); connect( m_packFieldsListModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), m_packsListView, SLOT(updateCurrent()) ); QToolButton* fieldMoveUpBtn = new QToolButton; fieldMoveUpBtn->setObjectName("field-up"); fieldMoveUpBtn->setIcon(QIcon(":/images/1uparrow.png")); fieldMoveUpBtn->setToolTip(tr("Move field up")); QToolButton* fieldMoveDownBtn = new QToolButton; fieldMoveDownBtn->setObjectName("field-down"); fieldMoveDownBtn->setIcon(QIcon(":/images/1downarrow.png")); fieldMoveDownBtn->setToolTip(tr("Move field down")); QVBoxLayout* fieldBtnsLt = new QVBoxLayout; fieldBtnsLt->addWidget( fieldMoveUpBtn ); fieldBtnsLt->addWidget( fieldMoveDownBtn ); fieldBtnsLt->addStretch( 1 ); connect( fieldMoveUpBtn, SIGNAL(clicked()), this, SLOT(moveItemsUpDown()) ); connect( fieldMoveDownBtn, SIGNAL(clicked()), this, SLOT(moveItemsUpDown()) ); m_fieldsListLt = new QGridLayout; m_fieldsListLt->addWidget( new QLabel(""+tr("Pack fields")+""), 0, 0, 1, 2 ); m_fieldsListLt->addWidget( m_fieldsListView, 1, 0 ); m_fieldsListLt->addLayout( fieldBtnsLt, 1, 1 ); } void PacksPage::createUnusedFieldsList() { m_unusedFieldsListModel = new UnusedFieldsListModel( m_parent ); m_unusedFieldsListView = new PackFieldsView( this ); m_unusedFieldsListView->setModel( m_unusedFieldsListModel ); connect( m_packsListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), m_unusedFieldsListModel, SLOT(changeParentRow(const QModelIndex&)) ); connect( m_packFieldsListModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), m_unusedFieldsListModel, SLOT(updateUnusedFields()) ); connect( m_packFieldsListModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), m_unusedFieldsListModel, SLOT(updateUnusedFields()) ); connect( m_parent->m_fieldsListModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), m_unusedFieldsListModel, SLOT(updateUnusedFields()) ); connect( m_parent->m_fieldsListModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), m_unusedFieldsListModel, SLOT(updateUnusedFields()) ); connect( m_parent->m_fieldsListModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), m_unusedFieldsListModel, SLOT(updateUnusedFields()) ); QToolButton* fieldRemoveBtn = new QToolButton; fieldRemoveBtn->setIcon(QIcon(":/images/down.png")); fieldRemoveBtn->setToolTip(tr("Remove field from pack")); QToolButton* fieldAddBtn = new QToolButton; fieldAddBtn->setIcon(QIcon(":/images/up.png")); fieldAddBtn->setToolTip(tr("Add field to pack")); QHBoxLayout* usedFieldsBtnsLt = new QHBoxLayout; usedFieldsBtnsLt->addWidget( fieldRemoveBtn ); usedFieldsBtnsLt->addWidget( fieldAddBtn ); connect( fieldRemoveBtn, SIGNAL(clicked()), this, SLOT(removeFields()) ); connect( fieldAddBtn, SIGNAL(clicked()), this, SLOT(addFields()) ); usesExactAnswerBox = new QCheckBox(tr("Uses exact answer")); connect(usesExactAnswerBox, SIGNAL(stateChanged(int)), SLOT(updatePackUsesExactAnswer(int))); m_unusedFieldsListLt = new QGridLayout; m_unusedFieldsListLt->addLayout( usedFieldsBtnsLt, 0, 0 ); m_unusedFieldsListLt->addWidget( new QLabel(""+tr("Unused fields")+""), 0, 1 ); m_unusedFieldsListLt->addWidget( m_unusedFieldsListView, 1, 0, 1, 2 ); m_unusedFieldsListLt->addWidget(usesExactAnswerBox, 2, 0, 1, 2); } void PacksPage::createPackPreview() { m_qstPreview = new CardSideView( CardSideView::QstMode ); m_qstPreview->setMinimumSize( 200, 70 ); m_ansPreview = new CardSideView( CardSideView::AnsMode ); m_ansPreview->setMinimumSize( 200, 70 ); m_previewLt = new QVBoxLayout; m_previewLt->addWidget( new QLabel( ""+tr("Preview")+"") ); m_previewLt->addWidget( m_qstPreview, 1 ); m_previewLt->addWidget( m_ansPreview, 1 ); // From: the packs list connect( m_packsListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), SLOT(updatePreviewForPack()) ); // From: the pack fields list connect( m_packFieldsListModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(updatePreviewForPack()) ); connect( m_packFieldsListModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SLOT(updatePreviewForPack()) ); // From: the dictionary field list at the "Fields" page connect( m_parent->m_fieldsListModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SLOT(updatePreviewForPack()) ); connect( m_parent->m_fieldsListModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SLOT(updatePreviewForPack()) ); } void PacksPage::updatePreviewForPack() { int selectedPack = m_packsListView->selectionModel()->currentIndex().row(); if( selectedPack > -1 ) // If any selection m_curPack = selectedPack; CardPack* pack = m_parent->m_dict.cardPack( m_curPack ); if( !pack ) return; const Field* qstField = pack->getQuestionField(); if( !qstField ) return; QStringList ansList; foreach( const Field* field, pack->getAnswerFields() ) ansList << field->name(); m_qstPreview->setPack( pack ); m_qstPreview->setQuestion( qstField->name() ); m_ansPreview->setPack( pack ); m_ansPreview->setQstAnsr( qstField->name(), ansList ); } void PacksPage::moveItemsUpDown() { PackFieldsView* view; if( sender()->objectName().contains("pack") ) view = m_packsListView; else if( sender()->objectName().contains("field") ) view = m_fieldsListView; else return; DraggableListModel* model = view->model(); QModelIndexList selectedIndexes = view->selectionModel()->selectedIndexes(); QList pSrcIndexes; foreach (QModelIndex idx, selectedIndexes) if( idx.isValid() ) pSrcIndexes << QPersistentModelIndex( idx ); int rowsNum = pSrcIndexes.size(); if( rowsNum == 0 ) return; qSort( pSrcIndexes ); int beginRow; if( sender()->objectName().contains("up") ) beginRow = pSrcIndexes[0].row()-1; else if( sender()->objectName().contains("down") ) beginRow = pSrcIndexes[rowsNum-1].row()+2; else return; if( rowsNum == 1 && (beginRow < 0 || beginRow > model->rowCount()) ) return; if( beginRow < 0 ) beginRow = 0; if( beginRow > model->rowCount() ) beginRow = model->rowCount(); QMimeData* mime = model->mimeData( selectedIndexes ); model->dropMimeData( mime, Qt::MoveAction, beginRow, 0, QModelIndex() ); foreach (QModelIndex index, pSrcIndexes) model->removeRow( index.row() ); } void PacksPage::removeFields() { if( m_packFieldsListModel->rowCount() <= 1 ) return; QModelIndexList selectedIndexes = m_fieldsListView->selectionModel()->selectedIndexes(); if( selectedIndexes.isEmpty() ) return; QList pSrcIndexes; foreach (QModelIndex idx, selectedIndexes) if( idx.isValid() ) pSrcIndexes << QPersistentModelIndex( idx ); foreach (QModelIndex index, pSrcIndexes) m_fieldsListView->model()->removeRow( index.row() ); } void PacksPage::addFields() { QModelIndexList selectedIndexes = m_unusedFieldsListView->selectionModel()->selectedIndexes(); if( selectedIndexes.isEmpty() ) return; int dstRow = m_fieldsListView->currentIndex().row()+1; QMimeData* mime = m_unusedFieldsListModel->mimeData( selectedIndexes ); m_packFieldsListModel->dropMimeData( mime, Qt::MoveAction, dstRow, 0, QModelIndex() ); } void PacksPage::addPack() { QModelIndexList selectedIndexes = m_packsListView->selectionModel()->selectedRows(); int row; if( selectedIndexes.size() > 0 ) { qSort(selectedIndexes); row = selectedIndexes[selectedIndexes.size()-1].row() + 1; } else row = 0; m_packsListModel->insertRow( row, QModelIndex() ); } void PacksPage::removePacks() { QModelIndexList selectedIndexes = m_packsListView->selectionModel()->selectedRows(); QList pIndexes; foreach (QModelIndex idx, selectedIndexes) if( idx.isValid() ) pIndexes << QPersistentModelIndex( idx ); if( pIndexes.size() == 0 ) return; foreach( QModelIndex idx, pIndexes ) m_packsListModel->removePack( idx.row() ); } void PacksPage::renamePack() { QModelIndex idx = m_packsListView->currentIndex(); if( !idx.isValid() ) return; m_packsListView->edit( idx ); } void PacksPage::updateUsesExactAnswer(const QModelIndex& index) { int selectedPack = index.row(); if( selectedPack > -1 ) // If any selection m_curPack = selectedPack; CardPack* pack = m_parent->m_dict.cardPack( m_curPack ); if( !pack ) return; usesExactAnswerBox->setChecked(pack->getUsesExactAnswer()); } void PacksPage::updatePackUsesExactAnswer(int state) { CardPack* pack = m_parent->m_dict.cardPack( m_curPack ); pack->setUsesExactAnswer(state == Qt::Checked); }