diff options
author | Jedidiah Barber <contact@jedbarber.id.au> | 2021-07-14 11:49:10 +1200 |
---|---|---|
committer | Jedidiah Barber <contact@jedbarber.id.au> | 2021-07-14 11:49:10 +1200 |
commit | d24f813f3f2a05c112e803e4256b53535895fc98 (patch) | |
tree | 601e6ae9a1cd44bcfdcf91739a5ca36aedd827c9 /src/dic-options/PacksPage.cpp |
Diffstat (limited to 'src/dic-options/PacksPage.cpp')
-rw-r--r-- | src/dic-options/PacksPage.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/src/dic-options/PacksPage.cpp b/src/dic-options/PacksPage.cpp new file mode 100644 index 0000000..e78bbf0 --- /dev/null +++ b/src/dic-options/PacksPage.cpp @@ -0,0 +1,345 @@ +#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 <QLabel> +#include <QPushButton> +#include <QToolButton> +#include <QStringListModel> + +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("<b>"+tr("Card packs")+"</b>"), 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("<b>"+tr("Pack fields")+"</b>"), 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("<b>"+tr("Unused fields")+"</b>"), 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( "<b>"+tr("Preview")+"</b>") ); + 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<QPersistentModelIndex> 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<QPersistentModelIndex> 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<QPersistentModelIndex> 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); +} |