/**********************************************************************
InsertFragmentDialog - Inserting fragments using the draw tool
Copyright (C) 2008 by Geoffrey Hutchison
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 "insertfragmentdialog.h"
#include "directorytreemodel.h"
// Defines INSTALL_PREFIX among other things
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace OpenBabel;
namespace Avogadro {
class InsertFragmentPrivate
{
public:
Molecule fragment;
OBConversion conv;
OBBuilder builder;
DirectoryTreeModel *model;
bool insertMode;
bool smilesMode;
InsertFragmentPrivate() : insertMode(false)
{ }
~InsertFragmentPrivate()
{
if (model)
delete model;
}
};
QStringList DefaultDirectoryList()
{
QStringList directoryList;
#ifdef Q_WS_X11
directoryList << QString( INSTALL_PREFIX ) + "/share/avogadro/fragments";
directoryList << QDir::homePath() + "/.avogadro/fragments";
#endif
#ifdef Q_WS_WIN
directoryList << QCoreApplication::applicationDirPath() + "/../share/avogadro/fragments";
#endif
#ifdef Q_WS_MAC
directoryList << "/Library/Application Support/Avogadro/Fragments";
directoryList << QDir::homePath() + "/Library/Application Support/Avogadro/Fragments";
#endif
return directoryList;
}
InsertFragmentDialog::InsertFragmentDialog(QWidget *parent, Qt::WindowFlags) : QDialog(parent)
{
// Use a small title bar (Qt::Tool) with no minimize or maximize buttons
// much like the Periodic Table widget
setWindowFlags(Qt::Dialog | Qt::Tool);
d = new InsertFragmentPrivate;
// There has to be a better way to set this based on the installation prefix
m_directoryList = DefaultDirectoryList();
d->model = new DirectoryTreeModel(m_directoryList, this);
ui.setupUi(this);
ui.directoryTreeView->setModel(d->model);
ui.directoryTreeView->setSelectionMode(QAbstractItemView::SingleSelection);
ui.directoryTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.directoryTreeView->setUniformRowHeights(true);
ui.directoryTreeView->expandToDepth(1);
ui.insertFragmentButton->setFocusPolicy(Qt::NoFocus);
connect(ui.insertFragmentButton, SIGNAL(clicked(bool)),
this, SLOT(setupInsertMode(bool)));
connect(ui.addDirectoryButton, SIGNAL(clicked(bool)),
this, SLOT(addDirectory(bool)));
connect(ui.clearListButton, SIGNAL(clicked(bool)),
this, SLOT(clearDirectoryList(bool)));
}
InsertFragmentDialog::~InsertFragmentDialog()
{
delete d;
}
const Molecule *InsertFragmentDialog::fragment()
{
d->fragment.clear();
OBMol obfragment;
// SMILES insert
if (d->smilesMode) {
// We should use the method because it will grab updates to the line edit
std::string SmilesString(smilesString().toAscii());
if(d->conv.SetInFormat("smi")
&& d->conv.ReadString(&obfragment, SmilesString))
{
d->builder.Build(obfragment);
d->fragment.setOBMol(&obfragment);
d->fragment.center();
d->fragment.addHydrogens();
}
} else {
QModelIndexList selected = ui.directoryTreeView->selectionModel()->selectedIndexes();
if (selected.count() != 0) {
QString file = d->model->filePath(selected.first());
if (!file.isEmpty()) {
std::string fileName(file.toAscii());
//OBFormat *inFormat = d->conv.FormatFromExt(fileName.c_str());
//if (!inFormat || !d->conv.SetInFormat(inFormat)) {
OBConversion conv;
OBFormat *inFormat = conv.FormatFromExt(fileName.c_str());
if (!inFormat || !conv.SetInFormat(inFormat)) {
QMessageBox::warning( (QWidget*)this, tr( "Avogadro" ),
tr( "Cannot read file format of file %1." )
.arg( QString(fileName.c_str()) ) );
return &d->fragment;
}
std::ifstream ifs;
ifs.open(fileName.c_str());
if (!ifs) {
QMessageBox::warning( (QWidget*)this, tr( "Avogadro" ),
tr( "Cannot read file %1." )
.arg( QString(fileName.c_str()) ) );
return &d->fragment;
}
//d->conv.Read(&d->fragment, &ifs);
conv.Read(&obfragment, &ifs);
d->fragment.setOBMol(&obfragment);
d->fragment.center();
ifs.close();
}
}
}
return &d->fragment;
}
const QString InsertFragmentDialog::smilesString()
{
if (!ui.smilesLineEdit->text().isEmpty()) {
m_smilesString = ui.smilesLineEdit->text();
}
return m_smilesString;
}
void InsertFragmentDialog::setSmilesString(const QString smiles)
{
m_smilesString = smiles;
ui.smilesLineEdit->setText(m_smilesString);
}
const QStringList InsertFragmentDialog::directoryList() const
{
return m_directoryList;
}
void InsertFragmentDialog::setDirectoryList(const QStringList dirList)
{
if (dirList.size() != 0)
m_directoryList = dirList;
refresh();
}
void InsertFragmentDialog::refresh()
{
d->model->setDirectoryList(m_directoryList);
ui.directoryTreeView->update();
}
void InsertFragmentDialog::setupInsertMode(bool)
{
bool inserting = (ui.insertFragmentButton->text() == tr("Stop Inserting"));
if(!inserting) {
if (ui.smilesLineEdit->hasFocus()) {
d->smilesMode = true;
} else {
d->smilesMode = false;
}
ui.toolTipLabel->setText(tr("Click to insert the fragment at that position."));
ui.insertFragmentButton->setText(tr("Stop Inserting"));
ui.smilesLineEdit->setEnabled(false);
ui.directoryTreeView->setEnabled(false);
} else {
ui.insertFragmentButton->setText(tr("Insert Fragment"));
ui.toolTipLabel->setText(QString());
ui.smilesLineEdit->setEnabled(true);
ui.directoryTreeView->setEnabled(true);
if (d->smilesMode) {
ui.smilesLineEdit->setFocus();
} else {
ui.directoryTreeView->setFocus();
}
}
emit setInsertMode(!inserting);
}
void InsertFragmentDialog::closeEvent(QCloseEvent *event)
{
// stop inserting
if (ui.insertFragmentButton->text() == tr("Stop Inserting"))
setupInsertMode(false);
event->accept();
}
void InsertFragmentDialog::addDirectory(bool)
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
"/home");
// If this is a new directory, add it in
if (!m_directoryList.contains(dir)) {
m_directoryList << dir;
refresh();
}
}
void InsertFragmentDialog::clearDirectoryList(bool)
{
m_directoryList.clear();
m_directoryList = DefaultDirectoryList();
refresh();
}
}
#include "insertfragmentdialog.moc"