/** @short Find a message body part through its slash-separated string path */ Imap::Mailbox::TreeItemPart *MsgPartNetAccessManager::pathToPart(const QModelIndex &message, const QString &path) { QStringList items = path.split('/', QString::SkipEmptyParts); const Mailbox::Model *model = 0; Imap::Mailbox::TreeItem *target = Mailbox::Model::realTreeItem(message, &model); Q_ASSERT(model); Q_ASSERT(target); bool ok = ! items.isEmpty(); // if it's empty, it's a bogous URL for (QStringList::const_iterator it = items.constBegin(); it != items.constEnd(); ++it) { uint offset = it->toUInt(&ok); if (!ok) { // special case, we have to dive into that funny, irregular special parts now if (*it == QLatin1String("HEADER")) target = target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_HEADER); else if (*it == QLatin1String("TEXT")) target = target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_TEXT); else if (*it == QLatin1String("MIME")) target = target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_MIME); else return 0; continue; } if (offset >= target->childrenCount(const_cast<Mailbox::Model *>(model))) { return 0; } target = target->child(offset, const_cast<Mailbox::Model *>(model)); } return dynamic_cast<Imap::Mailbox::TreeItemPart *>(target); }
bool CEPasteDialog::isVaspFormat(const QString &text) { QStringList lines = text.split("\n"); // Title + scale + 3 vectors + composition + direct/cartesian + (no atoms) if (lines.size() < 7) { return false; } unsigned int lineIndex = 0; const QString *line; QStringList lineList; bool ok; unsigned int numAtoms = 0; // First line is comment line = &lines[lineIndex++]; // Next is a scale factor, single float line = &lines[lineIndex++]; line->toDouble(&ok); if (!ok) { return false; } // Next three lines are cell vectors, three floats for (int vecInd = 0; vecInd < 3; ++vecInd) { line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); if (lineList.size() != 3) { return false; } for (int i = 0; i < 3; ++i) { lineList.at(i).toDouble(&ok); if (!ok) { return false; } } } // Next line is a list of unsigned integers (composition) line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); int numSpecies = lineList.size(); if (numSpecies == 0) { return false; } // Check if the first field is an unsigned int (VASP 4.x) or a char (5.x) bool vaspVersionLessThan5; lineList.first().toUInt(&vaspVersionLessThan5); // If vasp >= 5.x, skip the line containing the atomic symbols. if (!vaspVersionLessThan5) { line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); if (lineList.size() != numSpecies) { return false; } } // Read in the total number of atoms for (QStringList::const_iterator it = lineList.constBegin(), it_end = lineList.constEnd(); it != it_end; ++it) { numAtoms += it->toUInt(&ok); if (!ok) { return false; } } // Next line is a string. First character is important: line = &lines[lineIndex++]; if (line->size() && line->at(0).toLower() == QChar('s')){ // If first letter is s (selective dynamics), skip one more line line = &lines[lineIndex++]; } // Current line is a string, contents not important here // Next [numAtoms] lines are vectors. So long as they're ok, we // have a POSCAR or CONTCAR! for (unsigned int i = 0; i < numAtoms; ++i) { line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); if (lineList.size() != 3) { return false; } for (int i = 0; i < 3; ++i) { lineList.at(i).toDouble(&ok); if (!ok) { return false; } } } return true; }
bool CEPasteDialog::acceptVaspFormat() { // Validate identities field QStringList idents = ui.edit_identities->text().simplified() .split(QRegExp("\\s+|,|;")); if (static_cast<unsigned int>(idents.size()) != m_numAtomTypes) { QMessageBox::critical (this, tr("Bad Compostion"), tr("The identities field must contain the same number of " "space delimited entries as line 6 of the POSCAR.")); return false; } bool ok; QList<unsigned int> compAtomicNums; QList<unsigned int> compCounts; for (QStringList::const_iterator it = idents.constBegin(), it_end = idents.constEnd(); it != it_end; ++it) { // Attempt to use the string as a uint unsigned int atomicNum = it->toUInt(&ok); // If this doesn't work, try passing the string to OB's translator if (!ok) { atomicNum = OpenBabel::etab.GetAtomicNum(it->toStdString().c_str()); } compAtomicNums.append(atomicNum); } QStringList lines = m_text.split("\n"); unsigned int lineIndex = 0; const QString *line; QStringList lineList; unsigned int numAtoms = 0; QList<Eigen::Vector3d> positions; QList<unsigned int> atomicNums; Eigen::Matrix3d cellMatrix; // First line is comment line = &lines[lineIndex++]; // Next is a scale factor, single float line = &lines[lineIndex++]; double scale = line->toDouble(&ok); if (!ok) { return false; } // Next three lines are cell vectors, three floats for (int vecInd = 0; vecInd < 3; ++vecInd) { line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); if (lineList.size() != 3) { return false; } for (int i = 0; i < 3; ++i) { double v = lineList.at(i).toDouble(&ok); if (!ok) { return false; } cellMatrix(vecInd, i) = v * scale; } } // Next line is a list of unsigned integers (composition) line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); // If vasp >= 5.x, this may be a list of atomic symbols. Skip it if so, // since the user should have already specified/verified the composition // in the GUI by this point. if (lineList.isEmpty()) { return false; } bool vaspVersionLessThan5; lineList.first().toUInt(&vaspVersionLessThan5); if (!vaspVersionLessThan5) { line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); } for (QStringList::const_iterator it = lineList.constBegin(), it_end = lineList.constEnd(); it != it_end; ++it) { unsigned int v = it->toUInt(&ok); if (!ok) { return false; } numAtoms += v; compCounts.append(v); } // Next line is a string. First character is important: line = &lines[lineIndex++]; if (line->size() && line->at(0).toLower() == QChar('s')){ // If first letter is s (selective dynamics), skip one more line line = &lines[lineIndex++]; } // Current line is a string. If it starts with K, k, C, or c, // positions are in cartesian units. Otherwise, reciprocal units. bool isCartesian = false; if (line->size() && (line->at(0).toLower() == QChar('k') || line->at(0).toLower() == QChar('c') ) ) { isCartesian = true; } // Next [numAtoms] lines are vectors. So long as they're ok, we // have a POSCAR or CONTCAR! for (unsigned int i = 0; i < numAtoms; ++i) { line = &lines[lineIndex++]; lineList = line->simplified().split(QRegExp("\\s+|,|;")); if (lineList.size() != 3) { return false; } Eigen::Vector3d vec; for (int i = 0; i < 3; ++i) { double v = lineList.at(i).toDouble(&ok); if (!ok) { return false; } vec(i) = v; } positions.append(vec); } // Build list of atomic numbers Q_ASSERT(compAtomicNums.size() == compCounts.size()); for (int i = 0; i < compCounts.size(); ++i) { for (unsigned int j = 0; j < compCounts.at(i); ++j) { atomicNums.append(compAtomicNums.at(i)); } } Q_ASSERT(atomicNums.size() == positions.size()); // Set unit cell QWriteLocker locker (m_molecule->lock()); OpenBabel::OBUnitCell *cell = m_molecule->OBUnitCell(); cell->SetData(Eigen2OB(cellMatrix)); // Convert to cartesian coords if necessary: if (!isCartesian) { for (QList<Eigen::Vector3d>::iterator it = positions.begin(), it_end = positions.end(); it != it_end; ++it) { *it = OB2Eigen(cell->FractionalToCartesian (Eigen2OB(*it))); } } // Remove old atoms QList<Avogadro::Atom*> oldAtoms = m_molecule->atoms(); for (QList<Avogadro::Atom*>::iterator it = oldAtoms.begin(), it_end = oldAtoms.end(); it != it_end; ++it) { m_molecule->removeAtom(*it); } // Add new atoms for (int i = 0; i < positions.size(); ++i) { Atom *atom = m_molecule->addAtom(); atom->setAtomicNumber(atomicNums.at(i)); atom->setPos(positions.at(i)); } return true; }