/**********************************************************************
ZMatrixModel - ZMatrix Table Model
Copyright (C) 2009 by Marcus D. Hanwell
This file is part of the Avogadro molecular editor project.
For more information, see
Avogadro is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Avogadro is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
**********************************************************************/
#include "zmatrixmodel.h"
#include
#include
#include
namespace Avogadro {
using OpenBabel::etab;
ZMatrixModel::ZMatrixModel() : m_zMatrix(0)
{
}
ZMatrixModel::~ZMatrixModel()
{
}
void ZMatrixModel::setZMatrix(ZMatrix *zmatrix)
{
disconnect(m_zMatrix, 0, 0, 0);
m_zMatrix = zmatrix;
connect(m_zMatrix, SIGNAL(rowAdded(int)), this, SLOT(addRow(int)));
qDebug() << "Set z matrix" << m_zMatrix;
}
ZMatrix * ZMatrixModel::zMatrix()
{
return m_zMatrix;
}
int ZMatrixModel::rowCount(const QModelIndex &) const
{
if (m_zMatrix)
return m_zMatrix->rows();
else
return 0;
}
int ZMatrixModel::columnCount(const QModelIndex &) const
{
return 7;
}
QVariant ZMatrixModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return QString(tr("Symbol"));
break;
case 1:
case 3:
case 5:
return QVariant();
break;
case 2:
return QString(tr("Bond Length"));
break;
case 4:
return QString(tr("Bond Angle"));
break;
case 6:
return QString(tr("Dihedral Angle"));
break;
default:
return QString(tr("Unknown"));
}
}
else
return QString::number(section + 1);
}
Qt::ItemFlags ZMatrixModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
if (index.row() == 0 && index.column() > 0)
return Qt::NoItemFlags;
else if (index.row() == 1 && index.column() > 2)
return Qt::NoItemFlags;
else if (index.row() == 2 && index.column() > 4)
return Qt::NoItemFlags;
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
QVariant ZMatrixModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || !m_zMatrix)
return QVariant();
// Disable editing in the cells that have no meaning
if (!index.isValid())
return QVariant();
if (index.row() == 0 && index.column() > 0)
return QVariant();
else if (index.row() == 1 && index.column() > 2)
return QVariant();
else if (index.row() == 2 && index.column() > 4)
return QVariant();
else if (index.row() >= m_zMatrix->rows() || index.column() >= 7)
return QVariant();
if (role == Qt::DisplayRole) {
// Main segment of the display - actually display the z matrix
switch (index.column()) {
case 0: // Element symbol
return etab.GetSymbol(m_zMatrix->m_items[index.row()].atomicNumber);
break;
case 1: // Connectivity element 0
return m_zMatrix->m_items[index.row()].indices[0] + 1;
break;
case 2: // Bond length
return m_zMatrix->m_items[index.row()].lengths[0];
break;
case 3: // Connectivity element 1
return m_zMatrix->m_items[index.row()].indices[1] + 1;
break;
case 4: // Bond angle
return m_zMatrix->m_items[index.row()].lengths[1];
break;
case 5: // Connectivity element 2
return m_zMatrix->m_items[index.row()].indices[2] + 1;
break;
case 6: // Dihedral angle
return m_zMatrix->m_items[index.row()].lengths[2];
break;
default: // Should never happen!
return QVariant();
}
return QString("No worky!");
}
else
return QVariant();
}
bool ZMatrixModel::setData(const QModelIndex &index, const QVariant &value,
int role)
{
if (!index.isValid() || !m_zMatrix)
return false;
if (index.row() >= m_zMatrix->rows() || index.column() > 6)
return false;
if (index.isValid() && role == Qt::EditRole) {
int row = index.row();
// do stuff
switch (index.column()) {
case 0: {// Element symbol - take symbol and get number
QByteArray element(value.toByteArray());
int aNum = etab.GetAtomicNum(element.data());
qDebug() << "Atomic num" << value << aNum;
m_zMatrix->m_items[index.row()].atomicNumber = aNum;
break;
}
case 1: {// Connectivity element 0 - bonding
int connection = value.toInt() - 1;
if (connection > 0 && connection < row)
m_zMatrix->setBond(index.row(), connection);
break;
}
case 2: // Bond length
if (value.toDouble() > 0.0)
m_zMatrix->m_items[index.row()].lengths[0] = value.toDouble();
break;
case 3: {// Connectivity element 1
int connection = value.toInt() - 1;
if (connection > 0 && connection < row)
m_zMatrix->m_items[index.row()].indices[1] = connection;
break;
}
case 4: // Bond angle
m_zMatrix->m_items[index.row()].lengths[1] = value.toDouble();
break;
case 5: {// Connectivity element 2
int connection = value.toInt() - 1;
if (connection > 0 && connection < row)
m_zMatrix->m_items[index.row()].indices[2] = connection;
break;
}
case 6: // Dihedral angle
m_zMatrix->m_items[index.row()].lengths[2] = value.toDouble();
break;
default: // Should never happen!
return false;
}
m_zMatrix->update();
return true;
}
return false;
}
bool ZMatrixModel::insertRows(int position, int rows,
const QModelIndex &index)
{
if (m_zMatrix) {
beginInsertRows(QModelIndex(), position, position+rows-1);
for (int row = 0; row < rows; ++row) {
// FIXME Currently just adding new rows to the end of the matrix
m_zMatrix->addRow();
}
endInsertRows();
return true;
}
return false;
}
bool ZMatrixModel::removeRows(int position, int rows,
const QModelIndex &index)
{
}
void ZMatrixModel::addRow(int row)
{
beginInsertRows(QModelIndex(), row, row+1);
endRemoveRows();
}
} // End namespace Avogadro
#include "zmatrixmodel.moc"