<commit_before>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 * $Log$
 * Revision 1.9  2004/04/13 10:05:51  strk
 * GeometryLocation constructor made const-correct.
 * Fixed erroneus down-casting in DistanceOp::computeMinDistancePoints.
 *
 * Revision 1.8  2004/04/05 06:35:14  ybychkov
 * "operation/distance" upgraded to JTS 1.4
 *
 * Revision 1.7  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 * Revision 1.6  2003/10/16 08:50:00  strk
 * Memory leak fixes. Improved performance by mean of more calls to
 * new getCoordinatesRO() when applicable.
 *
 **********************************************************************/

#include "../../headers/opDistance.h"
#include "../../headers/geomUtil.h"

namespace geos {

/**
* Compute the distance between the closest points of two geometries.
* @param g0 a {@link Geometry}
* @param g1 another {@link Geometry}
* @return the distance between the geometries
*/
double DistanceOp::distance(Geometry *g0, Geometry *g1) {
	auto_ptr<DistanceOp> distOp(new DistanceOp(g0,g1));
	return distOp->distance();
}

/**
* Compute the the closest points of two geometries.
* The points are presented in the same order as the input Geometries.
*
* @param g0 a {@link Geometry}
* @param g1 another {@link Geometry}
* @return the closest points in the geometries
*/
CoordinateList* DistanceOp::closestPoints(Geometry *g0,Geometry *g1){
	auto_ptr<DistanceOp> distOp(new DistanceOp(g0,g1));
	return distOp->closestPoints();
}

DistanceOp::DistanceOp(Geometry *g0, Geometry *g1){
	ptLocator=new PointLocator();
	minDistance=DoubleInfinity;
	geom=new vector<Geometry*>(2);
//	minDistanceLocation=new vector<GeometryLocation*>();
	(*geom)[0]=g0;
	(*geom)[1]=g1;
}

DistanceOp::~DistanceOp(){
	delete ptLocator;
	delete geom;
//	delete minDistanceLocation;
}

/**
* Report the distance between the closest points on the input geometries.
*
* @return the distance between the geometries
*/
double DistanceOp::distance() {
	computeMinDistance();
	return minDistance;
}

/**
* Report the coordinates of the closest points in the input geometries.
* The points are presented in the same order as the input Geometries.
*
* @return a pair of {@link Coordinate}s of the closest points
*/
CoordinateList* DistanceOp::closestPoints() {
	computeMinDistance();
	CoordinateList* closestPts=CoordinateListFactory::internalFactory->createCoordinateList();
	closestPts->add((*minDistanceLocation)[0]->getCoordinate());
	closestPts->add((*minDistanceLocation)[1]->getCoordinate());
	return closestPts;
}

/**
* Report the locations of the closest points in the input geometries.
* The locations are presented in the same order as the input Geometries.
*
* @return a pair of {@link GeometryLocation}s for the closest points
*/
vector<GeometryLocation*>* DistanceOp::closestLocations(){
	computeMinDistance();
	return minDistanceLocation;
}

void DistanceOp::updateMinDistance(double dist) {
	if (dist<minDistance)
	minDistance=dist;
}

void DistanceOp::updateMinDistance(vector<GeometryLocation*> *locGeom, bool flip){
	// if not set then don't update
	if ((*locGeom)[0]==NULL) return;
	if (flip) {
		(*minDistanceLocation)[0]=(*locGeom)[1];
		(*minDistanceLocation)[1]=(*locGeom)[0];
	} else {
		(*minDistanceLocation)[0]=(*locGeom)[0];
		(*minDistanceLocation)[1]=(*locGeom)[1];
	}
}

void DistanceOp::computeMinDistance() {
    if (minDistanceLocation!=NULL) return;
    minDistanceLocation = new vector<GeometryLocation*>();
    computeContainmentDistance();
    if (minDistance<=0.0) return;
    computeLineDistance();
}

void DistanceOp::computeContainmentDistance() {
	vector<Geometry*> *polys0 = PolygonExtracter::getPolygons((*geom)[0]);
	vector<Geometry*> *polys1 = PolygonExtracter::getPolygons((*geom)[1]);
	vector<GeometryLocation*> *locPtPoly = new vector<GeometryLocation*>();
	// test if either geometry is wholely inside the other
	if (polys1->size()>0) {
		vector<GeometryLocation*> *insideLocs0 = ConnectedElementLocationFilter::getLocations((*geom)[0]);
		computeInside(insideLocs0, polys1, locPtPoly);
		if (minDistance <= 0.0) {
			(*minDistanceLocation)[0] = (*locPtPoly)[0];
			(*minDistanceLocation)[1] = (*locPtPoly)[1];
			delete polys0;
			delete polys1;
			delete locPtPoly;
			delete insideLocs0;
			return;
		}
		delete insideLocs0;
	}
	if (polys0->size()>0) {
		vector<GeometryLocation*> *insideLocs1 = ConnectedElementLocationFilter::getLocations((*geom)[1]);
		computeInside(insideLocs1, polys0, locPtPoly);
		if (minDistance <= 0.0) {
// flip locations, since we are testing geom 1 VS geom 0
			(*minDistanceLocation)[0] = (*locPtPoly)[1];
			(*minDistanceLocation)[1] = (*locPtPoly)[0];
			delete polys0;
			delete polys1;
			delete locPtPoly;
			delete insideLocs1;
			return;
		}
		delete insideLocs1;
	}
	delete polys0;
	delete polys1;
	delete locPtPoly;
}

void DistanceOp::computeInside(vector<GeometryLocation*> *locs,vector<Geometry*> *polys,vector<GeometryLocation*> *locPtPoly){
	for (int i=0;i<(int)locs->size();i++) {
		GeometryLocation *loc=(*locs)[i];
		for (int j=0;j<(int)polys->size();j++) {
			Polygon *poly=(Polygon*) (*polys)[j];
			computeInside(loc,poly,locPtPoly);
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeInside(GeometryLocation *ptLoc,Polygon *poly,vector<GeometryLocation*> *locPtPoly){
	Coordinate &pt=ptLoc->getCoordinate();
	if (Location::EXTERIOR!=ptLocator->locate(pt, poly)) {
		minDistance = 0.0;
		(*locPtPoly)[0] = ptLoc;
		GeometryLocation *locPoly = new GeometryLocation(poly, pt);
		(*locPtPoly)[1] = locPoly;
		return;
	}
}

void DistanceOp::computeLineDistance() {
	vector<GeometryLocation*> *locGeom = new vector<GeometryLocation*>;
	/**
	* Geometries are not wholely inside, so compute distance from lines and points
	* of one to lines and points of the other
	*/
	vector<Geometry*> *lines0=LinearComponentExtracter::getLines((*geom)[0]);
	vector<Geometry*> *lines1=LinearComponentExtracter::getLines((*geom)[1]);
	vector<Geometry*> *pts0=PointExtracter::getPoints((*geom)[0]);
	vector<Geometry*> *pts1=PointExtracter::getPoints((*geom)[1]);

	// bail whenever minDistance goes to zero, since it can't get any less
	computeMinDistanceLines(lines0, lines1, locGeom);
	updateMinDistance(locGeom, false);
	if (minDistance <= 0.0) {
		delete lines0;
		delete lines1;
		delete pts0;
		delete pts1;
		return;
	};
	(*locGeom)[0]=NULL;
	(*locGeom)[1]=NULL;
	computeMinDistanceLinesPoints(lines0, pts1, locGeom);
	updateMinDistance(locGeom, false);
	if (minDistance <= 0.0) {
		delete lines0;
		delete lines1;
		delete pts0;
		delete pts1;
		return;
	};
	(*locGeom)[0]=NULL;
	(*locGeom)[1]=NULL;
	computeMinDistanceLinesPoints(lines1, pts0, locGeom);
	updateMinDistance(locGeom, true);
	if (minDistance <= 0.0){
		delete lines0;
		delete lines1;
		delete pts0;
		delete pts1;
		return;
	};
	(*locGeom)[0]=NULL;
	(*locGeom)[1]=NULL;
	computeMinDistancePoints(pts0, pts1, locGeom);
	updateMinDistance(locGeom, false);
}

void DistanceOp::computeMinDistanceLines(vector<Geometry*> *lines0,vector<Geometry*> *lines1,vector<GeometryLocation*> *locGeom){
	for (int i=0;i<(int)lines0->size();i++) {
		LineString *line0=(LineString*) (*lines0)[i];
		for (int j=0;j<(int)lines1->size();j++) {
			LineString *line1=(LineString*) (*lines1)[j];
			computeMinDistance(line0,line1,locGeom);
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistancePoints(vector<Geometry*> *points0,vector<Geometry*> *points1,vector<GeometryLocation*> *locGeom){
	for (int i=0;i<(int)points0->size();i++) {
		//Point *pt0=(Point*) (*points0)[i];
		Geometry *pt0=(*points0)[i];
		for (int j=0;j<(int)points1->size();j++) {
			//Point *pt1=(Point*) (*points1)[j];
			Geometry *pt1=(*points1)[j];
			double dist=pt0->getCoordinate()->distance(*(pt1->getCoordinate()));
			if (dist < minDistance) {
				minDistance = dist;
				// this is wrong - need to determine closest points on both segments!!!
				(*locGeom)[0] = new GeometryLocation(pt0, 0, *(pt0->getCoordinate()));
				(*locGeom)[1] = new GeometryLocation(pt1, 0, *(pt1->getCoordinate()));
			}
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistanceLinesPoints(vector<Geometry*> *lines,vector<Geometry*> *points,vector<GeometryLocation*> *locGeom){
	for (int i=0;i<(int)lines->size();i++) {
		LineString *line=(LineString*) (*lines)[i];
		for (int j=0;j<(int)points->size();j++) {
			Point *pt=(Point*) (*points)[j];
			computeMinDistance(line,pt,locGeom);
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistance(LineString *line0, LineString *line1,vector<GeometryLocation*> *locGeom) {
	Envelope *env0=line0->getEnvelopeInternal();
	Envelope *env1=line1->getEnvelopeInternal();
	if (env0->distance(env1)>minDistance) {
		delete env0;
		delete env1;
		return;
	}
	delete env0;
	delete env1;
	CoordinateList *coord0=line0->getCoordinates();
	CoordinateList *coord1=line1->getCoordinates();
	// brute force approach!
	for(int i=0;i<coord0->getSize()-1;i++) {
		for(int j=0;j<coord1->getSize()-1;j++) {
			double dist=CGAlgorithms::distanceLineLine(coord0->getAt(i),coord0->getAt(i+1),
				coord1->getAt(j),coord1->getAt(j+1));
			if (dist < minDistance) {
				minDistance = dist;
				LineSegment *seg0 = new LineSegment(coord0->getAt(i), coord0->getAt(i + 1));
				LineSegment *seg1 = new LineSegment(coord1->getAt(j), coord1->getAt(j + 1));
				CoordinateList* closestPt = seg0->closestPoints(seg1);
				(*locGeom)[0] = new GeometryLocation(line0, i, (Coordinate)closestPt->getAt(0));
				(*locGeom)[1] = new GeometryLocation(line1, j, (Coordinate)closestPt->getAt(1));
			}
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistance(LineString *line,Point *pt,vector<GeometryLocation*> *locGeom){
	Envelope *env0=line->getEnvelopeInternal();
	Envelope *env1=pt->getEnvelopeInternal();
	if (env0->distance(env1)>minDistance) {
		delete env0;
		delete env1;
		return;
	}
	delete env0;
	delete env1;
	CoordinateList *coord0=line->getCoordinates();
	const Coordinate *coord=pt->getCoordinate();
	// brute force approach!
	for(int i=0;i<coord0->getSize()-1;i++) {
		double dist=CGAlgorithms::distancePointLine(*coord,coord0->getAt(i),coord0->getAt(i+1));
        if (dist < minDistance) {
          minDistance = dist;
		  LineSegment *seg = new LineSegment(coord0->getAt(i), coord0->getAt(i + 1));
          const Coordinate *segClosestPoint = seg->closestPoint(*coord);
          (*locGeom)[0] = new GeometryLocation(line, i, (Coordinate)*segClosestPoint);
          (*locGeom)[1] = new GeometryLocation(pt, 0, (Coordinate)*coord);
        }
		if (minDistance<=0.0) return;
	}
}
}

<commit_msg>Uncommented initializzazion and destruction of DistanceOp::minDistanceLocation<commit_after>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 * $Log$
 * Revision 1.10  2004/04/14 10:56:38  strk
 * Uncommented initializzazion and destruction of DistanceOp::minDistanceLocation
 *
 * Revision 1.9  2004/04/13 10:05:51  strk
 * GeometryLocation constructor made const-correct.
 * Fixed erroneus down-casting in DistanceOp::computeMinDistancePoints.
 *
 * Revision 1.8  2004/04/05 06:35:14  ybychkov
 * "operation/distance" upgraded to JTS 1.4
 *
 * Revision 1.7  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 * Revision 1.6  2003/10/16 08:50:00  strk
 * Memory leak fixes. Improved performance by mean of more calls to
 * new getCoordinatesRO() when applicable.
 *
 **********************************************************************/

#include "../../headers/opDistance.h"
#include "../../headers/geomUtil.h"

namespace geos {

/**
* Compute the distance between the closest points of two geometries.
* @param g0 a {@link Geometry}
* @param g1 another {@link Geometry}
* @return the distance between the geometries
*/
double DistanceOp::distance(Geometry *g0, Geometry *g1) {
	auto_ptr<DistanceOp> distOp(new DistanceOp(g0,g1));
	return distOp->distance();
}

/**
* Compute the the closest points of two geometries.
* The points are presented in the same order as the input Geometries.
*
* @param g0 a {@link Geometry}
* @param g1 another {@link Geometry}
* @return the closest points in the geometries
*/
CoordinateList* DistanceOp::closestPoints(Geometry *g0,Geometry *g1){
	auto_ptr<DistanceOp> distOp(new DistanceOp(g0,g1));
	return distOp->closestPoints();
}

DistanceOp::DistanceOp(Geometry *g0, Geometry *g1){
	ptLocator=new PointLocator();
	minDistance=DoubleInfinity;
	geom=new vector<Geometry*>(2);
	minDistanceLocation=new vector<GeometryLocation*>();
	(*geom)[0]=g0;
	(*geom)[1]=g1;
}

DistanceOp::~DistanceOp(){
	delete ptLocator;
	delete geom;
	delete minDistanceLocation;
}

/**
* Report the distance between the closest points on the input geometries.
*
* @return the distance between the geometries
*/
double DistanceOp::distance() {
	computeMinDistance();
	return minDistance;
}

/**
* Report the coordinates of the closest points in the input geometries.
* The points are presented in the same order as the input Geometries.
*
* @return a pair of {@link Coordinate}s of the closest points
*/
CoordinateList* DistanceOp::closestPoints() {
	computeMinDistance();
	CoordinateList* closestPts=CoordinateListFactory::internalFactory->createCoordinateList();
	closestPts->add((*minDistanceLocation)[0]->getCoordinate());
	closestPts->add((*minDistanceLocation)[1]->getCoordinate());
	return closestPts;
}

/**
* Report the locations of the closest points in the input geometries.
* The locations are presented in the same order as the input Geometries.
*
* @return a pair of {@link GeometryLocation}s for the closest points
*/
vector<GeometryLocation*>* DistanceOp::closestLocations(){
	computeMinDistance();
	return minDistanceLocation;
}

void DistanceOp::updateMinDistance(double dist) {
	if (dist<minDistance)
	minDistance=dist;
}

void DistanceOp::updateMinDistance(vector<GeometryLocation*> *locGeom, bool flip){
	// if not set then don't update
	if ((*locGeom)[0]==NULL) return;
	if (flip) {
		(*minDistanceLocation)[0]=(*locGeom)[1];
		(*minDistanceLocation)[1]=(*locGeom)[0];
	} else {
		(*minDistanceLocation)[0]=(*locGeom)[0];
		(*minDistanceLocation)[1]=(*locGeom)[1];
	}
}

void DistanceOp::computeMinDistance() {
    if (minDistanceLocation!=NULL) return;
    minDistanceLocation = new vector<GeometryLocation*>();
    computeContainmentDistance();
    if (minDistance<=0.0) return;
    computeLineDistance();
}

void DistanceOp::computeContainmentDistance() {
	vector<Geometry*> *polys0 = PolygonExtracter::getPolygons((*geom)[0]);
	vector<Geometry*> *polys1 = PolygonExtracter::getPolygons((*geom)[1]);
	vector<GeometryLocation*> *locPtPoly = new vector<GeometryLocation*>();
	// test if either geometry is wholely inside the other
	if (polys1->size()>0) {
		vector<GeometryLocation*> *insideLocs0 = ConnectedElementLocationFilter::getLocations((*geom)[0]);
		computeInside(insideLocs0, polys1, locPtPoly);
		if (minDistance <= 0.0) {
			(*minDistanceLocation)[0] = (*locPtPoly)[0];
			(*minDistanceLocation)[1] = (*locPtPoly)[1];
			delete polys0;
			delete polys1;
			delete locPtPoly;
			delete insideLocs0;
			return;
		}
		delete insideLocs0;
	}
	if (polys0->size()>0) {
		vector<GeometryLocation*> *insideLocs1 = ConnectedElementLocationFilter::getLocations((*geom)[1]);
		computeInside(insideLocs1, polys0, locPtPoly);
		if (minDistance <= 0.0) {
// flip locations, since we are testing geom 1 VS geom 0
			(*minDistanceLocation)[0] = (*locPtPoly)[1];
			(*minDistanceLocation)[1] = (*locPtPoly)[0];
			delete polys0;
			delete polys1;
			delete locPtPoly;
			delete insideLocs1;
			return;
		}
		delete insideLocs1;
	}
	delete polys0;
	delete polys1;
	delete locPtPoly;
}

void DistanceOp::computeInside(vector<GeometryLocation*> *locs,vector<Geometry*> *polys,vector<GeometryLocation*> *locPtPoly){
	for (int i=0;i<(int)locs->size();i++) {
		GeometryLocation *loc=(*locs)[i];
		for (int j=0;j<(int)polys->size();j++) {
			Polygon *poly=(Polygon*) (*polys)[j];
			computeInside(loc,poly,locPtPoly);
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeInside(GeometryLocation *ptLoc,Polygon *poly,vector<GeometryLocation*> *locPtPoly){
	Coordinate &pt=ptLoc->getCoordinate();
	if (Location::EXTERIOR!=ptLocator->locate(pt, poly)) {
		minDistance = 0.0;
		(*locPtPoly)[0] = ptLoc;
		GeometryLocation *locPoly = new GeometryLocation(poly, pt);
		(*locPtPoly)[1] = locPoly;
		return;
	}
}

void DistanceOp::computeLineDistance() {
	vector<GeometryLocation*> *locGeom = new vector<GeometryLocation*>;
	/**
	* Geometries are not wholely inside, so compute distance from lines and points
	* of one to lines and points of the other
	*/
	vector<Geometry*> *lines0=LinearComponentExtracter::getLines((*geom)[0]);
	vector<Geometry*> *lines1=LinearComponentExtracter::getLines((*geom)[1]);
	vector<Geometry*> *pts0=PointExtracter::getPoints((*geom)[0]);
	vector<Geometry*> *pts1=PointExtracter::getPoints((*geom)[1]);

	// bail whenever minDistance goes to zero, since it can't get any less
	computeMinDistanceLines(lines0, lines1, locGeom);
	updateMinDistance(locGeom, false);
	if (minDistance <= 0.0) {
		delete lines0;
		delete lines1;
		delete pts0;
		delete pts1;
		return;
	};
	(*locGeom)[0]=NULL;
	(*locGeom)[1]=NULL;
	computeMinDistanceLinesPoints(lines0, pts1, locGeom);
	updateMinDistance(locGeom, false);
	if (minDistance <= 0.0) {
		delete lines0;
		delete lines1;
		delete pts0;
		delete pts1;
		return;
	};
	(*locGeom)[0]=NULL;
	(*locGeom)[1]=NULL;
	computeMinDistanceLinesPoints(lines1, pts0, locGeom);
	updateMinDistance(locGeom, true);
	if (minDistance <= 0.0){
		delete lines0;
		delete lines1;
		delete pts0;
		delete pts1;
		return;
	};
	(*locGeom)[0]=NULL;
	(*locGeom)[1]=NULL;
	computeMinDistancePoints(pts0, pts1, locGeom);
	updateMinDistance(locGeom, false);
}

void DistanceOp::computeMinDistanceLines(vector<Geometry*> *lines0,vector<Geometry*> *lines1,vector<GeometryLocation*> *locGeom){
	for (int i=0;i<(int)lines0->size();i++) {
		LineString *line0=(LineString*) (*lines0)[i];
		for (int j=0;j<(int)lines1->size();j++) {
			LineString *line1=(LineString*) (*lines1)[j];
			computeMinDistance(line0,line1,locGeom);
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistancePoints(vector<Geometry*> *points0,vector<Geometry*> *points1,vector<GeometryLocation*> *locGeom){
	for (int i=0;i<(int)points0->size();i++) {
		//Point *pt0=(Point*) (*points0)[i];
		Geometry *pt0=(*points0)[i];
		for (int j=0;j<(int)points1->size();j++) {
			//Point *pt1=(Point*) (*points1)[j];
			Geometry *pt1=(*points1)[j];
			double dist=pt0->getCoordinate()->distance(*(pt1->getCoordinate()));
			if (dist < minDistance) {
				minDistance = dist;
				// this is wrong - need to determine closest points on both segments!!!
				(*locGeom)[0] = new GeometryLocation(pt0, 0, *(pt0->getCoordinate()));
				(*locGeom)[1] = new GeometryLocation(pt1, 0, *(pt1->getCoordinate()));
			}
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistanceLinesPoints(vector<Geometry*> *lines,vector<Geometry*> *points,vector<GeometryLocation*> *locGeom){
	for (int i=0;i<(int)lines->size();i++) {
		LineString *line=(LineString*) (*lines)[i];
		for (int j=0;j<(int)points->size();j++) {
			Point *pt=(Point*) (*points)[j];
			computeMinDistance(line,pt,locGeom);
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistance(LineString *line0, LineString *line1,vector<GeometryLocation*> *locGeom) {
	Envelope *env0=line0->getEnvelopeInternal();
	Envelope *env1=line1->getEnvelopeInternal();
	if (env0->distance(env1)>minDistance) {
		delete env0;
		delete env1;
		return;
	}
	delete env0;
	delete env1;
	CoordinateList *coord0=line0->getCoordinates();
	CoordinateList *coord1=line1->getCoordinates();
	// brute force approach!
	for(int i=0;i<coord0->getSize()-1;i++) {
		for(int j=0;j<coord1->getSize()-1;j++) {
			double dist=CGAlgorithms::distanceLineLine(coord0->getAt(i),coord0->getAt(i+1),
				coord1->getAt(j),coord1->getAt(j+1));
			if (dist < minDistance) {
				minDistance = dist;
				LineSegment *seg0 = new LineSegment(coord0->getAt(i), coord0->getAt(i + 1));
				LineSegment *seg1 = new LineSegment(coord1->getAt(j), coord1->getAt(j + 1));
				CoordinateList* closestPt = seg0->closestPoints(seg1);
				(*locGeom)[0] = new GeometryLocation(line0, i, (Coordinate)closestPt->getAt(0));
				(*locGeom)[1] = new GeometryLocation(line1, j, (Coordinate)closestPt->getAt(1));
			}
			if (minDistance<=0.0) return;
		}
	}
}

void DistanceOp::computeMinDistance(LineString *line,Point *pt,vector<GeometryLocation*> *locGeom){
	Envelope *env0=line->getEnvelopeInternal();
	Envelope *env1=pt->getEnvelopeInternal();
	if (env0->distance(env1)>minDistance) {
		delete env0;
		delete env1;
		return;
	}
	delete env0;
	delete env1;
	CoordinateList *coord0=line->getCoordinates();
	const Coordinate *coord=pt->getCoordinate();
	// brute force approach!
	for(int i=0;i<coord0->getSize()-1;i++) {
		double dist=CGAlgorithms::distancePointLine(*coord,coord0->getAt(i),coord0->getAt(i+1));
        if (dist < minDistance) {
          minDistance = dist;
		  LineSegment *seg = new LineSegment(coord0->getAt(i), coord0->getAt(i + 1));
          const Coordinate *segClosestPoint = seg->closestPoint(*coord);
          (*locGeom)[0] = new GeometryLocation(line, i, (Coordinate)*segClosestPoint);
          (*locGeom)[1] = new GeometryLocation(pt, 0, (Coordinate)*coord);
        }
		if (minDistance<=0.0) return;
	}
}
}

<|endoftext|>


<commit_before>#include <sltypes.h>
#include <slntuapi.h>
#include <slc.h>
#include <stdio.h>
#include <pushbase.h>
#include <hwinfo.h>
#include <sladl.h>
#include "AmdGpu.h"

#define R6XX_CONFIG_MEMSIZE 0x5428

SlAdl RdnAdl;

extern "C"
UINT8
GetRadeonTemp()
{
    UINT32 temp;

    temp = ReadGpuRegister(0x730);

    //printf("Tremp %x\n", temp);

    return temp;
}

/*extern "C"
UINT8
GetRadeonUsage()
{
     //ADL_Usages(0, &ADLactinfo);

    //return ADLactinfo.iActivityPercent;

    DWORD usage, reg6do;
    FLOAT f1;

    usage = ReadGpuRegister(0x668);

    reg6do = ReadGpuRegister(0x6D0);

    reg6do = (reg6do & 0x0000ffff);

    usage = (usage & 0x0000ffff);

    f1 = usage;

    f1 = f1 * 200.0f;

    f1 = f1 / (float) reg6do;

    return f1;
}*/

extern "C"
UINT16
GetRadeonMemorySize()
{
    return ReadGpuRegister(R6XX_CONFIG_MEMSIZE);
}

extern "C"
UINT16
RdnGetEngineClock()
{
    return RdnAdl.GetEngineClock();
}

extern "C"
UINT16
RdnGetMemoryClock()
{
    return RdnAdl.GetMemoryClock();
}

extern "C"
UINT16
RdnGetEngineClockMax()
{
    return RdnAdl.GetEngineClockMax();
}

extern "C"
UINT16
RdnGetMemoryClockMax()
{
    return RdnAdl.GetMemoryClockMax();
}

extern "C"
VOID
RdnSetMaxClocks()
{
    RdnAdl.SetMaxClocks();
}

UINT16
AmdGpu::GetEngineClock()
{
    return 0;
}

UINT16
AmdGpu::GetMemoryClock()
{
    return 0;
}

UINT64
AmdGpu::GetTotalMemory()
{
    return 0;
}

UINT64
AmdGpu::GetFreeMemory()
{
    return 0;
}

UINT8
AmdGpu::GetTemperature()
{
    return 0;
}

UINT8
AmdGpu::GetLoad()
{
    DWORD usage, reg6do;
    FLOAT f1;

    usage = ReadGpuRegister(0x668);

    reg6do = ReadGpuRegister(0x6D0);

    reg6do = (reg6do & 0x0000ffff);

    usage = (usage & 0x0000ffff);

    f1 = usage;

    f1 = f1 * 200.0f;

    f1 = f1 / (float) reg6do;

    return f1;
}

UINT16
AmdGpu::GetMaximumEngineClock()
{
    return 0;
}

UINT16
AmdGpu::GetMaximumMemoryClock()
{
    return 0;
}

VOID
AmdGpu::ForceMaximumClocks()
{

}<commit_msg>fixed amd gpu temperature<commit_after>#include <sltypes.h>
#include <slntuapi.h>
#include <slc.h>
#include <stdio.h>
#include <pushbase.h>
#include <hwinfo.h>
#include <sladl.h>
#include "AmdGpu.h"

#define R6XX_CONFIG_MEMSIZE 0x5428

SlAdl RdnAdl;

/*extern "C"
UINT8
GetRadeonTemp()
{
    UINT32 temp;

    temp = ReadGpuRegister(0x730);

    //printf("Tremp %x\n", temp);

    return temp;
}*/

extern "C"
UINT16
GetRadeonMemorySize()
{
    return ReadGpuRegister(R6XX_CONFIG_MEMSIZE);
}

extern "C"
UINT16
RdnGetEngineClock()
{
    return RdnAdl.GetEngineClock();
}

extern "C"
UINT16
RdnGetMemoryClock()
{
    return RdnAdl.GetMemoryClock();
}

extern "C"
UINT16
RdnGetEngineClockMax()
{
    return RdnAdl.GetEngineClockMax();
}

extern "C"
UINT16
RdnGetMemoryClockMax()
{
    return RdnAdl.GetMemoryClockMax();
}

extern "C"
VOID
RdnSetMaxClocks()
{
    RdnAdl.SetMaxClocks();
}

UINT16
AmdGpu::GetEngineClock()
{
    return 0;
}

UINT16
AmdGpu::GetMemoryClock()
{
    return 0;
}

UINT64
AmdGpu::GetTotalMemory()
{
    return 0;
}

UINT64
AmdGpu::GetFreeMemory()
{
    return 0;
}

UINT8
AmdGpu::GetTemperature()
{
    UINT32 temp;

    temp = ReadGpuRegister(0x730);

    return temp;
}

UINT8
AmdGpu::GetLoad()
{
    DWORD usage, reg6do;
    FLOAT f1;

    usage = ReadGpuRegister(0x668);

    reg6do = ReadGpuRegister(0x6D0);

    reg6do = (reg6do & 0x0000ffff);

    usage = (usage & 0x0000ffff);

    f1 = usage;

    f1 = f1 * 200.0f;

    f1 = f1 / (float) reg6do;

    return f1;
}

UINT16
AmdGpu::GetMaximumEngineClock()
{
    return 0;
}

UINT16
AmdGpu::GetMaximumMemoryClock()
{
    return 0;
}

VOID
AmdGpu::ForceMaximumClocks()
{

}<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/options/content_settings_window_view.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/views/options/advanced_page_view.h"
#include "chrome/browser/views/options/content_filter_page_view.h"
#include "chrome/browser/views/options/cookie_filter_page_view.h"
#include "chrome/browser/views/options/general_page_view.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "views/controls/tabbed_pane/tabbed_pane.h"
#include "views/widget/root_view.h"
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"

static ContentSettingsWindowView* instance_ = NULL;
// Content setting dialog bounds padding.
static const int kDialogPadding = 7;

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, public:

// static
void ContentSettingsWindowView::Show(ContentSettingsType page,
                                     Profile* profile) {
  DCHECK(profile);
  // If there's already an existing options window, activate it and switch to
  // the specified page.
  // TODO(beng): note this is not multi-simultaneous-profile-safe. When we care
  //             about this case this will have to be fixed.
  if (!instance_) {
    instance_ = new ContentSettingsWindowView(profile);
    views::Window::CreateChromeWindow(NULL, gfx::Rect(), instance_);
    // The window is alive by itself now...
  }
  instance_->ShowContentSettingsTab(page);
}

// static
void ContentSettingsWindowView::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0);
}

ContentSettingsWindowView::ContentSettingsWindowView(Profile* profile)
    // Always show preferences for the original profile. Most state when off
    // the record comes from the original profile, but we explicitly use
    // the original profile to avoid potential problems.
    : tabs_(NULL),
      profile_(profile->GetOriginalProfile()) {
  // We don't need to observe changes in this value.
  last_selected_page_.Init(prefs::kContentSettingsWindowLastTabIndex,
                           g_browser_process->local_state(), NULL);
}

ContentSettingsWindowView::~ContentSettingsWindowView() {
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, views::DialogDelegate implementation:

std::wstring ContentSettingsWindowView::GetWindowTitle() const {
  return l10n_util::GetString(IDS_CONTENT_SETTINGS_TITLE);
}

void ContentSettingsWindowView::WindowClosing() {
  instance_ = NULL;
}

bool ContentSettingsWindowView::Cancel() {
  return GetCurrentContentSettingsTabView()->CanClose();
}

views::View* ContentSettingsWindowView::GetContentsView() {
  return this;
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, views::TabbedPane::Listener implementation:

void ContentSettingsWindowView::TabSelectedAt(int index) {
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, views::View overrides:

void ContentSettingsWindowView::Layout() {
  tabs_->SetBounds(kDialogPadding, kDialogPadding,
                   width() - (2 * kDialogPadding),
                   height() - (2 * kDialogPadding));
}

gfx::Size ContentSettingsWindowView::GetPreferredSize() {
  return gfx::Size(views::Window::GetLocalizedContentsSize(
      IDS_CONTENT_SETTINGS_DIALOG_WIDTH_CHARS,
      IDS_CONTENT_SETTINGS_DIALOG_HEIGHT_LINES));
}

void ContentSettingsWindowView::ViewHierarchyChanged(bool is_add,
                                                     views::View* parent,
                                                     views::View* child) {
  // Can't init before we're inserted into a Container, because we require a
  // HWND to parent native child controls to.
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, private:

void ContentSettingsWindowView::Init() {
  // Make sure we don't leak memory by calling this twice.
  DCHECK(!tabs_);
  tabs_ = new views::TabbedPane;
  tabs_->SetListener(this);
  AddChildView(tabs_);
  int tab_index = 0;

  CookieFilterPageView* cookie_page = new CookieFilterPageView(profile_);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_COOKIES_TAB_LABEL),
                       cookie_page, false);

  ContentFilterPageView* image_page =
      new ContentFilterPageView(profile_,
                                IDS_IMAGES_SETTING_LABEL,
                                IDS_IMAGES_LOAD_RADIO,
                                IDS_IMAGES_NOLOAD_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_IMAGES_TAB_LABEL),
                       image_page, false);

  ContentFilterPageView* javascript_page =
      new ContentFilterPageView(profile_,
                                IDS_JS_SETTING_LABEL,
                                IDS_JS_ALLOW_RADIO,
                                IDS_JS_DONOTALLOW_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_JAVASCRIPT_TAB_LABEL),
                       javascript_page, false);

  ContentFilterPageView* plugin_page =
      new ContentFilterPageView(profile_,
                                IDS_PLUGIN_SETTING_LABEL,
                                IDS_PLUGIN_LOAD_RADIO,
                                IDS_PLUGIN_NOLOAD_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_PLUGIN_TAB_LABEL),
                       plugin_page, false);

  ContentFilterPageView* popup_page =
      new ContentFilterPageView(profile_,
                                IDS_POPUP_SETTING_LABEL,
                                IDS_POPUP_ALLOW_RADIO,
                                IDS_POPUP_BLOCK_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_POPUP_TAB_LABEL),
                       popup_page, false);

  DCHECK(tabs_->GetTabCount() == CONTENT_SETTINGS_NUM_TYPES);
}

void ContentSettingsWindowView::ShowContentSettingsTab(
    ContentSettingsType page) {
  // If the window is not yet visible, we need to show it (it will become
  // active), otherwise just bring it to the front.
  if (!window()->IsVisible())
    window()->Show();
  else
    window()->Activate();

  if (page == CONTENT_SETTINGS_TYPE_DEFAULT) {
    // Remember the last visited page from local state.
    page = static_cast<ContentSettingsType>(last_selected_page_.GetValue());
    if (page == CONTENT_SETTINGS_TYPE_DEFAULT)
      page = CONTENT_SETTINGS_FIRST_TYPE;
  }
  // If the page number is out of bounds, reset to the first tab.
  if (page < 0 || page >= tabs_->GetTabCount())
    page = CONTENT_SETTINGS_FIRST_TYPE;

  tabs_->SelectTabAt(static_cast<int>(page));
}

const OptionsPageView*
    ContentSettingsWindowView::GetCurrentContentSettingsTabView() const {
  return static_cast<OptionsPageView*>(tabs_->GetSelectedTab());
}
<commit_msg>Fix broken pref usage; I changed the registration to a user pref but didn't change the read.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/options/content_settings_window_view.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/views/options/advanced_page_view.h"
#include "chrome/browser/views/options/content_filter_page_view.h"
#include "chrome/browser/views/options/cookie_filter_page_view.h"
#include "chrome/browser/views/options/general_page_view.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "views/controls/tabbed_pane/tabbed_pane.h"
#include "views/widget/root_view.h"
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"

static ContentSettingsWindowView* instance_ = NULL;
// Content setting dialog bounds padding.
static const int kDialogPadding = 7;

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, public:

// static
void ContentSettingsWindowView::Show(ContentSettingsType page,
                                     Profile* profile) {
  DCHECK(profile);
  // If there's already an existing options window, activate it and switch to
  // the specified page.
  // TODO(beng): note this is not multi-simultaneous-profile-safe. When we care
  //             about this case this will have to be fixed.
  if (!instance_) {
    instance_ = new ContentSettingsWindowView(profile);
    views::Window::CreateChromeWindow(NULL, gfx::Rect(), instance_);
    // The window is alive by itself now...
  }
  instance_->ShowContentSettingsTab(page);
}

// static
void ContentSettingsWindowView::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0);
}

ContentSettingsWindowView::ContentSettingsWindowView(Profile* profile)
    // Always show preferences for the original profile. Most state when off
    // the record comes from the original profile, but we explicitly use
    // the original profile to avoid potential problems.
    : tabs_(NULL),
      profile_(profile->GetOriginalProfile()) {
  // We don't need to observe changes in this value.
  last_selected_page_.Init(prefs::kContentSettingsWindowLastTabIndex,
                           profile->GetPrefs(), NULL);
}

ContentSettingsWindowView::~ContentSettingsWindowView() {
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, views::DialogDelegate implementation:

std::wstring ContentSettingsWindowView::GetWindowTitle() const {
  return l10n_util::GetString(IDS_CONTENT_SETTINGS_TITLE);
}

void ContentSettingsWindowView::WindowClosing() {
  instance_ = NULL;
}

bool ContentSettingsWindowView::Cancel() {
  return GetCurrentContentSettingsTabView()->CanClose();
}

views::View* ContentSettingsWindowView::GetContentsView() {
  return this;
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, views::TabbedPane::Listener implementation:

void ContentSettingsWindowView::TabSelectedAt(int index) {
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, views::View overrides:

void ContentSettingsWindowView::Layout() {
  tabs_->SetBounds(kDialogPadding, kDialogPadding,
                   width() - (2 * kDialogPadding),
                   height() - (2 * kDialogPadding));
}

gfx::Size ContentSettingsWindowView::GetPreferredSize() {
  return gfx::Size(views::Window::GetLocalizedContentsSize(
      IDS_CONTENT_SETTINGS_DIALOG_WIDTH_CHARS,
      IDS_CONTENT_SETTINGS_DIALOG_HEIGHT_LINES));
}

void ContentSettingsWindowView::ViewHierarchyChanged(bool is_add,
                                                     views::View* parent,
                                                     views::View* child) {
  // Can't init before we're inserted into a Container, because we require a
  // HWND to parent native child controls to.
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// ContentSettingsWindowView, private:

void ContentSettingsWindowView::Init() {
  // Make sure we don't leak memory by calling this twice.
  DCHECK(!tabs_);
  tabs_ = new views::TabbedPane;
  tabs_->SetListener(this);
  AddChildView(tabs_);
  int tab_index = 0;

  CookieFilterPageView* cookie_page = new CookieFilterPageView(profile_);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_COOKIES_TAB_LABEL),
                       cookie_page, false);

  ContentFilterPageView* image_page =
      new ContentFilterPageView(profile_,
                                IDS_IMAGES_SETTING_LABEL,
                                IDS_IMAGES_LOAD_RADIO,
                                IDS_IMAGES_NOLOAD_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_IMAGES_TAB_LABEL),
                       image_page, false);

  ContentFilterPageView* javascript_page =
      new ContentFilterPageView(profile_,
                                IDS_JS_SETTING_LABEL,
                                IDS_JS_ALLOW_RADIO,
                                IDS_JS_DONOTALLOW_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_JAVASCRIPT_TAB_LABEL),
                       javascript_page, false);

  ContentFilterPageView* plugin_page =
      new ContentFilterPageView(profile_,
                                IDS_PLUGIN_SETTING_LABEL,
                                IDS_PLUGIN_LOAD_RADIO,
                                IDS_PLUGIN_NOLOAD_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_PLUGIN_TAB_LABEL),
                       plugin_page, false);

  ContentFilterPageView* popup_page =
      new ContentFilterPageView(profile_,
                                IDS_POPUP_SETTING_LABEL,
                                IDS_POPUP_ALLOW_RADIO,
                                IDS_POPUP_BLOCK_RADIO);
  tabs_->AddTabAtIndex(tab_index++,
                       l10n_util::GetString(IDS_POPUP_TAB_LABEL),
                       popup_page, false);

  DCHECK(tabs_->GetTabCount() == CONTENT_SETTINGS_NUM_TYPES);
}

void ContentSettingsWindowView::ShowContentSettingsTab(
    ContentSettingsType page) {
  // If the window is not yet visible, we need to show it (it will become
  // active), otherwise just bring it to the front.
  if (!window()->IsVisible())
    window()->Show();
  else
    window()->Activate();

  if (page == CONTENT_SETTINGS_TYPE_DEFAULT) {
    // Remember the last visited page from local state.
    page = static_cast<ContentSettingsType>(last_selected_page_.GetValue());
    if (page == CONTENT_SETTINGS_TYPE_DEFAULT)
      page = CONTENT_SETTINGS_FIRST_TYPE;
  }
  // If the page number is out of bounds, reset to the first tab.
  if (page < 0 || page >= tabs_->GetTabCount())
    page = CONTENT_SETTINGS_FIRST_TYPE;

  tabs_->SelectTabAt(static_cast<int>(page));
}

const OptionsPageView*
    ContentSettingsWindowView::GetCurrentContentSettingsTabView() const {
  return static_cast<OptionsPageView*>(tabs_->GetSelectedTab());
}
<|endoftext|>


<commit_before>/***************************************************************************
*   Copyright (C) 2004 by                                                 *
*   Jason Kivlighn (jkivlighn@gmail.com)                                  *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "authorlistview.h"

#include <kmessagebox.h>
#include <kconfig.h>
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kmenu.h>
#include <QList>

#include "backends/recipedb.h"
#include "dialogs/createelementdialog.h"
#include "dialogs/dependanciesdialog.h"

AuthorListView::AuthorListView( QWidget *parent, RecipeDB *db ) : DBListViewBase( parent, db, db->authorCount() )
{
	setAllColumnsShowFocus( true );
	setDefaultRenameAction( Q3ListView::Reject );
}

void AuthorListView::init()
{
	connect( database, SIGNAL( authorCreated( const Element & ) ), SLOT( checkCreateAuthor( const Element & ) ) );
	connect( database, SIGNAL( authorRemoved( int ) ), SLOT( removeAuthor( int ) ) );
}

void AuthorListView::load( int limit, int offset )
{
	ElementList authorList;
	database->loadAuthors( &authorList, limit, offset );

	setTotalItems(authorList.count());

	for ( ElementList::const_iterator ing_it = authorList.begin(); ing_it != authorList.end(); ++ing_it )
		createAuthor( *ing_it );
}

void AuthorListView::checkCreateAuthor( const Element &el )
{
	if ( handleElement(el.name) ) { //only create this author if the base class okays it
		createAuthor(el);
	}
}

StdAuthorListView::StdAuthorListView( QWidget *parent, RecipeDB *db, bool editable ) : AuthorListView( parent, db )
{
	addColumn( i18n( "Author" ) );

	KConfigGroup config = KGlobal::config()->group( "Advanced" );
	bool show_id = config.readEntry( "ShowID", false );
	addColumn( i18n( "Id" ), show_id ? -1 : 0 );

	if ( editable ) {
		setRenameable( 0, true );

		KIconLoader *il = KIconLoader::global();

		kpop = new KMenu( this );
		kpop->addAction( il->loadIcon( "document-new", KIconLoader::NoGroup, 16 ), i18n( "&Create" ), this, SLOT( createNew() ), Qt::CTRL + Qt::Key_N );
		kpop->addAction( il->loadIcon( "edit-delete", KIconLoader::NoGroup, 16 ), i18n( "&Delete" ), this, SLOT( remove
			                  () ), Qt::Key_Delete );
		kpop->addAction( il->loadIcon( "edit-rename", KIconLoader::NoGroup, 16 ), i18n( "&Rename" ), this, SLOT( slotRename() ), Qt::CTRL + Qt::Key_R );
		kpop->ensurePolished();

		connect( this, SIGNAL( contextMenu( K3ListView *, Q3ListViewItem *, const QPoint & ) ), SLOT( showPopup( K3ListView *, Q3ListViewItem *, const QPoint & ) ) );
		connect( this, SIGNAL( doubleClicked( Q3ListViewItem* ) ), this, SLOT( modAuthor( Q3ListViewItem* ) ) );
		connect( this, SIGNAL( itemRenamed( Q3ListViewItem* ) ), this, SLOT( saveAuthor( Q3ListViewItem* ) ) );
	}
}

void StdAuthorListView::showPopup( K3ListView * /*l*/, Q3ListViewItem *i, const QPoint &p )
{
	if ( i )
		kpop->exec( p );
}

void StdAuthorListView::createNew()
{
	CreateElementDialog * elementDialog = new CreateElementDialog( this, i18n( "New Author" ) );

	if ( elementDialog->exec() == QDialog::Accepted ) {
		QString result = elementDialog->newElementName();

		//check bounds first
		if ( checkBounds( result ) )
			database->createNewAuthor( result ); // Create the new author in the database
	}
        delete elementDialog;
}

void StdAuthorListView::remove
	()
{
	Q3ListViewItem * item = currentItem();

	if ( item ) {
		int id = item->text( 1 ).toInt();

		ElementList recipeDependancies;
		database->findUseOfAuthorInRecipes( &recipeDependancies, id );

		if ( recipeDependancies.isEmpty() ) {
			switch ( KMessageBox::warningContinueCancel( this, i18n( "Are you sure you want to delete this author?" ) ) ) {
				case KMessageBox::Continue:
					database->removeAuthor( id );
					break;
			}
			return;
		}
		else { // need warning!
			ListInfo info;
			info.list = recipeDependancies;
			info.name = i18n("Recipes");

			DependanciesDialog warnDialog( this, info, false );
			if ( warnDialog.exec() == QDialog::Accepted )
				database->removeAuthor( id );
		}
	}
}

void StdAuthorListView::slotRename()
{
    rename( 0, 0 );
}

void StdAuthorListView::rename( Q3ListViewItem* /*item*/,int /*c*/ )
{
	Q3ListViewItem * item = currentItem();

	if ( item )
		AuthorListView::rename( item, 0 );
}

void StdAuthorListView::createAuthor( const Element &author )
{
	createElement(new Q3ListViewItem( this, author.name, QString::number( author.id ) ));
}

void StdAuthorListView::removeAuthor( int id )
{
	Q3ListViewItem * item = findItem( QString::number( id ), 1 );
	removeElement(item);
}

void StdAuthorListView::modAuthor( Q3ListViewItem* i )
{
	if ( i )
		AuthorListView::rename( i, 0 );
}

void StdAuthorListView::saveAuthor( Q3ListViewItem* i )
{
	if ( !checkBounds( i->text( 0 ) ) ) {
		reload(ForceReload); //reset the changed text
		return ;
	}

	int existing_id = database->findExistingAuthorByName( i->text( 0 ) );
	int author_id = i->text( 1 ).toInt();
	if ( existing_id != -1 && existing_id != author_id )  //category already exists with this label... merge the two
	{
		switch ( KMessageBox::warningContinueCancel( this, i18n( "This author already exists.  Continuing will merge these two authors into one.  Are you sure?" ) ) )
		{
		case KMessageBox::Continue: {
				database->mergeAuthors( existing_id, author_id );
				break;
			}
		default:
			reload(ForceReload);
			break;
		}
	}
	else {
		database->modAuthor( ( i->text( 1 ) ).toInt(), i->text( 0 ) );
	}
}

bool StdAuthorListView::checkBounds( const QString &name )
{
	if ( name.length() > int(database->maxAuthorNameLength()) ) {
		KMessageBox::error( this, i18np( "Author name cannot be longer than 1 character.", "Author name cannot be longer than %1 characters." , database->maxAuthorNameLength() ));
		return false;
	}

	return true;
}

AuthorCheckListItem::AuthorCheckListItem( AuthorCheckListView* qlv, const Element &author ) : Q3CheckListItem( qlv, QString::null, Q3CheckListItem::CheckBox ),
	authorStored(author),
	m_listview(qlv)
{
}

AuthorCheckListItem::AuthorCheckListItem( AuthorCheckListView* qlv, Q3ListViewItem *after, const Element &author ) : Q3CheckListItem( qlv, after, QString::null, Q3CheckListItem::CheckBox ),
	authorStored(author),
	m_listview(qlv)
{
}

Element AuthorCheckListItem::author() const
{
	return authorStored;
}

QString AuthorCheckListItem::text( int column ) const
{
	switch ( column ) {
	case 0:
		return ( authorStored.name );
	case 1:
		return ( QString::number( authorStored.id ) );
	default:
		return QString::null;
	}
}

void AuthorCheckListItem::stateChange( bool on )
{
	m_listview->stateChange(this,on);
}

AuthorCheckListView::AuthorCheckListView( QWidget *parent, RecipeDB *db ) : AuthorListView( parent, db )
{
	addColumn( i18n( "Author" ) );

	KConfigGroup config = KGlobal::config()->group( "Advanced" );
	bool show_id = config.readEntry( "ShowID", false );
	addColumn( i18n( "Id" ), show_id ? -1 : 0 );
}

void AuthorCheckListView::createAuthor( const Element &author )
{
	createElement(new AuthorCheckListItem( this, author ));
}

void AuthorCheckListView::removeAuthor( int id )
{
	Q3ListViewItem * item = findItem( QString::number( id ), 1 );
	removeElement(item);
}

void AuthorCheckListView::load( int limit, int offset )
{
	AuthorListView::load(limit,offset);

	for ( QList<Element>::const_iterator author_it = m_selections.constBegin(); author_it != m_selections.constEnd(); ++author_it ) {
		Q3CheckListItem * item = ( Q3CheckListItem* ) findItem( QString::number( (*author_it).id ), 1 );
		if ( item ) {
			item->setOn(true);
		}
	}
}

void AuthorCheckListView::stateChange(AuthorCheckListItem *it,bool on)
{
	if ( !reloading() ) {
		if ( on )
			m_selections.append(it->author());
		else
			m_selections.removeAll(it->author());
	}
}

#include "authorlistview.moc"
<commit_msg>Fixes for krazy issues (not using QPointer when showing modal dialogs with exec() ), see: http://www.kdedevelopers.org/node/3919<commit_after>/***************************************************************************
*   Copyright (C) 2004 by                                                 *
*   Jason Kivlighn (jkivlighn@gmail.com)                                  *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "authorlistview.h"

#include <kmessagebox.h>
#include <kconfig.h>
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kmenu.h>
#include <QList>
#include <QPointer>

#include "backends/recipedb.h"
#include "dialogs/createelementdialog.h"
#include "dialogs/dependanciesdialog.h"

AuthorListView::AuthorListView( QWidget *parent, RecipeDB *db ) : DBListViewBase( parent, db, db->authorCount() )
{
	setAllColumnsShowFocus( true );
	setDefaultRenameAction( Q3ListView::Reject );
}

void AuthorListView::init()
{
	connect( database, SIGNAL( authorCreated( const Element & ) ), SLOT( checkCreateAuthor( const Element & ) ) );
	connect( database, SIGNAL( authorRemoved( int ) ), SLOT( removeAuthor( int ) ) );
}

void AuthorListView::load( int limit, int offset )
{
	ElementList authorList;
	database->loadAuthors( &authorList, limit, offset );

	setTotalItems(authorList.count());

	for ( ElementList::const_iterator ing_it = authorList.begin(); ing_it != authorList.end(); ++ing_it )
		createAuthor( *ing_it );
}

void AuthorListView::checkCreateAuthor( const Element &el )
{
	if ( handleElement(el.name) ) { //only create this author if the base class okays it
		createAuthor(el);
	}
}

StdAuthorListView::StdAuthorListView( QWidget *parent, RecipeDB *db, bool editable ) : AuthorListView( parent, db )
{
	addColumn( i18n( "Author" ) );

	KConfigGroup config = KGlobal::config()->group( "Advanced" );
	bool show_id = config.readEntry( "ShowID", false );
	addColumn( i18n( "Id" ), show_id ? -1 : 0 );

	if ( editable ) {
		setRenameable( 0, true );

		KIconLoader *il = KIconLoader::global();

		kpop = new KMenu( this );
		kpop->addAction( il->loadIcon( "document-new", KIconLoader::NoGroup, 16 ), i18n( "&Create" ), this, SLOT( createNew() ), Qt::CTRL + Qt::Key_N );
		kpop->addAction( il->loadIcon( "edit-delete", KIconLoader::NoGroup, 16 ), i18n( "&Delete" ), this, SLOT( remove
			                  () ), Qt::Key_Delete );
		kpop->addAction( il->loadIcon( "edit-rename", KIconLoader::NoGroup, 16 ), i18n( "&Rename" ), this, SLOT( slotRename() ), Qt::CTRL + Qt::Key_R );
		kpop->ensurePolished();

		connect( this, SIGNAL( contextMenu( K3ListView *, Q3ListViewItem *, const QPoint & ) ), SLOT( showPopup( K3ListView *, Q3ListViewItem *, const QPoint & ) ) );
		connect( this, SIGNAL( doubleClicked( Q3ListViewItem* ) ), this, SLOT( modAuthor( Q3ListViewItem* ) ) );
		connect( this, SIGNAL( itemRenamed( Q3ListViewItem* ) ), this, SLOT( saveAuthor( Q3ListViewItem* ) ) );
	}
}

void StdAuthorListView::showPopup( K3ListView * /*l*/, Q3ListViewItem *i, const QPoint &p )
{
	if ( i )
		kpop->exec( p );
}

void StdAuthorListView::createNew()
{
	QPointer<CreateElementDialog> elementDialog = new CreateElementDialog( this, i18n( "New Author" ) );

	if ( elementDialog->exec() == QDialog::Accepted ) {
		QString result = elementDialog->newElementName();

		//check bounds first
		if ( checkBounds( result ) )
			database->createNewAuthor( result ); // Create the new author in the database
	}
        delete elementDialog;
}

void StdAuthorListView::remove
	()
{
	Q3ListViewItem * item = currentItem();

	if ( item ) {
		int id = item->text( 1 ).toInt();

		ElementList recipeDependancies;
		database->findUseOfAuthorInRecipes( &recipeDependancies, id );

		if ( recipeDependancies.isEmpty() ) {
			switch ( KMessageBox::warningContinueCancel( this, i18n( "Are you sure you want to delete this author?" ) ) ) {
				case KMessageBox::Continue:
					database->removeAuthor( id );
					break;
			}
			return;
		}
		else { // need warning!
			ListInfo info;
			info.list = recipeDependancies;
			info.name = i18n("Recipes");

			QPointer<DependanciesDialog> warnDialog = new DependanciesDialog( this, info, false );
			if ( warnDialog->exec() == QDialog::Accepted )
				database->removeAuthor( id );

			delete warnDialog;
		}
	}
}

void StdAuthorListView::slotRename()
{
    rename( 0, 0 );
}

void StdAuthorListView::rename( Q3ListViewItem* /*item*/,int /*c*/ )
{
	Q3ListViewItem * item = currentItem();

	if ( item )
		AuthorListView::rename( item, 0 );
}

void StdAuthorListView::createAuthor( const Element &author )
{
	createElement(new Q3ListViewItem( this, author.name, QString::number( author.id ) ));
}

void StdAuthorListView::removeAuthor( int id )
{
	Q3ListViewItem * item = findItem( QString::number( id ), 1 );
	removeElement(item);
}

void StdAuthorListView::modAuthor( Q3ListViewItem* i )
{
	if ( i )
		AuthorListView::rename( i, 0 );
}

void StdAuthorListView::saveAuthor( Q3ListViewItem* i )
{
	if ( !checkBounds( i->text( 0 ) ) ) {
		reload(ForceReload); //reset the changed text
		return ;
	}

	int existing_id = database->findExistingAuthorByName( i->text( 0 ) );
	int author_id = i->text( 1 ).toInt();
	if ( existing_id != -1 && existing_id != author_id )  //category already exists with this label... merge the two
	{
		switch ( KMessageBox::warningContinueCancel( this, i18n( "This author already exists.  Continuing will merge these two authors into one.  Are you sure?" ) ) )
		{
		case KMessageBox::Continue: {
				database->mergeAuthors( existing_id, author_id );
				break;
			}
		default:
			reload(ForceReload);
			break;
		}
	}
	else {
		database->modAuthor( ( i->text( 1 ) ).toInt(), i->text( 0 ) );
	}
}

bool StdAuthorListView::checkBounds( const QString &name )
{
	if ( name.length() > int(database->maxAuthorNameLength()) ) {
		KMessageBox::error( this, i18np( "Author name cannot be longer than 1 character.", "Author name cannot be longer than %1 characters." , database->maxAuthorNameLength() ));
		return false;
	}

	return true;
}

AuthorCheckListItem::AuthorCheckListItem( AuthorCheckListView* qlv, const Element &author ) : Q3CheckListItem( qlv, QString::null, Q3CheckListItem::CheckBox ),
	authorStored(author),
	m_listview(qlv)
{
}

AuthorCheckListItem::AuthorCheckListItem( AuthorCheckListView* qlv, Q3ListViewItem *after, const Element &author ) : Q3CheckListItem( qlv, after, QString::null, Q3CheckListItem::CheckBox ),
	authorStored(author),
	m_listview(qlv)
{
}

Element AuthorCheckListItem::author() const
{
	return authorStored;
}

QString AuthorCheckListItem::text( int column ) const
{
	switch ( column ) {
	case 0:
		return ( authorStored.name );
	case 1:
		return ( QString::number( authorStored.id ) );
	default:
		return QString::null;
	}
}

void AuthorCheckListItem::stateChange( bool on )
{
	m_listview->stateChange(this,on);
}

AuthorCheckListView::AuthorCheckListView( QWidget *parent, RecipeDB *db ) : AuthorListView( parent, db )
{
	addColumn( i18n( "Author" ) );

	KConfigGroup config = KGlobal::config()->group( "Advanced" );
	bool show_id = config.readEntry( "ShowID", false );
	addColumn( i18n( "Id" ), show_id ? -1 : 0 );
}

void AuthorCheckListView::createAuthor( const Element &author )
{
	createElement(new AuthorCheckListItem( this, author ));
}

void AuthorCheckListView::removeAuthor( int id )
{
	Q3ListViewItem * item = findItem( QString::number( id ), 1 );
	removeElement(item);
}

void AuthorCheckListView::load( int limit, int offset )
{
	AuthorListView::load(limit,offset);

	for ( QList<Element>::const_iterator author_it = m_selections.constBegin(); author_it != m_selections.constEnd(); ++author_it ) {
		Q3CheckListItem * item = ( Q3CheckListItem* ) findItem( QString::number( (*author_it).id ), 1 );
		if ( item ) {
			item->setOn(true);
		}
	}
}

void AuthorCheckListView::stateChange(AuthorCheckListItem *it,bool on)
{
	if ( !reloading() ) {
		if ( on )
			m_selections.append(it->author());
		else
			m_selections.removeAll(it->author());
	}
}

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


<commit_before>/***************************************************************************
*   Copyright (C) 2004 by                                                 *
*   Jason Kivlighn (mizunoami44@users.sourceforge.net)                    *
*   Unai Garro (ugarro@users.sourceforge.net)                             *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "recipelistview.h"

#include <qintdict.h>
#include <qdatastream.h>

#include <kdebug.h>
#include <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>

#include "backends/recipedb.h"

class UncategorizedItem : public QListViewItem
{
public:
	UncategorizedItem( QListView *lv ) : QListViewItem( lv, i18n("Uncategorized") ){}
	int rtti() const { return 1006; }
};

RecipeItemDrag::RecipeItemDrag( RecipeListItem *recipeItem, QWidget *dragSource, const char *name )
		: QStoredDrag( RECIPEITEMMIMETYPE, dragSource, name )
{
	if ( recipeItem ) {
		QByteArray data;
		QDataStream out( data, IO_WriteOnly );
		out << recipeItem->recipeID();
		out << recipeItem->title();
		setEncodedData( data );
	}
}

bool RecipeItemDrag::canDecode( QMimeSource* e )
{
	return e->provides( RECIPEITEMMIMETYPE );
}

bool RecipeItemDrag::decode( const QMimeSource* e, RecipeListItem& item )
{
	if ( !e )
		return false;

	QByteArray data = e->encodedData( RECIPEITEMMIMETYPE );
	if ( data.isEmpty() )
		return false;

	QString title;
	int recipeID;
	QDataStream in( data, IO_ReadOnly );
	in >> recipeID;
	in >> title;

	item.setTitle( title );
	item.setRecipeID( recipeID );

	return true;
}

RecipeListView::RecipeListView( QWidget *parent, RecipeDB *db ) : StdCategoryListView( parent, db ),
		flat_list( false ),
		m_uncat_item(0)
{
	connect( database, SIGNAL( recipeCreated( const Element &, const ElementList & ) ), SLOT( createRecipe( const Element &, const ElementList & ) ) );
	connect( database, SIGNAL( recipeRemoved( int ) ), SLOT( removeRecipe( int ) ) );
	connect( database, SIGNAL( recipeRemoved( int, int ) ), SLOT( removeRecipe( int, int ) ) );
	connect( database, SIGNAL( recipeModified( const Element &, const ElementList & ) ), SLOT( modifyRecipe( const Element &, const ElementList & ) ) );

	setColumnText( 0, i18n( "Recipe" ) );

	KConfig *config = KGlobal::config(); config->setGroup( "Performance" );
	curr_limit = config->readNumEntry("CategoryLimit",-1);

	KIconLoader il;
	setPixmap( il.loadIcon( "categories", KIcon::NoGroup, 16 ) );
}

QDragObject *RecipeListView::dragObject()
{
	RecipeListItem * item = dynamic_cast<RecipeListItem*>( selectedItem() );
	if ( item != 0 ) {
		RecipeItemDrag * obj = new RecipeItemDrag( item, this, "Recipe drag item" );
		/*const QPixmap *pm = item->pixmap(0);
		if( pm )
			obj->setPixmap( *pm );*/
		return obj;
	}
	return 0;
}

bool RecipeListView::acceptDrag( QDropEvent *event ) const
{
	return RecipeItemDrag::canDecode( event );
}

void RecipeListView::load(int limit, int offset)
{
	m_uncat_item = 0;

	if ( flat_list ) {
		ElementList recipeList;
		database->loadRecipeList( &recipeList );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, -1 );
		}
	}
	else {
		StdCategoryListView::load(limit,offset);

		if ( offset == 0 ) {
			ElementList recipeList;
			database->loadUncategorizedRecipes( &recipeList );

			ElementList::const_iterator recipe_it;
			for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
				Recipe recipe;
				recipe.recipeID = ( *recipe_it ).id;
				recipe.title = ( *recipe_it ).name;
				createRecipe( recipe, -1 );
			}
		}
	}
}

void RecipeListView::populate( QListViewItem *item )
{
	StdCategoryListView::populate(item);

	if ( !flat_list ) {
		for ( QListViewItem *it = item->firstChild(); it; it = it->nextSibling() ) {
			if ( it->rtti() == RECIPELISTITEM_RTTI )
				return;
		}

		CategoryItemInfo *cat_item = dynamic_cast<CategoryItemInfo*>(item);
		if ( !cat_item ) return;

		int id = cat_item->categoryId();

		// Now show the recipes
		ElementList recipeList;
		database->loadRecipeList( &recipeList, id );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin(); recipe_it != recipeList.end(); ++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, id );
		}
	}
}

void RecipeListView::populateAll( QListViewItem *parent )
{
	if ( !parent )
		parent = firstChild();
	else {
		populate( parent );
		parent = parent->firstChild();
	}

	for ( QListViewItem *item = parent; item; item = item->nextSibling() ) {
		populateAll( item );
	}
}

void RecipeListView::createRecipe( const Recipe &recipe, int parent_id )
{
	if ( parent_id == -1 ) {
		if ( !m_uncat_item && curr_offset == 0 ) {
			m_uncat_item = new UncategorizedItem(this);
			if ( childCount() == 1 ) 		//only call createElement if this is the only item in the list
				createElement(m_uncat_item);	//otherwise, this item won't stay at the top
		}

		if ( m_uncat_item )
			new RecipeListItem( m_uncat_item, recipe );
	}
	else {
		CategoryListItem *parent = (CategoryListItem*)items_map[ parent_id ];
		if ( parent && parent->isPopulated() )
			createElement(new RecipeListItem( parent, recipe ));
	}
}

void RecipeListView::createRecipe( const Element &recipe_el, const ElementList &categories )
{
	Recipe recipe;
	recipe.recipeID = recipe_el.id;
	recipe.title = recipe_el.name;

	if ( categories.count() == 0 ) {
		createRecipe( recipe, -1 );
	}
	else {
		for ( ElementList::const_iterator cat_it = categories.begin(); cat_it != categories.end(); ++cat_it ) {
			int cur_cat_id = ( *cat_it ).id;

			QListViewItemIterator iterator( this );
			while ( iterator.current() ) {
				if ( iterator.current() ->rtti() == 1001 ) {
					CategoryListItem * cat_item = ( CategoryListItem* ) iterator.current();
					if ( cat_item->categoryId() == cur_cat_id ) {
						createRecipe( recipe, cur_cat_id );
					}
				}
				++iterator;
			}
		}
	}
}

void RecipeListView::modifyRecipe( const Element &recipe, const ElementList &categories )
{
	removeRecipe( recipe.id );
	createRecipe( recipe, categories );
}

void RecipeListView::removeRecipe( int id )
{
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();
			if ( recipe_it->recipeID() == id )
				removeElement(recipe_it);
		}
		++iterator;
	}
}

void RecipeListView::removeRecipe( int recipe_id, int cat_id )
{
	QListViewItem * item = items_map[ cat_id ];

	//find out if this is the only category the recipe belongs to
	int finds = 0;
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {
				if ( finds > 1 )
					break;
				finds++;
			}
		}
		++iterator;
	}

	//do this to only iterate over children of 'item'
	QListViewItem *pEndItem = NULL;
	QListViewItem *pStartItem = item;
	do {
		if ( pStartItem->nextSibling() )
			pEndItem = pStartItem->nextSibling();
		else
			pStartItem = pStartItem->parent();
	}
	while ( pStartItem && !pEndItem );

	iterator = QListViewItemIterator( item );
	while ( iterator.current() != pEndItem ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {

				if ( finds == 1 ) {
					//the item is now uncategorized
					if ( !m_uncat_item && curr_offset == 0 )
						m_uncat_item = new UncategorizedItem(this);
					if ( m_uncat_item ) {
						Recipe r;
						r.title = recipe_it->title(); r.recipeID = recipe_id;
						new RecipeListItem(m_uncat_item,r);
					}
				}
				removeElement(recipe_it);
				break;
			}
		}
		++iterator;
	}
}

void RecipeListView::removeCategory( int id )
{
	QListViewItem * item = items_map[ id ];
	if ( !item )
		return ; //this may have been deleted already by its parent being deleted

	moveChildrenToRoot( item );

	StdCategoryListView::removeCategory( id );
}

void RecipeListView::moveChildrenToRoot( QListViewItem *item )
{
	QListViewItem * next_sibling;
	for ( QListViewItem * it = item->firstChild(); it; it = next_sibling ) {
		next_sibling = it->nextSibling();
		if ( it->rtti() == 1000 ) {
			RecipeListItem *recipe_it = (RecipeListItem*) it;
			Recipe r;
			r.title = recipe_it->title(); r.recipeID = recipe_it->recipeID();

			//the item is now uncategorized
			removeElement(it,false);
			it->parent() ->takeItem( it );
			if ( !m_uncat_item && curr_offset == 0 )
				m_uncat_item = new UncategorizedItem(this);
			if ( m_uncat_item )
				new RecipeListItem(m_uncat_item,r);
		}
		moveChildrenToRoot( it );
		delete it;
	}
}

#include "recipelistview.moc"
<commit_msg>Boost performance just a bit on the search filter by performing fewer options to determine if an item has been populated.  In particular, we don't have to iterate through the listview to find this out.<commit_after>/***************************************************************************
*   Copyright (C) 2004 by                                                 *
*   Jason Kivlighn (mizunoami44@users.sourceforge.net)                    *
*   Unai Garro (ugarro@users.sourceforge.net)                             *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "recipelistview.h"

#include <qintdict.h>
#include <qdatastream.h>

#include <kdebug.h>
#include <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>

#include "backends/recipedb.h"

class UncategorizedItem : public QListViewItem
{
public:
	UncategorizedItem( QListView *lv ) : QListViewItem( lv, i18n("Uncategorized") ){}
	int rtti() const { return 1006; }
};

RecipeItemDrag::RecipeItemDrag( RecipeListItem *recipeItem, QWidget *dragSource, const char *name )
		: QStoredDrag( RECIPEITEMMIMETYPE, dragSource, name )
{
	if ( recipeItem ) {
		QByteArray data;
		QDataStream out( data, IO_WriteOnly );
		out << recipeItem->recipeID();
		out << recipeItem->title();
		setEncodedData( data );
	}
}

bool RecipeItemDrag::canDecode( QMimeSource* e )
{
	return e->provides( RECIPEITEMMIMETYPE );
}

bool RecipeItemDrag::decode( const QMimeSource* e, RecipeListItem& item )
{
	if ( !e )
		return false;

	QByteArray data = e->encodedData( RECIPEITEMMIMETYPE );
	if ( data.isEmpty() )
		return false;

	QString title;
	int recipeID;
	QDataStream in( data, IO_ReadOnly );
	in >> recipeID;
	in >> title;

	item.setTitle( title );
	item.setRecipeID( recipeID );

	return true;
}

RecipeListView::RecipeListView( QWidget *parent, RecipeDB *db ) : StdCategoryListView( parent, db ),
		flat_list( false ),
		m_uncat_item(0)
{
	connect( database, SIGNAL( recipeCreated( const Element &, const ElementList & ) ), SLOT( createRecipe( const Element &, const ElementList & ) ) );
	connect( database, SIGNAL( recipeRemoved( int ) ), SLOT( removeRecipe( int ) ) );
	connect( database, SIGNAL( recipeRemoved( int, int ) ), SLOT( removeRecipe( int, int ) ) );
	connect( database, SIGNAL( recipeModified( const Element &, const ElementList & ) ), SLOT( modifyRecipe( const Element &, const ElementList & ) ) );

	setColumnText( 0, i18n( "Recipe" ) );

	KConfig *config = KGlobal::config(); config->setGroup( "Performance" );
	curr_limit = config->readNumEntry("CategoryLimit",-1);

	KIconLoader il;
	setPixmap( il.loadIcon( "categories", KIcon::NoGroup, 16 ) );
}

QDragObject *RecipeListView::dragObject()
{
	RecipeListItem * item = dynamic_cast<RecipeListItem*>( selectedItem() );
	if ( item != 0 ) {
		RecipeItemDrag * obj = new RecipeItemDrag( item, this, "Recipe drag item" );
		/*const QPixmap *pm = item->pixmap(0);
		if( pm )
			obj->setPixmap( *pm );*/
		return obj;
	}
	return 0;
}

bool RecipeListView::acceptDrag( QDropEvent *event ) const
{
	return RecipeItemDrag::canDecode( event );
}

void RecipeListView::load(int limit, int offset)
{
	m_uncat_item = 0;

	if ( flat_list ) {
		ElementList recipeList;
		database->loadRecipeList( &recipeList );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, -1 );
		}
	}
	else {
		StdCategoryListView::load(limit,offset);

		if ( offset == 0 ) {
			ElementList recipeList;
			database->loadUncategorizedRecipes( &recipeList );

			ElementList::const_iterator recipe_it;
			for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
				Recipe recipe;
				recipe.recipeID = ( *recipe_it ).id;
				recipe.title = ( *recipe_it ).name;
				createRecipe( recipe, -1 );
			}
		}
	}
}

void RecipeListView::populate( QListViewItem *item )
{
	CategoryItemInfo *cat_item = dynamic_cast<CategoryItemInfo*>(item);
	if ( !cat_item || cat_item->isPopulated() ) return;

	StdCategoryListView::populate(item);

	if ( !flat_list ) {
		int id = cat_item->categoryId();

		// Now show the recipes
		ElementList recipeList;
		database->loadRecipeList( &recipeList, id );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin(); recipe_it != recipeList.end(); ++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, id );
		}
	}
}

void RecipeListView::populateAll( QListViewItem *parent )
{
	if ( !parent )
		parent = firstChild();
	else {
		populate( parent );
		parent = parent->firstChild();
	}

	for ( QListViewItem *item = parent; item; item = item->nextSibling() ) {
		populateAll( item );
	}
}

void RecipeListView::createRecipe( const Recipe &recipe, int parent_id )
{
	if ( parent_id == -1 ) {
		if ( !m_uncat_item && curr_offset == 0 ) {
			m_uncat_item = new UncategorizedItem(this);
			if ( childCount() == 1 ) 		//only call createElement if this is the only item in the list
				createElement(m_uncat_item);	//otherwise, this item won't stay at the top
		}

		if ( m_uncat_item )
			new RecipeListItem( m_uncat_item, recipe );
	}
	else {
		CategoryListItem *parent = (CategoryListItem*)items_map[ parent_id ];
		if ( parent && parent->isPopulated() )
			createElement(new RecipeListItem( parent, recipe ));
	}
}

void RecipeListView::createRecipe( const Element &recipe_el, const ElementList &categories )
{
	Recipe recipe;
	recipe.recipeID = recipe_el.id;
	recipe.title = recipe_el.name;

	if ( categories.count() == 0 ) {
		createRecipe( recipe, -1 );
	}
	else {
		for ( ElementList::const_iterator cat_it = categories.begin(); cat_it != categories.end(); ++cat_it ) {
			int cur_cat_id = ( *cat_it ).id;

			QListViewItemIterator iterator( this );
			while ( iterator.current() ) {
				if ( iterator.current() ->rtti() == 1001 ) {
					CategoryListItem * cat_item = ( CategoryListItem* ) iterator.current();
					if ( cat_item->categoryId() == cur_cat_id ) {
						createRecipe( recipe, cur_cat_id );
					}
				}
				++iterator;
			}
		}
	}
}

void RecipeListView::modifyRecipe( const Element &recipe, const ElementList &categories )
{
	removeRecipe( recipe.id );
	createRecipe( recipe, categories );
}

void RecipeListView::removeRecipe( int id )
{
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();
			if ( recipe_it->recipeID() == id )
				removeElement(recipe_it);
		}
		++iterator;
	}
}

void RecipeListView::removeRecipe( int recipe_id, int cat_id )
{
	QListViewItem * item = items_map[ cat_id ];

	//find out if this is the only category the recipe belongs to
	int finds = 0;
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {
				if ( finds > 1 )
					break;
				finds++;
			}
		}
		++iterator;
	}

	//do this to only iterate over children of 'item'
	QListViewItem *pEndItem = NULL;
	QListViewItem *pStartItem = item;
	do {
		if ( pStartItem->nextSibling() )
			pEndItem = pStartItem->nextSibling();
		else
			pStartItem = pStartItem->parent();
	}
	while ( pStartItem && !pEndItem );

	iterator = QListViewItemIterator( item );
	while ( iterator.current() != pEndItem ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {

				if ( finds == 1 ) {
					//the item is now uncategorized
					if ( !m_uncat_item && curr_offset == 0 )
						m_uncat_item = new UncategorizedItem(this);
					if ( m_uncat_item ) {
						Recipe r;
						r.title = recipe_it->title(); r.recipeID = recipe_id;
						new RecipeListItem(m_uncat_item,r);
					}
				}
				removeElement(recipe_it);
				break;
			}
		}
		++iterator;
	}
}

void RecipeListView::removeCategory( int id )
{
	QListViewItem * item = items_map[ id ];
	if ( !item )
		return ; //this may have been deleted already by its parent being deleted

	moveChildrenToRoot( item );

	StdCategoryListView::removeCategory( id );
}

void RecipeListView::moveChildrenToRoot( QListViewItem *item )
{
	QListViewItem * next_sibling;
	for ( QListViewItem * it = item->firstChild(); it; it = next_sibling ) {
		next_sibling = it->nextSibling();
		if ( it->rtti() == 1000 ) {
			RecipeListItem *recipe_it = (RecipeListItem*) it;
			Recipe r;
			r.title = recipe_it->title(); r.recipeID = recipe_it->recipeID();

			//the item is now uncategorized
			removeElement(it,false);
			it->parent() ->takeItem( it );
			if ( !m_uncat_item && curr_offset == 0 )
				m_uncat_item = new UncategorizedItem(this);
			if ( m_uncat_item )
				new RecipeListItem(m_uncat_item,r);
		}
		moveChildrenToRoot( it );
		delete it;
	}
}

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


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: BarChartTypeTemplate.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:45:18 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART_BARCHARTTYPETEMPLATE_HXX
#define CHART_BARCHARTTYPETEMPLATE_HXX

#include "OPropertySet.hxx"
#include "MutexContainer.hxx"

#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#include "ChartTypeTemplate.hxx"
#include "StackMode.hxx"

namespace chart
{

class BarChartTypeTemplate :
        public MutexContainer,
        public ChartTypeTemplate,
        public ::property::OPropertySet
{
public:
    enum BarDirection
    {
        HORIZONTAL,
        VERTICAL
    };

    explicit BarChartTypeTemplate(
        ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > const & xContext,
        const ::rtl::OUString & rServiceName,
        StackMode eStackMode,
        BarDirection eDirection,
        sal_Int32 nDim = 2 );
    virtual ~BarChartTypeTemplate();

    /// XServiceInfo declarations
    APPHELPER_XSERVICEINFO_DECL()

    /// merge XInterface implementations
     DECLARE_XINTERFACE()
    /// merge XTypeProvider implementations
     DECLARE_XTYPEPROVIDER()

protected:
    // ____ OPropertySet ____
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException);
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

    // ____ XPropertySet ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XChartTypeTemplate ____
    virtual sal_Bool SAL_CALL matchesTemplate(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram >& xDiagram,
        sal_Bool bAdaptProperties )
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > SAL_CALL
        getChartTypeForNewSeries( const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XChartType > >& aFormerlyUsedChartTypes )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL applyStyle(
        const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries,
        ::sal_Int32 nChartTypeGroupIndex,
        ::sal_Int32 nSeriesIndex,
        ::sal_Int32 nSeriesCount )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL resetStyles(
        const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& xDiagram )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ ChartTypeTemplate ____
    virtual sal_Int32 getDimension() const;
    virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const;

    virtual void createCoordinateSystems(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XCoordinateSystemContainer > & xCooSysCnt );

private:
    StackMode          m_eStackMode;
    BarDirection       m_eBarDirection;
    sal_Int32          m_nDim;
};

} //  namespace chart

// CHART_BARCHARTTYPETEMPLATE_HXX
#endif
<commit_msg>INTEGRATION: CWS chart17 (1.6.66); FILE MERGED 2007/11/05 14:04:10 iha 1.6.66.1: #i63857#, #i4039# more flexible placement of data point labels, best fit for pie labels<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: BarChartTypeTemplate.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-23 12:00:12 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART_BARCHARTTYPETEMPLATE_HXX
#define CHART_BARCHARTTYPETEMPLATE_HXX

#include "OPropertySet.hxx"
#include "MutexContainer.hxx"

#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#include "ChartTypeTemplate.hxx"
#include "StackMode.hxx"

namespace chart
{

class BarChartTypeTemplate :
        public MutexContainer,
        public ChartTypeTemplate,
        public ::property::OPropertySet
{
public:
    enum BarDirection
    {
        HORIZONTAL,
        VERTICAL
    };

    explicit BarChartTypeTemplate(
        ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > const & xContext,
        const ::rtl::OUString & rServiceName,
        StackMode eStackMode,
        BarDirection eDirection,
        sal_Int32 nDim = 2 );
    virtual ~BarChartTypeTemplate();

    /// XServiceInfo declarations
    APPHELPER_XSERVICEINFO_DECL()

    /// merge XInterface implementations
     DECLARE_XINTERFACE()
    /// merge XTypeProvider implementations
     DECLARE_XTYPEPROVIDER()

protected:
    // ____ OPropertySet ____
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException);
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

    // ____ XPropertySet ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XChartTypeTemplate ____
    virtual sal_Bool SAL_CALL matchesTemplate(
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDiagram >& xDiagram,
        sal_Bool bAdaptProperties )
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > SAL_CALL
        getChartTypeForNewSeries( const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XChartType > >& aFormerlyUsedChartTypes )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL applyStyle(
        const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries,
        ::sal_Int32 nChartTypeGroupIndex,
        ::sal_Int32 nSeriesIndex,
        ::sal_Int32 nSeriesCount )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL resetStyles(
        const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& xDiagram )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ ChartTypeTemplate ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >
                getChartTypeForIndex( sal_Int32 nChartTypeIndex );
    virtual sal_Int32 getDimension() const;
    virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const;
    virtual bool isSwapXAndY() const;

    virtual void createCoordinateSystems(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XCoordinateSystemContainer > & xCooSysCnt );

private:
    StackMode          m_eStackMode;
    BarDirection       m_eBarDirection;
    sal_Int32          m_nDim;
};

} //  namespace chart

// CHART_BARCHARTTYPETEMPLATE_HXX
#endif
<|endoftext|>


<commit_before>/**
   @file Clculo del coste de los caminos mnimos. Algoritmo de Floyd.
*/

#include <iostream>
using namespace std;
#include <ctime>
#include <cstdlib>
#include <climits>
#include <cassert>
#include <cmath>

static int const MAX_LONG  = 10;

/**********************************************************************/

/**
   @brief Reserva espacio en memoria dinmica para una matriz cuadrada.

   @param dim: dimensin de la matriz. dim > 0.

   @returns puntero a la zona de memoria reservada.
*/
int ** ReservaMatriz(int dim);

/**********************************************************************/

/**
   @brief Libera el espacio asignado a una matriz cuadrada.

   @param M: puntero a la zona de memoria reservada. Es MODIFICADO.
   @param dim: dimensin de la matriz. dim > 0.

   Liberar la zona memoria asignada a M y lo pone a NULL.
*/
void LiberaMatriz(int ** & M, int dim);

/**********************************************************************/

/**
   @brief Rellena una matriz cuadrada con valores aleaotorias.

   @param M: puntero a la zona de memoria reservada. Es MODIFICADO.
   @param dim: dimensin de la matriz. dim > 0.

   Asigna un valor aleatorio entero de [0, MAX_LONG - 1] a cada
   elemento de la matriz M, salvo los de la diagonal principal
   que quedan a 0..
*/
void RellenaMatriz(int **M, int dim);

/**********************************************************************/
/**
   @brief Clculo de caminos mnimos.

   @param M: Matriz de longitudes de los caminos. Es MODIFICADO.
   @param dim: dimensin de la matriz. dim > 0.

   Calcula la longitud del camino mnimo entre cada par de nodos (i,j),
   que se almacena en M[i][j].
*/
void Floyd(int **M, int dim);

/**********************************************************************/

/**
   Implementacin de las funciones
**/

int ** ReservaMatriz(int dim)
{
  int **M;
  if (dim  <= 0)
    {
      cerr<< "\n ERROR: Dimension de la matriz debe ser mayor que 0" << endl;
      exit(1);
    }
  M = new int * [dim];
  if (M == NULL)
    {
      cerr << "\n ERROR: No puedo reservar memoria para un matriz de "
	   << dim << " x " << dim << "elementos" << endl;
      exit(1);
    }
  for (int i = 0; i < dim; i++)
    {
      M[i]= new int [dim];
      if (M[i] == NULL)
	{
	  cerr << "ERROR: No puedo reservar memoria para un matriz de "
	       << dim << " x " << dim << endl;
	  for (int j = 0; j < i; j++)
	    delete [] M[i];
	  delete [] M;
	  exit(1);
	}
    }
  return M;
}

/**********************************************************************/

void LiberaMatriz(int ** & M, int dim)
{
  for (int i = 0; i < dim; i++)
    delete [] M[i];
  delete [] M;
  M = NULL;
}

/**********************************************************************/
void RellenaMatriz(int **M, int dim)
{
  for (int i = 0; i < dim; i++)
    for (int j = 0; j < dim; j++)
      if (i != j)
	M[i][j]= (rand() % MAX_LONG);
}

/**********************************************************************/
void Floyd(int **M, int dim)
{
	for (int k = 0; k < dim; k++)
	  for (int i = 0; i < dim;i++)
	    for (int j = 0; j < dim;j++)
	      {
		int sum = M[i][k] + M[k][j];
	    	M[i][j] = (M[i][j] > sum) ? sum : M[i][j];
	      }
}

/**********************************************************************/
int main (int argc, char **argv)
{
  clock_t tantes;    // Valor del reloj antes de la ejecucin
  clock_t tdespues;  // Valor del reloj despus de la ejecucin
  int dim;           // Dimensin de la matriz

  //Lectura de los parametros de entrada
  if (argc != 2)
    {
      cout << "Parmetros de entrada: " << endl
	   << "1.- Nmero de nodos" << endl << endl;
      return 1;
    }

  dim = atoi(argv[1]);
  int ** M = ReservaMatriz(dim);

  RellenaMatriz(M,dim);

  // Empieza el algoritmo de floyd
  tantes = clock();
  Floyd(M,dim);
  tdespues = clock();
  cout << dim << " " << ((double)(tdespues-tantes))/CLOCKS_PER_SEC << endl;
  LiberaMatriz(M,dim);

  return 0;
}

<commit_msg>Delete floyd.cpp<commit_after><|endoftext|>