/** @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);
}
Esempio n. 2
0
  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;
  }
Esempio n. 3
0
  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;
  }