summaryrefslogtreecommitdiff
path: root/src/dic-options/PacksPage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dic-options/PacksPage.cpp')
-rw-r--r--src/dic-options/PacksPage.cpp345
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);
+}