diff options
Diffstat (limited to 'src/dic-options/FieldsListModel.cpp')
-rw-r--r-- | src/dic-options/FieldsListModel.cpp | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/dic-options/FieldsListModel.cpp b/src/dic-options/FieldsListModel.cpp new file mode 100644 index 0000000..9fd23ac --- /dev/null +++ b/src/dic-options/FieldsListModel.cpp @@ -0,0 +1,222 @@ +#include "FieldsListModel.h" +#include "../dictionary/Field.h" + +#include <QMimeData> + +QVariant FieldsListModel::data( const QModelIndex &index, int role ) const + { + if (!index.isValid()) + return QVariant(); + if (index.row() >= rowCount()) + return QVariant(); + + const Field* field = m_parent->m_dict.field( index.row() ); + switch( role ) + { + case Qt::DisplayRole: + switch( index.column() ) + { + case 0: + return field->name(); + case 1: + return field->style(); + default: + return QVariant(); + } + case Qt::EditRole: + switch( index.column() ) + { + case 0: + return field->name(); + case 1: + return field->style(); + default: + return QVariant(); + } + case EStyleRole: + return field->style(); + default: + return QVariant(); + } + } + +QVariant FieldsListModel::headerData(int section, Qt::Orientation orientation, + int role) const + { + if( role != Qt::DisplayRole ) + return QVariant(); + if( orientation == Qt::Horizontal ) + switch( section ) + { + case 0: + return tr("Field"); + case 1: + return tr("Style"); + default: + return QVariant(); + } + else + return QVariant(); + } + +Qt::ItemFlags FieldsListModel::flags(const QModelIndex &index) const + { + Qt::ItemFlags defaultFlags = QAbstractTableModel::flags(index); + if (index.isValid()) + return Qt::ItemIsEditable | Qt::ItemIsDragEnabled | defaultFlags; + else + return Qt::ItemIsDropEnabled | defaultFlags; + } + +bool FieldsListModel::setData(const QModelIndex &index, const QVariant &value, int role) + { + if( !index.isValid() || role!=Qt::EditRole ) + return false; + switch( index.column() ) + { + case 0: + m_parent->m_dict.setFieldName(index.row(), value.toString()); + emit dataChanged(index, index); + return true; + case 1: + m_parent->m_dict.setFieldStyle(index.row(), value.toString()); + emit dataChanged(index, index); + return true; + default: + return true; + } + } + +bool FieldsListModel::insertRows(int position, int rows, const QModelIndex &/*parent*/) + { + beginInsertRows(QModelIndex(), position, position+rows-1); + for (int row = 0; row < rows; ++row) + m_parent->m_dict.insertField( position, tr("new field") ); + endInsertRows(); + return true; + } + +bool FieldsListModel::removeRows(int position, int rows, const QModelIndex &/*parent*/) + { + beginRemoveRows(QModelIndex(), position, position+rows-1); + for (int row = 0; row < rows; ++row) + m_parent->m_dict.removeField( position ); + endRemoveRows(); + return true; + } + +void FieldsListModel::removeField(int aPos ) + { + beginRemoveRows(QModelIndex(), aPos, aPos); + m_parent->m_dict.destroyField( aPos ); + endRemoveRows(); + } + +void FieldsListModel::insertField(int aPos, Field* aField ) + { + beginInsertRows(QModelIndex(), aPos, aPos); + m_parent->m_dict.insertField( aPos, aField ); + endInsertRows(); + } + +Qt::DropActions FieldsListModel::supportedDropActions() const + { + return Qt::MoveAction; + } + +QStringList FieldsListModel::mimeTypes() const + { + QStringList types; + types << "application/octet-stream"; + return types; + } + +QMimeData *FieldsListModel::mimeData(const QModelIndexList &indexes) const + { + QStringList list; + QModelIndexList validIndexes; + foreach (QModelIndex index, indexes) + if (index.isValid() && index.column() == 0) + validIndexes << index; + qSort(validIndexes); + + int num = validIndexes.size(); + QByteArray encodedData; + QDataStream stream( &encodedData, QIODevice::WriteOnly ); + const Field** fieldPtrs = new const Field*[num]; + int i=0; + foreach (QModelIndex index, validIndexes) + fieldPtrs[i++] = m_parent->m_dict.field( index.row() ); + stream.writeBytes( (char*)fieldPtrs, num*sizeof(Field*) ); + delete fieldPtrs; + QMimeData *mimeData = new QMimeData(); + mimeData->setData( "application/octet-stream", encodedData ); + return mimeData; + } + +bool FieldsListModel::dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) + { + if (action == Qt::IgnoreAction) + return true; + if (!data->hasFormat("application/octet-stream")) + return false; + if (column > 0) + column = 0; + + int beginRow; + if (row != -1) + beginRow = row; + else if (parent.isValid()) + beginRow = parent.row(); + else + beginRow = rowCount(QModelIndex()); + + QByteArray encodedData = data->data("application/octet-stream"); + QDataStream stream( &encodedData, QIODevice::ReadOnly ); + Field** fieldPtrs = new Field*[ m_parent->m_dict.fieldsNum() ]; + uint num; + stream.readBytes( (char*&)fieldPtrs, num ); //TODO: Avoid converting pointer to other types + num /= sizeof(Field*); + + QList<QPersistentModelIndex> movedIndexes; + for(uint i=0; i<num; i++) + { + insertField( beginRow + i, fieldPtrs[i] ); + movedIndexes << QPersistentModelIndex( index(beginRow + i, 0, QModelIndex()) ); + } + delete fieldPtrs; + emit indexesDropped( movedIndexes ); + return true; + } + +void FieldsListModel::moveIndexesUpDown( QModelIndexList aIndexes, int aDirection ) + { + QList<QPersistentModelIndex> pSrcIndexes; + foreach (QModelIndex idx, aIndexes) + if( idx.isValid() && idx.column() == 0 ) + pSrcIndexes << QPersistentModelIndex( idx ); + + int rowsNum = pSrcIndexes.size(); + if( rowsNum == 0 ) + return; + + qSort( pSrcIndexes ); + + int beginRow; + if( aDirection < 0 ) + beginRow = pSrcIndexes[0].row()-1; + else + beginRow = pSrcIndexes[rowsNum-1].row()+2; + if( rowsNum == 1 && (beginRow < 0 || beginRow > rowCount()) ) + return; + if( beginRow < 0 ) + beginRow = 0; + if( beginRow > rowCount() ) + beginRow = rowCount(); + + QMimeData* mime = mimeData( aIndexes ); + dropMimeData( mime, Qt::MoveAction, beginRow, 0, QModelIndex() ); + foreach (QModelIndex index, pSrcIndexes) + removeRow( index.row() ); + } |