<commit_before>
/******************************************************************
*
*	CyberX3D for C++
*
*	Copyright (C) Satoshi Konno 1996-2007
*
*	File:	ConeNode.cpp
*
******************************************************************/

#include <cybergarage/x3d/ConeNode.h>
#include <cybergarage/x3d/Graphic3D.h>

using namespace CyberX3D;

ConeNode::ConeNode()
{
	setHeaderFlag(false);
	setType(CONE_NODE);

	// bottomRadius field
	bottomRadiusField = new SFFloat(1.0f);
	addExposedField(bottomRadiusFieldString, bottomRadiusField);

	// height field
	heightField = new SFFloat(2.0f);
	addExposedField(heightFieldString, heightField);

	// side field
	sideField = new SFBool(true);
	addExposedField(sideFieldString, sideField);

	// bottom field
	bottomField = new SFBool(true);
	addExposedField(bottomFieldString, bottomField);

	///////////////////////////
	// Slice
	///////////////////////////

	setSlices(DEFAULT_CONENODE_SLICES);
}

ConeNode::~ConeNode()
{
}

////////////////////////////////////////////////
//	bottomRadius
////////////////////////////////////////////////

SFFloat *ConeNode::getBottomRadiusField() const
{
	if (isInstanceNode() == false)
		return bottomRadiusField;
	return (SFFloat *)getExposedField(bottomRadiusFieldString);
}

void ConeNode::setBottomRadius(float value)
{
	getBottomRadiusField()->setValue(value);
}

float ConeNode::getBottomRadius()  const
{
	return getBottomRadiusField()->getValue();
}

////////////////////////////////////////////////
//	height
////////////////////////////////////////////////

SFFloat *ConeNode::getHeightField() const
{
	if (isInstanceNode() == false)
		return heightField;
	return (SFFloat *)getExposedField(heightFieldString);
}

void ConeNode::setHeight(float value)
{
	getHeightField()->setValue(value);
}

float ConeNode::getHeight()  const
{
	return getHeightField()->getValue();
}

////////////////////////////////////////////////
//	side
////////////////////////////////////////////////

SFBool *ConeNode::getSideField() const
{
	if (isInstanceNode() == false)
		return sideField;
	return (SFBool *)getExposedField(sideFieldString);
}

void ConeNode::setSide(bool value)
{
	getSideField()->setValue(value);
}

void ConeNode::setSide(int value)
{
	setSide(value ? true : false);
}

bool ConeNode::getSide()  const
{
	return getSideField()->getValue();
}

////////////////////////////////////////////////
//	bottom
////////////////////////////////////////////////

SFBool *ConeNode::getBottomField() const
{
	if (isInstanceNode() == false)
		return bottomField;
	return (SFBool *)getExposedField(bottomFieldString);
}

void ConeNode::setBottom(bool value)
{
	getBottomField()->setValue(value);
}

void ConeNode::setBottom(int value)
{
	setBottom(value ? true : false);
}

bool ConeNode::getBottom()  const
{
	return getBottomField()->getValue();
}

////////////////////////////////////////////////
//	List
////////////////////////////////////////////////

ConeNode *ConeNode::next()  const
{
	return (ConeNode *)Node::next(getType());
}

ConeNode *ConeNode::nextTraversal()  const
{
	return (ConeNode *)Node::nextTraversalByType(getType());
}

////////////////////////////////////////////////
//	functions
////////////////////////////////////////////////

bool ConeNode::isChildNodeType(Node *node) const
{
	return false;
}

void ConeNode::initialize()
{
	recomputeBoundingBox();
#ifdef CX3D_SUPPORT_OPENGL
	recomputeDisplayList();
#endif
}

void ConeNode::uninitialize()
{
}

void ConeNode::update()
{
}

////////////////////////////////////////////////
//	BoundingBox
////////////////////////////////////////////////

void ConeNode::recomputeBoundingBox()
{
	setBoundingBoxCenter(0.0f, 0.0f, 0.0f);
	setBoundingBoxSize(getBottomRadius(), getHeight()/2.0f, getBottomRadius());
}

////////////////////////////////////////////////
//	Polygons
////////////////////////////////////////////////

int ConeNode::getNPolygons() const
{
	int nPolys = 0;
	int slices = getSlices();

	if (getSide() == true)
		nPolys += slices;

	if (getBottom() == true)
		nPolys += slices;

	return nPolys;
}

////////////////////////////////////////////////
//	Infomation
////////////////////////////////////////////////

void ConeNode::outputContext(std::ostream &printStream, const char *indentString) const
{
	SFBool *side = getSideField();
	SFBool *bottom = getBottomField();

	printStream << indentString << "\t" << "bottomRadius " << getBottomRadius() << std::endl;
	printStream << indentString << "\t" << "height " << getHeight() << std::endl;
	printStream << indentString << "\t" << "side " << side << std::endl;
	printStream << indentString << "\t" << "bottom " << bottom << std::endl;
}

////////////////////////////////////////////////
//	ConeNode::getVertexArray
////////////////////////////////////////////////

size_t ConeNode::getNumVertexArrays()
{
	return 1;
}

void ConeNode::getVertexArray(VertexArray& array, size_t id)
{
	if (id != 0) return;

	VertexFormat format;
	format.addAttribute<float>("position", 3);
	format.addAttribute<float>("normal", 3);
	format.addAttribute<float>("texcoord", 2);
	array = VertexArray(getSlices() * 6, 0, false, format);
}

////////////////////////////////////////////////
//	ConeNode::getVertexData
////////////////////////////////////////////////

void ConeNode::getVertexData(size_t id, void *vertex_data)
{
	if (id >= getNumVertexArrays() || getSlices() == 0.0) {
		return;
	}

	const size_t count = 6;//getBottom() ? 6 : 3;
	const size_t start = getSide() ? 0 : 3;

	if (start == count) {
		return;
	}

	VertexArray array;
	getVertexArray(array, id);
 	const VertexFormat& format = array.getFormat();

#define hPI 1.57079632679489661923
#define PI_2 6.28318530717958647693

	const int slices = getSlices();

	char* buffer = (char*)vertex_data;

	const Attribute& pos = *format.getAttribute(0);
	const Attribute& norm = *format.getAttribute(1);
	const Attribute& tex = *format.getAttribute(2);

	// TODO Stacks?

	const float h = getHeight();
	const float r = getBottomRadius();
	const float ny = (hPI - atan(h/r)) / hPI;
	const float segment_radius = PI_2 / getSlices();
	const float segment_length = 1.0 / getSlices();
	const float bottom_n[3] = {0.0, -1.0, 0.0};

	// TODO indexed list
	for (int i = 0; i < slices; ++i) {
		const float length = i * segment_length;
		const float length2 = length + segment_length;
		const float angle = i * segment_radius;
		const float angle2 = angle + segment_radius;
		const float xz[2] = {r * cos(angle), r * sin(angle)};
		const float xz2[2] = {r * cos(angle2), r * sin(angle2)};

		const float verts[6][3] = {
			{xz[0], 0.0, xz[1]},
			{0.0, h, 0.0},
			{xz2[0], 0.0, xz2[1]},
			{0.0, 0.0, 0.0},
			{xz[0], 0.0, xz[1]},
			{xz2[0], 0.0, xz2[1]}
		};

		const float t[6][2] = {
			{1.0 - length, 0.0},
			{1.0 - length, 1.0},
			{1.0 - length2, 0.0},
			{0.5, 0.5},
			{(0.5 * sin(angle)) + 0.5, (0.5 * cos(angle)) + 0.5},
			{(0.5 * sin(angle2)) + 0.5, (0.5 * cos(angle2)) + 0.5},
		};

		for (int j = start; j < count; ++j) {
			const size_t vertex_id = ((j > 2) ? (slices * 3) : 0) +
						 ((3*i) + (j % 3));

			const float (&v)[3] = verts[j];

			memcpy(buffer + getIndexForVert(vertex_id, array, pos),
			       v, pos.getByteSize());
			const float len = sqrt((v[0] * v[0])
						+ (v[2] * v[2]));
			const float n[3] = {
				xz[0], ny, xz[1]
			};

			memcpy(buffer + getIndexForVert(vertex_id, array, norm),
			       (j > 2) ? bottom_n : n, norm.getByteSize());

			memcpy(buffer + getIndexForVert(vertex_id, array, tex),
			       t[j], tex.getByteSize());
		}
	}
}

////////////////////////////////////////////////
//	ConeNode::recomputeDisplayList
////////////////////////////////////////////////

#ifdef CX3D_SUPPORT_OPENGL

void ConeNode::recomputeDisplayList() {
	unsigned int nCurrentDisplayList = getDisplayList();
	if (0 < nCurrentDisplayList)
		glDeleteLists(nCurrentDisplayList, 1);

	int slices = getSlices();

	unsigned int nNewDisplayList = glGenLists(1);
	glNewList(nNewDisplayList, GL_COMPILE);

		glFrontFace(GL_CCW);

		GLUquadricObj *quadObj;

	    glPushMatrix ();

		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
	    glRotatef (180.0, 0.0, 1.0, 0.0);

		glMatrixMode(GL_MODELVIEW);

	    glRotatef (180.0, 0.0, 1.0, 0.0);
	    glRotatef (90.0, 1.0, 0.0, 0.0);
	    glTranslatef (0.0, 0.0, -getHeight()/2.0f);

		if (getSide()) {
		    quadObj = gluNewQuadric ();
		    gluQuadricDrawStyle (quadObj, GLU_FILL);
			gluQuadricNormals (quadObj, GLU_SMOOTH);
		    gluQuadricTexture(quadObj, GL_TRUE);
		    gluCylinder (quadObj, 0.0, getBottomRadius(), getHeight(), slices, 10);
			gluDeleteQuadric(quadObj);
		}

		if (getBottom()) {
		    glTranslatef (0.0, 0.0, getHeight());
		    quadObj = gluNewQuadric ();
		    gluQuadricTexture(quadObj, GL_TRUE);
			gluDisk(quadObj, 0.0, getBottomRadius(), slices, 10);
			gluDeleteQuadric(quadObj);
		    glTranslatef (0.0, 0.0, -1.0);
		}

	    glPopMatrix ();
	glEndList();

	setDisplayList(nNewDisplayList);
};

#endif

<commit_msg>Correct position of cone<commit_after>
/******************************************************************
*
*	CyberX3D for C++
*
*	Copyright (C) Satoshi Konno 1996-2007
*
*	File:	ConeNode.cpp
*
******************************************************************/

#include <cybergarage/x3d/ConeNode.h>
#include <cybergarage/x3d/Graphic3D.h>

using namespace CyberX3D;

ConeNode::ConeNode()
{
	setHeaderFlag(false);
	setType(CONE_NODE);

	// bottomRadius field
	bottomRadiusField = new SFFloat(1.0f);
	addExposedField(bottomRadiusFieldString, bottomRadiusField);

	// height field
	heightField = new SFFloat(2.0f);
	addExposedField(heightFieldString, heightField);

	// side field
	sideField = new SFBool(true);
	addExposedField(sideFieldString, sideField);

	// bottom field
	bottomField = new SFBool(true);
	addExposedField(bottomFieldString, bottomField);

	///////////////////////////
	// Slice
	///////////////////////////

	setSlices(DEFAULT_CONENODE_SLICES);
}

ConeNode::~ConeNode()
{
}

////////////////////////////////////////////////
//	bottomRadius
////////////////////////////////////////////////

SFFloat *ConeNode::getBottomRadiusField() const
{
	if (isInstanceNode() == false)
		return bottomRadiusField;
	return (SFFloat *)getExposedField(bottomRadiusFieldString);
}

void ConeNode::setBottomRadius(float value)
{
	getBottomRadiusField()->setValue(value);
}

float ConeNode::getBottomRadius()  const
{
	return getBottomRadiusField()->getValue();
}

////////////////////////////////////////////////
//	height
////////////////////////////////////////////////

SFFloat *ConeNode::getHeightField() const
{
	if (isInstanceNode() == false)
		return heightField;
	return (SFFloat *)getExposedField(heightFieldString);
}

void ConeNode::setHeight(float value)
{
	getHeightField()->setValue(value);
}

float ConeNode::getHeight()  const
{
	return getHeightField()->getValue();
}

////////////////////////////////////////////////
//	side
////////////////////////////////////////////////

SFBool *ConeNode::getSideField() const
{
	if (isInstanceNode() == false)
		return sideField;
	return (SFBool *)getExposedField(sideFieldString);
}

void ConeNode::setSide(bool value)
{
	getSideField()->setValue(value);
}

void ConeNode::setSide(int value)
{
	setSide(value ? true : false);
}

bool ConeNode::getSide()  const
{
	return getSideField()->getValue();
}

////////////////////////////////////////////////
//	bottom
////////////////////////////////////////////////

SFBool *ConeNode::getBottomField() const
{
	if (isInstanceNode() == false)
		return bottomField;
	return (SFBool *)getExposedField(bottomFieldString);
}

void ConeNode::setBottom(bool value)
{
	getBottomField()->setValue(value);
}

void ConeNode::setBottom(int value)
{
	setBottom(value ? true : false);
}

bool ConeNode::getBottom()  const
{
	return getBottomField()->getValue();
}

////////////////////////////////////////////////
//	List
////////////////////////////////////////////////

ConeNode *ConeNode::next()  const
{
	return (ConeNode *)Node::next(getType());
}

ConeNode *ConeNode::nextTraversal()  const
{
	return (ConeNode *)Node::nextTraversalByType(getType());
}

////////////////////////////////////////////////
//	functions
////////////////////////////////////////////////

bool ConeNode::isChildNodeType(Node *node) const
{
	return false;
}

void ConeNode::initialize()
{
	recomputeBoundingBox();
#ifdef CX3D_SUPPORT_OPENGL
	recomputeDisplayList();
#endif
}

void ConeNode::uninitialize()
{
}

void ConeNode::update()
{
}

////////////////////////////////////////////////
//	BoundingBox
////////////////////////////////////////////////

void ConeNode::recomputeBoundingBox()
{
	setBoundingBoxCenter(0.0f, 0.0f, 0.0f);
	setBoundingBoxSize(getBottomRadius(), getHeight()/2.0f, getBottomRadius());
}

////////////////////////////////////////////////
//	Polygons
////////////////////////////////////////////////

int ConeNode::getNPolygons() const
{
	int nPolys = 0;
	int slices = getSlices();

	if (getSide() == true)
		nPolys += slices;

	if (getBottom() == true)
		nPolys += slices;

	return nPolys;
}

////////////////////////////////////////////////
//	Infomation
////////////////////////////////////////////////

void ConeNode::outputContext(std::ostream &printStream, const char *indentString) const
{
	SFBool *side = getSideField();
	SFBool *bottom = getBottomField();

	printStream << indentString << "\t" << "bottomRadius " << getBottomRadius() << std::endl;
	printStream << indentString << "\t" << "height " << getHeight() << std::endl;
	printStream << indentString << "\t" << "side " << side << std::endl;
	printStream << indentString << "\t" << "bottom " << bottom << std::endl;
}

////////////////////////////////////////////////
//	ConeNode::getVertexArray
////////////////////////////////////////////////

size_t ConeNode::getNumVertexArrays()
{
	return 1;
}

void ConeNode::getVertexArray(VertexArray& array, size_t id)
{
	if (id != 0) return;

	VertexFormat format;
	format.addAttribute<float>("position", 3);
	format.addAttribute<float>("normal", 3);
	format.addAttribute<float>("texcoord", 2);
	array = VertexArray(getSlices() * 6, 0, false, format);
}

////////////////////////////////////////////////
//	ConeNode::getVertexData
////////////////////////////////////////////////

void ConeNode::getVertexData(size_t id, void *vertex_data)
{
	if (id >= getNumVertexArrays() || getSlices() == 0.0) {
		return;
	}

	const size_t count = 6;//getBottom() ? 6 : 3;
	const size_t start = getSide() ? 0 : 3;

	if (start == count) {
		return;
	}

	VertexArray array;
	getVertexArray(array, id);
 	const VertexFormat& format = array.getFormat();

#define hPI 1.57079632679489661923
#define PI_2 6.28318530717958647693

	const int slices = getSlices();

	char* buffer = (char*)vertex_data;

	const Attribute& pos = *format.getAttribute(0);
	const Attribute& norm = *format.getAttribute(1);
	const Attribute& tex = *format.getAttribute(2);

	// TODO Stacks?

	const float h = getHeight();
	const float r = getBottomRadius();
	const float ny = (hPI - atan(h/r)) / hPI;
	const float segment_radius = PI_2 / getSlices();
	const float segment_length = 1.0 / getSlices();
	const float bottom_n[3] = {0.0, -1.0, 0.0};

	// TODO indexed list
	for (int i = 0; i < slices; ++i) {
		const float length = i * segment_length;
		const float length2 = length + segment_length;
		const float angle = i * segment_radius;
		const float angle2 = angle + segment_radius;
		const float xz[2] = {r * cos(angle), r * sin(angle)};
		const float xz2[2] = {r * cos(angle2), r * sin(angle2)};

		const float verts[6][3] = {
			{xz[0], -h/2.0, xz[1]},
			{0.0, h/2.0, 0.0},
			{xz2[0], -h/2.0, xz2[1]},
			{0.0, h/2.0, 0.0},
			{xz[0], -h/2.0, xz[1]},
			{xz2[0], -h/2.0, xz2[1]}
		};

		const float t[6][2] = {
			{1.0 - length, 0.0},
			{1.0 - length, 1.0},
			{1.0 - length2, 0.0},
			{0.5, 0.5},
			{(0.5 * sin(angle)) + 0.5, (0.5 * cos(angle)) + 0.5},
			{(0.5 * sin(angle2)) + 0.5, (0.5 * cos(angle2)) + 0.5},
		};

		for (int j = start; j < count; ++j) {
			const size_t vertex_id = ((j > 2) ? (slices * 3) : 0) +
						 ((3*i) + (j % 3));

			const float (&v)[3] = verts[j];

			memcpy(buffer + getIndexForVert(vertex_id, array, pos),
			       v, pos.getByteSize());
			const float len = sqrt((v[0] * v[0])
						+ (v[2] * v[2]));
			const float n[3] = {
				xz[0], ny, xz[1]
			};

			memcpy(buffer + getIndexForVert(vertex_id, array, norm),
			       (j > 2) ? bottom_n : n, norm.getByteSize());

			memcpy(buffer + getIndexForVert(vertex_id, array, tex),
			       t[j], tex.getByteSize());
		}
	}
}

////////////////////////////////////////////////
//	ConeNode::recomputeDisplayList
////////////////////////////////////////////////

#ifdef CX3D_SUPPORT_OPENGL

void ConeNode::recomputeDisplayList() {
	unsigned int nCurrentDisplayList = getDisplayList();
	if (0 < nCurrentDisplayList)
		glDeleteLists(nCurrentDisplayList, 1);

	int slices = getSlices();

	unsigned int nNewDisplayList = glGenLists(1);
	glNewList(nNewDisplayList, GL_COMPILE);

		glFrontFace(GL_CCW);

		GLUquadricObj *quadObj;

	    glPushMatrix ();

		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
	    glRotatef (180.0, 0.0, 1.0, 0.0);

		glMatrixMode(GL_MODELVIEW);

	    glRotatef (180.0, 0.0, 1.0, 0.0);
	    glRotatef (90.0, 1.0, 0.0, 0.0);
	    glTranslatef (0.0, 0.0, -getHeight()/2.0f);

		if (getSide()) {
		    quadObj = gluNewQuadric ();
		    gluQuadricDrawStyle (quadObj, GLU_FILL);
			gluQuadricNormals (quadObj, GLU_SMOOTH);
		    gluQuadricTexture(quadObj, GL_TRUE);
		    gluCylinder (quadObj, 0.0, getBottomRadius(), getHeight(), slices, 10);
			gluDeleteQuadric(quadObj);
		}

		if (getBottom()) {
		    glTranslatef (0.0, 0.0, getHeight());
		    quadObj = gluNewQuadric ();
		    gluQuadricTexture(quadObj, GL_TRUE);
			gluDisk(quadObj, 0.0, getBottomRadius(), slices, 10);
			gluDeleteQuadric(quadObj);
		    glTranslatef (0.0, 0.0, -1.0);
		}

	    glPopMatrix ();
	glEndList();

	setDisplayList(nNewDisplayList);
};

#endif

<|endoftext|>


<commit_before>/*
 * libMaia - maiaObject.cpp
 * Copyright (c) 2003 Frerich Raabe <raabe@kde.org> and
 *                    Ian Reinhart Geiser <geiseri@kde.org>
 * Copyright (c) 2007 Sebastian Wiedenroth <wiedi@frubar.net>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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 AUTHOR ``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 AUTHOR 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 "maiaObject.h"

MaiaObject::MaiaObject(QObject* parent) : QObject(parent){
	QDomImplementation::setInvalidDataPolicy(QDomImplementation::DropInvalidChars);
}

QDomElement MaiaObject::toXml(QVariant arg) {

	//dummy document
	QDomDocument doc;
	//value element, we need this in each case
	QDomElement tagValue = doc.createElement("value");

	switch(arg.type()) {
	case QVariant::String: {

		QDomElement tagString = doc.createElement("string");
		QDomText textString = doc.createTextNode(arg.toString());

		tagValue.appendChild(tagString);
		tagString.appendChild(textString);

		return tagValue;

	} case QVariant::Int: {

		QDomElement tagInt = doc.createElement("int");
		QDomText textInt = doc.createTextNode(QString::number(arg.toInt()));

		tagValue.appendChild(tagInt);
		tagInt.appendChild(textInt);

		return tagValue;

	} case QVariant::Double: {

		QDomElement tagDouble = doc.createElement("double");
		QDomText textDouble = doc.createTextNode(QString::number(arg.toDouble()));

		tagValue.appendChild(tagDouble);
		tagDouble.appendChild(textDouble);

		return tagValue;

	} case QVariant::Bool: {

		QString textValue = arg.toBool() ? "true" : "false";

		QDomElement tag = doc.createElement("boolean");
		QDomText text = doc.createTextNode(textValue);

		tagValue.appendChild(tag);
		tag.appendChild(text);

		return tagValue;

	} case QVariant::ByteArray: {

		QString textValue = arg.toByteArray().toBase64();

		QDomElement tag = doc.createElement("base64");
		QDomText text = doc.createTextNode(textValue);

		tagValue.appendChild(tag);
		tag.appendChild(text);

		return tagValue;

	} case QVariant::DateTime: {

		QString textValue = arg.toDateTime().toString("yyyyMMddThh:mm:ss");

		QDomElement tag = doc.createElement("datetime.iso8601");
		QDomText text = doc.createTextNode(textValue);

		tagValue.appendChild(tag);
		tag.appendChild(text);

		return tagValue;

	} case QVariant::List: {

		QDomElement tagArray = doc.createElement("array");
		QDomElement tagData = doc.createElement("data");
		tagArray.appendChild(tagData);
		tagValue.appendChild(tagArray);

		const QList<QVariant> args = arg.toList();
		for(int i = 0; i < args.size(); ++i) {
			tagData.appendChild(toXml(args.at(i)));
		}

		return tagValue;

	} case QVariant::Map: {

		QDomElement tagStruct = doc.createElement("struct");
		QDomElement member;
		QDomElement name;

		tagValue.appendChild(tagStruct);

		QMap<QString, QVariant> map = arg.toMap();
		QMapIterator<QString, QVariant> i(map);
		while(i.hasNext()) {
			i.next();

			member = doc.createElement("member");
			name = doc.createElement("name");

			// (key) -> name -> member -> struct
			tagStruct.appendChild(member);
			member.appendChild(name);
			name.appendChild(doc.createTextNode(i.key()));

			// add variables by recursion
			member.appendChild(toXml(i.value()));
		}

		return tagValue;

	} default:
		qDebug() << "Failed to marshal unknown variant type: " << arg.type() << endl;
	}
	return QDomElement(); //QString::null;
}

QVariant MaiaObject::fromXml(const QDomElement &elem) {
	if(elem.tagName().toLower() != "value") {
		return QVariant();
	}

	// If no type is indicated, the type is string.
	if(!elem.firstChild().isElement()) {
		return QVariant(elem.text());
	}

	const QDomElement typeElement = elem.firstChild().toElement();
	const QString typeName = typeElement.tagName().toLower();

	if(typeName == "string")
		return QVariant(typeElement.text());
	else if(typeName == "i4" || typeName == "int")
		return QVariant(typeElement.text().toInt());
	else if(typeName == "double")
		return QVariant(typeElement.text().toDouble());
	else if (typeName == "boolean") {
		if(typeElement.text().toLower() == "true" || typeElement.text() == "1")
			return QVariant(true);
		else
			return QVariant(false);
	} else if(typeName == "base64")
		return QVariant(QByteArray::fromBase64( typeElement.text().toLatin1()));
	else if(typeName == "datetime" || typeName == "datetime.iso8601")
		return QVariant(QDateTime::fromString(typeElement.text(), "yyyyMMddThh:mm:ss"));
	else if ( typeName == "array" ) {
		QList<QVariant> values;
		QDomNode valueNode = typeElement.firstChild().firstChild();
		while(!valueNode.isNull()) {
			values << fromXml(valueNode.toElement());
			valueNode = valueNode.nextSibling();
		}
		return QVariant(values);
	}
	else if ( typeName == "struct" ) {
		QMap<QString, QVariant> map;
		QDomNode memberNode = typeElement.firstChild();
		while(!memberNode.isNull())	{
			const QString key = memberNode.toElement().elementsByTagName("name").item(0).toElement().text();
			const QVariant data = fromXml(memberNode.toElement().elementsByTagName("value").item(0).toElement());
			map[key] = data;
			memberNode = memberNode.nextSibling();
		}
		return QVariant(map);
	} else {
		qDebug() << "Cannot demarshal unknown type " << typeElement.tagName().toLower();
	}
	return QVariant();
}

QString MaiaObject::prepareCall(QString method, QList<QVariant> args) {

	QDomDocument doc;

	QDomProcessingInstruction header = doc.createProcessingInstruction( "xml", QString("version=\"1.0\" encoding=\"UTF-8\"" ));
	doc.appendChild(header);

	QDomElement methodCall = doc.createElement("methodCall");
	QDomElement methodName = doc.createElement("methodName");
	QDomElement params = doc.createElement("params");
	QDomElement param;

	doc.appendChild(methodCall);
	methodCall.appendChild(methodName);
	methodName.appendChild(doc.createTextNode(method));

	methodCall.appendChild(params);

	for(int i = 0; i < args.size(); ++i) {
		param = doc.createElement("param");
		param.appendChild(toXml(args.at(i)));
		params.appendChild(param);
	}

	return doc.toString();
}

QString MaiaObject::prepareResponse(QVariant arg) {

	QDomDocument doc;

	QDomProcessingInstruction header = doc.createProcessingInstruction( "xml", QString("version=\"1.0\" encoding=\"UTF-8\"" ));
	doc.appendChild(header);

	QDomElement methodResponse = doc.createElement("methodResponse");
	QDomElement params = doc.createElement("params");
	QDomElement param;

	doc.appendChild(methodResponse);

	methodResponse.appendChild(params);

	if(!arg.isNull()) {
		param = doc.createElement("param");
		param.appendChild(toXml(arg));
		params.appendChild(param);
	}
	return doc.toString();
}

void MaiaObject::parseResponse(QString response, QNetworkReply* reply) {
	QDomDocument doc;
	QVariant arg;
	QString errorMsg;
	int errorLine;
	int errorColumn;
	if(!doc.setContent(response, &errorMsg, &errorLine, &errorColumn)) {
		emit fault(-32700, QString("parse error: response not well formed at line %1: %2").arg(errorLine).arg(errorMsg), reply);
		delete this;
		return;
	}
	if(doc.documentElement().firstChild().toElement().tagName().toLower() == "params") {
		QDomNode paramNode = doc.documentElement().firstChild().firstChild();
		if(!paramNode.isNull()) {
			arg = fromXml( paramNode.firstChild().toElement() );
		}
		emit aresponse(arg, reply);
	} else if(doc.documentElement().firstChild().toElement().tagName().toLower() == "fault") {
		const QVariant errorVariant = fromXml(doc.documentElement().firstChild().firstChild().toElement());
		emit fault(errorVariant.toMap() [ "faultCode" ].toInt(),
		           errorVariant.toMap() [ "faultString" ].toString(),
		           reply);
	} else {
		emit fault(-32600,
		           tr("parse error: invalid xml-rpc. not conforming to spec."),
		           reply);
	}
	delete this;
	return;
}

<commit_msg>send the correct bool types<commit_after>/*
 * libMaia - maiaObject.cpp
 * Copyright (c) 2003 Frerich Raabe <raabe@kde.org> and
 *                    Ian Reinhart Geiser <geiseri@kde.org>
 * Copyright (c) 2007 Sebastian Wiedenroth <wiedi@frubar.net>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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 AUTHOR ``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 AUTHOR 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 "maiaObject.h"

MaiaObject::MaiaObject(QObject* parent) : QObject(parent){
	QDomImplementation::setInvalidDataPolicy(QDomImplementation::DropInvalidChars);
}

QDomElement MaiaObject::toXml(QVariant arg) {

	//dummy document
	QDomDocument doc;
	//value element, we need this in each case
	QDomElement tagValue = doc.createElement("value");

	switch(arg.type()) {
	case QVariant::String: {

		QDomElement tagString = doc.createElement("string");
		QDomText textString = doc.createTextNode(arg.toString());

		tagValue.appendChild(tagString);
		tagString.appendChild(textString);

		return tagValue;

	} case QVariant::Int: {

		QDomElement tagInt = doc.createElement("int");
		QDomText textInt = doc.createTextNode(QString::number(arg.toInt()));

		tagValue.appendChild(tagInt);
		tagInt.appendChild(textInt);

		return tagValue;

	} case QVariant::Double: {

		QDomElement tagDouble = doc.createElement("double");
		QDomText textDouble = doc.createTextNode(QString::number(arg.toDouble()));

		tagValue.appendChild(tagDouble);
		tagDouble.appendChild(textDouble);

		return tagValue;

	} case QVariant::Bool: {

		QString textValue = arg.toBool() ? "1" : "0";

		QDomElement tag = doc.createElement("boolean");
		QDomText text = doc.createTextNode(textValue);

		tagValue.appendChild(tag);
		tag.appendChild(text);

		return tagValue;

	} case QVariant::ByteArray: {

		QString textValue = arg.toByteArray().toBase64();

		QDomElement tag = doc.createElement("base64");
		QDomText text = doc.createTextNode(textValue);

		tagValue.appendChild(tag);
		tag.appendChild(text);

		return tagValue;

	} case QVariant::DateTime: {

		QString textValue = arg.toDateTime().toString("yyyyMMddThh:mm:ss");

		QDomElement tag = doc.createElement("datetime.iso8601");
		QDomText text = doc.createTextNode(textValue);

		tagValue.appendChild(tag);
		tag.appendChild(text);

		return tagValue;

	} case QVariant::List: {

		QDomElement tagArray = doc.createElement("array");
		QDomElement tagData = doc.createElement("data");
		tagArray.appendChild(tagData);
		tagValue.appendChild(tagArray);

		const QList<QVariant> args = arg.toList();
		for(int i = 0; i < args.size(); ++i) {
			tagData.appendChild(toXml(args.at(i)));
		}

		return tagValue;

	} case QVariant::Map: {

		QDomElement tagStruct = doc.createElement("struct");
		QDomElement member;
		QDomElement name;

		tagValue.appendChild(tagStruct);

		QMap<QString, QVariant> map = arg.toMap();
		QMapIterator<QString, QVariant> i(map);
		while(i.hasNext()) {
			i.next();

			member = doc.createElement("member");
			name = doc.createElement("name");

			// (key) -> name -> member -> struct
			tagStruct.appendChild(member);
			member.appendChild(name);
			name.appendChild(doc.createTextNode(i.key()));

			// add variables by recursion
			member.appendChild(toXml(i.value()));
		}

		return tagValue;

	} default:
		qDebug() << "Failed to marshal unknown variant type: " << arg.type() << endl;
	}
	return QDomElement(); //QString::null;
}

QVariant MaiaObject::fromXml(const QDomElement &elem) {
	if(elem.tagName().toLower() != "value") {
		return QVariant();
	}

	// If no type is indicated, the type is string.
	if(!elem.firstChild().isElement()) {
		return QVariant(elem.text());
	}

	const QDomElement typeElement = elem.firstChild().toElement();
	const QString typeName = typeElement.tagName().toLower();

	if(typeName == "string")
		return QVariant(typeElement.text());
	else if(typeName == "i4" || typeName == "int")
		return QVariant(typeElement.text().toInt());
	else if(typeName == "double")
		return QVariant(typeElement.text().toDouble());
	else if (typeName == "boolean") {
		if(typeElement.text().toLower() == "true" || typeElement.text() == "1")
			return QVariant(true);
		else
			return QVariant(false);
	} else if(typeName == "base64")
		return QVariant(QByteArray::fromBase64( typeElement.text().toLatin1()));
	else if(typeName == "datetime" || typeName == "datetime.iso8601")
		return QVariant(QDateTime::fromString(typeElement.text(), "yyyyMMddThh:mm:ss"));
	else if ( typeName == "array" ) {
		QList<QVariant> values;
		QDomNode valueNode = typeElement.firstChild().firstChild();
		while(!valueNode.isNull()) {
			values << fromXml(valueNode.toElement());
			valueNode = valueNode.nextSibling();
		}
		return QVariant(values);
	}
	else if ( typeName == "struct" ) {
		QMap<QString, QVariant> map;
		QDomNode memberNode = typeElement.firstChild();
		while(!memberNode.isNull())	{
			const QString key = memberNode.toElement().elementsByTagName("name").item(0).toElement().text();
			const QVariant data = fromXml(memberNode.toElement().elementsByTagName("value").item(0).toElement());
			map[key] = data;
			memberNode = memberNode.nextSibling();
		}
		return QVariant(map);
	} else {
		qDebug() << "Cannot demarshal unknown type " << typeElement.tagName().toLower();
	}
	return QVariant();
}

QString MaiaObject::prepareCall(QString method, QList<QVariant> args) {

	QDomDocument doc;

	QDomProcessingInstruction header = doc.createProcessingInstruction( "xml", QString("version=\"1.0\" encoding=\"UTF-8\"" ));
	doc.appendChild(header);

	QDomElement methodCall = doc.createElement("methodCall");
	QDomElement methodName = doc.createElement("methodName");
	QDomElement params = doc.createElement("params");
	QDomElement param;

	doc.appendChild(methodCall);
	methodCall.appendChild(methodName);
	methodName.appendChild(doc.createTextNode(method));

	methodCall.appendChild(params);

	for(int i = 0; i < args.size(); ++i) {
		param = doc.createElement("param");
		param.appendChild(toXml(args.at(i)));
		params.appendChild(param);
	}

	return doc.toString();
}

QString MaiaObject::prepareResponse(QVariant arg) {

	QDomDocument doc;

	QDomProcessingInstruction header = doc.createProcessingInstruction( "xml", QString("version=\"1.0\" encoding=\"UTF-8\"" ));
	doc.appendChild(header);

	QDomElement methodResponse = doc.createElement("methodResponse");
	QDomElement params = doc.createElement("params");
	QDomElement param;

	doc.appendChild(methodResponse);

	methodResponse.appendChild(params);

	if(!arg.isNull()) {
		param = doc.createElement("param");
		param.appendChild(toXml(arg));
		params.appendChild(param);
	}
	return doc.toString();
}

void MaiaObject::parseResponse(QString response, QNetworkReply* reply) {
	QDomDocument doc;
	QVariant arg;
	QString errorMsg;
	int errorLine;
	int errorColumn;
	if(!doc.setContent(response, &errorMsg, &errorLine, &errorColumn)) {
		emit fault(-32700, QString("parse error: response not well formed at line %1: %2").arg(errorLine).arg(errorMsg), reply);
		delete this;
		return;
	}
	if(doc.documentElement().firstChild().toElement().tagName().toLower() == "params") {
		QDomNode paramNode = doc.documentElement().firstChild().firstChild();
		if(!paramNode.isNull()) {
			arg = fromXml( paramNode.firstChild().toElement() );
		}
		emit aresponse(arg, reply);
	} else if(doc.documentElement().firstChild().toElement().tagName().toLower() == "fault") {
		const QVariant errorVariant = fromXml(doc.documentElement().firstChild().firstChild().toElement());
		emit fault(errorVariant.toMap() [ "faultCode" ].toInt(),
		           errorVariant.toMap() [ "faultString" ].toString(),
		           reply);
	} else {
		emit fault(-32600,
		           tr("parse error: invalid xml-rpc. not conforming to spec."),
		           reply);
	}
	delete this;
	return;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 - 2015, Roland Bock
 * All rights reserved.
 *
 * 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 <memory>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/connection_config.h>
#include "connection_handle.h"

namespace sqlpp
{
  namespace sqlite3
  {
    namespace detail
    {
      connection_handle::connection_handle(connection_config conf) : config(conf), sqlite(nullptr)
      {
        auto rc = sqlite3_open_v2(conf.path_to_database.c_str(), &sqlite, conf.flags,
                                  conf.vfs.empty() ? nullptr : conf.vfs.c_str());
        if (rc != SQLITE_OK)
        {
          const std::string msg = sqlite3_errmsg(sqlite);
          sqlite3_close(sqlite);
          throw sqlpp::exception("Sqlite3 error: Can't open database: " + msg);
        }
#ifdef SQLITE_HAS_CODEC
        if (conf.password.size()>0)
        {
          int ret = sqlite3_key(sqlite, conf.password.data(),conf.password.size()+1);
          if (ret!=SQLITE_OK)
          {
            const std::string msg = sqlite3_errmsg(sqlite);
            sqlite3_close(sqlite);
            throw sqlpp::exception("Sqlite3 error: Can't set password to database: " + msg);
          }
        }
#endif
      }

      connection_handle::~connection_handle()
      {
        auto rc = sqlite3_close(sqlite);
        if (rc != SQLITE_OK)
        {
          std::cerr << "Sqlite3 error: Can't close database: " << sqlite3_errmsg(sqlite) << std::endl;
        }
      }
    }
  }
}
<commit_msg>Fix sqlite3_key call<commit_after>/*
 * Copyright (c) 2013 - 2015, Roland Bock
 * All rights reserved.
 *
 * 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 <memory>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/connection_config.h>
#include "connection_handle.h"

namespace sqlpp
{
  namespace sqlite3
  {
    namespace detail
    {
      connection_handle::connection_handle(connection_config conf) : config(conf), sqlite(nullptr)
      {
        auto rc = sqlite3_open_v2(conf.path_to_database.c_str(), &sqlite, conf.flags,
                                  conf.vfs.empty() ? nullptr : conf.vfs.c_str());
        if (rc != SQLITE_OK)
        {
          const std::string msg = sqlite3_errmsg(sqlite);
          sqlite3_close(sqlite);
          throw sqlpp::exception("Sqlite3 error: Can't open database: " + msg);
        }
#ifdef SQLITE_HAS_CODEC
        if (conf.password.size()>0)
        {
          int ret = sqlite3_key(sqlite, conf.password.data(),conf.password.size());
          if (ret!=SQLITE_OK)
          {
            const std::string msg = sqlite3_errmsg(sqlite);
            sqlite3_close(sqlite);
            throw sqlpp::exception("Sqlite3 error: Can't set password to database: " + msg);
          }
        }
#endif
      }

      connection_handle::~connection_handle()
      {
        auto rc = sqlite3_close(sqlite);
        if (rc != SQLITE_OK)
        {
          std::cerr << "Sqlite3 error: Can't close database: " << sqlite3_errmsg(sqlite) << std::endl;
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>#include "atom.h"
#include "variable.h"
#include "number.h"

#include <string>

#include <iostream>
using namespace std;

bool Number::match(Atom *A){
    return false;
}

bool Number::match(Variable *V){
    if(!assignFlag && V->get_assign()){
        assignFlag = true;
        V->setNptr(this);
        V->set_assign_false();
        return true;
    }
    else{
        ptr1 = this;
        ptr2 = V->getNptr();
        if(ptr1 == ptr2) return true;
        else return false;
    }

}

bool Number::match(Number *N){
    if(vFlag){
        if(this->value().compare(N->value()) == 0) return true;
        else return false;
    }
    else return false;
}

bool Number::match(Atom A){
    return false;
}

bool Number::match(Variable &V){
    if(!this->assignFlag && V.get_assign()){
        //this->assignFlag = true;
        V.setX(this->symbol());
        V.set_assign_false();
        return true;
    }
    else{
        s1 = this->symbol();
        s2 = V.getX();
        if(s1.compare(s2)==0) return true;
        else return false;
    }
}

bool Number::match(Number N){
    this->match(&N);
}

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


<commit_before>#include "stdafx.h"
#include "kdb+.h"

#include "kdb+.util/util.h"
#include "kdb+.util/K_ptr.h"
#include "kdb+.util/type_convert.h"
#include <cassert>
#include <vector>
#include <sstream>

#include <zlib.h>
#include <zconf.h>
#pragma comment(lib, "zlibwapi.lib")
static_assert(sizeof(::uInt) <= sizeof(J), "type oversize: uInt vs J");
static_assert(sizeof(::Bytef) == sizeof(G), "type mismatch: Bytef vs G");

namespace {

	char const* zlibError(int errCode) {
		switch (errCode) {
#		define ZLIB_ERROR(x)  case (x): return (#x)
			ZLIB_ERROR(Z_OK);
			ZLIB_ERROR(Z_STREAM_END);
			ZLIB_ERROR(Z_NEED_DICT);
			ZLIB_ERROR(Z_ERRNO);
			ZLIB_ERROR(Z_STREAM_ERROR);
			ZLIB_ERROR(Z_DATA_ERROR);
			ZLIB_ERROR(Z_MEM_ERROR);
			ZLIB_ERROR(Z_BUF_ERROR);
			ZLIB_ERROR(Z_VERSION_ERROR);
#		undef ZLIB_ERROR
		default:
			return "<BUG> unexpected ZLIB error";
		}
	}

	std::string zlibError(int errCode, char const* errMsg) {
		std::ostringstream buffer;
		buffer << zlibError(errCode);
		if (NULL != errMsg) {
			buffer << " (" << errMsg << ')';
		}
		return buffer.str();
	}

	size_t q2BlockSize(K blockSize) throw(std::runtime_error) {
		long long const chunkSize = q::q2Dec(blockSize);
		if (chunkSize < 4 * 1024) {
			throw std::runtime_error("blockSize too small (min 2^12)");
		}
		else if (chunkSize > 1024 * 1024) {
			throw std::runtime_error("blockSize too large (max 2^20)");
		}
		else {
			return static_cast<size_t>(chunkSize);
		}
	}

	int q2Level(K level) throw(std::runtime_error) {
		long long const lvl = q::q2Dec(level);
		if ((0 > lvl) || (lvl > 9)) {
			throw std::runtime_error("level must be within [0, 9]");
		}
		else {
			return static_cast<int>(lvl);
		}
	}

	Bytef* q2Bytes(K bytes, size_t& length) throw(std::runtime_error) {
		if (bytes == K_NIL) {
			length = 0;
			return Z_NULL;
		}
		switch (bytes->t) {
		case KG:
		case KC:
			assert((0 <= bytes->n) && (bytes->n <= std::numeric_limits<size_t>::max()));
			length = static_cast<size_t>(bytes->n);
			return kG(bytes);
		default:
			throw std::runtime_error("not bytes or chars");
		}
	}

}//namespace /*anonymous*/

//@see https://www.zlib.net/zlib_how.html
KDB_API K K_DECL gzipCompress(K blockSize, K cprzLevel, K bytes) {
	// Input sanity check
	Bytef* input;
	size_t length, chunkSize;
	int level;
	try {
		chunkSize = q2BlockSize(blockSize);
		level = q2Level(cprzLevel);
		input = q2Bytes(bytes, length);
	}
	catch (std::runtime_error const& ex) {
		return q::error2q(ex.what());
	}
	if (length > std::numeric_limits<uInt>::max()) {
		return q::error2q("input stream too long (zlib)");
	}
	assert(!!input);

	// Initialize zlib for deflate
	::z_stream stream;
	stream.zalloc = Z_NULL;
	stream.zfree = Z_NULL;
	stream.opaque = Z_NULL;
	stream.avail_in = 0;
	stream.next_in = Z_NULL;
	int status = ::deflateInit2(&stream, level, Z_DEFLATED, 16 + MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
	if (Z_OK != status) {
		return q::error2q(zlibError(status, stream.msg));
	}

	// Deflate chunk by chunk
	std::vector<G> chunk(chunkSize, '\0');
	std::vector<G> output;
	stream.avail_in = static_cast<uInt>(length);	//already sanity checked
	stream.next_in = kG(bytes);
	do {
		do {
			assert(chunkSize <= std::numeric_limits<uInt>::max());
			stream.avail_out = static_cast<uInt>(chunkSize);
			stream.next_out = &chunk[0];
			status = ::deflate(&stream, (stream.avail_in == 0) ? Z_FINISH : Z_NO_FLUSH);
			assert(status != Z_STREAM_ERROR);	//zlib state not clobbered
			switch (status) {
			case Z_STREAM_ERROR:
				return q::error2q("Z_STREAM_ERROR: zlib state clobbered!");
			case Z_NEED_DICT:
			case Z_DATA_ERROR:
			case Z_MEM_ERROR:
				::deflateEnd(&stream);
				return q::error2q(zlibError(status, stream.msg));
			default:
				;//no-op
			}
			size_t const outSize = chunkSize - stream.avail_out;
			size_t const prevSize = output.size();
			assert(stream.total_out == prevSize + outSize);
			output.resize(stream.total_out);
			std::copy(chunk.cbegin(), chunk.cbegin() + outSize, output.begin() + prevSize);
		} while (stream.avail_out == 0);
	} while (status != Z_STREAM_END);
	::deflateEnd(&stream);
	chunk.clear();

	q::K_ptr result(ktn(bytes->t, output.size()));
	assert(!!result);
	std::copy(output.cbegin(), output.cend(), kG(result.get()));
	return result.release();
}

//@see https://www.zlib.net/zlib_how.html
//@see http://windrealm.org/tutorials/decompress-gzip-stream.php
//@see https://github.com/lmartinking/qgz
KDB_API K K_DECL gzipDecompress(K blockSize, K isRaw, K bytes) {
	// Input sanity check
	Bytef* input;
	size_t length, chunkSize;
	bool raw;
	try {
		chunkSize = q2BlockSize(blockSize);
		raw = !!q::q2Dec(isRaw);
		input = q2Bytes(bytes, length);
	}
	catch (std::runtime_error const& ex) {
		return q::error2q(ex.what());
	}
	if (length < 10 + 8) {
		return q::error2q("compressed stream too short");
	}
	else if (length > std::numeric_limits<uInt>::max()) {
		return q::error2q("compressed stream too long (zlib)");
	}
	assert(!!input);

	// Initialize zlib for inflate
	::z_stream stream;
	stream.zalloc = Z_NULL;
	stream.zfree = Z_NULL;
	stream.opaque = Z_NULL;
	stream.avail_in = 0;
	stream.next_in = Z_NULL;
	int status = ::inflateInit2(&stream, raw ? (-MAX_WBITS) : (16 + MAX_WBITS));
	if (Z_OK != status) {
		return q::error2q(zlibError(status, stream.msg));
	}

	// Inflate chunk by chunk
	std::vector<G> chunk(chunkSize, '\0');
	std::vector<G> output;
	stream.avail_in = static_cast<uInt>(length);	//already sanity checked
	stream.next_in = kG(bytes);
	do {
		do {
			assert(chunkSize <= std::numeric_limits<uInt>::max());
			stream.avail_out = static_cast<uInt>(chunkSize);
			stream.next_out = &chunk[0];
			status = ::inflate(&stream, Z_NO_FLUSH);
			assert(status != Z_STREAM_ERROR);	//zlib state not clobbered
			switch (status) {
			case Z_STREAM_ERROR:
				return q::error2q("Z_STREAM_ERROR: zlib state clobbered!");
			case Z_NEED_DICT:
			case Z_DATA_ERROR:
			case Z_MEM_ERROR:
				::inflateEnd(&stream);
				return q::error2q(zlibError(status, stream.msg));
			default:
				;//no-op
			}
			size_t const outSize = chunkSize - stream.avail_out;
			size_t const prevSize = output.size();
			assert(stream.total_out == prevSize + outSize);
			output.resize(stream.total_out);
			std::copy(chunk.cbegin(), chunk.cbegin() + outSize, output.begin() + prevSize);
		} while (stream.avail_out == 0);
	} while (status != Z_STREAM_END);
	::inflateEnd(&stream);
	chunk.clear();

	q::K_ptr result(ktn(bytes->t, output.size()));
	assert(!!result);
	std::copy(output.cbegin(), output.cend(), kG(result.get()));
	return result.release();
}<commit_msg>fix 64-bit build warning<commit_after>#include "stdafx.h"
#include "kdb+.h"

#include "kdb+.util/util.h"
#include "kdb+.util/K_ptr.h"
#include "kdb+.util/type_convert.h"
#include <cassert>
#include <vector>
#include <sstream>

#include <zlib.h>
#include <zconf.h>
#pragma comment(lib, "zlibwapi.lib")
static_assert(sizeof(::uInt) <= sizeof(J), "type oversize: uInt vs J");
static_assert(sizeof(::Bytef) == sizeof(G), "type mismatch: Bytef vs G");

namespace {

	char const* zlibError(int errCode) {
		switch (errCode) {
#		define ZLIB_ERROR(x)  case (x): return (#x)
			ZLIB_ERROR(Z_OK);
			ZLIB_ERROR(Z_STREAM_END);
			ZLIB_ERROR(Z_NEED_DICT);
			ZLIB_ERROR(Z_ERRNO);
			ZLIB_ERROR(Z_STREAM_ERROR);
			ZLIB_ERROR(Z_DATA_ERROR);
			ZLIB_ERROR(Z_MEM_ERROR);
			ZLIB_ERROR(Z_BUF_ERROR);
			ZLIB_ERROR(Z_VERSION_ERROR);
#		undef ZLIB_ERROR
		default:
			return "<BUG> unexpected ZLIB error";
		}
	}

	std::string zlibError(int errCode, char const* errMsg) {
		std::ostringstream buffer;
		buffer << zlibError(errCode);
		if (NULL != errMsg) {
			buffer << " (" << errMsg << ')';
		}
		return buffer.str();
	}

	size_t q2BlockSize(K blockSize) throw(std::runtime_error) {
		long long const chunkSize = q::q2Dec(blockSize);
		if (chunkSize < 4 * 1024) {
			throw std::runtime_error("blockSize too small (min 2^12)");
		}
		else if (chunkSize > 1024 * 1024) {
			throw std::runtime_error("blockSize too large (max 2^20)");
		}
		else {
			return static_cast<size_t>(chunkSize);
		}
	}

	int q2Level(K level) throw(std::runtime_error) {
		long long const lvl = q::q2Dec(level);
		if ((0 > lvl) || (lvl > 9)) {
			throw std::runtime_error("level must be within [0, 9]");
		}
		else {
			return static_cast<int>(lvl);
		}
	}

	Bytef* q2Bytes(K bytes, size_t& length) throw(std::runtime_error) {
		if (bytes == K_NIL) {
			length = 0;
			return Z_NULL;
		}
		switch (bytes->t) {
		case KG:
		case KC:
			assert((0 <= bytes->n) && (static_cast<size_t>(bytes->n) <= std::numeric_limits<size_t>::max()));
			length = static_cast<size_t>(bytes->n);
			return kG(bytes);
		default:
			throw std::runtime_error("not bytes or chars");
		}
	}

}//namespace /*anonymous*/

//@see https://www.zlib.net/zlib_how.html
KDB_API K K_DECL gzipCompress(K blockSize, K cprzLevel, K bytes) {
	// Input sanity check
	Bytef* input;
	size_t length, chunkSize;
	int level;
	try {
		chunkSize = q2BlockSize(blockSize);
		level = q2Level(cprzLevel);
		input = q2Bytes(bytes, length);
	}
	catch (std::runtime_error const& ex) {
		return q::error2q(ex.what());
	}
	if (length > std::numeric_limits<uInt>::max()) {
		return q::error2q("input stream too long (zlib)");
	}
	assert(!!input);

	// Initialize zlib for deflate
	::z_stream stream;
	stream.zalloc = Z_NULL;
	stream.zfree = Z_NULL;
	stream.opaque = Z_NULL;
	stream.avail_in = 0;
	stream.next_in = Z_NULL;
	int status = ::deflateInit2(&stream, level, Z_DEFLATED, 16 + MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
	if (Z_OK != status) {
		return q::error2q(zlibError(status, stream.msg));
	}

	// Deflate chunk by chunk
	std::vector<G> chunk(chunkSize, '\0');
	std::vector<G> output;
	stream.avail_in = static_cast<uInt>(length);	//already sanity checked
	stream.next_in = kG(bytes);
	do {
		do {
			assert(chunkSize <= std::numeric_limits<uInt>::max());
			stream.avail_out = static_cast<uInt>(chunkSize);
			stream.next_out = &chunk[0];
			status = ::deflate(&stream, (stream.avail_in == 0) ? Z_FINISH : Z_NO_FLUSH);
			assert(status != Z_STREAM_ERROR);	//zlib state not clobbered
			switch (status) {
			case Z_STREAM_ERROR:
				return q::error2q("Z_STREAM_ERROR: zlib state clobbered!");
			case Z_NEED_DICT:
			case Z_DATA_ERROR:
			case Z_MEM_ERROR:
				::deflateEnd(&stream);
				return q::error2q(zlibError(status, stream.msg));
			default:
				;//no-op
			}
			size_t const outSize = chunkSize - stream.avail_out;
			size_t const prevSize = output.size();
			assert(stream.total_out == prevSize + outSize);
			output.resize(stream.total_out);
			std::copy(chunk.cbegin(), chunk.cbegin() + outSize, output.begin() + prevSize);
		} while (stream.avail_out == 0);
	} while (status != Z_STREAM_END);
	::deflateEnd(&stream);
	chunk.clear();

	q::K_ptr result(ktn(bytes->t, output.size()));
	assert(!!result);
	std::copy(output.cbegin(), output.cend(), kG(result.get()));
	return result.release();
}

//@see https://www.zlib.net/zlib_how.html
//@see http://windrealm.org/tutorials/decompress-gzip-stream.php
//@see https://github.com/lmartinking/qgz
KDB_API K K_DECL gzipDecompress(K blockSize, K isRaw, K bytes) {
	// Input sanity check
	Bytef* input;
	size_t length, chunkSize;
	bool raw;
	try {
		chunkSize = q2BlockSize(blockSize);
		raw = !!q::q2Dec(isRaw);
		input = q2Bytes(bytes, length);
	}
	catch (std::runtime_error const& ex) {
		return q::error2q(ex.what());
	}
	if (length < 10 + 8) {
		return q::error2q("compressed stream too short");
	}
	else if (length > std::numeric_limits<uInt>::max()) {
		return q::error2q("compressed stream too long (zlib)");
	}
	assert(!!input);

	// Initialize zlib for inflate
	::z_stream stream;
	stream.zalloc = Z_NULL;
	stream.zfree = Z_NULL;
	stream.opaque = Z_NULL;
	stream.avail_in = 0;
	stream.next_in = Z_NULL;
	int status = ::inflateInit2(&stream, raw ? (-MAX_WBITS) : (16 + MAX_WBITS));
	if (Z_OK != status) {
		return q::error2q(zlibError(status, stream.msg));
	}

	// Inflate chunk by chunk
	std::vector<G> chunk(chunkSize, '\0');
	std::vector<G> output;
	stream.avail_in = static_cast<uInt>(length);	//already sanity checked
	stream.next_in = kG(bytes);
	do {
		do {
			assert(chunkSize <= std::numeric_limits<uInt>::max());
			stream.avail_out = static_cast<uInt>(chunkSize);
			stream.next_out = &chunk[0];
			status = ::inflate(&stream, Z_NO_FLUSH);
			assert(status != Z_STREAM_ERROR);	//zlib state not clobbered
			switch (status) {
			case Z_STREAM_ERROR:
				return q::error2q("Z_STREAM_ERROR: zlib state clobbered!");
			case Z_NEED_DICT:
			case Z_DATA_ERROR:
			case Z_MEM_ERROR:
				::inflateEnd(&stream);
				return q::error2q(zlibError(status, stream.msg));
			default:
				;//no-op
			}
			size_t const outSize = chunkSize - stream.avail_out;
			size_t const prevSize = output.size();
			assert(stream.total_out == prevSize + outSize);
			output.resize(stream.total_out);
			std::copy(chunk.cbegin(), chunk.cbegin() + outSize, output.begin() + prevSize);
		} while (stream.avail_out == 0);
	} while (status != Z_STREAM_END);
	::inflateEnd(&stream);
	chunk.clear();

	q::K_ptr result(ktn(bytes->t, output.size()));
	assert(!!result);
	std::copy(output.cbegin(), output.cend(), kG(result.get()));
	return result.release();
}<|endoftext|>


<commit_before>/*
 * Main Send File Transfer Window
 *
 * Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <KFileItem>
#include <KApplication>
#include <KMimeType>
#include <KDebug>
#include <KMessageBox>
#include <KPixmapSequence>
#include <KPixmapSequenceOverlayPainter>
#include <KLineEdit>
#include <KIO/PreviewJob>

#include <QtGui/QPushButton>

#include <TelepathyQt/AccountManager>
#include <TelepathyQt/PendingChannelRequest>
#include <TelepathyQt/PendingReady>

#include <KTp/actions.h>
#include <KTp/contact-factory.h>
#include <KTp/Models/contacts-list-model.h>
#include <KTp/Models/contacts-filter-model.h>
#include <KTp/Widgets/contact-grid-widget.h>

MainWindow::MainWindow(const KUrl::List &urls, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow),
    m_urls(urls),
    m_contactsModel(0)
{
    Tp::registerTypes();

    ui->setupUi(this);
    if (urls.size() == 1) {
        setWindowTitle(i18n("Send file - %1", urls.first().fileName()));

        ui->filesInfoLabel->hide();
        ui->fileNameLabel->setText(urls.first().fileName());
    } else {
        QString fileNames;
        Q_FOREACH(const KUrl &file, urls) {
            fileNames += file.fileName() + " ";
        }
        setWindowTitle(i18n("Send files - %1", fileNames.trimmed()));

        ui->messageLabel->setText(i18n("You are about to send these files"));
        ui->filesInfoLabel->setText(i18n("%1 files selected", QString::number(urls.count())));
        ui->fileNameLabel->setText(fileNames.replace(" ", "
"));
    }

    kDebug() << KApplication::arguments();

    m_busyOverlay = new KPixmapSequenceOverlayPainter(this);
    m_busyOverlay->setSequence(KPixmapSequence("process-working", 22));
    m_busyOverlay->setWidget(ui->filePreview);
    m_busyOverlay->start();

    if (urls.size() == 1) {
        KFileItem file(KFileItem::Unknown, KFileItem::Unknown, urls.first());
        QStringList availablePlugins = KIO::PreviewJob::availablePlugins();
        KIO::PreviewJob* job = KIO::filePreview(KFileItemList() << file, QSize(280, 280), &availablePlugins);
        job->setOverlayIconAlpha(0);
        job->setScaleType(KIO::PreviewJob::Unscaled);
        connect(job, SIGNAL(gotPreview(KFileItem, QPixmap)),
                this, SLOT(onPreviewLoaded(KFileItem, QPixmap)));
        connect(job, SIGNAL(failed(KFileItem)),
                this, SLOT(onPreviewFailed(KFileItem)));
    } else {
        ui->filePreview->setPixmap(QPixmap(DesktopIcon("dialog-information.png", 128)));
        m_busyOverlay->stop();
    }

    Tp::AccountFactoryPtr  accountFactory = Tp::AccountFactory::create(QDBusConnection::sessionBus(),
                                                                       Tp::Features() << Tp::Account::FeatureCore
                                                                       << Tp::Account::FeatureAvatar
                                                                       << Tp::Account::FeatureProtocolInfo
                                                                       << Tp::Account::FeatureProfile
                                                                       << Tp::Account::FeatureCapabilities);

    Tp::ConnectionFactoryPtr connectionFactory = Tp::ConnectionFactory::create(QDBusConnection::sessionBus(),
                                                                               Tp::Features() << Tp::Connection::FeatureCore
                                                                               << Tp::Connection::FeatureRosterGroups
                                                                               << Tp::Connection::FeatureRoster
                                                                               << Tp::Connection::FeatureSelfContact);

    Tp::ContactFactoryPtr contactFactory = KTp::ContactFactory::create(Tp::Features()  << Tp::Contact::FeatureAlias
                                                                      << Tp::Contact::FeatureAvatarData
                                                                      << Tp::Contact::FeatureSimplePresence
                                                                      << Tp::Contact::FeatureCapabilities);

    Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus());

    m_accountManager = Tp::AccountManager::create(QDBusConnection::sessionBus(),
                                                  accountFactory,
                                                  connectionFactory,
                                                  channelFactory,
                                                  contactFactory);

    m_contactsModel = new KTp::ContactsListModel(this);
    connect(m_accountManager->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady()));

    m_contactGridWidget = new KTp::ContactGridWidget(m_contactsModel, this);
    m_contactGridWidget->contactFilterLineEdit()->setClickMessage(i18n("Search in Contacts..."));
    m_contactGridWidget->filter()->setPresenceTypeFilterFlags(KTp::ContactsFilterModel::ShowOnlyConnected);
    m_contactGridWidget->filter()->setCapabilityFilterFlags(KTp::ContactsFilterModel::FilterByFileTransferCapability);
    ui->recipientVLayout->addWidget(m_contactGridWidget);

    connect(m_contactGridWidget,
            SIGNAL(selectionChanged(Tp::AccountPtr,Tp::ContactPtr)),
            SLOT(onContactSelectionChanged(Tp::AccountPtr,Tp::ContactPtr)));

    ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
    connect(ui->buttonBox, SIGNAL(accepted()), SLOT(onDialogAccepted()));
    connect(ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onAccountManagerReady()
{
    m_contactsModel->setAccountManager(m_accountManager);
}

void MainWindow::onDialogAccepted()
{
    // don't do anytghing if no contact has been selected
    if (!m_contactGridWidget->hasSelection()) {
        // show message box?
        return;
    }

    // start sending file
    Q_FOREACH(const KUrl &url, m_urls) {
        Tp::PendingChannelRequest* channelRequest = KTp::Actions::startFileTransfer(m_contactGridWidget->selectedAccount(),
                                                                                m_contactGridWidget->selectedContact(),
                                                                                url.path());

        connect(channelRequest, SIGNAL(finished(Tp::PendingOperation*)), SLOT(slotFileTransferFinished(Tp::PendingOperation*)));
    }

    //disable the buttons
    foreach(QAbstractButton* button, ui->buttonBox->buttons()) {
        button->setEnabled(false);
    }
}

void MainWindow::onContactSelectionChanged(Tp::AccountPtr account, Tp::ContactPtr contact)
{
    Q_UNUSED(account)
    Q_UNUSED(contact)

    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_contactGridWidget->hasSelection());
}

void MainWindow::slotFileTransferFinished(Tp::PendingOperation* op)
{
    if (op->isError()) {
        //FIXME map to human readable strings.
        QString errorMsg(op->errorName() + ": " + op->errorMessage());
        kDebug() << "ERROR!: " << errorMsg;
        KMessageBox::error(this, i18n("Failed to send file"), i18n("File Transfer Failed"));
        close();
    } else {
        kDebug() << "Transfer started";
        // now I can close the dialog
        close();
    }
}

void MainWindow::onPreviewLoaded(const KFileItem& item, const QPixmap& preview)
{
    Q_UNUSED(item);
    ui->filePreview->setPixmap(preview);
    m_busyOverlay->stop();
}

void MainWindow::onPreviewFailed(const KFileItem& item)
{
    kWarning() << "Loading thumb failed" << item.name();
    ui->filePreview->setPixmap(KIconLoader::global()->loadIcon(item.iconName(), KIconLoader::Desktop, 128));
    m_busyOverlay->stop();
}
<commit_msg>Pluralize message: some languages have different plural forms for numbers > 1.<commit_after>/*
 * Main Send File Transfer Window
 *
 * Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <KFileItem>
#include <KApplication>
#include <KMimeType>
#include <KDebug>
#include <KMessageBox>
#include <KPixmapSequence>
#include <KPixmapSequenceOverlayPainter>
#include <KLineEdit>
#include <KIO/PreviewJob>

#include <QtGui/QPushButton>

#include <TelepathyQt/AccountManager>
#include <TelepathyQt/PendingChannelRequest>
#include <TelepathyQt/PendingReady>

#include <KTp/actions.h>
#include <KTp/contact-factory.h>
#include <KTp/Models/contacts-list-model.h>
#include <KTp/Models/contacts-filter-model.h>
#include <KTp/Widgets/contact-grid-widget.h>

MainWindow::MainWindow(const KUrl::List &urls, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow),
    m_urls(urls),
    m_contactsModel(0)
{
    Tp::registerTypes();

    ui->setupUi(this);
    if (urls.size() == 1) {
        setWindowTitle(i18n("Send file - %1", urls.first().fileName()));

        ui->filesInfoLabel->hide();
        ui->fileNameLabel->setText(urls.first().fileName());
    } else {
        QString fileNames;
        Q_FOREACH(const KUrl &file, urls) {
            fileNames += file.fileName() + " ";
        }
        setWindowTitle(i18n("Send files - %1", fileNames.trimmed()));

        ui->messageLabel->setText(i18n("You are about to send these files"));
        ui->filesInfoLabel->setText(i18np("1 file selected", "%1 files selected",  QString::number(urls.count())));
        ui->fileNameLabel->setText(fileNames.replace(" ", "
"));
    }

    kDebug() << KApplication::arguments();

    m_busyOverlay = new KPixmapSequenceOverlayPainter(this);
    m_busyOverlay->setSequence(KPixmapSequence("process-working", 22));
    m_busyOverlay->setWidget(ui->filePreview);
    m_busyOverlay->start();

    if (urls.size() == 1) {
        KFileItem file(KFileItem::Unknown, KFileItem::Unknown, urls.first());
        QStringList availablePlugins = KIO::PreviewJob::availablePlugins();
        KIO::PreviewJob* job = KIO::filePreview(KFileItemList() << file, QSize(280, 280), &availablePlugins);
        job->setOverlayIconAlpha(0);
        job->setScaleType(KIO::PreviewJob::Unscaled);
        connect(job, SIGNAL(gotPreview(KFileItem, QPixmap)),
                this, SLOT(onPreviewLoaded(KFileItem, QPixmap)));
        connect(job, SIGNAL(failed(KFileItem)),
                this, SLOT(onPreviewFailed(KFileItem)));
    } else {
        ui->filePreview->setPixmap(QPixmap(DesktopIcon("dialog-information.png", 128)));
        m_busyOverlay->stop();
    }

    Tp::AccountFactoryPtr  accountFactory = Tp::AccountFactory::create(QDBusConnection::sessionBus(),
                                                                       Tp::Features() << Tp::Account::FeatureCore
                                                                       << Tp::Account::FeatureAvatar
                                                                       << Tp::Account::FeatureProtocolInfo
                                                                       << Tp::Account::FeatureProfile
                                                                       << Tp::Account::FeatureCapabilities);

    Tp::ConnectionFactoryPtr connectionFactory = Tp::ConnectionFactory::create(QDBusConnection::sessionBus(),
                                                                               Tp::Features() << Tp::Connection::FeatureCore
                                                                               << Tp::Connection::FeatureRosterGroups
                                                                               << Tp::Connection::FeatureRoster
                                                                               << Tp::Connection::FeatureSelfContact);

    Tp::ContactFactoryPtr contactFactory = KTp::ContactFactory::create(Tp::Features()  << Tp::Contact::FeatureAlias
                                                                      << Tp::Contact::FeatureAvatarData
                                                                      << Tp::Contact::FeatureSimplePresence
                                                                      << Tp::Contact::FeatureCapabilities);

    Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(QDBusConnection::sessionBus());

    m_accountManager = Tp::AccountManager::create(QDBusConnection::sessionBus(),
                                                  accountFactory,
                                                  connectionFactory,
                                                  channelFactory,
                                                  contactFactory);

    m_contactsModel = new KTp::ContactsListModel(this);
    connect(m_accountManager->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady()));

    m_contactGridWidget = new KTp::ContactGridWidget(m_contactsModel, this);
    m_contactGridWidget->contactFilterLineEdit()->setClickMessage(i18n("Search in Contacts..."));
    m_contactGridWidget->filter()->setPresenceTypeFilterFlags(KTp::ContactsFilterModel::ShowOnlyConnected);
    m_contactGridWidget->filter()->setCapabilityFilterFlags(KTp::ContactsFilterModel::FilterByFileTransferCapability);
    ui->recipientVLayout->addWidget(m_contactGridWidget);

    connect(m_contactGridWidget,
            SIGNAL(selectionChanged(Tp::AccountPtr,Tp::ContactPtr)),
            SLOT(onContactSelectionChanged(Tp::AccountPtr,Tp::ContactPtr)));

    ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true);
    connect(ui->buttonBox, SIGNAL(accepted()), SLOT(onDialogAccepted()));
    connect(ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onAccountManagerReady()
{
    m_contactsModel->setAccountManager(m_accountManager);
}

void MainWindow::onDialogAccepted()
{
    // don't do anytghing if no contact has been selected
    if (!m_contactGridWidget->hasSelection()) {
        // show message box?
        return;
    }

    // start sending file
    Q_FOREACH(const KUrl &url, m_urls) {
        Tp::PendingChannelRequest* channelRequest = KTp::Actions::startFileTransfer(m_contactGridWidget->selectedAccount(),
                                                                                m_contactGridWidget->selectedContact(),
                                                                                url.path());

        connect(channelRequest, SIGNAL(finished(Tp::PendingOperation*)), SLOT(slotFileTransferFinished(Tp::PendingOperation*)));
    }

    //disable the buttons
    foreach(QAbstractButton* button, ui->buttonBox->buttons()) {
        button->setEnabled(false);
    }
}

void MainWindow::onContactSelectionChanged(Tp::AccountPtr account, Tp::ContactPtr contact)
{
    Q_UNUSED(account)
    Q_UNUSED(contact)

    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_contactGridWidget->hasSelection());
}

void MainWindow::slotFileTransferFinished(Tp::PendingOperation* op)
{
    if (op->isError()) {
        //FIXME map to human readable strings.
        QString errorMsg(op->errorName() + ": " + op->errorMessage());
        kDebug() << "ERROR!: " << errorMsg;
        KMessageBox::error(this, i18n("Failed to send file"), i18n("File Transfer Failed"));
        close();
    } else {
        kDebug() << "Transfer started";
        // now I can close the dialog
        close();
    }
}

void MainWindow::onPreviewLoaded(const KFileItem& item, const QPixmap& preview)
{
    Q_UNUSED(item);
    ui->filePreview->setPixmap(preview);
    m_busyOverlay->stop();
}

void MainWindow::onPreviewFailed(const KFileItem& item)
{
    kWarning() << "Loading thumb failed" << item.name();
    ui->filePreview->setPixmap(KIconLoader::global()->loadIcon(item.iconName(), KIconLoader::Desktop, 128));
    m_busyOverlay->stop();
}
<|endoftext|>


<commit_before>#include <QtWidgets>
#include "mainwindow.h"
#include <fts_fuzzy_match.h>
#include <glob.h>
#include <string>
#include <map>

Window::Window(QWidget *parent) : QWidget(parent)
{
    textLabel = new QLabel(tr("Search:"));
    searchBox = new SearchBox();
    connect(searchBox, SIGNAL(updateMatches(std::map<double, QString>)), this, SLOT(showFiles(std::map<double, QString>)));
    createFilesTable();
    connect(searchBox, SIGNAL(returnPressed()), filesTable, SLOT(setFocus()) );

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(textLabel, 0, 0);
    mainLayout->addWidget(searchBox, 0, 1, 1, 1);
    mainLayout->addWidget(filesTable, 1, 0, 1, 4);
    setLayout(mainLayout);

    setWindowTitle(tr("Find Recipes"));
    resize(500, 300);
}

// Get list of files according to glob patternn
QStringList globVector(const std::string& pattern){
    glob_t glob_result;
    glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
    QStringList files;
    for(unsigned int i=0; i<glob_result.gl_pathc; ++i){
        files << QString(glob_result.gl_pathv[i]);
    }
    globfree(&glob_result);
    return files;
}

void SearchBox::keyPressEvent(QKeyEvent *evt){

    QLineEdit::keyPressEvent(evt);
    QStringList files = globVector("*/*.md");
    std::map<double, QString> matches;
    if (!text().isEmpty()){
        matches = findFiles(files, text());
    }
    emit updateMatches(matches);
}

std::map<double, QString> SearchBox::findFiles(const QStringList &files, const QString &text)
{
    std::map<double, QString> matchingFiles;

    std::string txtstr = text.toStdString();
    for (int i=0; i<files.size(); ++i){
        int score;
        std::string filestr = files[i].toStdString();
        if (fts::fuzzy_match_score(txtstr.c_str(), filestr.c_str(), score)){
            // If a map entry already has the current score, increase score by 0.01. When dispaying, we'll round back to int.
            double dbscore = (double)score;
            if (matchingFiles.count(dbscore) > 0){
                dbscore += 0.01;
            }
            matchingFiles[dbscore] = files[i];
        }
    }
    return matchingFiles;
}

void Window::showFiles(const std::map<double, QString> &files)
{
    filesTable->setRowCount(0);

    for (auto iter = files.rbegin(); iter != files.rend(); ++iter){
        QTableWidgetItem *fileNameItem = new QTableWidgetItem(iter->second.split('/')[1]);
        fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable);
        QTableWidgetItem *rankItem = new QTableWidgetItem(tr("%1").arg(int(round(iter->first)) ));
        rankItem->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);
        fileNameItem->setFlags(rankItem->flags() ^ Qt::ItemIsEditable);

        int row = filesTable->rowCount();
        filesTable->insertRow(row);
        filesTable->setItem(row, 0, fileNameItem);
        filesTable->setItem(row, 1, rankItem);
    }
    filesTable->selectRow(0);
}

void Window::createFilesTable()
{
    filesTable = new QTableWidget(0, 2);
    filesTable->setSelectionBehavior(QAbstractItemView::SelectRows);

    QStringList labels;
    labels << tr("Recipe") << tr("Rank");
    filesTable->setHorizontalHeaderLabels(labels);
    filesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
    filesTable->verticalHeader()->hide();
    filesTable->setShowGrid(false);

    connect(filesTable, &QTableWidget::cellActivated,
            this, &Window::openFileOfItem);
}

void Window::openFileOfItem(int row, int /* column */)
{
    QTableWidgetItem *item = filesTable->item(row, 0);

    QDesktopServices::openUrl(QUrl::fromLocalFile(currentDir.absoluteFilePath(item->text())));
}
<commit_msg>Revert removal of folder from recipe name. This breaks ability to open file.<commit_after>#include <QtWidgets>
#include "mainwindow.h"
#include <fts_fuzzy_match.h>
#include <glob.h>
#include <string>
#include <map>

Window::Window(QWidget *parent) : QWidget(parent)
{
    textLabel = new QLabel(tr("Search:"));
    searchBox = new SearchBox();
    connect(searchBox, SIGNAL(updateMatches(std::map<double, QString>)), this, SLOT(showFiles(std::map<double, QString>)));
    createFilesTable();
    connect(searchBox, SIGNAL(returnPressed()), filesTable, SLOT(setFocus()) );

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(textLabel, 0, 0);
    mainLayout->addWidget(searchBox, 0, 1, 1, 1);
    mainLayout->addWidget(filesTable, 1, 0, 1, 4);
    setLayout(mainLayout);

    setWindowTitle(tr("Find Recipes"));
    resize(500, 300);
}

// Get list of files according to glob patternn
QStringList globVector(const std::string& pattern){
    glob_t glob_result;
    glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
    QStringList files;
    for(unsigned int i=0; i<glob_result.gl_pathc; ++i){
        files << QString(glob_result.gl_pathv[i]);
    }
    globfree(&glob_result);
    return files;
}

void SearchBox::keyPressEvent(QKeyEvent *evt){

    QLineEdit::keyPressEvent(evt);
    QStringList files = globVector("*/*.md");
    std::map<double, QString> matches;
    if (!text().isEmpty()){
        matches = findFiles(files, text());
    }
    emit updateMatches(matches);
}

std::map<double, QString> SearchBox::findFiles(const QStringList &files, const QString &text)
{
    std::map<double, QString> matchingFiles;

    std::string txtstr = text.toStdString();
    for (int i=0; i<files.size(); ++i){
        int score;
        std::string filestr = files[i].toStdString();
        if (fts::fuzzy_match_score(txtstr.c_str(), filestr.c_str(), score)){
            // If a map entry already has the current score, increase score by 0.01. When dispaying, we'll round back to int.
            double dbscore = (double)score;
            if (matchingFiles.count(dbscore) > 0){
                dbscore += 0.01;
            }
            matchingFiles[dbscore] = files[i];
        }
    }
    return matchingFiles;
}

void Window::showFiles(const std::map<double, QString> &files)
{
    filesTable->setRowCount(0);

    for (auto iter = files.rbegin(); iter != files.rend(); ++iter){
        QTableWidgetItem *fileNameItem = new QTableWidgetItem(iter->second);
        fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable);
        QTableWidgetItem *rankItem = new QTableWidgetItem(tr("%1").arg(int(round(iter->first)) ));
        rankItem->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);
        fileNameItem->setFlags(rankItem->flags() ^ Qt::ItemIsEditable);

        int row = filesTable->rowCount();
        filesTable->insertRow(row);
        filesTable->setItem(row, 0, fileNameItem);
        filesTable->setItem(row, 1, rankItem);
    }
    filesTable->selectRow(0);
}

void Window::createFilesTable()
{
    filesTable = new QTableWidget(0, 2);
    filesTable->setSelectionBehavior(QAbstractItemView::SelectRows);

    QStringList labels;
    labels << tr("Recipe") << tr("Rank");
    filesTable->setHorizontalHeaderLabels(labels);
    filesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
    filesTable->verticalHeader()->hide();
    filesTable->setShowGrid(false);

    connect(filesTable, &QTableWidget::cellActivated,
            this, &Window::openFileOfItem);
}

void Window::openFileOfItem(int row, int /* column */)
{
    QTableWidgetItem *item = filesTable->item(row, 0);

    QDesktopServices::openUrl(QUrl::fromLocalFile(currentDir.absoluteFilePath(item->text())));
}
<|endoftext|>