/********************************************************************** 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"