<commit_before>#include "data.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;
data::data()
{
}

bool data::openDatabase()
{
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName("vika2.sqlite");
    //m_db.setDatabaseName("..\\..\\sqldatabase\\vika2.sqlite");

    if (!m_db.open())
    {
       return false;
    }
    else
    {
       return true;
    }
}

void data::read(vector<Person>& pers)
{
    QSqlQuery query("SELECT ID, Name, Sex, Birth, Death, Status FROM persons");
    int idID = query.record().indexOf("ID");
    int idName = query.record().indexOf("Name");
    int idSex = query.record().indexOf("Sex");
    int idBirth = query.record().indexOf("Birth");
    int idDeath = query.record().indexOf("Death");
    int idStatus = query.record().indexOf("Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
        QString qid = query.value(idID).toString();
        string id = qid.toLocal8Bit().constData();
        QString qname = query.value(idName).toString();
        string name = qname.toLocal8Bit().constData();
        QString qsex = query.value(idSex).toString();
        string sex = qsex.toLocal8Bit().constData();
        QString qbirth = query.value(idBirth).toString();
        string birth = qbirth.toLocal8Bit().constData();
        QString qdeath = query.value(idDeath).toString();
        string death = qdeath.toLocal8Bit().constData();
        Person p(id, name, sex, birth, death);
        pers.push_back(p);
        }
    }
}

void data::write(string& firstname, string& sex, string& birth, string& death)
{
    QSqlQuery query;
    QString qfirstname = QString::fromStdString(firstname);
    QString qsex = QString::fromStdString(sex);
    QString qbirth = QString::fromStdString(birth);

    QString qdeath= QString::fromStdString(death);
    query.prepare("INSERT INTO persons (Name, Sex, Birth, Death,Status)"
                   "VALUES (:name, :sex, :birth, :death, :status)");

    query.bindValue(":name", qfirstname);
    query.bindValue(":sex", qsex);
    query.bindValue(":birth", qbirth);
    query.bindValue(":death", qdeath);
    query.bindValue(":status",0);
    query.exec();
}

vector<Person> data::sortPersons(string& type)
{
    vector<Person> pers;
    QSqlQuery query;
    if (type == "-nameasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Name ASC");
    }
    else if (type == "-sexasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Sex ASC");
    }
    else if (type == "-birthasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Birth ASC");
    }
    else if (type == "-deathasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Death ASC");
    }
    else if (type == "-namedesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Name DESC");
    }
    else if (type == "-sexdesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Sex DESC");
    }
    else if (type == "-birthdesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Birth DESC");
    }
    else if (type == "-deathdesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Death DESC");
    }

    int idID = query.record().indexOf("ID");
    int idName = query.record().indexOf("Name");
    int idSex = query.record().indexOf("Sex");
    int idBirth = query.record().indexOf("Birth");
    int idDeath = query.record().indexOf("Death");
    int idStatus = query.record().indexOf("Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qname = query.value(idName).toString();
            string name = qname.toLocal8Bit().constData();
            QString qsex = query.value(idSex).toString();
            string sex = qsex.toLocal8Bit().constData();
            QString qbirth = query.value(idBirth).toString();
            string birth = qbirth.toLocal8Bit().constData();
            QString qdeath = query.value(idDeath).toString();
            string death = qdeath.toLocal8Bit().constData();
            Person p(id, name, sex, birth, death);
            pers.push_back(p);
        }
    }

    return pers;
}

void data::remove(string& ID, int& type) {
    QSqlQuery query;
    QString qID = QString::fromStdString(ID);
    if (type == 0)
    {
        query.prepare("UPDATE persons SET status = 1 WHERE ID = :id");
        query.bindValue(":id", qID);
    }
    else if (type == 1)
    {
        query.prepare("UPDATE computer SET computer_status = 1 WHERE computer_ID = :id");
        query.bindValue(":id", qID);
    }

    query.exec();
}

void data::edit(string& ID, string& value, string& type)
{
    QSqlQuery query;
    QString qID = QString::fromStdString(ID);
    QString qvalue = QString::fromStdString(value);
    if (type == "-name")
    {
        query.prepare("Update persons SET name = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-sex")
    {
        query.prepare("Update persons SET sex = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-birth")
    {
        query.prepare("Update persons SET birth = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-death")
    {
        query.prepare("Update persons SET death = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    query.exec();
}

void data::readComputer(vector<Computer>& comp)
{
    QSqlQuery query("SELECT computer_ID, computer_Name, computer_Year, "
                   "computer_Type, computer_Built, computer_Status FROM computer");

    int idID = query.record().indexOf("computer_ID");
    int idName = query.record().indexOf("computer_name");
    int idYear = query.record().indexOf("computer_Year");
    int idType = query.record().indexOf("computer_Type");
    int idBuilt = query.record().indexOf("computer_Built");
    int idStatus = query.record().indexOf("computer_Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qname = query.value(idName).toString();
            string name = qname.toLocal8Bit().constData();
            QString qyear = query.value(idYear).toString();
            string year = qyear.toLocal8Bit().constData();
            QString qtype = query.value(idType).toString();
            string type = qtype.toLocal8Bit().constData();
            QString qbuilt = query.value(idBuilt).toString();
            string built = qbuilt.toLocal8Bit().constData();
            Computer c(id, name, year, type, built);
            comp.push_back(c);
        }
    }
}

void data::writeComputer(string& name, string& year, string& type, string& built)
{
    QSqlQuery query;
    QString qname = QString::fromStdString(name);
    QString qyear = QString::fromStdString(year);
    QString qtype = QString::fromStdString(type);
    QString qbuilt = QString::fromStdString(built);
    query.prepare("INSERT INTO computer (computer_name, computer_year, computer_type, computer_built)"
                  "VALUES (:name, :year, :type, :built)");
        query.bindValue(":name", qname);
        query.bindValue(":year", qyear);
        query.bindValue(":type", qtype);
        query.bindValue(":built", qbuilt);
        query.exec();
}

void data::editComp(string& ID, string& value, string& type)
{
    QSqlQuery query;
    QString qID = QString::fromStdString(ID);
    QString qvalue = QString::fromStdString(value);
    if (type == "-name")
    {
        query.prepare("Update computer SET computer_name = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-year")
    {
        query.prepare("Update computer SET computer_year = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-type")
    {
        query.prepare("Update computer SET computer_type = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-built")
    {
        query.prepare("Update computer SET computer_built = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    query.exec();
}

vector<Computer> data::sortComputer(string& type)
{
    vector<Computer> comp;
    QSqlQuery query;
    if (type == "-nameasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_name ASC");
    }
    else if (type == "-yearasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_year ASC");
    }
    else if (type == "-typeasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_type ASC");
    }
    else if (type == "-builtasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_built ASC");
    }
    else if (type == "-namedesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_name DESC");
    }
    else if (type == "-yeardesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_year DESC");
    }
    else if (type == "-typedesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_type DESC");
    }
    else if (type == "-builtdesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_built DESC");
    }
    int idID = query.record().indexOf("computer_ID");
    int idName = query.record().indexOf("computer_name");
    int idYear = query.record().indexOf("computer_Year");
    int idType = query.record().indexOf("computer_Type");
    int idBuilt = query.record().indexOf("computer_Built");
    int idStatus = query.record().indexOf("computer_Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qname = query.value(idName).toString();
            string name = qname.toLocal8Bit().constData();
            QString qyear = query.value(idYear).toString();
            string year = qyear.toLocal8Bit().constData();
            QString qtype = query.value(idType).toString();
            string type = qtype.toLocal8Bit().constData();
            QString qbuilt = query.value(idBuilt).toString();
            string built = qbuilt.toLocal8Bit().constData();
            Computer c(id, name, year, type, built);
            comp.push_back(c);
        }
    }
    return comp;
}

void data::getPACjoined(vector<PersonsAndComputers>& pAc) {
    QSqlQuery query("SELECT ID, computer_ID, person_ID, pac_status FROM personsandcomputers");

    int idID = query.record().indexOf("ID");
    int idComp_ID = query.record().indexOf("computer_ID");
    int idPers_ID = query.record().indexOf("person_ID");
    int idStatus = query.record().indexOf("pac_status");
    while (query.next())
    {
        if (query.value(idStatus) == 0) {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qcomp_id = query.value(idComp_ID).toString();
            string comp_id = qcomp_id.toLocal8Bit().constData();
            QString qpers_id = query.value(idPers_ID).toString();
            string pers_id = qpers_id.toLocal8Bit().constData();
            PersonsAndComputers pc(id, pers_id, comp_id);
            pAc.push_back(pc);
        }
    }
}

void data::writePAC(string& pers_id, string& comp_id)
{
    QSqlQuery query;
    QString qpers_id = QString::fromStdString(pers_id);
    QString qcomp_id = QString::fromStdString(comp_id);
    query.prepare("INSERT INTO personsandcomputers (person_id, computer_id) VALUES (:pers_id, :comp_id)");
        query.bindValue(":pers_id", qpers_id);
        query.bindValue(":comp_id", qcomp_id);
        query.exec();
}
<commit_msg>lagfæring á slaufum<commit_after>#include "data.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;
data::data()
{
}

bool data::openDatabase()
{
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName("vika2.sqlite");
    //m_db.setDatabaseName("..\\..\\sqldatabase\\vika2.sqlite");

    if (!m_db.open())
    {
       return false;
    }
    else
    {
       return true;
    }
}

void data::read(vector<Person>& pers)
{
    QSqlQuery query("SELECT ID, Name, Sex, Birth, Death, Status FROM persons");
    int idID = query.record().indexOf("ID");
    int idName = query.record().indexOf("Name");
    int idSex = query.record().indexOf("Sex");
    int idBirth = query.record().indexOf("Birth");
    int idDeath = query.record().indexOf("Death");
    int idStatus = query.record().indexOf("Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
        QString qid = query.value(idID).toString();
        string id = qid.toLocal8Bit().constData();
        QString qname = query.value(idName).toString();
        string name = qname.toLocal8Bit().constData();
        QString qsex = query.value(idSex).toString();
        string sex = qsex.toLocal8Bit().constData();
        QString qbirth = query.value(idBirth).toString();
        string birth = qbirth.toLocal8Bit().constData();
        QString qdeath = query.value(idDeath).toString();
        string death = qdeath.toLocal8Bit().constData();
        Person p(id, name, sex, birth, death);
        pers.push_back(p);
        }
    }
}

void data::write(string& firstname, string& sex, string& birth, string& death)
{
    QSqlQuery query;
    QString qfirstname = QString::fromStdString(firstname);
    QString qsex = QString::fromStdString(sex);
    QString qbirth = QString::fromStdString(birth);

    QString qdeath= QString::fromStdString(death);
    query.prepare("INSERT INTO persons (Name, Sex, Birth, Death,Status)"
                   "VALUES (:name, :sex, :birth, :death, :status)");

    query.bindValue(":name", qfirstname);
    query.bindValue(":sex", qsex);
    query.bindValue(":birth", qbirth);
    query.bindValue(":death", qdeath);
    query.bindValue(":status",0);
    query.exec();
}

vector<Person> data::sortPersons(string& type)
{
    vector<Person> pers;
    QSqlQuery query;
    if (type == "-nameasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Name ASC");
    }
    else if (type == "-sexasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Sex ASC");
    }
    else if (type == "-birthasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Birth ASC");
    }
    else if (type == "-deathasc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Death ASC");
    }
    else if (type == "-namedesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Name DESC");
    }
    else if (type == "-sexdesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Sex DESC");
    }
    else if (type == "-birthdesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Birth DESC");
    }
    else if (type == "-deathdesc")
    {
        query.exec("SELECT ID, Name, Sex, Birth, Death, Status FROM persons ORDER BY Death DESC");
    }

    int idID = query.record().indexOf("ID");
    int idName = query.record().indexOf("Name");
    int idSex = query.record().indexOf("Sex");
    int idBirth = query.record().indexOf("Birth");
    int idDeath = query.record().indexOf("Death");
    int idStatus = query.record().indexOf("Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qname = query.value(idName).toString();
            string name = qname.toLocal8Bit().constData();
            QString qsex = query.value(idSex).toString();
            string sex = qsex.toLocal8Bit().constData();
            QString qbirth = query.value(idBirth).toString();
            string birth = qbirth.toLocal8Bit().constData();
            QString qdeath = query.value(idDeath).toString();
            string death = qdeath.toLocal8Bit().constData();
            Person p(id, name, sex, birth, death);
            pers.push_back(p);
        }
    }

    return pers;
}

void data::remove(string& ID, int& type)
{
    QSqlQuery query;
    QString qID = QString::fromStdString(ID);
    if (type == 0)
    {
        query.prepare("UPDATE persons SET status = 1 WHERE ID = :id");
        query.bindValue(":id", qID);
    }
    else if (type == 1)
    {
        query.prepare("UPDATE computer SET computer_status = 1 WHERE computer_ID = :id");
        query.bindValue(":id", qID);
    }

    query.exec();
}

void data::edit(string& ID, string& value, string& type)
{
    QSqlQuery query;
    QString qID = QString::fromStdString(ID);
    QString qvalue = QString::fromStdString(value);
    if (type == "-name")
    {
        query.prepare("Update persons SET name = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-sex")
    {
        query.prepare("Update persons SET sex = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-birth")
    {
        query.prepare("Update persons SET birth = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-death")
    {
        query.prepare("Update persons SET death = :value WHERE ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    query.exec();
}

void data::readComputer(vector<Computer>& comp)
{
    QSqlQuery query("SELECT computer_ID, computer_Name, computer_Year, "
                   "computer_Type, computer_Built, computer_Status FROM computer");

    int idID = query.record().indexOf("computer_ID");
    int idName = query.record().indexOf("computer_name");
    int idYear = query.record().indexOf("computer_Year");
    int idType = query.record().indexOf("computer_Type");
    int idBuilt = query.record().indexOf("computer_Built");
    int idStatus = query.record().indexOf("computer_Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qname = query.value(idName).toString();
            string name = qname.toLocal8Bit().constData();
            QString qyear = query.value(idYear).toString();
            string year = qyear.toLocal8Bit().constData();
            QString qtype = query.value(idType).toString();
            string type = qtype.toLocal8Bit().constData();
            QString qbuilt = query.value(idBuilt).toString();
            string built = qbuilt.toLocal8Bit().constData();
            Computer c(id, name, year, type, built);
            comp.push_back(c);
        }
    }
}

void data::writeComputer(string& name, string& year, string& type, string& built)
{
    QSqlQuery query;
    QString qname = QString::fromStdString(name);
    QString qyear = QString::fromStdString(year);
    QString qtype = QString::fromStdString(type);
    QString qbuilt = QString::fromStdString(built);
    query.prepare("INSERT INTO computer (computer_name, computer_year, computer_type, computer_built)"
                  "VALUES (:name, :year, :type, :built)");
        query.bindValue(":name", qname);
        query.bindValue(":year", qyear);
        query.bindValue(":type", qtype);
        query.bindValue(":built", qbuilt);
        query.exec();
}

void data::editComp(string& ID, string& value, string& type)
{
    QSqlQuery query;
    QString qID = QString::fromStdString(ID);
    QString qvalue = QString::fromStdString(value);
    if (type == "-name")
    {
        query.prepare("Update computer SET computer_name = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-year")
    {
        query.prepare("Update computer SET computer_year = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-type")
    {
        query.prepare("Update computer SET computer_type = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    else if (type == "-built")
    {
        query.prepare("Update computer SET computer_built = :value WHERE computer_ID = :id");
        query.bindValue(":id", qID);
        query.bindValue(":value", qvalue);
    }
    query.exec();
}

vector<Computer> data::sortComputer(string& type)
{
    vector<Computer> comp;
    QSqlQuery query;
    if (type == "-nameasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_name ASC");
    }
    else if (type == "-yearasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_year ASC");
    }
    else if (type == "-typeasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_type ASC");
    }
    else if (type == "-builtasc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_built ASC");
    }
    else if (type == "-namedesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_name DESC");
    }
    else if (type == "-yeardesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_year DESC");
    }
    else if (type == "-typedesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_type DESC");
    }
    else if (type == "-builtdesc")
    {
        query.exec("SELECT computer_ID, computer_Name, computer_Year, computer_Type, "
                        "computer_Built, computer_Status FROM computer ORDER BY computer_built DESC");
    }
    int idID = query.record().indexOf("computer_ID");
    int idName = query.record().indexOf("computer_name");
    int idYear = query.record().indexOf("computer_Year");
    int idType = query.record().indexOf("computer_Type");
    int idBuilt = query.record().indexOf("computer_Built");
    int idStatus = query.record().indexOf("computer_Status");
    while (query.next())
    {
        if (query.value(idStatus) == 0)
        {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qname = query.value(idName).toString();
            string name = qname.toLocal8Bit().constData();
            QString qyear = query.value(idYear).toString();
            string year = qyear.toLocal8Bit().constData();
            QString qtype = query.value(idType).toString();
            string type = qtype.toLocal8Bit().constData();
            QString qbuilt = query.value(idBuilt).toString();
            string built = qbuilt.toLocal8Bit().constData();
            Computer c(id, name, year, type, built);
            comp.push_back(c);
        }
    }
    return comp;
}

void data::getPACjoined(vector<PersonsAndComputers>& pAc)
{
    QSqlQuery query("SELECT ID, computer_ID, person_ID, pac_status FROM personsandcomputers");

    int idID = query.record().indexOf("ID");
    int idComp_ID = query.record().indexOf("computer_ID");
    int idPers_ID = query.record().indexOf("person_ID");
    int idStatus = query.record().indexOf("pac_status");
    while (query.next())
    {
        if (query.value(idStatus) == 0) {
            QString qid = query.value(idID).toString();
            string id = qid.toLocal8Bit().constData();
            QString qcomp_id = query.value(idComp_ID).toString();
            string comp_id = qcomp_id.toLocal8Bit().constData();
            QString qpers_id = query.value(idPers_ID).toString();
            string pers_id = qpers_id.toLocal8Bit().constData();
            PersonsAndComputers pc(id, pers_id, comp_id);
            pAc.push_back(pc);
        }
    }
}

void data::writePAC(string& pers_id, string& comp_id)
{
    QSqlQuery query;
    QString qpers_id = QString::fromStdString(pers_id);
    QString qcomp_id = QString::fromStdString(comp_id);
    query.prepare("INSERT INTO personsandcomputers (person_id, computer_id) VALUES (:pers_id, :comp_id)");
        query.bindValue(":pers_id", qpers_id);
        query.bindValue(":comp_id", qcomp_id);
        query.exec();
}
<|endoftext|>


<commit_before>/**
 * @file llnotificationofferhandler.cpp
 * @brief Provides set of utility methods for notifications processing.
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 *
 * Copyright (c) 2000-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "llnotificationhandler.h"
#include "llnotifications.h"
#include "llimview.h"
#include "llagent.h"
#include "llfloaterreg.h"
#include "llnearbychat.h"
#include "llimfloater.h"

using namespace LLNotificationsUI;

const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM(
				"ObjectGiveItem"), OBJECT_GIVE_ITEM_UNKNOWN_USER(
				"ObjectGiveItemUnknownUser"), PAYMENT_RECIVED("PaymentRecived"),
						ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
						USER_GIVE_ITEM("UserGiveItem"),
						INVENTORY_ACCEPTED("InventoryAccepted"),
						INVENTORY_DECLINED("InventoryDeclined"),
						OFFER_FRIENDSHIP("OfferFriendship"),
						FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
						FRIENDSHIP_OFFERED("FriendshipOffered"),
						FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"),
						FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
						FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
						SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
						TELEPORT_OFFERED("TeleportOffered");

// static
bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
{
	return GRANTED_MODIFY_RIGHTS == notification->getName()
			|| REVOKED_MODIFY_RIGHTS == notification->getName()
			|| PAYMENT_RECIVED == notification->getName()
			|| OFFER_FRIENDSHIP == notification->getName()
			|| FRIENDSHIP_OFFERED == notification->getName()
			|| FRIENDSHIP_ACCEPTED_BYME == notification->getName()
			|| FRIENDSHIP_DECLINED_BYME == notification->getName()
			|| SERVER_OBJECT_MESSAGE == notification->getName()
			|| INVENTORY_ACCEPTED == notification->getName()
			|| INVENTORY_DECLINED == notification->getName();
}

// static
bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
{
	return notification->getType() == "notifytip"
			&&  FRIEND_ONLINE != notification->getName()
			&& FRIEND_OFFLINE != notification->getName()
			&& INVENTORY_ACCEPTED != notification->getName()
			&& INVENTORY_DECLINED != notification->getName();
}

// static
bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
{
	return OFFER_FRIENDSHIP == notification->getName()
			|| FRIENDSHIP_ACCEPTED == notification->getName()
			|| USER_GIVE_ITEM == notification->getName()
			|| INVENTORY_ACCEPTED == notification->getName()
			|| INVENTORY_DECLINED == notification->getName();
}

// static
bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
{
	return OFFER_FRIENDSHIP == notification->getName()
					|| USER_GIVE_ITEM == notification->getName();
}

// static
bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
{
	return canLogToIM(notification) && canSpawnIMSession(notification);
}

// static
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
		const std::string& session_name, const std::string& from_name,
		const std::string& message, const LLUUID& session_owner_id,
		const LLUUID& from_id)
{
	LLUUID session_id = LLIMMgr::computeSessionID(session_type,
			session_owner_id);
	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
			session_id);
	if (session == NULL)
	{
		LLIMModel::instance().logToFile(session_name, from_name, from_id, message);
	}
	else
	{
		// store active session id
		const LLUUID & active_session_id =
				LLIMModel::instance().getActiveSessionID();

		// set searched session as active to avoid IM toast popup
		LLIMModel::instance().setActiveSessionID(session_id);

		LLIMModel::instance().addMessage(session_id, from_name, from_id,
				message);

		// restore active session id
		if (active_session_id.isNull())
		{
			LLIMModel::instance().resetActiveSessionID();
		}
		else
		{
			LLIMModel::instance().setActiveSessionID(active_session_id);
		}
	}
}

// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
{
	logToIMP2P(notification, false);
}

// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
{
	const std::string name = LLHandlerUtil::getSubstitutionName(notification);

	std::string session_name = notification->getPayload().has(
			"SESSION_NAME") ? notification->getPayload()["SESSION_NAME"].asString() : name;

	// don't create IM p2p session with objects, it's necessary condition to log
	if (notification->getName() != OBJECT_GIVE_ITEM && notification->getName()
			!= OBJECT_GIVE_ITEM_UNKNOWN_USER)
	{
		LLUUID from_id = notification->getPayload()["from_id"];

		//*HACK for ServerObjectMessage the sesson name is really weird, see EXT-4779
		if (SERVER_OBJECT_MESSAGE == notification->getName())
		{
			session_name = "chat";
		}

		//there still appears a log history file with weird name " .txt"
		if (" " == session_name || "{waiting}" == session_name || "{nobody}" == session_name)
		{
			llwarning("Weird session name (" + session_name + ") for notification " + notification->getName(), 666)
		}

		if(to_file_only)
		{
			logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(),
					LLUUID(), LLUUID());
		}
		else
		{
			logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(),
					from_id, from_id);
		}
	}
}

// static
void LLHandlerUtil::logGroupNoticeToIMGroup(
		const LLNotificationPtr& notification)
{

	const LLSD& payload = notification->getPayload();
	LLGroupData groupData;
	if (!gAgent.getGroupData(payload["group_id"].asUUID(), groupData))
	{
		llwarns
						<< "Group notice for unkown group: "
								<< payload["group_id"].asUUID() << llendl;
	}

	const std::string group_name = groupData.mName;
	const std::string sender_name = payload["sender_name"].asString();

	// we can't retrieve sender id from group notice system message, so try to lookup it from cache
	LLUUID sender_id;
	gCacheName->getUUID(sender_name, sender_id);

	logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"],
			payload["group_id"], sender_id);
}

// static
void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
{
	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
	if(nearby_chat)
	{
		LLChat chat_msg(notification->getMessage());
		chat_msg.mSourceType = type;
		chat_msg.mFromName = SYSTEM_FROM;
		nearby_chat->addMessage(chat_msg);
	}
}

// static
LLUUID LLHandlerUtil::spawnIMSession(const std::string& name, const LLUUID& from_id)
{
	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);

	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
			session_id);
	if (session == NULL)
	{
		session_id = LLIMMgr::instance().addSession(name, IM_NOTHING_SPECIAL, from_id);
	}

	return session_id;
}

// static
std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notification)
{
	return notification->getSubstitutions().has("NAME")
		? notification->getSubstitutions()["NAME"]
		: notification->getSubstitutions()["[NAME]"];
}

// static
void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
{
	const std::string name = LLHandlerUtil::getSubstitutionName(notification);
	LLUUID from_id = notification->getPayload()["from_id"];

	LLUUID session_id = spawnIMSession(name, from_id);
	// add offer to session
	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
			session_id);
	llassert_always(session != NULL);

	LLSD offer;
	offer["notification_id"] = notification->getID();
	offer["from_id"] = notification->getPayload()["from_id"];
	offer["from"] = name;
	offer["time"] = LLLogChat::timestamp(true);
	offer["index"] = (LLSD::Integer)session->mMsgs.size();
	session->mMsgs.push_front(offer);

	LLIMFloater::show(session_id);
}
<commit_msg>EXT-2891 "Group notices should be recorded into group IM history", corrected logging of stub group notices;<commit_after>/**
 * @file llnotificationofferhandler.cpp
 * @brief Provides set of utility methods for notifications processing.
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 *
 * Copyright (c) 2000-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "llnotificationhandler.h"
#include "llnotifications.h"
#include "llimview.h"
#include "llagent.h"
#include "llfloaterreg.h"
#include "llnearbychat.h"
#include "llimfloater.h"

using namespace LLNotificationsUI;

const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM(
				"ObjectGiveItem"), OBJECT_GIVE_ITEM_UNKNOWN_USER(
				"ObjectGiveItemUnknownUser"), PAYMENT_RECIVED("PaymentRecived"),
						ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
						USER_GIVE_ITEM("UserGiveItem"),
						INVENTORY_ACCEPTED("InventoryAccepted"),
						INVENTORY_DECLINED("InventoryDeclined"),
						OFFER_FRIENDSHIP("OfferFriendship"),
						FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
						FRIENDSHIP_OFFERED("FriendshipOffered"),
						FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"),
						FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
						FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
						SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
						TELEPORT_OFFERED("TeleportOffered");

// static
bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
{
	return GRANTED_MODIFY_RIGHTS == notification->getName()
			|| REVOKED_MODIFY_RIGHTS == notification->getName()
			|| PAYMENT_RECIVED == notification->getName()
			|| OFFER_FRIENDSHIP == notification->getName()
			|| FRIENDSHIP_OFFERED == notification->getName()
			|| FRIENDSHIP_ACCEPTED_BYME == notification->getName()
			|| FRIENDSHIP_DECLINED_BYME == notification->getName()
			|| SERVER_OBJECT_MESSAGE == notification->getName()
			|| INVENTORY_ACCEPTED == notification->getName()
			|| INVENTORY_DECLINED == notification->getName();
}

// static
bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
{
	return notification->getType() == "notifytip"
			&&  FRIEND_ONLINE != notification->getName()
			&& FRIEND_OFFLINE != notification->getName()
			&& INVENTORY_ACCEPTED != notification->getName()
			&& INVENTORY_DECLINED != notification->getName();
}

// static
bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
{
	return OFFER_FRIENDSHIP == notification->getName()
			|| FRIENDSHIP_ACCEPTED == notification->getName()
			|| USER_GIVE_ITEM == notification->getName()
			|| INVENTORY_ACCEPTED == notification->getName()
			|| INVENTORY_DECLINED == notification->getName();
}

// static
bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
{
	return OFFER_FRIENDSHIP == notification->getName()
					|| USER_GIVE_ITEM == notification->getName();
}

// static
bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
{
	return canLogToIM(notification) && canSpawnIMSession(notification);
}

// static
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
		const std::string& session_name, const std::string& from_name,
		const std::string& message, const LLUUID& session_owner_id,
		const LLUUID& from_id)
{
	LLUUID session_id = LLIMMgr::computeSessionID(session_type,
			session_owner_id);
	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
			session_id);
	if (session == NULL)
	{
		LLIMModel::instance().logToFile(session_name, from_name, from_id, message);
	}
	else
	{
		// store active session id
		const LLUUID & active_session_id =
				LLIMModel::instance().getActiveSessionID();

		// set searched session as active to avoid IM toast popup
		LLIMModel::instance().setActiveSessionID(session_id);

		LLIMModel::instance().addMessage(session_id, from_name, from_id,
				message);

		// restore active session id
		if (active_session_id.isNull())
		{
			LLIMModel::instance().resetActiveSessionID();
		}
		else
		{
			LLIMModel::instance().setActiveSessionID(active_session_id);
		}
	}
}

// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
{
	logToIMP2P(notification, false);
}

// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
{
	const std::string name = LLHandlerUtil::getSubstitutionName(notification);

	std::string session_name = notification->getPayload().has(
			"SESSION_NAME") ? notification->getPayload()["SESSION_NAME"].asString() : name;

	// don't create IM p2p session with objects, it's necessary condition to log
	if (notification->getName() != OBJECT_GIVE_ITEM && notification->getName()
			!= OBJECT_GIVE_ITEM_UNKNOWN_USER)
	{
		LLUUID from_id = notification->getPayload()["from_id"];

		//*HACK for ServerObjectMessage the sesson name is really weird, see EXT-4779
		if (SERVER_OBJECT_MESSAGE == notification->getName())
		{
			session_name = "chat";
		}

		//there still appears a log history file with weird name " .txt"
		if (" " == session_name || "{waiting}" == session_name || "{nobody}" == session_name)
		{
			llwarning("Weird session name (" + session_name + ") for notification " + notification->getName(), 666)
		}

		if(to_file_only)
		{
			logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(),
					LLUUID(), LLUUID());
		}
		else
		{
			logToIM(IM_NOTHING_SPECIAL, session_name, name, notification->getMessage(),
					from_id, from_id);
		}
	}
}

// static
void LLHandlerUtil::logGroupNoticeToIMGroup(
		const LLNotificationPtr& notification)
{

	const LLSD& payload = notification->getPayload();
	LLGroupData groupData;
	if (!gAgent.getGroupData(payload["group_id"].asUUID(), groupData))
	{
		llwarns
						<< "Group notice for unkown group: "
								<< payload["group_id"].asUUID() << llendl;
		return;
	}

	const std::string group_name = groupData.mName;
	const std::string sender_name = payload["sender_name"].asString();

	// we can't retrieve sender id from group notice system message, so try to lookup it from cache
	LLUUID sender_id;
	gCacheName->getUUID(sender_name, sender_id);

	logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"],
			payload["group_id"], sender_id);
}

// static
void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
{
	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
	if(nearby_chat)
	{
		LLChat chat_msg(notification->getMessage());
		chat_msg.mSourceType = type;
		chat_msg.mFromName = SYSTEM_FROM;
		nearby_chat->addMessage(chat_msg);
	}
}

// static
LLUUID LLHandlerUtil::spawnIMSession(const std::string& name, const LLUUID& from_id)
{
	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);

	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
			session_id);
	if (session == NULL)
	{
		session_id = LLIMMgr::instance().addSession(name, IM_NOTHING_SPECIAL, from_id);
	}

	return session_id;
}

// static
std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notification)
{
	return notification->getSubstitutions().has("NAME")
		? notification->getSubstitutions()["NAME"]
		: notification->getSubstitutions()["[NAME]"];
}

// static
void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
{
	const std::string name = LLHandlerUtil::getSubstitutionName(notification);
	LLUUID from_id = notification->getPayload()["from_id"];

	LLUUID session_id = spawnIMSession(name, from_id);
	// add offer to session
	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
			session_id);
	llassert_always(session != NULL);

	LLSD offer;
	offer["notification_id"] = notification->getID();
	offer["from_id"] = notification->getPayload()["from_id"];
	offer["from"] = name;
	offer["time"] = LLLogChat::timestamp(true);
	offer["index"] = (LLSD::Integer)session->mMsgs.size();
	session->mMsgs.push_front(offer);

	LLIMFloater::show(session_id);
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Plenluno All rights reserved.

#include <gtest/gtest.h>
#include <libj/console.h>
#include <libj/js_function.h>
#include <libj/status.h>
#include <libj/thread.h>

#include <stdlib.h>
#include <unistd.h>

namespace libj {

class GTestThreadFunc : LIBJ_JS_FUNCTION(GTestThreadFunc)
 public:
    GTestThreadFunc(UInt id) : id_(id) {}

    Value operator()(JsArray::Ptr args) {
        sleep(rand() % 2);
        console::log("run %d", id_);
        return Status::OK;
    }

 private:
    UInt id_;
};

TEST(GTestThread, TestCreate) {
    Thread::Ptr th = Thread::create(JsFunction::null());
    ASSERT_TRUE(!th);

    th = Thread::create(Function::Ptr(new GTestThreadFunc(0)));
    ASSERT_TRUE(!!th);
}

TEST(GTestThread, TestStart) {
    Thread::Ptr th = Thread::create(Function::Ptr(new GTestThreadFunc(9)));
    th->start();
}

TEST(GTestThread, TestStartAndJoin) {
    const Size n = 9;

    JsArray::Ptr threads = JsArray::create();
    for (Size i = 0; i < n; i++) {
        threads->add(Thread::create(Function::Ptr(new GTestThreadFunc(i))));
    }

    for (Size i = 0; i < n; i++) {
        threads->getPtr<Thread>(i)->start();
    }

    for (Size i = 0; i < n; i++) {
        threads->getPtr<Thread>(i)->join();
    }
}

}  // namespace libj
<commit_msg>fix a cpplint warning<commit_after>// Copyright (c) 2013 Plenluno All rights reserved.

#include <gtest/gtest.h>
#include <libj/console.h>
#include <libj/js_function.h>
#include <libj/status.h>
#include <libj/thread.h>

#include <unistd.h>

namespace libj {

class GTestThreadFunc : LIBJ_JS_FUNCTION(GTestThreadFunc)
 public:
    GTestThreadFunc(UInt id) : id_(id) {}

    Value operator()(JsArray::Ptr args) {
        sleep(id_ % 2);
        console::log("run %d", id_);
        return Status::OK;
    }

 private:
    UInt id_;
};

TEST(GTestThread, TestCreate) {
    Thread::Ptr th = Thread::create(JsFunction::null());
    ASSERT_TRUE(!th);

    th = Thread::create(Function::Ptr(new GTestThreadFunc(0)));
    ASSERT_TRUE(!!th);
}

TEST(GTestThread, TestStart) {
    Thread::Ptr th = Thread::create(Function::Ptr(new GTestThreadFunc(9)));
    th->start();
}

TEST(GTestThread, TestStartAndJoin) {
    const Size n = 9;

    JsArray::Ptr threads = JsArray::create();
    for (Size i = 0; i < n; i++) {
        threads->add(Thread::create(Function::Ptr(new GTestThreadFunc(i))));
    }

    for (Size i = 0; i < n; i++) {
        threads->getPtr<Thread>(i)->start();
    }

    for (Size i = 0; i < n; i++) {
        threads->getPtr<Thread>(i)->join();
    }
}

}  // namespace libj
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include "common/log.h"
#include "common/utils.h"

#include "encodeinput.h"
#include "encodeInputDecoder.h"

using namespace YamiMediaCodec;

#define MAX_WIDTH  8192
#define MAX_HEIGHT 4320
EncodeInput * EncodeInput::create(const char* inputFileName, uint32_t fourcc, int width, int height)
{
    EncodeInput *input = NULL;
    if (!inputFileName) {
#if ANDROID
        input = new EncodeInputSurface();
#else
        return NULL;
#endif
    }
    else {
#ifndef ANDROID // temp disable transcoding and camera support on android
        DecodeInput* decodeInput = DecodeInput::create(inputFileName);
        if (decodeInput) {
            input = new EncodeInputDecoder(decodeInput);
        }
        else if (!strncmp(inputFileName, "/dev/video", strlen("/dev/video"))) {
            input = new EncodeInputCamera;
        }
        else
#endif
        {
            input = new EncodeInputFile;
        }
    }

    if (!input)
        return NULL;

    if (!(input->init(inputFileName, fourcc, width, height))) {
        delete input;
        return NULL;
    }

    return input;
}

EncodeInputFile::EncodeInputFile()
    : m_fp(NULL)
    , m_buffer(NULL)
    , m_readToEOS(false)
{
}

bool EncodeInputFile::init(const char* inputFileName, uint32_t fourcc, int width, int height)
{
    if (!width || !height) {
        if (!guessResolution(inputFileName, width, height)) {
            fprintf(stderr, "failed to guess input width and height\n");
            return false;
        }
    }
    m_width = width;
    m_height = height;
    m_fourcc = fourcc;

    if ((m_width <= 0) ||(m_height <= 0) ||(m_width > MAX_WIDTH) || (m_height > MAX_HEIGHT)) {
        fprintf(stderr, "input width and height is invalid\n");
        return false;
    }

    if (!m_fourcc)
        m_fourcc = guessFourcc(inputFileName);

    if (!m_fourcc)
        m_fourcc = VA_FOURCC('I', '4', '2', '0');

    switch (m_fourcc) {
    case VA_FOURCC_NV12:
    case VA_FOURCC('I', '4', '2', '0'):
    case VA_FOURCC_YV12:
        m_frameSize = m_width * m_height * 3 / 2;
        break;
    case VA_FOURCC_P010:
        m_frameSize = m_width * m_height * 3;
        break;
    case VA_FOURCC_YUY2:
        m_frameSize = m_width * m_height * 2;
    break;
    default:
        ASSERT(0);
    break;
    }

    m_fp = fopen(inputFileName, "r");
    if (!m_fp) {
        fprintf(stderr, "fail to open input file: %s", inputFileName);
        return false;
    }

    m_buffer = static_cast<uint8_t*>(malloc(m_frameSize));
    return true;
}

bool EncodeInputFile::getOneFrameInput(VideoFrameRawData &inputBuffer)
{
    if (m_readToEOS)
        return false;

    uint8_t *buffer = m_buffer;
    if (inputBuffer.handle)
        buffer = reinterpret_cast<uint8_t*>(inputBuffer.handle);

    size_t ret = fread(buffer, sizeof(uint8_t), m_frameSize, m_fp);

    if (ret <= 0) {
        m_readToEOS = true;
        return false;
    }

    if (ret < m_frameSize) {
        fprintf (stderr, "data is not enough to read(read size: %zu, m_frameSize: %zu), maybe resolution is wrong\n", ret, m_frameSize);
        return false;
    }

    return fillFrameRawData(&inputBuffer, m_fourcc, m_width, m_height, buffer);
}

EncodeInputFile::~EncodeInputFile()
{
    if(m_fp)
        fclose(m_fp);

    if(m_buffer)
        free(m_buffer);
}

EncodeOutput::EncodeOutput():m_fp(NULL)
{
}

EncodeOutput::~EncodeOutput()
{
    if (m_fp)
        fclose(m_fp);
}

EncodeOutput* EncodeOutput::create(const char* outputFileName, int width,
    int height, int fps, const char* codecName)
{
    EncodeOutput* output = NULL;
    if (outputFileName == NULL)
        return NULL;
    const char* ext = strrchr(outputFileName, '.');
    std::string codec(""); // needed for strcasecmp to work
    if (!ext && !codecName)
        return NULL;
    ext++;

    if (codecName)
        codec.assign(codecName);

    if (!strcasecmp("AVC", codec.c_str()) || !strcasecmp(ext, "h264")
        || !strcasecmp(ext, "264") || !strcasecmp(ext, "jsv")
        || !strcasecmp(ext, "avc") || !strcasecmp(ext, "26l")
        || !strcasecmp(ext, "jvt")) {
        output = new EncodeOutputH264();
    }
    else if (!strcasecmp("VP8", codec.c_str())
             || (!strcasecmp("VP8", codec.c_str()) && !strcasecmp(ext, "ivf"))
             || !strcasecmp(ext, "vp8")) {
        output = new EncodeOutputVP8();
    }
    else if (!strcasecmp("VP9", codec.c_str())
             || (!strcasecmp("VP9", codec.c_str()) && !strcasecmp(ext, "ivf"))
             || !strcasecmp(ext, "vp9")) {
        output = new EncodeOutputVP9();
    }
    else if (!strcasecmp("JPEG", codec.c_str()) || !strcasecmp(ext, "jpg")
             || !strcasecmp(ext, "jpeg")) {
        output = new EncodeStreamOutputJpeg();
    }
    else if (!strcasecmp("HEVC", codec.c_str()) || !strcasecmp(ext, "h265")
             || !strcasecmp(ext, "265") || !strcasecmp(ext, "hevc")) {
        output = new EncodeOutputHEVC();
    }
    else
        return NULL;

    if (!output->init(outputFileName, width, height, fps)) {
        delete output;
        return NULL;
    }
    return output;
}

bool EncodeOutput::init(const char* outputFileName, int width, int height, int fps)
{
    m_fp = fopen(outputFileName, "w+");
    if (!m_fp) {
        fprintf(stderr, "fail to open output file: %s\n", outputFileName);
        return false;
    }
    return true;
}

bool EncodeOutput::write(void* data, int size)
{
    return fwrite(data, 1, size, m_fp) == (size_t)size;
}

const char* EncodeOutputH264::getMimeType()
{
    return YAMI_MIME_H264;
}

const char* EncodeStreamOutputJpeg::getMimeType()
{
    return "image/jpeg";
}

const char* EncodeOutputVP8::getMimeType()
{
    return YAMI_MIME_VP8;
}

const char* EncodeOutputVP9::getMimeType()
{
    return YAMI_MIME_VP9;
}

const char* EncodeOutputHEVC::getMimeType()
{
    return YAMI_MIME_HEVC;
}

void setUint32(uint8_t* header, uint32_t value)
{
    uint32_t* h = (uint32_t*)header;
    *h = value;
}

void setUint16(uint8_t* header, uint16_t value)
{
    uint16_t* h = (uint16_t*)header;
    *h = value;
}

void EncodeOutputVPX::getIVFFileHeader(uint8_t* header, int width, int height, int fps)
{
    setUint32(header, YAMI_FOURCC('D','K','I','F'));
    setUint16(header+4, 0);                     // version
    setUint16(header+6,  32);                   // headersize
    setUint32(header+8,  m_fourcc);             // fourcc
    setUint16(header+12, width);                // width
    setUint16(header+14, height);               // height
    setUint32(header + 16, fps); // rate
    setUint32(header+20, 1);                    // scale
    setUint32(header+24, m_frameCount);         // framecount
    setUint32(header+28, 0);                    // unused
}

bool EncodeOutputVPX::init(const char* outputFileName, int width, int height, int fps)
{
    if (!EncodeOutput::init(outputFileName, width, height))
        return false;
    uint8_t header[32];
    getIVFFileHeader(header, width, height, fps);
    return EncodeOutput::write(header, sizeof(header));
}

bool EncodeOutputVPX::write(void* data, int size)
{
    uint8_t header[12];
    memset(header, 0, sizeof(header));
    setUint32(header, size);
    if (!EncodeOutput::write(&header, sizeof(header)))
        return false;
    if (!EncodeOutput::write(data, size))
        return false;
    m_frameCount++;
    return true;
}
EncodeOutputVPX::EncodeOutputVPX()
    : m_frameCount(0)
    , m_fourcc(0)
{
}

EncodeOutputVPX::~EncodeOutputVPX()
{
    if (m_fp && !fseek(m_fp, 24,SEEK_SET)) {
        EncodeOutput::write(&m_frameCount, sizeof(m_frameCount));
    }
}

EncodeOutputVP8::EncodeOutputVP8()
{
    EncodeOutputVPX::setFourcc(YAMI_FOURCC('V','P','8','0'));
}

EncodeOutputVP9::EncodeOutputVP9()
{
    EncodeOutputVPX::setFourcc(YAMI_FOURCC('V','P','9','0'));
}

bool createOutputBuffer(VideoEncOutputBuffer* outputBuffer, int maxOutSize)
{
    uint8_t* tmp;
    tmp = static_cast<uint8_t*>(malloc(maxOutSize));
    if (!tmp)
        return false;
    outputBuffer->bufferSize = maxOutSize;
    outputBuffer->format = OUTPUT_EVERYTHING;
    if (outputBuffer->data)
        free(outputBuffer->data);
    outputBuffer->data = tmp;
    return true;
}

#ifdef __BUILD_GET_MV__
bool createMVBuffer(VideoEncMVBuffer* MVBuffer, int Size)
{
    MVBuffer->data = static_cast<uint8_t*>(malloc(Size));
    if (!MVBuffer->data)
        return false;
    MVBuffer->bufferSize = Size;
    return true;
}
#endif
<commit_msg>vpx_enc: set time stamp into every frame<commit_after>/*
 * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include "common/log.h"
#include "common/utils.h"

#include "encodeinput.h"
#include "encodeInputDecoder.h"

using namespace YamiMediaCodec;

#define MAX_WIDTH  8192
#define MAX_HEIGHT 4320
EncodeInput * EncodeInput::create(const char* inputFileName, uint32_t fourcc, int width, int height)
{
    EncodeInput *input = NULL;
    if (!inputFileName) {
#if ANDROID
        input = new EncodeInputSurface();
#else
        return NULL;
#endif
    }
    else {
#ifndef ANDROID // temp disable transcoding and camera support on android
        DecodeInput* decodeInput = DecodeInput::create(inputFileName);
        if (decodeInput) {
            input = new EncodeInputDecoder(decodeInput);
        }
        else if (!strncmp(inputFileName, "/dev/video", strlen("/dev/video"))) {
            input = new EncodeInputCamera;
        }
        else
#endif
        {
            input = new EncodeInputFile;
        }
    }

    if (!input)
        return NULL;

    if (!(input->init(inputFileName, fourcc, width, height))) {
        delete input;
        return NULL;
    }

    return input;
}

EncodeInputFile::EncodeInputFile()
    : m_fp(NULL)
    , m_buffer(NULL)
    , m_readToEOS(false)
{
}

bool EncodeInputFile::init(const char* inputFileName, uint32_t fourcc, int width, int height)
{
    if (!width || !height) {
        if (!guessResolution(inputFileName, width, height)) {
            fprintf(stderr, "failed to guess input width and height\n");
            return false;
        }
    }
    m_width = width;
    m_height = height;
    m_fourcc = fourcc;

    if ((m_width <= 0) ||(m_height <= 0) ||(m_width > MAX_WIDTH) || (m_height > MAX_HEIGHT)) {
        fprintf(stderr, "input width and height is invalid\n");
        return false;
    }

    if (!m_fourcc)
        m_fourcc = guessFourcc(inputFileName);

    if (!m_fourcc)
        m_fourcc = VA_FOURCC('I', '4', '2', '0');

    switch (m_fourcc) {
    case VA_FOURCC_NV12:
    case VA_FOURCC('I', '4', '2', '0'):
    case VA_FOURCC_YV12:
        m_frameSize = m_width * m_height * 3 / 2;
        break;
    case VA_FOURCC_P010:
        m_frameSize = m_width * m_height * 3;
        break;
    case VA_FOURCC_YUY2:
        m_frameSize = m_width * m_height * 2;
    break;
    default:
        ASSERT(0);
    break;
    }

    m_fp = fopen(inputFileName, "r");
    if (!m_fp) {
        fprintf(stderr, "fail to open input file: %s", inputFileName);
        return false;
    }

    m_buffer = static_cast<uint8_t*>(malloc(m_frameSize));
    return true;
}

bool EncodeInputFile::getOneFrameInput(VideoFrameRawData &inputBuffer)
{
    if (m_readToEOS)
        return false;

    uint8_t *buffer = m_buffer;
    if (inputBuffer.handle)
        buffer = reinterpret_cast<uint8_t*>(inputBuffer.handle);

    size_t ret = fread(buffer, sizeof(uint8_t), m_frameSize, m_fp);

    if (ret <= 0) {
        m_readToEOS = true;
        return false;
    }

    if (ret < m_frameSize) {
        fprintf (stderr, "data is not enough to read(read size: %zu, m_frameSize: %zu), maybe resolution is wrong\n", ret, m_frameSize);
        return false;
    }

    return fillFrameRawData(&inputBuffer, m_fourcc, m_width, m_height, buffer);
}

EncodeInputFile::~EncodeInputFile()
{
    if(m_fp)
        fclose(m_fp);

    if(m_buffer)
        free(m_buffer);
}

EncodeOutput::EncodeOutput():m_fp(NULL)
{
}

EncodeOutput::~EncodeOutput()
{
    if (m_fp)
        fclose(m_fp);
}

EncodeOutput* EncodeOutput::create(const char* outputFileName, int width,
    int height, int fps, const char* codecName)
{
    EncodeOutput* output = NULL;
    if (outputFileName == NULL)
        return NULL;
    const char* ext = strrchr(outputFileName, '.');
    std::string codec(""); // needed for strcasecmp to work
    if (!ext && !codecName)
        return NULL;
    ext++;

    if (codecName)
        codec.assign(codecName);

    if (!strcasecmp("AVC", codec.c_str()) || !strcasecmp(ext, "h264")
        || !strcasecmp(ext, "264") || !strcasecmp(ext, "jsv")
        || !strcasecmp(ext, "avc") || !strcasecmp(ext, "26l")
        || !strcasecmp(ext, "jvt")) {
        output = new EncodeOutputH264();
    }
    else if (!strcasecmp("VP8", codec.c_str())
             || (!strcasecmp("VP8", codec.c_str()) && !strcasecmp(ext, "ivf"))
             || !strcasecmp(ext, "vp8")) {
        output = new EncodeOutputVP8();
    }
    else if (!strcasecmp("VP9", codec.c_str())
             || (!strcasecmp("VP9", codec.c_str()) && !strcasecmp(ext, "ivf"))
             || !strcasecmp(ext, "vp9")) {
        output = new EncodeOutputVP9();
    }
    else if (!strcasecmp("JPEG", codec.c_str()) || !strcasecmp(ext, "jpg")
             || !strcasecmp(ext, "jpeg")) {
        output = new EncodeStreamOutputJpeg();
    }
    else if (!strcasecmp("HEVC", codec.c_str()) || !strcasecmp(ext, "h265")
             || !strcasecmp(ext, "265") || !strcasecmp(ext, "hevc")) {
        output = new EncodeOutputHEVC();
    }
    else
        return NULL;

    if (!output->init(outputFileName, width, height, fps)) {
        delete output;
        return NULL;
    }
    return output;
}

bool EncodeOutput::init(const char* outputFileName, int width, int height, int fps)
{
    m_fp = fopen(outputFileName, "w+");
    if (!m_fp) {
        fprintf(stderr, "fail to open output file: %s\n", outputFileName);
        return false;
    }
    return true;
}

bool EncodeOutput::write(void* data, int size)
{
    return fwrite(data, 1, size, m_fp) == (size_t)size;
}

const char* EncodeOutputH264::getMimeType()
{
    return YAMI_MIME_H264;
}

const char* EncodeStreamOutputJpeg::getMimeType()
{
    return "image/jpeg";
}

const char* EncodeOutputVP8::getMimeType()
{
    return YAMI_MIME_VP8;
}

const char* EncodeOutputVP9::getMimeType()
{
    return YAMI_MIME_VP9;
}

const char* EncodeOutputHEVC::getMimeType()
{
    return YAMI_MIME_HEVC;
}

void setUint64(uint8_t* header, uint64_t value)
{
    uint64_t* h = (uint64_t*)header;
    *h = value;
}

void setUint32(uint8_t* header, uint32_t value)
{
    uint32_t* h = (uint32_t*)header;
    *h = value;
}

void setUint16(uint8_t* header, uint16_t value)
{
    uint16_t* h = (uint16_t*)header;
    *h = value;
}

void EncodeOutputVPX::getIVFFileHeader(uint8_t* header, int width, int height, int fps)
{
    setUint32(header, YAMI_FOURCC('D','K','I','F'));
    setUint16(header+4, 0);                     // version
    setUint16(header+6,  32);                   // headersize
    setUint32(header+8,  m_fourcc);             // fourcc
    setUint16(header+12, width);                // width
    setUint16(header+14, height);               // height
    setUint32(header + 16, fps); // rate
    setUint32(header+20, 1);                    // scale
    setUint32(header+24, m_frameCount);         // framecount
    setUint32(header+28, 0);                    // unused
}

bool EncodeOutputVPX::init(const char* outputFileName, int width, int height, int fps)
{
    if (!EncodeOutput::init(outputFileName, width, height))
        return false;
    uint8_t header[32];
    getIVFFileHeader(header, width, height, fps);
    return EncodeOutput::write(header, sizeof(header));
}

bool EncodeOutputVPX::write(void* data, int size)
{
    uint8_t header[12];
    memset(header, 0, sizeof(header));
    setUint32(header, size);
    setUint64(&header[4], m_frameCount);
    if (!EncodeOutput::write(&header, sizeof(header)))
        return false;
    if (!EncodeOutput::write(data, size))
        return false;
    m_frameCount++;
    return true;
}
EncodeOutputVPX::EncodeOutputVPX()
    : m_frameCount(0)
    , m_fourcc(0)
{
}

EncodeOutputVPX::~EncodeOutputVPX()
{
    if (m_fp && !fseek(m_fp, 24,SEEK_SET)) {
        EncodeOutput::write(&m_frameCount, sizeof(m_frameCount));
    }
}

EncodeOutputVP8::EncodeOutputVP8()
{
    EncodeOutputVPX::setFourcc(YAMI_FOURCC('V','P','8','0'));
}

EncodeOutputVP9::EncodeOutputVP9()
{
    EncodeOutputVPX::setFourcc(YAMI_FOURCC('V','P','9','0'));
}

bool createOutputBuffer(VideoEncOutputBuffer* outputBuffer, int maxOutSize)
{
    uint8_t* tmp;
    tmp = static_cast<uint8_t*>(malloc(maxOutSize));
    if (!tmp)
        return false;
    outputBuffer->bufferSize = maxOutSize;
    outputBuffer->format = OUTPUT_EVERYTHING;
    if (outputBuffer->data)
        free(outputBuffer->data);
    outputBuffer->data = tmp;
    return true;
}

#ifdef __BUILD_GET_MV__
bool createMVBuffer(VideoEncMVBuffer* MVBuffer, int Size)
{
    MVBuffer->data = static_cast<uint8_t*>(malloc(Size));
    if (!MVBuffer->data)
        return false;
    MVBuffer->bufferSize = Size;
    return true;
}
#endif
<|endoftext|>


<commit_before>// Chemfiles, a modern library for chemistry file reading and writing
// Copyright (C) Guillaume Fraux and contributors -- BSD license

#include <fstream>
#include "catch.hpp"
#include "helpers.hpp"
#include "chemfiles.hpp"
using namespace chemfiles;

template <typename T>
static bool contains(const std::vector<T> haystack, const T& needle) {
    return std::find(haystack.begin(), haystack.end(), needle) != haystack.end();
}

TEST_CASE("Read files in PDB format"){
    SECTION("Read next step") {
        Trajectory file("data/pdb/water.pdb");
        Frame frame = file.read();

        CHECK(frame.natoms() == 297);
        auto positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.417, 8.303, 11.737), 1e-3));
        CHECK(approx_eq(positions[296], Vector3D(6.664, 11.6148, 12.961), 1e-3));

        auto cell = frame.cell();
        CHECK(cell.shape() == UnitCell::ORTHORHOMBIC);
        CHECK(fabs(cell.a() - 15.0) < 1e-5);

        file.read(); // Skip a frame
        frame = file.read();

        CHECK(frame.natoms() == 297);
        positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.299, 8.310, 11.721), 1e-4));
        CHECK(approx_eq(positions[296], Vector3D(6.798, 11.509, 12.704), 1e-4));
    }

    SECTION("Read a specific step"){
        Trajectory file("data/pdb/water.pdb");

        auto frame = file.read_step(2);
        CHECK(frame.natoms() == 297);
        auto positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.299, 8.310, 11.721), 1e-4));
        CHECK(approx_eq(positions[296], Vector3D(6.798, 11.509, 12.704), 1e-4));

        frame = file.read_step(0);
        CHECK(frame.natoms() == 297);
        positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.417, 8.303, 11.737), 1e-3));
        CHECK(approx_eq(positions[296], Vector3D(6.664, 11.6148, 12.961), 1e-3));

        auto cell = frame.cell();
        CHECK(cell.shape() == UnitCell::ORTHORHOMBIC);
        CHECK(fabs(cell.a() - 15.0) < 1e-5);
    }

    SECTION("Read bonds") {
        Trajectory file("data/pdb/MOF-5.pdb");
        Frame frame = file.read();

        auto topology = frame.topology();

        CHECK(topology.natoms() == 65);

        CHECK(topology[0].type() == "Zn");
        CHECK(topology[1].type() == "O");

        CHECK(topology[0].name() == "ZN");
        CHECK(topology[1].name() == "O");

        CHECK(topology.bonds().size() == 68);

        CHECK(contains(topology.bonds(), Bond(9, 38)));
        CHECK(contains(topology.bonds(), Bond(58, 62)));
        CHECK(contains(topology.bonds(), Bond(37, 24)));
        CHECK(contains(topology.bonds(), Bond(27, 31)));

        CHECK(contains(topology.angles(), Angle(20, 21, 23)));
        CHECK(contains(topology.angles(), Angle(9, 38, 44)));

        CHECK(contains(topology.dihedrals(), Dihedral(64, 62, 58, 53)));
        CHECK(contains(topology.dihedrals(), Dihedral(22, 21, 23, 33)));
    }

    SECTION("Support short records") {
        Trajectory file("data/pdb/cryst1.pdb");
        Frame frame = file.read();
    }

    SECTION("Read residue information") {
        Trajectory file("data/pdb/water.pdb");
        Frame frame = file.read();

        CHECK(frame.topology().residues().size() == 99);

        REQUIRE(frame.topology().residue(1));
        auto residue = (*frame.topology().residue(1));
        CHECK(residue.size() == 3);
        CHECK(residue.contains(0));
        CHECK(residue.contains(1));
        CHECK(residue.contains(2));

        file = Trajectory("data/pdb/MOF-5.pdb");
        frame = file.read();

        CHECK(frame.topology().residues().size() == 1);
        residue = frame.topology().residues()[0];
        CHECK(residue.size() == frame.natoms());
        CHECK(residue.name() == "LIG");
    }

    SECTION("Read ATOM/HETATM information") {
      Trajectory file("data/pdb/hemo.pdb");
      Frame frame = file.read();

      for (size_t i = 0; i < 73; i++)
        CHECK(frame.topology()[i].get("is_hetatm")->as_bool());
      for (size_t i = 73; i < 522; i++)
        CHECK(frame.topology()[i].get("is_hetatm")->as_bool() == false);

    }
}

TEST_CASE("Write files in PDB format") {
    auto tmpfile = NamedTempPath(".pdb");
    const auto EXPECTED_CONTENT =
    "CRYST1   22.000   22.000   22.000  90.00  90.00  90.00 P 1           1\n"
    "ATOM      1 A    XXX X   1       1.000   2.000   3.000  1.00  0.00           A\n"
    "HETATM    2 B    XXX X   2       1.000   2.000   3.000  1.00  0.00           B\n"
    "ATOM      3 C    XXX X   3       1.000   2.000   3.000  1.00  0.00           C\n"
    "HETATM    4 D    XXX X   4       1.000   2.000   3.000  1.00  0.00           D\n"
    "CONECT    1    2\n"
    "CONECT    2    1\n"
    "END\n"
    "CRYST1   22.000   22.000   22.000  90.00  90.00  90.00 P 1           1\n"
    "ATOM      1 A    XXX X   4       4.000   5.000   6.000  1.00  0.00           A\n"
    "HETATM    2 B    foo X   3       4.000   5.000   6.000  1.00  0.00           B\n"
    "ATOM      3 C    foo X   3       4.000   5.000   6.000  1.00  0.00           C\n"
    "HETATM    4 D    bar X  -1       4.000   5.000   6.000  1.00  0.00           D\n"
    "HETATM    5 E    XXX X   5       4.000   5.000   6.000  1.00  0.00           E\n"
    "HETATM    6 F    XXX X   6       4.000   5.000   6.000  1.00  0.00           F\n"
    "HETATM    7 G    XXX X   7       4.000   5.000   6.000  1.00  0.00           G\n"

    "CONECT    1    2    7\n"
    "CONECT    2    1    7\n"
    "CONECT    3    7\n"
    "CONECT    4    7\n"
    "CONECT    5    6    7\n"
    "CONECT    6    5    7\n"
    "CONECT    7    1    2    3    4\n"
    "CONECT    7    5    6\n"
    "END\n";

    Topology topology;
    topology.add_atom(Atom("A"));
    topology.add_atom(Atom("B"));
    topology.add_atom(Atom("C"));
    topology.add_atom(Atom("D"));
    topology.add_bond(0, 1);
    topology[0].set("is_hetatm", false);
    topology[1].set("is_hetatm", true);
    topology[2].set("is_hetatm", false);
    topology[3].set("is_hetatm", true);

    Frame frame(topology);
    frame.set_cell(UnitCell(22));

    auto positions = frame.positions();
    for(size_t i=0; i<4; i++) {
        positions[i] = Vector3D(1, 2, 3);
    }

    {
        auto file = Trajectory(tmpfile, 'w');
        file.write(frame);
    }

    frame.resize(7);
    positions = frame.positions();
    for(size_t i=0; i<7; i++)
        positions[i] = Vector3D(4, 5, 6);

    topology.add_atom(Atom("E"));
    topology.add_atom(Atom("F"));
    topology.add_atom(Atom("G"));
    topology.add_bond(4, 5);
    topology.add_bond(0, 6);
    topology.add_bond(1, 6);
    topology.add_bond(2, 6);
    topology.add_bond(3, 6);
    topology.add_bond(4, 6);
    topology.add_bond(5, 6);

    Residue residue("foo", 3);
    residue.add_atom(1);
    residue.add_atom(2);
    topology.add_residue(residue);

    residue = Residue("barbar"); // This will be truncated in output
    residue.add_atom(3);
    topology.add_residue(residue);

    frame.set_topology(topology);

    {
        auto file = Trajectory(tmpfile, 'a');
        file.write(frame);
    }

    std::ifstream checking(tmpfile);
    std::string content((std::istreambuf_iterator<char>(checking)),
                         std::istreambuf_iterator<char>());
    CHECK(content == EXPECTED_CONTENT);
}

TEST_CASE("PDB files with big values") {
    auto tmpfile = NamedTempPath(".pdb");
    auto trajectory = Trajectory(tmpfile, 'w');

    auto frame = Frame(1);
    frame.set_cell(UnitCell(1234567890));
    CHECK_THROWS_AS(trajectory.write(frame), FormatError);

    frame.set_cell(UnitCell(12));
    frame.positions()[0] = Vector3D(123456789, 2, 3);
    CHECK_THROWS_AS(trajectory.write(frame), FormatError);
}
<commit_msg>Added for-loop brackets in pdb.cpp test.<commit_after>// Chemfiles, a modern library for chemistry file reading and writing
// Copyright (C) Guillaume Fraux and contributors -- BSD license

#include <fstream>
#include "catch.hpp"
#include "helpers.hpp"
#include "chemfiles.hpp"
using namespace chemfiles;

template <typename T>
static bool contains(const std::vector<T> haystack, const T& needle) {
    return std::find(haystack.begin(), haystack.end(), needle) != haystack.end();
}

TEST_CASE("Read files in PDB format"){
    SECTION("Read next step") {
        Trajectory file("data/pdb/water.pdb");
        Frame frame = file.read();

        CHECK(frame.natoms() == 297);
        auto positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.417, 8.303, 11.737), 1e-3));
        CHECK(approx_eq(positions[296], Vector3D(6.664, 11.6148, 12.961), 1e-3));

        auto cell = frame.cell();
        CHECK(cell.shape() == UnitCell::ORTHORHOMBIC);
        CHECK(fabs(cell.a() - 15.0) < 1e-5);

        file.read(); // Skip a frame
        frame = file.read();

        CHECK(frame.natoms() == 297);
        positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.299, 8.310, 11.721), 1e-4));
        CHECK(approx_eq(positions[296], Vector3D(6.798, 11.509, 12.704), 1e-4));
    }

    SECTION("Read a specific step"){
        Trajectory file("data/pdb/water.pdb");

        auto frame = file.read_step(2);
        CHECK(frame.natoms() == 297);
        auto positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.299, 8.310, 11.721), 1e-4));
        CHECK(approx_eq(positions[296], Vector3D(6.798, 11.509, 12.704), 1e-4));

        frame = file.read_step(0);
        CHECK(frame.natoms() == 297);
        positions = frame.positions();
        CHECK(approx_eq(positions[0], Vector3D(0.417, 8.303, 11.737), 1e-3));
        CHECK(approx_eq(positions[296], Vector3D(6.664, 11.6148, 12.961), 1e-3));

        auto cell = frame.cell();
        CHECK(cell.shape() == UnitCell::ORTHORHOMBIC);
        CHECK(fabs(cell.a() - 15.0) < 1e-5);
    }

    SECTION("Read bonds") {
        Trajectory file("data/pdb/MOF-5.pdb");
        Frame frame = file.read();

        auto topology = frame.topology();

        CHECK(topology.natoms() == 65);

        CHECK(topology[0].type() == "Zn");
        CHECK(topology[1].type() == "O");

        CHECK(topology[0].name() == "ZN");
        CHECK(topology[1].name() == "O");

        CHECK(topology.bonds().size() == 68);

        CHECK(contains(topology.bonds(), Bond(9, 38)));
        CHECK(contains(topology.bonds(), Bond(58, 62)));
        CHECK(contains(topology.bonds(), Bond(37, 24)));
        CHECK(contains(topology.bonds(), Bond(27, 31)));

        CHECK(contains(topology.angles(), Angle(20, 21, 23)));
        CHECK(contains(topology.angles(), Angle(9, 38, 44)));

        CHECK(contains(topology.dihedrals(), Dihedral(64, 62, 58, 53)));
        CHECK(contains(topology.dihedrals(), Dihedral(22, 21, 23, 33)));
    }

    SECTION("Support short records") {
        Trajectory file("data/pdb/cryst1.pdb");
        Frame frame = file.read();
    }

    SECTION("Read residue information") {
        Trajectory file("data/pdb/water.pdb");
        Frame frame = file.read();

        CHECK(frame.topology().residues().size() == 99);

        REQUIRE(frame.topology().residue(1));
        auto residue = (*frame.topology().residue(1));
        CHECK(residue.size() == 3);
        CHECK(residue.contains(0));
        CHECK(residue.contains(1));
        CHECK(residue.contains(2));

        file = Trajectory("data/pdb/MOF-5.pdb");
        frame = file.read();

        CHECK(frame.topology().residues().size() == 1);
        residue = frame.topology().residues()[0];
        CHECK(residue.size() == frame.natoms());
        CHECK(residue.name() == "LIG");
    }

    SECTION("Read ATOM/HETATM information") {
      Trajectory file("data/pdb/hemo.pdb");
      Frame frame = file.read();

      for (size_t i = 0; i < 73; i++) {
        CHECK(frame.topology()[i].get("is_hetatm")->as_bool());
      }
      for (size_t i = 73; i < 522; i++) {
        CHECK(frame.topology()[i].get("is_hetatm")->as_bool() == false);
      }

    }
}

TEST_CASE("Write files in PDB format") {
    auto tmpfile = NamedTempPath(".pdb");
    const auto EXPECTED_CONTENT =
    "CRYST1   22.000   22.000   22.000  90.00  90.00  90.00 P 1           1\n"
    "ATOM      1 A    XXX X   1       1.000   2.000   3.000  1.00  0.00           A\n"
    "HETATM    2 B    XXX X   2       1.000   2.000   3.000  1.00  0.00           B\n"
    "ATOM      3 C    XXX X   3       1.000   2.000   3.000  1.00  0.00           C\n"
    "HETATM    4 D    XXX X   4       1.000   2.000   3.000  1.00  0.00           D\n"
    "CONECT    1    2\n"
    "CONECT    2    1\n"
    "END\n"
    "CRYST1   22.000   22.000   22.000  90.00  90.00  90.00 P 1           1\n"
    "ATOM      1 A    XXX X   4       4.000   5.000   6.000  1.00  0.00           A\n"
    "HETATM    2 B    foo X   3       4.000   5.000   6.000  1.00  0.00           B\n"
    "ATOM      3 C    foo X   3       4.000   5.000   6.000  1.00  0.00           C\n"
    "HETATM    4 D    bar X  -1       4.000   5.000   6.000  1.00  0.00           D\n"
    "HETATM    5 E    XXX X   5       4.000   5.000   6.000  1.00  0.00           E\n"
    "HETATM    6 F    XXX X   6       4.000   5.000   6.000  1.00  0.00           F\n"
    "HETATM    7 G    XXX X   7       4.000   5.000   6.000  1.00  0.00           G\n"

    "CONECT    1    2    7\n"
    "CONECT    2    1    7\n"
    "CONECT    3    7\n"
    "CONECT    4    7\n"
    "CONECT    5    6    7\n"
    "CONECT    6    5    7\n"
    "CONECT    7    1    2    3    4\n"
    "CONECT    7    5    6\n"
    "END\n";

    Topology topology;
    topology.add_atom(Atom("A"));
    topology.add_atom(Atom("B"));
    topology.add_atom(Atom("C"));
    topology.add_atom(Atom("D"));
    topology.add_bond(0, 1);
    topology[0].set("is_hetatm", false);
    topology[1].set("is_hetatm", true);
    topology[2].set("is_hetatm", false);
    topology[3].set("is_hetatm", true);

    Frame frame(topology);
    frame.set_cell(UnitCell(22));

    auto positions = frame.positions();
    for(size_t i=0; i<4; i++) {
        positions[i] = Vector3D(1, 2, 3);
    }

    {
        auto file = Trajectory(tmpfile, 'w');
        file.write(frame);
    }

    frame.resize(7);
    positions = frame.positions();
    for(size_t i=0; i<7; i++)
        positions[i] = Vector3D(4, 5, 6);

    topology.add_atom(Atom("E"));
    topology.add_atom(Atom("F"));
    topology.add_atom(Atom("G"));
    topology.add_bond(4, 5);
    topology.add_bond(0, 6);
    topology.add_bond(1, 6);
    topology.add_bond(2, 6);
    topology.add_bond(3, 6);
    topology.add_bond(4, 6);
    topology.add_bond(5, 6);

    Residue residue("foo", 3);
    residue.add_atom(1);
    residue.add_atom(2);
    topology.add_residue(residue);

    residue = Residue("barbar"); // This will be truncated in output
    residue.add_atom(3);
    topology.add_residue(residue);

    frame.set_topology(topology);

    {
        auto file = Trajectory(tmpfile, 'a');
        file.write(frame);
    }

    std::ifstream checking(tmpfile);
    std::string content((std::istreambuf_iterator<char>(checking)),
                         std::istreambuf_iterator<char>());
    CHECK(content == EXPECTED_CONTENT);
}

TEST_CASE("PDB files with big values") {
    auto tmpfile = NamedTempPath(".pdb");
    auto trajectory = Trajectory(tmpfile, 'w');

    auto frame = Frame(1);
    frame.set_cell(UnitCell(1234567890));
    CHECK_THROWS_AS(trajectory.write(frame), FormatError);

    frame.set_cell(UnitCell(12));
    frame.positions()[0] = Vector3D(123456789, 2, 3);
    CHECK_THROWS_AS(trajectory.write(frame), FormatError);
}
<|endoftext|>


<commit_before>/*
    This file is part of KAddressBook.
    Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>

    This program 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.

    This program 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlayout.h>
#include <qpushbutton.h>
#include <qtimer.h>

#include <kabc/resource.h>
#include <kdialog.h>
#include <kinputdialog.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kresources/configdialog.h>

#include "core.h"

#include "resourceselection.h"

class AddressBookWrapper : public KABC::AddressBook
{
  public:
    AddressBookWrapper( KABC::AddressBook* );

    KRES::Manager<KABC::Resource>* getResourceManager()
    {
      return resourceManager();
    }
};

class ResourceItem : public QCheckListItem
{
  public:
    ResourceItem( KListView *parent, KABC::Resource *resource )
      : QCheckListItem( parent, "", CheckBox ),
        mResource( resource ), mChecked( false )
    {
      setOn( resource->isActive() );
      mChecked = resource->isActive();
    }

    virtual QString text( int column ) const
    {
      if ( column == 0 )
        return mResource->resourceName();
      else
        return QString::null;
    }

    void setChecked( bool state )
    {
      mChecked = state;
    }

    bool checked() const { return mChecked; }
    KABC::Resource *resource() const { return mResource; }

  private:
    KABC::Resource *mResource;
    bool mChecked;
};

ResourceSelection::ResourceSelection( KAB::Core *core, QWidget *parent, const char *name )
  : KAB::ExtensionWidget( core, parent, name ), mManager( 0 )
{
  initGUI();

  AddressBookWrapper *wrapper = static_cast<AddressBookWrapper*>( core->addressBook() );
  mManager = wrapper->getResourceManager();

  connect( mAddButton, SIGNAL( clicked() ), SLOT( add() ) );
  connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) );
  connect( mRemoveButton, SIGNAL( clicked() ), SLOT( remove() ) );

  connect( mView, SIGNAL( clicked( QListViewItem* ) ),
           SLOT( currentChanged( QListViewItem* ) ) );

  QTimer::singleShot( 0, this, SLOT( updateView() ) );
}

ResourceSelection::~ResourceSelection()
{
}

QString ResourceSelection::title() const
{
  return i18n( "Address Books" );
}

QString ResourceSelection::identifier() const
{
  return "resourceselection";
}

void ResourceSelection::add()
{
  QStringList types = mManager->resourceTypeNames();
  QStringList descs = mManager->resourceTypeDescriptions();

  bool ok = false;
  QString desc = KInputDialog::getItem( i18n( "Add Address Book" ),
                                        i18n( "Please select type of the new address book:" ),
                                        descs, 0, false, &ok, this );
  if ( !ok )
    return;

  QString type = types[ descs.findIndex( desc ) ];

  // Create new resource
  KABC::Resource *resource = mManager->createResource( type );
  if( !resource ) {
    KMessageBox::error( this, i18n("<qt>Unable to create an address book of type %1.</qt>")
                              .arg( type ) );
    return;
  }

  resource->setResourceName( i18n( "%1 address book" ).arg( type ) );

  KRES::ConfigDialog dlg( this, QString( "contact" ), resource );

  if ( dlg.exec() ) {
    core()->addressBook()->addResource( resource );
    resource->asyncLoad();

    mLastResource = resource->identifier();
    updateView();
  } else {
    delete resource;
    resource = 0;
  }
}

void ResourceSelection::edit()
{
  ResourceItem *item = selectedItem();
  if ( !item )
    return;

  KRES::ConfigDialog dlg( this, QString( "contact" ), item->resource() );

  if ( dlg.exec() ) {
    mManager->change( item->resource() );
    item->resource()->asyncLoad();

    mLastResource = item->resource()->identifier();
    updateView();
  }
}

void ResourceSelection::remove()
{
  ResourceItem *item = selectedItem();
  if ( !item )
    return;

  int result = KMessageBox::warningContinueCancel( this,
        i18n( "<qt>Do you really want to remove the address book %1?</qt>" )
        .arg( item->resource()->resourceName() ), "",
        KGuiItem( i18n( "&Remove" ), "editdelete" ) );
  if ( result == KMessageBox::Cancel )
    return;

  mLastResource = item->resource()->identifier();

  core()->addressBook()->removeResource( item->resource() );
  core()->addressBook()->emitAddressBookChanged();

  updateView();
}

void ResourceSelection::currentChanged( QListViewItem *item )
{
  bool state = (item != 0);

  mEditButton->setEnabled( state );
  mRemoveButton->setEnabled( state );

  ResourceItem *resItem = static_cast<ResourceItem*>( item );
  if ( !resItem )
    return;

  KABC::Resource *resource = resItem->resource();

  if ( resItem->checked() != resItem->isOn() ) {
    resItem->setChecked( resItem->isOn() );
    resource->setActive( resItem->isOn() );

    mManager->change( resource );
    resource->asyncLoad();

    mLastResource = resource->identifier();
    updateView();
  }
}

void ResourceSelection::updateView()
{
  if ( !mManager )
    return;

  mView->clear();

  KRES::Manager<KABC::Resource>::Iterator it;
  for ( it = mManager->begin(); it != mManager->end(); ++it )
    new ResourceItem( mView, *it );

  QListViewItemIterator itemIt( mView );
  while ( itemIt.current() ) {
    ResourceItem *item = static_cast<ResourceItem*>( itemIt.current() );
    if ( item->resource()->identifier() == mLastResource ) {
      mView->setSelected( item, true );
      mView->ensureItemVisible( item );
      break;
    }
    ++itemIt;
  }

  core()->addressBook()->emitAddressBookChanged();
}

ResourceItem* ResourceSelection::selectedItem() const
{
  return static_cast<ResourceItem*>( mView->selectedItem() );
}

void ResourceSelection::initGUI()
{
  QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(),
                                         KDialog::spacingHint() );

  mView = new KListView( this );
  mView->addColumn( i18n( "Address Books" ) );
  mView->setFullWidth( true );
  layout->addMultiCellWidget( mView, 0, 0, 0, 2 );

  mAddButton = new QPushButton( i18n( "Add..." ), this );
  mEditButton = new QPushButton( i18n( "Edit..." ), this );
  mEditButton->setEnabled( false );
  mRemoveButton = new QPushButton( i18n( "Remove" ), this );
  mRemoveButton->setEnabled( false );

  layout->addWidget( mAddButton, 1, 0 );
  layout->addWidget( mEditButton, 1, 1 );
  layout->addWidget( mRemoveButton, 1, 2 );
}

class ResourceSelectionFactory : public KAB::ExtensionFactory
{
  public:
    KAB::ExtensionWidget *extension( KAB::Core *core, QWidget *parent, const char *name )
    {
      return new ResourceSelection( core, parent, name );
    }

    QString identifier() const
    {
      return "resourceselection";
    }
};

extern "C" {
  void *init_libkaddrbk_resourceselection()
  {
    return ( new ResourceSelectionFactory );
  }
}

#include "resourceselection.moc"
<commit_msg>Open resource first if it's not open yet and reload it only when we check them.<commit_after>/*
    This file is part of KAddressBook.
    Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>

    This program 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.

    This program 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlayout.h>
#include <qpushbutton.h>
#include <qtimer.h>

#include <kabc/resource.h>
#include <kdialog.h>
#include <kinputdialog.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kresources/configdialog.h>

#include "core.h"

#include "resourceselection.h"

class AddressBookWrapper : public KABC::AddressBook
{
  public:
    AddressBookWrapper( KABC::AddressBook* );

    KRES::Manager<KABC::Resource>* getResourceManager()
    {
      return resourceManager();
    }
};

class ResourceItem : public QCheckListItem
{
  public:
    ResourceItem( KListView *parent, KABC::Resource *resource )
      : QCheckListItem( parent, "", CheckBox ),
        mResource( resource ), mChecked( false )
    {
      setOn( resource->isActive() );
      mChecked = resource->isActive();
    }

    virtual QString text( int column ) const
    {
      if ( column == 0 )
        return mResource->resourceName();
      else
        return QString::null;
    }

    void setChecked( bool state )
    {
      mChecked = state;
    }

    bool checked() const { return mChecked; }
    KABC::Resource *resource() const { return mResource; }

  private:
    KABC::Resource *mResource;
    bool mChecked;
};

ResourceSelection::ResourceSelection( KAB::Core *core, QWidget *parent, const char *name )
  : KAB::ExtensionWidget( core, parent, name ), mManager( 0 )
{
  initGUI();

  AddressBookWrapper *wrapper = static_cast<AddressBookWrapper*>( core->addressBook() );
  mManager = wrapper->getResourceManager();

  connect( mAddButton, SIGNAL( clicked() ), SLOT( add() ) );
  connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) );
  connect( mRemoveButton, SIGNAL( clicked() ), SLOT( remove() ) );

  connect( mView, SIGNAL( clicked( QListViewItem* ) ),
           SLOT( currentChanged( QListViewItem* ) ) );

  QTimer::singleShot( 0, this, SLOT( updateView() ) );
}

ResourceSelection::~ResourceSelection()
{
}

QString ResourceSelection::title() const
{
  return i18n( "Address Books" );
}

QString ResourceSelection::identifier() const
{
  return "resourceselection";
}

void ResourceSelection::add()
{
  QStringList types = mManager->resourceTypeNames();
  QStringList descs = mManager->resourceTypeDescriptions();

  bool ok = false;
  QString desc = KInputDialog::getItem( i18n( "Add Address Book" ),
                                        i18n( "Please select type of the new address book:" ),
                                        descs, 0, false, &ok, this );
  if ( !ok )
    return;

  QString type = types[ descs.findIndex( desc ) ];

  // Create new resource
  KABC::Resource *resource = mManager->createResource( type );
  if( !resource ) {
    KMessageBox::error( this, i18n("<qt>Unable to create an address book of type %1.</qt>")
                              .arg( type ) );
    return;
  }

  resource->setResourceName( i18n( "%1 address book" ).arg( type ) );

  KRES::ConfigDialog dlg( this, QString( "contact" ), resource );

  if ( dlg.exec() ) {
    core()->addressBook()->addResource( resource );
    resource->asyncLoad();

    mLastResource = resource->identifier();
    updateView();
  } else {
    delete resource;
    resource = 0;
  }
}

void ResourceSelection::edit()
{
  ResourceItem *item = selectedItem();
  if ( !item )
    return;

  KRES::ConfigDialog dlg( this, QString( "contact" ), item->resource() );

  if ( dlg.exec() ) {
    mManager->change( item->resource() );
    item->resource()->asyncLoad();

    mLastResource = item->resource()->identifier();
    updateView();
  }
}

void ResourceSelection::remove()
{
  ResourceItem *item = selectedItem();
  if ( !item )
    return;

  int result = KMessageBox::warningContinueCancel( this,
        i18n( "<qt>Do you really want to remove the address book %1?</qt>" )
        .arg( item->resource()->resourceName() ), "",
        KGuiItem( i18n( "&Remove" ), "editdelete" ) );
  if ( result == KMessageBox::Cancel )
    return;

  mLastResource = item->resource()->identifier();

  core()->addressBook()->removeResource( item->resource() );
  core()->addressBook()->emitAddressBookChanged();

  updateView();
}

void ResourceSelection::currentChanged( QListViewItem *item )
{
  bool state = (item != 0);

  mEditButton->setEnabled( state );
  mRemoveButton->setEnabled( state );

  ResourceItem *resItem = static_cast<ResourceItem*>( item );
  if ( !resItem )
    return;

  KABC::Resource *resource = resItem->resource();

  if ( resItem->checked() != resItem->isOn() ) {
    resItem->setChecked( resItem->isOn() );
    resource->setActive( resItem->isOn() );

    mManager->change( resource );

    if ( resItem->checked() ) {
      if ( !resource->isOpen() )
        resource->open();

      resource->asyncLoad();
    }

    mLastResource = resource->identifier();
    updateView();
  }
}

void ResourceSelection::updateView()
{
  if ( !mManager )
    return;

  mView->clear();

  KRES::Manager<KABC::Resource>::Iterator it;
  for ( it = mManager->begin(); it != mManager->end(); ++it )
    new ResourceItem( mView, *it );

  QListViewItemIterator itemIt( mView );
  while ( itemIt.current() ) {
    ResourceItem *item = static_cast<ResourceItem*>( itemIt.current() );
    if ( item->resource()->identifier() == mLastResource ) {
      mView->setSelected( item, true );
      mView->ensureItemVisible( item );
      break;
    }
    ++itemIt;
  }

  core()->addressBook()->emitAddressBookChanged();
}

ResourceItem* ResourceSelection::selectedItem() const
{
  return static_cast<ResourceItem*>( mView->selectedItem() );
}

void ResourceSelection::initGUI()
{
  QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(),
                                         KDialog::spacingHint() );

  mView = new KListView( this );
  mView->addColumn( i18n( "Address Books" ) );
  mView->setFullWidth( true );
  layout->addMultiCellWidget( mView, 0, 0, 0, 2 );

  mAddButton = new QPushButton( i18n( "Add..." ), this );
  mEditButton = new QPushButton( i18n( "Edit..." ), this );
  mEditButton->setEnabled( false );
  mRemoveButton = new QPushButton( i18n( "Remove" ), this );
  mRemoveButton->setEnabled( false );

  layout->addWidget( mAddButton, 1, 0 );
  layout->addWidget( mEditButton, 1, 1 );
  layout->addWidget( mRemoveButton, 1, 2 );
}

class ResourceSelectionFactory : public KAB::ExtensionFactory
{
  public:
    KAB::ExtensionWidget *extension( KAB::Core *core, QWidget *parent, const char *name )
    {
      return new ResourceSelection( core, parent, name );
    }

    QString identifier() const
    {
      return "resourceselection";
    }
};

extern "C" {
  void *init_libkaddrbk_resourceselection()
  {
    return ( new ResourceSelectionFactory );
  }
}

#include "resourceselection.moc"
<|endoftext|>