<commit_before>#include "major.hpp"

Major::Major(string s) {
	string str = removeStartingText(s, " ");
	department = Department(str);
	name = department.getFullName();

	string contentsOfFile = getFileContents("majors/" + department.getName() + ".txt");
	vector<string> record = split(contentsOfFile, '\n');

	parse(record);

	name = department.getFullName();
}

void Major::parse(vector<string> record) {
	string activeHeading, activeRequirement;
	for (string str : record) {
		std::transform(str.begin(), str.end(), str.begin(), ::toupper);
		string leftSide, rightSide;
		long found;
		if (activeHeading.empty())
			activeHeading = "NAME";
		found = str.find_first_of("#");
		if (found == 0 && (str.substr(0, 2) != "##")) {
			str = str.substr(found+1, str.size()-found);
			activeHeading = removeStartingText(str, " ");
			continue;
		}
		if (activeHeading == "SPECIAL") {
			// why was this blank?
		};
		found = str.find_first_of("=");
		if (found != string::npos) {
			leftSide = str.substr(0, found-1);
			rightSide = str.substr(found+2, str.size()-found);
			if (leftSide == "NAME")
				name = rightSide;
			else if (leftSide == "DEPARTMENT")
				department = Department(rightSide);
			else if (leftSide == "NEEDED") {
				int x = stringToInt(rightSide);
				if (activeHeading == "REQUIREMENTS")
					getMajorRequirement(activeRequirement)->setNeeded(x);
				else if (activeHeading == "SPECIAL")
					getSpecialRequirement(activeRequirement)->setNeeded(x);
				else if (activeHeading == "SETS")
					getSetRequirement(activeRequirement)->setNeeded(x);
			}

			else if (leftSide == "VALIDCOURSES") {
				vector<string> validCourseList = split(rightSide, ',');
				for (vector<string>::iterator idx = validCourseList.begin(); idx != validCourseList.end(); ++idx) {
					if (activeHeading == "REQUIREMENTS") {
						MajorRequirement* mr = getMajorRequirement(activeRequirement);
						mr->addCourse(ID(*idx));
					}
					else if (activeHeading == "SETS") {
						MajorRequirement* mr = getSetRequirement(activeRequirement);
						mr->addCourse(ID(*idx));
					}
				}
			}

			else if (leftSide == "VALIDSETS") {
				SpecialRequirement* sp = getSpecialRequirement(activeRequirement);
				vector<string> validSetList = split(rightSide, ',');
				for (vector<string>::iterator idx = validSetList.begin(); idx != validSetList.end(); ++idx)
					sp->addSet(*getSetRequirement(*idx));
			}
		}
//		else if (str != "") {
		else if (!str.empty()) {
			if (str.substr(0, 2) == "//") {
				// it's a comment
			}
			else if (str.substr(0, 2) == "##") {
				str = str.substr(2, str.length()-2);
				str = removeStartingText(str, " ");
				if (activeHeading == "REQUIREMENTS") {
					requirements.push_back(MajorRequirement(str));
					activeRequirement = str;
				}
				else if (activeHeading == "SETS") {
					setRequirements.push_back(MajorRequirement(str));
					activeRequirement = str;
				}
				else if (activeHeading == "SPECIAL") {
					specialRequirements.push_back(SpecialRequirement(str));
					activeRequirement = str;
				}
			}
		}
	}
}

MajorRequirement* Major::getMajorRequirement(string str) {
	str = removeStartingText(str, " ");
	for (MajorRequirement *m : requirements)
		if (m->getName() == str)
			return m;
	return nullptr;
}

SpecialRequirement* Major::getSpecialRequirement(string str) {
	str = removeStartingText(str, " ");
	for (SpecialRequirement *s : specialRequirements)
		if (s->getName() == str)
			return s;
	return nullptr;
}

MajorRequirement* Major::getSetRequirement(string str) {
	str = removeStartingText(str, " ");
	for (MajorRequirement *i : setRequirements)
		if (i->getName() == str)
			return i;
	return nullptr;
}

vector<MajorRequirement>* Major::getRequirements() {
	return &requirements;
}

vector<SpecialRequirement>* Major::getSpecialRequirements() {
	return &specialRequirements;
}

vector<MajorRequirement>* Major::getSetRequirements() {
	return &setRequirements;
}

ostream& Major::getData(ostream &os) {
	os << name;
	return os;
}

ostream &operator<<(ostream &os, Major &item) {
	return item.getData(os);
}

void Major::display() {
	cout << *this << endl;
}
<commit_msg>Return the actual requirement, rather than a copy (from Major::get*Requirement)<commit_after>#include "major.hpp"

Major::Major(string s) {
	string str = removeStartingText(s, " ");
	department = Department(str);
	name = department.getFullName();

	string contentsOfFile = getFileContents("majors/" + department.getName() + ".txt");
	vector<string> record = split(contentsOfFile, '\n');

	parse(record);

	name = department.getFullName();
}

void Major::parse(vector<string> record) {
	string activeHeading, activeRequirement;
	for (string str : record) {
		std::transform(str.begin(), str.end(), str.begin(), ::toupper);
		string leftSide, rightSide;
		long found;
		if (activeHeading.empty())
			activeHeading = "NAME";
		found = str.find_first_of("#");
		if (found == 0 && (str.substr(0, 2) != "##")) {
			str = str.substr(found+1, str.size()-found);
			activeHeading = removeStartingText(str, " ");
			continue;
		}
		if (activeHeading == "SPECIAL") {
			// why was this blank?
		};
		found = str.find_first_of("=");
		if (found != string::npos) {
			leftSide = str.substr(0, found-1);
			rightSide = str.substr(found+2, str.size()-found);
			if (leftSide == "NAME")
				name = rightSide;
			else if (leftSide == "DEPARTMENT")
				department = Department(rightSide);
			else if (leftSide == "NEEDED") {
				int x = stringToInt(rightSide);
				if (activeHeading == "REQUIREMENTS")
					getMajorRequirement(activeRequirement)->setNeeded(x);
				else if (activeHeading == "SPECIAL")
					getSpecialRequirement(activeRequirement)->setNeeded(x);
				else if (activeHeading == "SETS")
					getSetRequirement(activeRequirement)->setNeeded(x);
			}

			else if (leftSide == "VALIDCOURSES") {
				vector<string> validCourseList = split(rightSide, ',');
				for (vector<string>::iterator idx = validCourseList.begin(); idx != validCourseList.end(); ++idx) {
					if (activeHeading == "REQUIREMENTS") {
						MajorRequirement* mr = getMajorRequirement(activeRequirement);
						mr->addCourse(ID(*idx));
					}
					else if (activeHeading == "SETS") {
						MajorRequirement* mr = getSetRequirement(activeRequirement);
						mr->addCourse(ID(*idx));
					}
				}
			}

			else if (leftSide == "VALIDSETS") {
				SpecialRequirement* sp = getSpecialRequirement(activeRequirement);
				vector<string> validSetList = split(rightSide, ',');
				for (vector<string>::iterator idx = validSetList.begin(); idx != validSetList.end(); ++idx)
					sp->addSet(*getSetRequirement(*idx));
			}
		}
//		else if (str != "") {
		else if (!str.empty()) {
			if (str.substr(0, 2) == "//") {
				// it's a comment
			}
			else if (str.substr(0, 2) == "##") {
				str = str.substr(2, str.length()-2);
				str = removeStartingText(str, " ");
				if (activeHeading == "REQUIREMENTS") {
					requirements.push_back(MajorRequirement(str));
					activeRequirement = str;
				}
				else if (activeHeading == "SETS") {
					setRequirements.push_back(MajorRequirement(str));
					activeRequirement = str;
				}
				else if (activeHeading == "SPECIAL") {
					specialRequirements.push_back(SpecialRequirement(str));
					activeRequirement = str;
				}
			}
		}
	}
}

MajorRequirement* Major::getMajorRequirement(string str) {
	str = removeStartingText(str, " ");
	for (int i = 0; i < requirements.size(); i++)
		if (requirements[i].getName() == str)
			return &requirements[i];
	return nullptr;
}

SpecialRequirement* Major::getSpecialRequirement(string str) {
	str = removeStartingText(str, " ");
	for (int i = 0; i < specialRequirements.size(); i++)
		if (specialRequirements[i].getName() == str)
			return &specialRequirements[i];
	return nullptr;
}

MajorRequirement* Major::getSetRequirement(string str) {
	str = removeStartingText(str, " ");
	for (int i = 0; i < setRequirements.size(); i++)
		if (setRequirements[i].getName() == str)
			return &setRequirements[i];
	return nullptr;
}

vector<MajorRequirement>* Major::getRequirements() {
	return &requirements;
}

vector<SpecialRequirement>* Major::getSpecialRequirements() {
	return &specialRequirements;
}

vector<MajorRequirement>* Major::getSetRequirements() {
	return &setRequirements;
}

ostream& Major::getData(ostream &os) {
	os << name;
	return os;
}

ostream &operator<<(ostream &os, Major &item) {
	return item.getData(os);
}

void Major::display() {
	cout << *this << endl;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2013, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Chen Tang <ctang40@gatech.edu>,
 *            Jeongseok Lee <jslee02@gmail.com>
 * Date: 05/01/2013
 *
 * Geoorgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include "dart/collision/fcl_mesh/FCLMeshCollisionNode.h"

#include <iostream>
#include <vector>

#include <fcl/shape/geometric_shapes.h>
#include <fcl/shape/geometric_shape_to_BVH_model.h>
#include <fcl/BVH/BVH_model.h>

#include "dart/dynamics/BodyNode.h"
#include "dart/dynamics/Shape.h"
#include "dart/dynamics/MeshShape.h"
#include "dart/dynamics/EllipsoidShape.h"
#include "dart/dynamics/CylinderShape.h"
#include "dart/renderer/LoadOpengl.h"
#include "dart/collision/fcl_mesh/CollisionShapes.h"
#include "dart/collision/fcl_mesh/FCLMeshCollisionDetector.h"

namespace dart {
namespace collision {

FCLMeshCollisionNode::FCLMeshCollisionNode(dynamics::BodyNode* _bodyNode)
  : CollisionNode(_bodyNode) {
  for (int i = 0; i < _bodyNode->getNumCollisionShapes(); i++) {
    dynamics::Shape *shape = _bodyNode->getCollisionShape(i);
    fcl::Transform3f shapeTransform =
        getFclTransform(shape->getLocalTransform());
    switch (shape->getShapeType()) {
      case dynamics::Shape::ELLIPSOID: {
        dynamics::EllipsoidShape* ellipsoid =
            static_cast<dynamics::EllipsoidShape*>(shape);
        if (ellipsoid->isSphere()) {
          fcl::BVHModel<fcl::OBBRSS>* mesh = new fcl::BVHModel<fcl::OBBRSS>;
          fcl::generateBVHModel<fcl::OBBRSS>(
              *mesh,
              fcl::Sphere(shape->getDim()[0]*0.5),
              shapeTransform, 10, 10);
          mMeshes.push_back(mesh);
        } else {
          mMeshes.push_back(createEllipsoid<fcl::OBBRSS>(shape->getDim()[0],
                                                         shape->getDim()[1],
                                                         shape->getDim()[2],
                                                         shapeTransform));
        }
        break;
      }
      case dynamics::Shape::BOX: {
        mMeshes.push_back(createCube<fcl::OBBRSS>(shape->getDim()[0],
                                                  shape->getDim()[1],
                                                  shape->getDim()[2],
                                                  shapeTransform));
        break;
      }
      case dynamics::Shape::CYLINDER: {
        dynamics::CylinderShape *cylinder =
            static_cast<dynamics::CylinderShape *>(shape);
        if (cylinder) {
          double radius = cylinder->getRadius();
          double height = cylinder->getHeight();
          mMeshes.push_back(createCylinder<fcl::OBBRSS>(
                              radius, radius, height, 16, 16, shapeTransform));
        }
        break;
      }
      case dynamics::Shape::MESH: {
        dynamics::MeshShape *shapeMesh =
            static_cast<dynamics::MeshShape *>(shape);
        if (shapeMesh) {
          mMeshes.push_back(createMesh<fcl::OBBRSS>(shape->getDim()[0],
                                                    shape->getDim()[1],
                                                    shape->getDim()[2],
                                                    shapeMesh->getMesh(),
                                                    shapeTransform));
        }
        break;
      }
      default: {
        std::cout << "ERROR: Collision checking does not support "
                  << _bodyNode->getName() << "'s Shape type\n";
        break;
      }
    }
  }
}

FCLMeshCollisionNode::~FCLMeshCollisionNode() {
  for (int i = 0; i < mMeshes.size(); i++)
    delete mMeshes[i];
}

bool FCLMeshCollisionNode::detectCollision(FCLMeshCollisionNode* _otherNode,
                                           std::vector<Contact>* _contactPoints,
                                           int _num_max_contact) {
  evalRT();
  _otherNode->evalRT();
  bool collision = false;

  for (int i = 0; i < mMeshes.size(); i++) {
    for (int j = 0; j < _otherNode->mMeshes.size(); j++) {
      fcl::CollisionResult res;
      fcl::CollisionRequest req;

      // only evaluate contact points if data structure for returning the
      // contact points was provided
      req.enable_contact = _contactPoints;
      req.num_max_contacts = _num_max_contact;
      fcl::collide(mMeshes[i],
                   mFclWorldTrans,
                   _otherNode->mMeshes[j],
                   _otherNode->mFclWorldTrans,
                   req, res);

      if (res.isCollision()) {
        collision = true;
      }
      if (!_contactPoints) {
        return collision;
      }

      int numCoplanarContacts = 0;
      int numNoContacts = 0;
      int numContacts = 0;

      std::vector<Contact> unfilteredContactPoints;
      unfilteredContactPoints.reserve(res.numContacts());

      for (int k = 0; k < res.numContacts(); k++) {
        // for each pair of intersecting triangles, we create two contact points
        Contact pair1, pair2;
        //            pair1.bd1 = mBodyNode;
        //            pair1.bd2 = _otherNode->mBodyNode;
        //            pair1.bdID1 = this->mBodyNodeID;
        //            pair1.bdID2 = _otherNode->mBodyNodeID;
        pair1.collisionNode1 = this;
        pair1.collisionNode2 = _otherNode;
        fcl::Vec3f v;
        pair1.triID1 = res.getContact(k).b1;
        pair1.triID2 = res.getContact(k).b2;
        pair1.penetrationDepth = res.getContact(k).penetration_depth;
        pair2 = pair1;
        int contactResult =
            evalContactPosition(res.getContact(k), mMeshes[i],
                                _otherNode->mMeshes[j],
                                mFclWorldTrans, _otherNode->mFclWorldTrans,
                                &pair1.point, &pair2.point);
        if (contactResult == COPLANAR_CONTACT) {
          numCoplanarContacts++;
          //                if (numContacts != 0 || numCoplanarContacts > 1)
          if (numContacts > 2)
            continue;
        } else if (contactResult == NO_CONTACT) {
          numNoContacts++;
          continue;
        } else {
          numContacts++;
        }
        v = -res.getContact(k).normal;
        pair1.normal = Eigen::Vector3d(v[0], v[1], v[2]);
        pair2.normal = Eigen::Vector3d(v[0], v[1], v[2]);

        unfilteredContactPoints.push_back(pair1);
        unfilteredContactPoints.push_back(pair2);
      }

      const double ZERO = 0.000001;
      const double ZERO2 = ZERO*ZERO;

      std::vector<bool> markForDeletion(unfilteredContactPoints.size(), false);

      // mark all the repeated points
      for (unsigned int k = 0; k < unfilteredContactPoints.size(); k++) {
        for (unsigned int l = k + 1; l < unfilteredContactPoints.size(); l++) {
          Eigen::Vector3d diff = unfilteredContactPoints[k].point
                                 - unfilteredContactPoints[l].point;
          if (diff.dot(diff) < 3 * ZERO2) {
            markForDeletion[k] = true;
            break;
          }
        }
      }

      // remove all the co-linear contact points
      for (unsigned int k = 0; k < unfilteredContactPoints.size(); k++) {
        if (markForDeletion[k])
          continue;
        for (unsigned int l = 0; l < unfilteredContactPoints.size(); l++) {
          if (l == k || markForDeletion[l])
            continue;
          if (markForDeletion[k])
            break;
          for (int m = l + 1; m < unfilteredContactPoints.size(); m++) {
            if (k == m)
              continue;
            Eigen::Vector3d  v =
                (unfilteredContactPoints[k].point
                 - unfilteredContactPoints[l].point).cross(
                  unfilteredContactPoints[k].point
                  - unfilteredContactPoints[m].point);
            if (v.dot(v) < ZERO2
                && ((unfilteredContactPoints[k].point
                     - unfilteredContactPoints[l].point).dot(
                      unfilteredContactPoints[k].point
                      - unfilteredContactPoints[m].point) < 0)) {
              markForDeletion[k] = true;
              break;
            }
          }
        }
      }

      for (unsigned int k = 0; k < unfilteredContactPoints.size(); k++) {
        if (!markForDeletion[k]) {
          _contactPoints->push_back(unfilteredContactPoints[k]);
        }
      }
    }
  }
  return collision;
}

void FCLMeshCollisionNode::evalRT() {
  mWorldTrans = mBodyNode->getWorldTransform();
  mFclWorldTrans = getFclTransform(mWorldTrans);
}

fcl::Transform3f FCLMeshCollisionNode::getFclTransform(
    const Eigen::Isometry3d& _m) {
  return fcl::Transform3f(fcl::Matrix3f(_m(0, 0), _m(0, 1), _m(0, 2),
                                        _m(1, 0), _m(1, 1), _m(1, 2),
                                        _m(2, 0), _m(2, 1), _m(2, 2)),
                          fcl::Vec3f(_m(0, 3), _m(1, 3), _m(2, 3)));
}

int FCLMeshCollisionNode::evalContactPosition(
    const fcl::Contact& _fclContact,
    fcl::BVHModel<fcl::OBBRSS>* _mesh1,
    fcl::BVHModel<fcl::OBBRSS>* _mesh2,
    const fcl::Transform3f& _transform1,
    const fcl::Transform3f& _transform2,
    Eigen::Vector3d* _contactPosition1,
    Eigen::Vector3d* _contactPosition2) {
  int id1 = _fclContact.b1;
  int id2 = _fclContact.b2;
  fcl::Triangle tri1 = _mesh1->tri_indices[id1];
  fcl::Triangle tri2 = _mesh2->tri_indices[id2];

  fcl::Vec3f v1, v2, v3, p1, p2, p3;
  v1 = _mesh1->vertices[tri1[0]];
  v2 = _mesh1->vertices[tri1[1]];
  v3 = _mesh1->vertices[tri1[2]];

  p1 = _mesh2->vertices[tri2[0]];
  p2 = _mesh2->vertices[tri2[1]];
  p3 = _mesh2->vertices[tri2[2]];

  fcl::Vec3f contact1, contact2;
  v1 = _transform1.transform(v1);
  v2 = _transform1.transform(v2);
  v3 = _transform1.transform(v3);
  p1 = _transform2.transform(p1);
  p2 = _transform2.transform(p2);
  p3 = _transform2.transform(p3);
  int testRes = FFtest(v1, v2, v3, p1, p2, p3, &contact1, &contact2);

  if (testRes == COPLANAR_CONTACT) {
    double area1 = triArea(v1, v2, v3);
    double area2 = triArea(p1, p2, p3);
//    std::cout << "this node = " << this->mBodynodeID << " other node = "
//              << _other->mBodynodeID << std::endl;
    if (area1 < area2)
      contact1 = v1 + v2 + v3;
    else
      contact1 = p1 + p2 + p3;
    contact1[0] /= 3.0;
    contact1[1] /= 3.0;
    contact1[2] /= 3.0;
    contact2 = contact1;
//    std::cout << contact1[0] << " " << contact1[1] << " "
//              << contact1[2] << std::endl;
  }
  *_contactPosition1 = Eigen::Vector3d(contact1[0], contact1[1], contact1[2]);
  *_contactPosition2 = Eigen::Vector3d(contact2[0], contact2[1], contact2[2]);
  return testRes;
}

void FCLMeshCollisionNode::drawCollisionSkeletonNode(bool _bTrans) {
  evalRT();
  double M[16];
  for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
      M[j * 4 + i] = mWorldTrans(i, j);
//  fcl::Vec3f v1, v2, v3;
  glPushMatrix();
  if (_bTrans)
    glMultMatrixd(M);
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glBegin(GL_TRIANGLES);
  for (int i = 0; i < mMeshes.size(); i++) {
    for (int j = 0; j < mMeshes[i]->num_tris; j++) {
      fcl::Triangle tri = mMeshes[i]->tri_indices[j];
      glVertex3f(mMeshes[i]->vertices[tri[0]][0],
                 mMeshes[i]->vertices[tri[0]][1],
                 mMeshes[i]->vertices[tri[0]][2]);
      glVertex3f(mMeshes[i]->vertices[tri[1]][0],
                 mMeshes[i]->vertices[tri[1]][1],
                 mMeshes[i]->vertices[tri[1]][2]);
      glVertex3f(mMeshes[i]->vertices[tri[2]][0],
                 mMeshes[i]->vertices[tri[2]][1],
                 mMeshes[i]->vertices[tri[2]][2]);
    }
  }
  glEnd();
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glPopMatrix();
}

}  // namespace collision
}  // namespace dart
<commit_msg>Fix style of FCLMeshCollisionNode.cpp for readability<commit_after>/*
 * Copyright (c) 2011-2013, Georgia Tech Research Corporation
 * All rights reserved.
 *
 * Author(s): Chen Tang <ctang40@gatech.edu>,
 *            Jeongseok Lee <jslee02@gmail.com>
 * Date: 05/01/2013
 *
 * Geoorgia Tech Graphics Lab and Humanoid Robotics Lab
 *
 * Directed by Prof. C. Karen Liu and Prof. Mike Stilman
 * <karenliu@cc.gatech.edu> <mstilman@cc.gatech.edu>
 *
 * This file is provided under the following "BSD-style" License:
 *   Redistribution and use in source and binary forms, with or
 *   without modification, are permitted provided that the following
 *   conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *   POSSIBILITY OF SUCH DAMAGE.
 */

#include "dart/collision/fcl_mesh/FCLMeshCollisionNode.h"

#include <iostream>
#include <vector>

#include <fcl/shape/geometric_shapes.h>
#include <fcl/shape/geometric_shape_to_BVH_model.h>
#include <fcl/BVH/BVH_model.h>

#include "dart/dynamics/BodyNode.h"
#include "dart/dynamics/Shape.h"
#include "dart/dynamics/MeshShape.h"
#include "dart/dynamics/EllipsoidShape.h"
#include "dart/dynamics/CylinderShape.h"
#include "dart/renderer/LoadOpengl.h"
#include "dart/collision/fcl_mesh/CollisionShapes.h"
#include "dart/collision/fcl_mesh/FCLMeshCollisionDetector.h"

namespace dart {
namespace collision {

FCLMeshCollisionNode::FCLMeshCollisionNode(dynamics::BodyNode* _bodyNode)
  : CollisionNode(_bodyNode) {
  // using-declaration
  using dart::dynamics::Shape;
  using dart::dynamics::EllipsoidShape;
  using dart::dynamics::CylinderShape;
  using dart::dynamics::MeshShape;

  // Create meshes according to types of the shapes
  for (int i = 0; i < _bodyNode->getNumCollisionShapes(); i++) {
    Shape* shape = _bodyNode->getCollisionShape(i);
    fcl::Transform3f shapeT = getFclTransform(shape->getLocalTransform());
    switch (shape->getShapeType()) {
      case Shape::ELLIPSOID: {
        EllipsoidShape* ellipsoid = static_cast<EllipsoidShape*>(shape);
        // Sphere
        if (ellipsoid->isSphere()) {
          fcl::BVHModel<fcl::OBBRSS>* mesh = new fcl::BVHModel<fcl::OBBRSS>;
          fcl::generateBVHModel<fcl::OBBRSS>(
              *mesh, fcl::Sphere(shape->getDim()[0]*0.5), shapeT, 10, 10);
          mMeshes.push_back(mesh);
        // Ellipsoid
        } else {
          mMeshes.push_back(createEllipsoid<fcl::OBBRSS>(shape->getDim()[0],
                                                         shape->getDim()[1],
                                                         shape->getDim()[2],
                                                         shapeT));
        }
        break;
      }
      case dynamics::Shape::BOX: {
        mMeshes.push_back(createCube<fcl::OBBRSS>(shape->getDim()[0],
                                                  shape->getDim()[1],
                                                  shape->getDim()[2],
                                                  shapeT));
        break;
      }
      case dynamics::Shape::CYLINDER: {
        CylinderShape* cylinder = static_cast<CylinderShape*>(shape);
        double radius = cylinder->getRadius();
        double height = cylinder->getHeight();
        mMeshes.push_back(createCylinder<fcl::OBBRSS>(
                            radius, radius, height, 16, 16, shapeT));
        break;
      }
      case dynamics::Shape::MESH: {
        MeshShape* shapeMesh = static_cast<MeshShape*>(shape);
        mMeshes.push_back(createMesh<fcl::OBBRSS>(shape->getDim()[0],
                                                  shape->getDim()[1],
                                                  shape->getDim()[2],
                                                  shapeMesh->getMesh(),
                                                  shapeT));
        break;
      }
      default: {
        std::cout << "ERROR: Collision checking does not support "
                  << _bodyNode->getName() << "'s Shape type\n";
        break;
      }
    }
  }
}

FCLMeshCollisionNode::~FCLMeshCollisionNode() {
  for (int i = 0; i < mMeshes.size(); i++)
    delete mMeshes[i];
}

bool FCLMeshCollisionNode::detectCollision(FCLMeshCollisionNode* _otherNode,
                                           std::vector<Contact>* _contactPoints,
                                           int _num_max_contact) {
  evalRT();
  _otherNode->evalRT();
  bool collision = false;

  for (int i = 0; i < mMeshes.size(); i++) {
    for (int j = 0; j < _otherNode->mMeshes.size(); j++) {
      fcl::CollisionResult res;
      fcl::CollisionRequest req;

      // only evaluate contact points if data structure for returning the
      // contact points was provided
      req.enable_contact = _contactPoints;
      req.num_max_contacts = _num_max_contact;
      fcl::collide(mMeshes[i],
                   mFclWorldTrans,
                   _otherNode->mMeshes[j],
                   _otherNode->mFclWorldTrans,
                   req, res);

      if (res.isCollision()) {
        collision = true;
      }
      if (!_contactPoints) {
        return collision;
      }

      int numCoplanarContacts = 0;
      int numNoContacts = 0;
      int numContacts = 0;

      std::vector<Contact> unfilteredContactPoints;
      unfilteredContactPoints.reserve(res.numContacts());

      for (int k = 0; k < res.numContacts(); k++) {
        // for each pair of intersecting triangles, we create two contact points
        Contact pair1, pair2;
        //            pair1.bd1 = mBodyNode;
        //            pair1.bd2 = _otherNode->mBodyNode;
        //            pair1.bdID1 = this->mBodyNodeID;
        //            pair1.bdID2 = _otherNode->mBodyNodeID;
        pair1.collisionNode1 = this;
        pair1.collisionNode2 = _otherNode;
        fcl::Vec3f v;
        pair1.triID1 = res.getContact(k).b1;
        pair1.triID2 = res.getContact(k).b2;
        pair1.penetrationDepth = res.getContact(k).penetration_depth;
        pair2 = pair1;
        int contactResult =
            evalContactPosition(res.getContact(k), mMeshes[i],
                                _otherNode->mMeshes[j],
                                mFclWorldTrans, _otherNode->mFclWorldTrans,
                                &pair1.point, &pair2.point);
        if (contactResult == COPLANAR_CONTACT) {
          numCoplanarContacts++;
          //                if (numContacts != 0 || numCoplanarContacts > 1)
          if (numContacts > 2)
            continue;
        } else if (contactResult == NO_CONTACT) {
          numNoContacts++;
          continue;
        } else {
          numContacts++;
        }
        v = -res.getContact(k).normal;
        pair1.normal = Eigen::Vector3d(v[0], v[1], v[2]);
        pair2.normal = Eigen::Vector3d(v[0], v[1], v[2]);

        unfilteredContactPoints.push_back(pair1);
        unfilteredContactPoints.push_back(pair2);
      }

      const double ZERO = 0.000001;
      const double ZERO2 = ZERO*ZERO;

      std::vector<bool> markForDeletion(unfilteredContactPoints.size(), false);

      // mark all the repeated points
      for (unsigned int k = 0; k < unfilteredContactPoints.size(); k++) {
        for (unsigned int l = k + 1; l < unfilteredContactPoints.size(); l++) {
          Eigen::Vector3d diff = unfilteredContactPoints[k].point
                                 - unfilteredContactPoints[l].point;
          if (diff.dot(diff) < 3 * ZERO2) {
            markForDeletion[k] = true;
            break;
          }
        }
      }

      // remove all the co-linear contact points
      for (unsigned int k = 0; k < unfilteredContactPoints.size(); k++) {
        if (markForDeletion[k])
          continue;
        for (unsigned int l = 0; l < unfilteredContactPoints.size(); l++) {
          if (l == k || markForDeletion[l])
            continue;
          if (markForDeletion[k])
            break;
          for (int m = l + 1; m < unfilteredContactPoints.size(); m++) {
            if (k == m)
              continue;
            Eigen::Vector3d  v =
                (unfilteredContactPoints[k].point
                 - unfilteredContactPoints[l].point).cross(
                  unfilteredContactPoints[k].point
                  - unfilteredContactPoints[m].point);
            if (v.dot(v) < ZERO2
                && ((unfilteredContactPoints[k].point
                     - unfilteredContactPoints[l].point).dot(
                      unfilteredContactPoints[k].point
                      - unfilteredContactPoints[m].point) < 0)) {
              markForDeletion[k] = true;
              break;
            }
          }
        }
      }

      for (unsigned int k = 0; k < unfilteredContactPoints.size(); k++) {
        if (!markForDeletion[k]) {
          _contactPoints->push_back(unfilteredContactPoints[k]);
        }
      }
    }
  }
  return collision;
}

void FCLMeshCollisionNode::evalRT() {
  mWorldTrans = mBodyNode->getWorldTransform();
  mFclWorldTrans = getFclTransform(mWorldTrans);
}

fcl::Transform3f FCLMeshCollisionNode::getFclTransform(
    const Eigen::Isometry3d& _m) {
  return fcl::Transform3f(fcl::Matrix3f(_m(0, 0), _m(0, 1), _m(0, 2),
                                        _m(1, 0), _m(1, 1), _m(1, 2),
                                        _m(2, 0), _m(2, 1), _m(2, 2)),
                          fcl::Vec3f(_m(0, 3), _m(1, 3), _m(2, 3)));
}

int FCLMeshCollisionNode::evalContactPosition(
    const fcl::Contact& _fclContact,
    fcl::BVHModel<fcl::OBBRSS>* _mesh1,
    fcl::BVHModel<fcl::OBBRSS>* _mesh2,
    const fcl::Transform3f& _transform1,
    const fcl::Transform3f& _transform2,
    Eigen::Vector3d* _contactPosition1,
    Eigen::Vector3d* _contactPosition2) {
  int id1 = _fclContact.b1;
  int id2 = _fclContact.b2;
  fcl::Triangle tri1 = _mesh1->tri_indices[id1];
  fcl::Triangle tri2 = _mesh2->tri_indices[id2];

  fcl::Vec3f v1, v2, v3, p1, p2, p3;
  v1 = _mesh1->vertices[tri1[0]];
  v2 = _mesh1->vertices[tri1[1]];
  v3 = _mesh1->vertices[tri1[2]];

  p1 = _mesh2->vertices[tri2[0]];
  p2 = _mesh2->vertices[tri2[1]];
  p3 = _mesh2->vertices[tri2[2]];

  fcl::Vec3f contact1, contact2;
  v1 = _transform1.transform(v1);
  v2 = _transform1.transform(v2);
  v3 = _transform1.transform(v3);
  p1 = _transform2.transform(p1);
  p2 = _transform2.transform(p2);
  p3 = _transform2.transform(p3);
  int testRes = FFtest(v1, v2, v3, p1, p2, p3, &contact1, &contact2);

  if (testRes == COPLANAR_CONTACT) {
    double area1 = triArea(v1, v2, v3);
    double area2 = triArea(p1, p2, p3);
//    std::cout << "this node = " << this->mBodynodeID << " other node = "
//              << _other->mBodynodeID << std::endl;
    if (area1 < area2)
      contact1 = v1 + v2 + v3;
    else
      contact1 = p1 + p2 + p3;
    contact1[0] /= 3.0;
    contact1[1] /= 3.0;
    contact1[2] /= 3.0;
    contact2 = contact1;
//    std::cout << contact1[0] << " " << contact1[1] << " "
//              << contact1[2] << std::endl;
  }
  *_contactPosition1 = Eigen::Vector3d(contact1[0], contact1[1], contact1[2]);
  *_contactPosition2 = Eigen::Vector3d(contact2[0], contact2[1], contact2[2]);
  return testRes;
}

void FCLMeshCollisionNode::drawCollisionSkeletonNode(bool _bTrans) {
  evalRT();
  double M[16];
  for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
      M[j * 4 + i] = mWorldTrans(i, j);
//  fcl::Vec3f v1, v2, v3;
  glPushMatrix();
  if (_bTrans)
    glMultMatrixd(M);
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glBegin(GL_TRIANGLES);
  for (int i = 0; i < mMeshes.size(); i++) {
    for (int j = 0; j < mMeshes[i]->num_tris; j++) {
      fcl::Triangle tri = mMeshes[i]->tri_indices[j];
      glVertex3f(mMeshes[i]->vertices[tri[0]][0],
                 mMeshes[i]->vertices[tri[0]][1],
                 mMeshes[i]->vertices[tri[0]][2]);
      glVertex3f(mMeshes[i]->vertices[tri[1]][0],
                 mMeshes[i]->vertices[tri[1]][1],
                 mMeshes[i]->vertices[tri[1]][2]);
      glVertex3f(mMeshes[i]->vertices[tri[2]][0],
                 mMeshes[i]->vertices[tri[2]][1],
                 mMeshes[i]->vertices[tri[2]][2]);
    }
  }
  glEnd();
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glPopMatrix();
}

}  // namespace collision
}  // namespace dart
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: menuconfiguration.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 14:30:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_CLASSES_MENUCONFIGURATION_HXX_
#include <xml/menuconfiguration.hxx>
#endif

#ifndef __FRAMEWORK_CLASSES_BMKMENU_HXX_
#include <classes/bmkmenu.hxx>
#endif

#ifndef __FRAMEWORK_CLASSES_ADDONMENU_HXX_
#include <classes/addonmenu.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_MENUDOCUMENTHANDLER_HXX_
#include <xml/menudocumenthandler.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_SAXNAMESPACEFILTER_HXX_
#include <xml/saxnamespacefilter.hxx>
#endif

#ifndef _FRAMEWORK_SERVICES_LAYOUTMANAGER_HXX_
#include <services/layoutmanager.hxx>
#endif

#ifndef _FRAMEWORK_UIELEMENT_ROOTITEMCONTAINER_HXX_
#include <uielement/rootitemcontainer.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP_
#include <com/sun/star/xml/sax/XParser.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
#include <com/sun/star/io/XActiveDataSource.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

//_________________________________________________________________________________________________________________
//  namespace
//_________________________________________________________________________________________________________________

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::io;

namespace framework
{

BOOL MenuConfiguration::IsPickListItemId( USHORT nId )
{
    return (( START_ITEMID_PICKLIST <= nId ) && ( nId <= END_ITEMID_PICKLIST ));
}

BOOL MenuConfiguration::IsWindowListItemId( USHORT nId )
{
    return (( START_ITEMID_WINDOWLIST <= nId ) && ( nId <= END_ITEMID_WINDOWLIST ));
}

MenuConfiguration::MenuConfiguration(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager )
:   m_rxServiceManager( rServiceManager )
{
}

MenuConfiguration::~MenuConfiguration()
{
}

Reference< XIndexAccess > MenuConfiguration::CreateMenuBarConfigurationFromXML(
    Reference< XInputStream >& rInputStream )
throw ( WrappedTargetException )
{
    Reference< XParser > xParser( m_rxServiceManager->createInstance(
                                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ))),
                                  UNO_QUERY);

    // connect stream to input stream to the parser
    InputSource aInputSource;

    aInputSource.aInputStream = rInputStream;

    // create menu bar
    Reference< XIndexContainer > xItemContainer( static_cast< cppu::OWeakObject *>( new RootItemContainer()), UNO_QUERY );

    // create namespace filter and set menudocument handler inside to support xml namespaces

    // #110897# Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( xItemContainer ));
    Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( m_rxServiceManager, xItemContainer ));

    Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));

    // connect parser and filter
    xParser->setDocumentHandler( xFilter );

    try
    {
        xParser->parseStream( aInputSource );
        return Reference< XIndexAccess >( xItemContainer, UNO_QUERY );
    }
    catch ( RuntimeException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
    catch( SAXException& e )
    {
        SAXException aWrappedSAXException;

        if ( !( e.WrappedException >>= aWrappedSAXException ))
            throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
        else
            throw WrappedTargetException( aWrappedSAXException.Message, Reference< XInterface >(), Any() );
    }
    catch( ::com::sun::star::io::IOException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
}

PopupMenu* MenuConfiguration::CreateBookmarkMenu(
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame,
    const ::rtl::OUString& aURL )
throw ( ::com::sun::star::lang::WrappedTargetException )
{
    if ( aURL == BOOKMARK_NEWMENU )
        return new BmkMenu( rFrame, BmkMenu::BMK_NEWMENU );
    else if ( aURL == BOOKMARK_WIZARDMENU )
        return new BmkMenu( rFrame, BmkMenu::BMK_WIZARDMENU );
    else
        return NULL;
}

void MenuConfiguration::StoreMenuBarConfigurationToXML(
    Reference< XIndexAccess >& rMenuBarConfiguration,
    Reference< XOutputStream >& rOutputStream )
throw ( WrappedTargetException )
{
    Reference< XDocumentHandler > xWriter;

    xWriter = Reference< XDocumentHandler >( m_rxServiceManager->createInstance(
            ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" )), UNO_QUERY) ;

    Reference< XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
    xDataSource->setOutputStream( rOutputStream );

    try
    {
        OWriteMenuDocumentHandler aWriteMenuDocumentHandler( rMenuBarConfiguration, xWriter );
        aWriteMenuDocumentHandler.WriteMenuDocument();
    }
    catch ( RuntimeException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
    catch ( SAXException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
    catch ( ::com::sun::star::io::IOException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
}

}
<commit_msg>INTEGRATION: CWS changefileheader (1.5.262); FILE MERGED 2008/04/01 10:58:18 thb 1.5.262.2: #i85898# Stripping all external header guards 2008/03/28 15:35:40 rt 1.5.262.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: menuconfiguration.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________
#include <xml/menuconfiguration.hxx>

#ifndef __FRAMEWORK_CLASSES_BMKMENU_HXX_
#include <classes/bmkmenu.hxx>
#endif
#include <classes/addonmenu.hxx>
#include <xml/menudocumenthandler.hxx>
#include <xml/saxnamespacefilter.hxx>

#ifndef _FRAMEWORK_SERVICES_LAYOUTMANAGER_HXX_
#include <services/layoutmanager.hxx>
#endif

#ifndef _FRAMEWORK_UIELEMENT_ROOTITEMCONTAINER_HXX_
#include <uielement/rootitemcontainer.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/frame/XFrame.hpp>

//_________________________________________________________________________________________________________________
//  namespace
//_________________________________________________________________________________________________________________

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::io;

namespace framework
{

BOOL MenuConfiguration::IsPickListItemId( USHORT nId )
{
    return (( START_ITEMID_PICKLIST <= nId ) && ( nId <= END_ITEMID_PICKLIST ));
}

BOOL MenuConfiguration::IsWindowListItemId( USHORT nId )
{
    return (( START_ITEMID_WINDOWLIST <= nId ) && ( nId <= END_ITEMID_WINDOWLIST ));
}

MenuConfiguration::MenuConfiguration(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager )
:   m_rxServiceManager( rServiceManager )
{
}

MenuConfiguration::~MenuConfiguration()
{
}

Reference< XIndexAccess > MenuConfiguration::CreateMenuBarConfigurationFromXML(
    Reference< XInputStream >& rInputStream )
throw ( WrappedTargetException )
{
    Reference< XParser > xParser( m_rxServiceManager->createInstance(
                                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ))),
                                  UNO_QUERY);

    // connect stream to input stream to the parser
    InputSource aInputSource;

    aInputSource.aInputStream = rInputStream;

    // create menu bar
    Reference< XIndexContainer > xItemContainer( static_cast< cppu::OWeakObject *>( new RootItemContainer()), UNO_QUERY );

    // create namespace filter and set menudocument handler inside to support xml namespaces

    // #110897# Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( xItemContainer ));
    Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( m_rxServiceManager, xItemContainer ));

    Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));

    // connect parser and filter
    xParser->setDocumentHandler( xFilter );

    try
    {
        xParser->parseStream( aInputSource );
        return Reference< XIndexAccess >( xItemContainer, UNO_QUERY );
    }
    catch ( RuntimeException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
    catch( SAXException& e )
    {
        SAXException aWrappedSAXException;

        if ( !( e.WrappedException >>= aWrappedSAXException ))
            throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
        else
            throw WrappedTargetException( aWrappedSAXException.Message, Reference< XInterface >(), Any() );
    }
    catch( ::com::sun::star::io::IOException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
}

PopupMenu* MenuConfiguration::CreateBookmarkMenu(
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame,
    const ::rtl::OUString& aURL )
throw ( ::com::sun::star::lang::WrappedTargetException )
{
    if ( aURL == BOOKMARK_NEWMENU )
        return new BmkMenu( rFrame, BmkMenu::BMK_NEWMENU );
    else if ( aURL == BOOKMARK_WIZARDMENU )
        return new BmkMenu( rFrame, BmkMenu::BMK_WIZARDMENU );
    else
        return NULL;
}

void MenuConfiguration::StoreMenuBarConfigurationToXML(
    Reference< XIndexAccess >& rMenuBarConfiguration,
    Reference< XOutputStream >& rOutputStream )
throw ( WrappedTargetException )
{
    Reference< XDocumentHandler > xWriter;

    xWriter = Reference< XDocumentHandler >( m_rxServiceManager->createInstance(
            ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" )), UNO_QUERY) ;

    Reference< XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
    xDataSource->setOutputStream( rOutputStream );

    try
    {
        OWriteMenuDocumentHandler aWriteMenuDocumentHandler( rMenuBarConfiguration, xWriter );
        aWriteMenuDocumentHandler.WriteMenuDocument();
    }
    catch ( RuntimeException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
    catch ( SAXException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
    catch ( ::com::sun::star::io::IOException& e )
    {
        throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
    }
}

}
<|endoftext|>


<commit_before>
#include <stringzeug/conversion.h>

namespace stringzeug
{

template <>
char fromString<char>(const std::string & string)
{
    std::stringstream stream(string);
    int value;
    stream >> value;
    return static_cast<char>(value);
}

template <>
unsigned char fromString<unsigned char>(const std::string & string)
{
    std::stringstream stream(string);
    unsigned int value;
    stream >> value;
    return static_cast<unsigned char>(value);
}

template <>
std::string toString<char>(const char & value)
{
    std::stringstream stream;
    stream << static_cast<int>(value);
    return stream.str();
}

template <>
std::string toString<unsigned char>(const unsigned char & value)
{
    std::stringstream stream;
    stream << static_cast<unsigned int>(value);
    return stream.str();
}

} // namespace stringzeug
<commit_msg>Use default-initialized values in string conversion<commit_after>
#include <stringzeug/conversion.h>

namespace stringzeug
{

template <>
char fromString<char>(const std::string & string)
{
    std::stringstream stream(string);
    auto value = int();
    stream >> value;
    return static_cast<char>(value);
}

template <>
unsigned char fromString<unsigned char>(const std::string & string)
{
    std::stringstream stream(string);
    auto value = unsigned int();
    stream >> value;
    return static_cast<unsigned char>(value);
}

template <>
std::string toString<char>(const char & value)
{
    std::stringstream stream;
    stream << static_cast<int>(value);
    return stream.str();
}

template <>
std::string toString<unsigned char>(const unsigned char & value)
{
    std::stringstream stream;
    stream << static_cast<unsigned int>(value);
    return stream.str();
}

} // namespace stringzeug
<|endoftext|>


<commit_before>/*
* @Author: Ubi de Feo | Future Tailors
* @Date:   2017-07-09 16:34:07
* @Last Modified by:   ubi
* @Last Modified time: 2017-07-09 16:41:17
*/

#include "FTDebouncer.h"
/*	CONSTRUCTORS/DESTRUCTOR						*/
FTDebouncer::FTDebouncer() : debounceDelay(40) {
	debouncedItemsCount = 0;
	firstDebounceItem = lastDebounceItem = nullptr;
}
FTDebouncer::FTDebouncer(uint16_t _debounceTime) : debounceDelay(_debounceTime) {
	debouncedItemsCount = 0;
	firstDebounceItem = lastDebounceItem = nullptr;
}
FTDebouncer::~FTDebouncer() {
}

/*	METHODS										*/
void FTDebouncer::addPin(
	uint8_t _pinNr, uint8_t _restState) {
	DebounceItem *dbItem = new DebounceItem();

	dbItem->pinNumber = _pinNr;
	dbItem->restState = _restState;

	if (firstDebounceItem == nullptr) {
		firstDebounceItem = dbItem;
	} else {
		lastDebounceItem->nextItem = dbItem;
	}
	lastDebounceItem = dbItem;

	pinMode(_pinNr, INPUT);
	debouncedItemsCount++;

}
void FTDebouncer::addPin(uint8_t _pinNr, uint8_t _restState, uint8_t _pullUpMode) {
	DebounceItem *dbItem = new DebounceItem();

	dbItem->pinNumber = _pinNr;
	dbItem->restState = _restState;

	if (firstDebounceItem == nullptr) {
		firstDebounceItem = dbItem;
	} else {
		lastDebounceItem->nextItem = dbItem;
	}

	lastDebounceItem = dbItem;

	if (_pullUpMode == 0) {
		pinMode(_pinNr, INPUT);
	} else {
		pinMode(_pinNr, _pullUpMode);
	}

	debouncedItemsCount++;

}

void FTDebouncer::init() {
	unsigned long currentMs = millis();
	DebounceItem *dbItem = firstDebounceItem;

	while (1) {
		dbItem->lastTimeChecked = currentMs;
		dbItem->currentState = dbItem->previousState = dbItem->restState;
		dbItem->currentDebouncedState = dbItem->previousDebouncedState = dbItem->restState;
		dbItem = dbItem->nextItem;
		if (dbItem == nullptr) break;
	}
}

void FTDebouncer::run() {
	DebounceItem *dbItem = firstDebounceItem;
	while (1) {
		dbItem->currentState = digitalRead(dbItem->pinNumber);
		dbItem = dbItem->nextItem;
		if (dbItem == nullptr) break;
	}

	debouncePins();
	checkStateChange();
}
void FTDebouncer::debouncePins() {
	unsigned long currentMs = millis();
	DebounceItem *dbItem = firstDebounceItem;
	while (1) {
		if (dbItem->currentState != dbItem->previousState) {
			dbItem->lastTimeChecked = currentMs;
		}
		if (currentMs - dbItem->lastTimeChecked > debounceDelay) {
			if (dbItem->previousState == dbItem->currentState) {
				dbItem->lastTimeChecked = currentMs;
				dbItem->currentDebouncedState = dbItem->currentState;
			}
		}
		dbItem->previousState = dbItem->currentState;
		dbItem = dbItem->nextItem;
		if (dbItem == nullptr) break;
	}
}

void FTDebouncer::checkStateChange() {
	DebounceItem *dbItem = firstDebounceItem;

	while (1) {
		if (dbItem->previousDebouncedState != dbItem->currentDebouncedState) {
			if (dbItem->currentDebouncedState == !dbItem->restState) {
				pinActivated(dbItem->pinNumber);
			}
			if (dbItem->currentDebouncedState == dbItem->restState) {
				pinDeactivated(dbItem->pinNumber);
			}
		}
		dbItem->previousDebouncedState = dbItem->currentDebouncedState;
		dbItem = dbItem->nextItem;
		if (dbItem == nullptr) break;
	}
}
uint8_t FTDebouncer::getPinsCount(){
	return debouncedItemsCount;
}<commit_msg>Use pointer as loop condition<commit_after>/*
* @Author: Ubi de Feo | Future Tailors
* @Date:   2017-07-09 16:34:07
* @Last Modified by:   ubi
* @Last Modified time: 2017-07-09 16:41:17
*/

#include "FTDebouncer.h"
/*	CONSTRUCTORS/DESTRUCTOR						*/
FTDebouncer::FTDebouncer() : debounceDelay(40) {
	debouncedItemsCount = 0;
	firstDebounceItem = lastDebounceItem = nullptr;
}
FTDebouncer::FTDebouncer(uint16_t _debounceTime) : debounceDelay(_debounceTime) {
	debouncedItemsCount = 0;
	firstDebounceItem = lastDebounceItem = nullptr;
}
FTDebouncer::~FTDebouncer() {
}

/*	METHODS										*/
void FTDebouncer::addPin(
	uint8_t _pinNr, uint8_t _restState) {
	DebounceItem *dbItem = new DebounceItem();

	dbItem->pinNumber = _pinNr;
	dbItem->restState = _restState;

	if (firstDebounceItem == nullptr) {
		firstDebounceItem = dbItem;
	} else {
		lastDebounceItem->nextItem = dbItem;
	}
	lastDebounceItem = dbItem;

	pinMode(_pinNr, INPUT);
	debouncedItemsCount++;

}
void FTDebouncer::addPin(uint8_t _pinNr, uint8_t _restState, uint8_t _pullUpMode) {
	DebounceItem *dbItem = new DebounceItem();

	dbItem->pinNumber = _pinNr;
	dbItem->restState = _restState;

	if (firstDebounceItem == nullptr) {
		firstDebounceItem = dbItem;
	} else {
		lastDebounceItem->nextItem = dbItem;
	}

	lastDebounceItem = dbItem;

	if (_pullUpMode == 0) {
		pinMode(_pinNr, INPUT);
	} else {
		pinMode(_pinNr, _pullUpMode);
	}

	debouncedItemsCount++;

}

void FTDebouncer::init() {
	unsigned long currentMs = millis();
	DebounceItem *dbItem = firstDebounceItem;

	while (dbItem != nullptr) {
		dbItem->lastTimeChecked = currentMs;
		dbItem->currentState = dbItem->previousState = dbItem->restState;
		dbItem->currentDebouncedState = dbItem->previousDebouncedState = dbItem->restState;
		dbItem = dbItem->nextItem;
	}
}

void FTDebouncer::run() {
	DebounceItem *dbItem = firstDebounceItem;
	while (dbItem != nullptr) {
		dbItem->currentState = digitalRead(dbItem->pinNumber);
		dbItem = dbItem->nextItem;
	}

	debouncePins();
	checkStateChange();
}
void FTDebouncer::debouncePins() {
	unsigned long currentMs = millis();
	DebounceItem *dbItem = firstDebounceItem;
	while (dbItem != nullptr) {
		if (dbItem->currentState != dbItem->previousState) {
			dbItem->lastTimeChecked = currentMs;
		}
		if (currentMs - dbItem->lastTimeChecked > debounceDelay) {
			if (dbItem->previousState == dbItem->currentState) {
				dbItem->lastTimeChecked = currentMs;
				dbItem->currentDebouncedState = dbItem->currentState;
			}
		}
		dbItem->previousState = dbItem->currentState;
		dbItem = dbItem->nextItem;
	}
}

void FTDebouncer::checkStateChange() {
	DebounceItem *dbItem = firstDebounceItem;

	while (dbItem != nullptr) {
		if (dbItem->previousDebouncedState != dbItem->currentDebouncedState) {
			if (dbItem->currentDebouncedState == !dbItem->restState) {
				pinActivated(dbItem->pinNumber);
			}
			if (dbItem->currentDebouncedState == dbItem->restState) {
				pinDeactivated(dbItem->pinNumber);
			}
		}
		dbItem->previousDebouncedState = dbItem->currentDebouncedState;
		dbItem = dbItem->nextItem;
	}
}
uint8_t FTDebouncer::getPinsCount(){
	return debouncedItemsCount;
}<|endoftext|>


<commit_before>/***************************************************`*************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: lorn.potter@jollamobile.com
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
****************************************************************************/

#include "qofonovoicecallmanager.h"
#include "dbus/ofonovoicecallmanager.h"

class QOfonoVoiceCallManagerPrivate
{
public:
    QOfonoVoiceCallManagerPrivate();
    QString modemPath;
    OfonoVoiceCallManager *voiceCallManager;
    QVariantMap properties;
    QStringList callList;
    QString errorMessage;

};

QOfonoVoiceCallManagerPrivate::QOfonoVoiceCallManagerPrivate() :
    modemPath(QString())
  , voiceCallManager(0)
  , callList(QStringList())
{
}

QOfonoVoiceCallManager::QOfonoVoiceCallManager(QObject *parent) :
    QObject(parent)
  , d_ptr(new QOfonoVoiceCallManagerPrivate)
{
}

QOfonoVoiceCallManager::~QOfonoVoiceCallManager()
{
    delete d_ptr;
}

void QOfonoVoiceCallManager::setModemPath(const QString &path)
{
    if (path == d_ptr->modemPath ||
            path.isEmpty())
        return;

    if (path != modemPath()) {
        if (d_ptr->voiceCallManager) {
            delete d_ptr->voiceCallManager;
            d_ptr->voiceCallManager = 0;
            d_ptr->properties.clear();
        }
        d_ptr->voiceCallManager = new OfonoVoiceCallManager("org.ofono", path, QDBusConnection::systemBus(),this);

        if (d_ptr->voiceCallManager->isValid()) {
            d_ptr->modemPath = path;

            connect(d_ptr->voiceCallManager,SIGNAL(PropertyChanged(QString,QDBusVariant)),
                    this,SLOT(propertyChanged(QString,QDBusVariant)));
            connectSignals();
            QDBusPendingReply<QVariantMap> reply;
            reply = d_ptr->voiceCallManager->GetProperties();
            reply.waitForFinished();
            d_ptr->properties = reply.value();
            Q_EMIT modemPathChanged(path);
        }
    }
}

QString QOfonoVoiceCallManager::modemPath() const
{
    return d_ptr->modemPath;
}

void QOfonoVoiceCallManager::propertyChanged(const QString& property, const QDBusVariant& dbusvalue)
{
    QVariant value = dbusvalue.variant();
    d_ptr->properties.insert(property,value);

    if (property == QLatin1String("EmergencyNumbers")) {
        Q_EMIT emergencyNumbersChanged(value.value<QStringList>());
    }
}

QStringList QOfonoVoiceCallManager::emergencyNumbers() const
{
    if(d_ptr->voiceCallManager)
       return  d_ptr->properties["EmergencyNumbers"].toStringList();

    return QStringList();
}

QStringList QOfonoVoiceCallManager::getCalls() const
{
    if(d_ptr->voiceCallManager) {
        d_ptr->callList.clear();
        QDBusReply<ObjectPathPropertiesList> reply = d_ptr->voiceCallManager->GetCalls();
        foreach(ObjectPathProperties calls, reply.value()) {
            d_ptr->callList << calls.path.path();
        }
    }
    return d_ptr->callList;
}

 void QOfonoVoiceCallManager::connectSignals()
 {
     disconnect(d_ptr->voiceCallManager,SIGNAL(CallAdded(QDBusObjectPath,QVariantMap)),
             this,SLOT(onCallAdded(QDBusObjectPath,QVariantMap)));
     disconnect(d_ptr->voiceCallManager,SIGNAL(CallRemoved(QDBusObjectPath)),
             this,SLOT(onCallRemoved(QDBusObjectPath)));

     disconnect(d_ptr->voiceCallManager,SIGNAL(BarringActive(QString)),
             this,SIGNAL(barringActive(QString)));
     disconnect(d_ptr->voiceCallManager,SIGNAL(Forwarded(QString)),
             this,SIGNAL(forwarded(QString)));

     connect(d_ptr->voiceCallManager,SIGNAL(CallAdded(QDBusObjectPath,QVariantMap)),
             this,SLOT(onCallAdded(QDBusObjectPath,QVariantMap)));
     connect(d_ptr->voiceCallManager,SIGNAL(CallRemoved(QDBusObjectPath)),
             this,SIGNAL(onCallRemoved(QDBusObjectPath)));

     connect(d_ptr->voiceCallManager,SIGNAL(BarringActive(QString)),
             this,SIGNAL(barringActive(QString)));
     connect(d_ptr->voiceCallManager,SIGNAL(Forwarded(QString)),
             this,SIGNAL(forwarded(QString)));

 }

 void QOfonoVoiceCallManager::dial(const QString &number, const QString &calleridHide)
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->Dial(number,calleridHide);
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(dialFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::hangupAll()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result =  d_ptr->voiceCallManager->HangupAll();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(hangupAllFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::sendTones(const QString &tonestring)
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->SendTones(tonestring);
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(sendTonesFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::transfer()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->Transfer();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(transferFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::swapCalls()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result =  d_ptr->voiceCallManager->SwapCalls();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(swapCallsFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::releaseAndAnswer()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->ReleaseAndAnswer();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(releaseAndAnswerFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::holdAndAnswer()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->HoldAndAnswer();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(holdAndAnswerFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::privateChat(const QString &path)
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<QList<QDBusObjectPath> > result = d_ptr->voiceCallManager->PrivateChat(QDBusObjectPath(path));
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(privateChatFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::createMultiparty()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<QList<QDBusObjectPath> > result = d_ptr->voiceCallManager->CreateMultiparty();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(createMultipartyFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::hangupMultiparty()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->HangupMultiparty();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(hangupMultipartyFinished(QDBusPendingCallWatcher*)));
     }
 }

 bool QOfonoVoiceCallManager::isValid() const
 {
     return d_ptr->voiceCallManager->isValid();
 }

 void QOfonoVoiceCallManager::dialFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT dialComplete(ok);

 }

 void QOfonoVoiceCallManager::hangupAllFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT hangupAllComplete(ok);
 }

 void QOfonoVoiceCallManager::sendTonesFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
//     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
//         ok = false;
     }
   //  Q_EMIT sendTonesComplete(ok);
 }

 void QOfonoVoiceCallManager::transferFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT transferComplete(ok);
 }

 void QOfonoVoiceCallManager::swapCallsFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT swapCallsComplete(ok);
 }

 void QOfonoVoiceCallManager::releaseAndAnswerFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT releaseAndAnswerComplete(ok);
 }

 void QOfonoVoiceCallManager::holdAndAnswerFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
          d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
          ok = false;
     }
    Q_EMIT holdAndAnswerComplete(ok);
 }

 void QOfonoVoiceCallManager::privateChatFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<QList<QDBusObjectPath> > reply = *call;
     QStringList calls;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     } else {
         Q_FOREACH(const QDBusObjectPath &path, reply.value())
             calls << path.path();

     }
     Q_EMIT privateChatComplete(ok, calls);
 }

 void QOfonoVoiceCallManager::createMultipartyFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
          d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
          ok = false;
     }
     Q_EMIT createMultipartyComplete(ok, QStringList());
 }

 void QOfonoVoiceCallManager::hangupMultipartyFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
          d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
          ok = false;
     }
     Q_EMIT hangupMultipartyComplete(ok);
 }

 QString QOfonoVoiceCallManager::errorMessage() const
 {
     return d_ptr->errorMessage;
 }

 void QOfonoVoiceCallManager::onCallRemoved(const QDBusObjectPath &path)
 {
     Q_EMIT callRemoved(path.path());
 }

 void QOfonoVoiceCallManager::onCallAdded(const QDBusObjectPath &path, const QVariantMap &)
 {
     Q_EMIT callAdded(path.path());
 }
<commit_msg>[libqofono] its a slot not a signal<commit_after>/***************************************************`*************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: lorn.potter@jollamobile.com
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
****************************************************************************/

#include "qofonovoicecallmanager.h"
#include "dbus/ofonovoicecallmanager.h"

class QOfonoVoiceCallManagerPrivate
{
public:
    QOfonoVoiceCallManagerPrivate();
    QString modemPath;
    OfonoVoiceCallManager *voiceCallManager;
    QVariantMap properties;
    QStringList callList;
    QString errorMessage;

};

QOfonoVoiceCallManagerPrivate::QOfonoVoiceCallManagerPrivate() :
    modemPath(QString())
  , voiceCallManager(0)
  , callList(QStringList())
{
}

QOfonoVoiceCallManager::QOfonoVoiceCallManager(QObject *parent) :
    QObject(parent)
  , d_ptr(new QOfonoVoiceCallManagerPrivate)
{
}

QOfonoVoiceCallManager::~QOfonoVoiceCallManager()
{
    delete d_ptr;
}

void QOfonoVoiceCallManager::setModemPath(const QString &path)
{
    if (path == d_ptr->modemPath ||
            path.isEmpty())
        return;

    if (path != modemPath()) {
        if (d_ptr->voiceCallManager) {
            delete d_ptr->voiceCallManager;
            d_ptr->voiceCallManager = 0;
            d_ptr->properties.clear();
        }
        d_ptr->voiceCallManager = new OfonoVoiceCallManager("org.ofono", path, QDBusConnection::systemBus(),this);

        if (d_ptr->voiceCallManager->isValid()) {
            d_ptr->modemPath = path;

            connect(d_ptr->voiceCallManager,SIGNAL(PropertyChanged(QString,QDBusVariant)),
                    this,SLOT(propertyChanged(QString,QDBusVariant)));
            connectSignals();
            QDBusPendingReply<QVariantMap> reply;
            reply = d_ptr->voiceCallManager->GetProperties();
            reply.waitForFinished();
            d_ptr->properties = reply.value();
            Q_EMIT modemPathChanged(path);
        }
    }
}

QString QOfonoVoiceCallManager::modemPath() const
{
    return d_ptr->modemPath;
}

void QOfonoVoiceCallManager::propertyChanged(const QString& property, const QDBusVariant& dbusvalue)
{
    QVariant value = dbusvalue.variant();
    d_ptr->properties.insert(property,value);

    if (property == QLatin1String("EmergencyNumbers")) {
        Q_EMIT emergencyNumbersChanged(value.value<QStringList>());
    }
}

QStringList QOfonoVoiceCallManager::emergencyNumbers() const
{
    if(d_ptr->voiceCallManager)
       return  d_ptr->properties["EmergencyNumbers"].toStringList();

    return QStringList();
}

QStringList QOfonoVoiceCallManager::getCalls() const
{
    if(d_ptr->voiceCallManager) {
        d_ptr->callList.clear();
        QDBusReply<ObjectPathPropertiesList> reply = d_ptr->voiceCallManager->GetCalls();
        foreach(ObjectPathProperties calls, reply.value()) {
            d_ptr->callList << calls.path.path();
        }
    }
    return d_ptr->callList;
}

 void QOfonoVoiceCallManager::connectSignals()
 {
     disconnect(d_ptr->voiceCallManager,SIGNAL(CallAdded(QDBusObjectPath,QVariantMap)),
             this,SLOT(onCallAdded(QDBusObjectPath,QVariantMap)));
     disconnect(d_ptr->voiceCallManager,SIGNAL(CallRemoved(QDBusObjectPath)),
             this,SLOT(onCallRemoved(QDBusObjectPath)));

     disconnect(d_ptr->voiceCallManager,SIGNAL(BarringActive(QString)),
             this,SIGNAL(barringActive(QString)));
     disconnect(d_ptr->voiceCallManager,SIGNAL(Forwarded(QString)),
             this,SIGNAL(forwarded(QString)));

     connect(d_ptr->voiceCallManager,SIGNAL(CallAdded(QDBusObjectPath,QVariantMap)),
             this,SLOT(onCallAdded(QDBusObjectPath,QVariantMap)));
     connect(d_ptr->voiceCallManager,SIGNAL(CallRemoved(QDBusObjectPath)),
             this,SLOT(onCallRemoved(QDBusObjectPath)));

     connect(d_ptr->voiceCallManager,SIGNAL(BarringActive(QString)),
             this,SIGNAL(barringActive(QString)));
     connect(d_ptr->voiceCallManager,SIGNAL(Forwarded(QString)),
             this,SIGNAL(forwarded(QString)));

 }

 void QOfonoVoiceCallManager::dial(const QString &number, const QString &calleridHide)
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->Dial(number,calleridHide);
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(dialFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::hangupAll()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result =  d_ptr->voiceCallManager->HangupAll();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(hangupAllFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::sendTones(const QString &tonestring)
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->SendTones(tonestring);
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(sendTonesFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::transfer()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->Transfer();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(transferFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::swapCalls()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result =  d_ptr->voiceCallManager->SwapCalls();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(swapCallsFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::releaseAndAnswer()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->ReleaseAndAnswer();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(releaseAndAnswerFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::holdAndAnswer()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->HoldAndAnswer();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(holdAndAnswerFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::privateChat(const QString &path)
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<QList<QDBusObjectPath> > result = d_ptr->voiceCallManager->PrivateChat(QDBusObjectPath(path));
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(privateChatFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::createMultiparty()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<QList<QDBusObjectPath> > result = d_ptr->voiceCallManager->CreateMultiparty();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(createMultipartyFinished(QDBusPendingCallWatcher*)));
     }
 }

 void QOfonoVoiceCallManager::hangupMultiparty()
 {
     if(d_ptr->voiceCallManager) {
         QDBusPendingReply<> result = d_ptr->voiceCallManager->HangupMultiparty();
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this);
         connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
                 SLOT(hangupMultipartyFinished(QDBusPendingCallWatcher*)));
     }
 }

 bool QOfonoVoiceCallManager::isValid() const
 {
     return d_ptr->voiceCallManager->isValid();
 }

 void QOfonoVoiceCallManager::dialFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT dialComplete(ok);

 }

 void QOfonoVoiceCallManager::hangupAllFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT hangupAllComplete(ok);
 }

 void QOfonoVoiceCallManager::sendTonesFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
//     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
//         ok = false;
     }
   //  Q_EMIT sendTonesComplete(ok);
 }

 void QOfonoVoiceCallManager::transferFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT transferComplete(ok);
 }

 void QOfonoVoiceCallManager::swapCallsFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT swapCallsComplete(ok);
 }

 void QOfonoVoiceCallManager::releaseAndAnswerFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     }
     Q_EMIT releaseAndAnswerComplete(ok);
 }

 void QOfonoVoiceCallManager::holdAndAnswerFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
          d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
          ok = false;
     }
    Q_EMIT holdAndAnswerComplete(ok);
 }

 void QOfonoVoiceCallManager::privateChatFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<QList<QDBusObjectPath> > reply = *call;
     QStringList calls;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
         d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
         ok = false;
     } else {
         Q_FOREACH(const QDBusObjectPath &path, reply.value())
             calls << path.path();

     }
     Q_EMIT privateChatComplete(ok, calls);
 }

 void QOfonoVoiceCallManager::createMultipartyFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
          d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
          ok = false;
     }
     Q_EMIT createMultipartyComplete(ok, QStringList());
 }

 void QOfonoVoiceCallManager::hangupMultipartyFinished(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<> reply = *call;
     bool ok = true;
     if (reply.isError()) {
         qWarning() << Q_FUNC_INFO << "failed:" << reply.error();
          d_ptr->errorMessage = reply.error().name() + " " + reply.error().message();
          ok = false;
     }
     Q_EMIT hangupMultipartyComplete(ok);
 }

 QString QOfonoVoiceCallManager::errorMessage() const
 {
     return d_ptr->errorMessage;
 }

 void QOfonoVoiceCallManager::onCallRemoved(const QDBusObjectPath &path)
 {
     Q_EMIT callRemoved(path.path());
 }

 void QOfonoVoiceCallManager::onCallAdded(const QDBusObjectPath &path, const QVariantMap &)
 {
     Q_EMIT callAdded(path.path());
 }
<|endoftext|>


<commit_before>#include "files.h"

#include "globals.h"

using namespace std;

Files::Files() {}

Files::Files(const Directory &folder, string type) {
  addFiles(folder, type);
}

Files::~Files() {}

Files Files::loadFromCpp(const File &file) {
  Files result;

  if (!file.isValid()) {
    cout << "Error: The file " << file.getFullPath().c_str() << " does not exist." << endl;
    return result;
  }

  ifstream* f = file.read();

  while (!f->eof()) {
    string line;
    getline(*f, line);

    vector<string> tokens = parseLine(line);
    if (tokens[0] == "#include") {
      string &token = tokens[1];
      if (token[0] == '"') {
	if (token[token.size() - 1] == '"') {
	  cout << "Adding " << token.substr(1, token.size() - 2) << endl;
	  File toAdd(file.getDirectory(), token.substr(1, token.size() - 2));
	  if (toAdd.isValid()) {
	    result.add(File(file.getDirectory(), token.substr(1, token.size() - 2)));
	  } else {
	    cout << "In " << file.getFullPath().c_str() << ": The included file " << toAdd.getFullPath().c_str() << " does not exist." << endl;
	  }
	}
      }
    }
  }

  delete f;

  return result;
}

vector<string> Files::parseLine(const string &line) {
  list<string> tokens;
  bool inString = false;
  string current = "";
  for (int i = 0; i < line.size(); i++) {
    if (inString) {
      current = current + string(1, line[i]);
      if (line[i] == '"') inString = false;
    } else if (line[i] == ' ') {
      if (current != "") tokens.push_back(current);
      current = "";
    } else {
      current = current + string(1, line[i]);
    }
  }

  if (current != "") tokens.push_back(current);

  return vector<string>(tokens.begin(), tokens.end());
}

void Files::addFiles(const Directory &folder, string type) {
  //cout << "Adding folders to \"" << folder.getPath() << "\"...\n";
  for (list<File>::const_iterator iter = folder.folders.begin(); iter != folder.folders.end(); iter++) {
    const File *i = &(*iter);
    if (i->isDirectory()) {
      if (!i->isPrevious()) {
	addFiles(Directory(*i), type);
      }
    }
  }

  //cout << "Adding files to \"" << folder.getPath() << "\"...\n";
  for (list<File>::const_iterator iter = folder.files.begin(); iter != folder.files.end(); iter++) {
    const File *i = &(*iter);
    if (i->isType(type)) add(*i); //files.push_back(*i);
  }

  //cout << "Done adding files to \"" << folder.getPath() << "\"\n";
}

void Files::output(ostream &to) {
  for (list<File>::iterator i = files.begin(); i != files.end(); i++) {
    File *f = &(*i);
    to << *f;
    to << endl;
  }
}

ostream &operator <<(ostream &to, Files &o) {
  o.output(to);
  return to;
}

void Files::append(const Files &files) {

  for (list<File>::const_iterator i = files.files.begin(); i != files.files.end(); i++) {
    bool found = false;
    for (list<File>::iterator j = this->files.begin(); j != this->files.end(); j++) {
      if (*i == *j) {
	found = true;
	break;
      }
    }

    if (!found) this->files.push_back(*i);
  }
}

void Files::add(const File &file) {
   bool found = false;
   for (list<File>::iterator j = this->files.begin(); j != this->files.end(); j++) {
     if (file == *j) {
       found = true;
       break;
     }
   }

   if (!found) this->files.push_back(file);
}

time_t Files::getLastModified() const {
  time_t latestTime = 0;
  for (list<File>::const_iterator i = files.begin(); i != files.end(); i++) {
    if (latestTime < i->getLastModified()) {
      latestTime = i->getLastModified();
    }
  }

  return latestTime;
}

Files Files::changeFiletypes(const string &to) {
  Files ret;

  for (list<File>::const_iterator i = files.begin(); i != files.end(); i++) {
    File modified = i->modifyType(to);
    if (modified.isValid()) ret.files.push_back(i->modifyType(to));
  }

  return ret;
}

bool Files::load(const File &file) {
  string f = file.getFullPath();

  if (settings.cache.files.count(f) <= 0) return false;

  IncludeCache::CachedCpp &cpp = settings.cache.files[f];

  if (cpp.modified < file.getLastModified()) {
    if (settings.debugOutput) {
      cout << "The file " << file.getTitle().c_str() <<
          " have been modified from " << cpp.modified << " to " <<
          file.getLastModified() << ". Renewing cache..." << endl;
    }
    return false;
  }

  bool valid = true;
  for (list<IncludeCache::CachedFile>::const_iterator i = cpp.includedFiles.begin(); i != cpp.includedFiles.end(); i++) {
    File incFile = File(i->file);
    if (i->modified < incFile.getLastModified()) {
      if (settings.debugOutput) {
	cout << "The file " << incFile.getTitle().c_str() <<
          " have been modified from " << i->modified << " to " <<
          incFile.getLastModified() << ". Renewing cache..." << endl;
      }
      valid = false;
      break;
    }

    files.push_back(incFile);
  }

  if (!valid) files.clear();

  return valid;
}

void Files::save(const File &file) const {
  IncludeCache::CachedCpp &cpp = settings.cache.files[file.getFullPath()];

  cpp.file = file.getFullPath();
  cpp.modified = file.getLastModified();

  cpp.includedFiles.clear();

  for (list<File>::const_iterator i = files.begin(); i != files.end(); i++) {
    File f(*i);
    if (settings.debugOutput) cout << "Stored file: " << f.getTitle().c_str() << ", time " << f.getLastModified() << endl;
    cpp.includedFiles.push_back(IncludeCache::CachedFile(f.getFullPath(), f.getLastModified()));
  }
}
<commit_msg>Forgot to remove a debug output<commit_after>#include "files.h"

#include "globals.h"

using namespace std;

Files::Files() {}

Files::Files(const Directory &folder, string type) {
  addFiles(folder, type);
}

Files::~Files() {}

Files Files::loadFromCpp(const File &file) {
  Files result;

  if (!file.isValid()) {
    cout << "Error: The file " << file.getFullPath().c_str() << " does not exist." << endl;
    return result;
  }

  ifstream* f = file.read();

  while (!f->eof()) {
    string line;
    getline(*f, line);

    vector<string> tokens = parseLine(line);
    if (tokens[0] == "#include") {
      string &token = tokens[1];
      if (token[0] == '"') {
	if (token[token.size() - 1] == '"') {
	  File toAdd(file.getDirectory(), token.substr(1, token.size() - 2));
	  if (toAdd.isValid()) {
	    result.add(File(file.getDirectory(), token.substr(1, token.size() - 2)));
	  } else {
	    cout << "In " << file.getFullPath().c_str() << ": The included file " << toAdd.getFullPath().c_str() << " does not exist." << endl;
	  }
	}
      }
    }
  }

  delete f;

  return result;
}

vector<string> Files::parseLine(const string &line) {
  list<string> tokens;
  bool inString = false;
  string current = "";
  for (int i = 0; i < line.size(); i++) {
    if (inString) {
      current = current + string(1, line[i]);
      if (line[i] == '"') inString = false;
    } else if (line[i] == ' ') {
      if (current != "") tokens.push_back(current);
      current = "";
    } else {
      current = current + string(1, line[i]);
    }
  }

  if (current != "") tokens.push_back(current);

  return vector<string>(tokens.begin(), tokens.end());
}

void Files::addFiles(const Directory &folder, string type) {
  //cout << "Adding folders to \"" << folder.getPath() << "\"...\n";
  for (list<File>::const_iterator iter = folder.folders.begin(); iter != folder.folders.end(); iter++) {
    const File *i = &(*iter);
    if (i->isDirectory()) {
      if (!i->isPrevious()) {
	addFiles(Directory(*i), type);
      }
    }
  }

  //cout << "Adding files to \"" << folder.getPath() << "\"...\n";
  for (list<File>::const_iterator iter = folder.files.begin(); iter != folder.files.end(); iter++) {
    const File *i = &(*iter);
    if (i->isType(type)) add(*i); //files.push_back(*i);
  }

  //cout << "Done adding files to \"" << folder.getPath() << "\"\n";
}

void Files::output(ostream &to) {
  for (list<File>::iterator i = files.begin(); i != files.end(); i++) {
    File *f = &(*i);
    to << *f;
    to << endl;
  }
}

ostream &operator <<(ostream &to, Files &o) {
  o.output(to);
  return to;
}

void Files::append(const Files &files) {

  for (list<File>::const_iterator i = files.files.begin(); i != files.files.end(); i++) {
    bool found = false;
    for (list<File>::iterator j = this->files.begin(); j != this->files.end(); j++) {
      if (*i == *j) {
	found = true;
	break;
      }
    }

    if (!found) this->files.push_back(*i);
  }
}

void Files::add(const File &file) {
   bool found = false;
   for (list<File>::iterator j = this->files.begin(); j != this->files.end(); j++) {
     if (file == *j) {
       found = true;
       break;
     }
   }

   if (!found) this->files.push_back(file);
}

time_t Files::getLastModified() const {
  time_t latestTime = 0;
  for (list<File>::const_iterator i = files.begin(); i != files.end(); i++) {
    if (latestTime < i->getLastModified()) {
      latestTime = i->getLastModified();
    }
  }

  return latestTime;
}

Files Files::changeFiletypes(const string &to) {
  Files ret;

  for (list<File>::const_iterator i = files.begin(); i != files.end(); i++) {
    File modified = i->modifyType(to);
    if (modified.isValid()) ret.files.push_back(i->modifyType(to));
  }

  return ret;
}

bool Files::load(const File &file) {
  string f = file.getFullPath();

  if (settings.cache.files.count(f) <= 0) return false;

  IncludeCache::CachedCpp &cpp = settings.cache.files[f];

  if (cpp.modified < file.getLastModified()) {
    if (settings.debugOutput) {
      cout << "The file " << file.getTitle().c_str() <<
          " have been modified from " << cpp.modified << " to " <<
          file.getLastModified() << ". Renewing cache..." << endl;
    }
    return false;
  }

  bool valid = true;
  for (list<IncludeCache::CachedFile>::const_iterator i = cpp.includedFiles.begin(); i != cpp.includedFiles.end(); i++) {
    File incFile = File(i->file);
    if (i->modified < incFile.getLastModified()) {
      if (settings.debugOutput) {
	cout << "The file " << incFile.getTitle().c_str() <<
          " have been modified from " << i->modified << " to " <<
          incFile.getLastModified() << ". Renewing cache..." << endl;
      }
      valid = false;
      break;
    }

    files.push_back(incFile);
  }

  if (!valid) files.clear();

  return valid;
}

void Files::save(const File &file) const {
  IncludeCache::CachedCpp &cpp = settings.cache.files[file.getFullPath()];

  cpp.file = file.getFullPath();
  cpp.modified = file.getLastModified();

  cpp.includedFiles.clear();

  for (list<File>::const_iterator i = files.begin(); i != files.end(); i++) {
    File f(*i);
    if (settings.debugOutput) cout << "Stored file: " << f.getTitle().c_str() << ", time " << f.getLastModified() << endl;
    cpp.includedFiles.push_back(IncludeCache::CachedFile(f.getFullPath(), f.getLastModified()));
  }
}
<|endoftext|>