From 99bc38e1d21b0081618485e49b0ab1bcd5bef22f Mon Sep 17 00:00:00 2001
From: Mateusz Piekos <mateuszpiekos@gmail.com>
Date: Tue, 26 Jun 2012 12:18:33 +0200
Subject: Added handling of circles(ellipses)


diff --git a/Swift/QtUI/Whiteboard/GView.cpp b/Swift/QtUI/Whiteboard/GView.cpp
index e904b32..badbb8e 100644
--- a/Swift/QtUI/Whiteboard/GView.cpp
+++ b/Swift/QtUI/Whiteboard/GView.cpp
@@ -90,14 +90,29 @@ namespace Swift {
 			}
 		}
 		else if (mode == Circle) {
-			QGraphicsPathItem* item = qgraphicsitem_cast<QGraphicsPathItem*>(lastItem);
+			QGraphicsEllipseItem* item = qgraphicsitem_cast<QGraphicsEllipseItem*>(lastItem);
 			QPainterPath path;
 			QPointF beginPoint = item->data(0).toPointF();
 			QPointF newPoint = this->mapToScene(event->pos());
-			path.moveTo((newPoint.x()+beginPoint.x())/2, beginPoint.y());
-			path.cubicTo(beginPoint.x(), beginPoint.y(), beginPoint.x(), newPoint.y(), (newPoint.x()+beginPoint.x())/2, newPoint.y());
-			path.cubicTo(newPoint.x(), newPoint.y(), newPoint.x(), beginPoint.y(), (newPoint.x()+beginPoint.x())/2, beginPoint.y());
-			item->setPath(path);
+			QRectF rect = item->rect();
+			if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
+				rect.setTopLeft(beginPoint);
+				rect.setBottomRight(newPoint);
+			}
+			else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
+				rect.setTopRight(beginPoint);
+				rect.setBottomLeft(newPoint);
+			}
+			else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
+				rect.setBottomLeft(beginPoint);
+				rect.setTopRight(newPoint);
+			}
+			else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
+				rect.setBottomRight(beginPoint);
+				rect.setTopLeft(newPoint);
+			}
+
+			item->setRect(rect);
 		}
 		else if (mode == HandLine) {
 			FreehandLineItem* item  = qgraphicsitem_cast<FreehandLineItem*>(lastItem);
@@ -177,7 +192,7 @@ namespace Swift {
 		}
 		else if (mode == Circle) {
 			QPointF point = this->mapToScene(event->pos());
-			QGraphicsPathItem* item = scene()->addPath(QPainterPath(), pen, brush);
+			QGraphicsEllipseItem* item = scene()->addEllipse(point.x(), point.y(), 0, 0, pen, brush);
 			QString id = QString::fromStdString(idGenerator.generateID());
 			items_.insert(id, item);
 			item->setZValue(zValue++);
@@ -217,6 +232,7 @@ namespace Swift {
 			item->setData(0, id);
 			item->setDefaultTextColor(pen.color());
 			textDialog = new TextDialog(item, this);
+			connect(textDialog, SIGNAL(accepted()), this, SIGNAL(lastItemChanged(textDialog)));
 			textDialog->setAttribute(Qt::WA_DeleteOnClose);
 			textDialog->show();
 			item->setPos(point);
diff --git a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
index a53b0dd..55d3479 100644
--- a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
+++ b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
@@ -295,6 +295,25 @@ namespace Swift {
 			element->setID(polygonItem->data(0).toString().toStdString());
 			whiteboardSession_->sendElement(element);
 		}
+
+		QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+		if (ellipseItem) {
+			QRectF rect = ellipseItem->rect();
+			int cx = rect.x()+rect.width()/2;
+			int cy = rect.y()+rect.height()/2;
+			int rx = rect.width()/2;
+			int ry = rect.height()/2;
+			WhiteboardEllipseElement::ref element = boost::make_shared<WhiteboardEllipseElement>(cx, cy, rx, ry);
+
+			QColor penColor = ellipseItem->pen().color();
+			QColor brushColor = ellipseItem->brush().color();
+			element->setPenColor(Color(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+			element->setBrushColor(Color(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+			element->setPenWidth(ellipseItem->pen().width());
+
+			element->setID(ellipseItem->data(1).toString().toStdString());
+			whiteboardSession_->sendElement(element);
+		}
 	}
 
 	void QtWhiteboardWindow::handleSessionTerminate() {
diff --git a/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h b/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
index ebc9045..4b2f7ed 100644
--- a/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
+++ b/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
@@ -10,8 +10,10 @@
 #include <Swiften/Whiteboard/Elements/WhiteboardLineElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardTextElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardFreehandPathElement.h>
 #include <Swift/QtUI/Whiteboard/GView.h>
+#include <QtSwiftUtil.h>
 
 namespace Swift {
 	class WhiteboardElementDrawingVisitor : public WhiteboardElementVisitor {
@@ -60,7 +62,7 @@ namespace Swift {
 		}
 
 		void visit(WhiteboardPolygonElement& element) {
-			QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(graphicsView_->getItem(QString::fromStdString(element.getID())));
+			QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
 			if (item == 0) {
 				item = new QGraphicsPolygonItem();
 				QPen pen;
@@ -86,6 +88,25 @@ namespace Swift {
 
 		}
 
+		void visit(WhiteboardEllipseElement& element) {
+			QRectF rect;
+
+			rect.setTopLeft(QPointF(element.getCX()-element.getRX(), element.getCY()-element.getRY()));
+			rect.setBottomRight(QPointF(element.getCX()+element.getRX(), element.getCY()+element.getRY()));
+
+			QGraphicsEllipseItem* item = new QGraphicsEllipseItem(rect);
+			QPen pen;
+			QBrush brush(Qt::SolidPattern);
+			Color penColor = element.getPenColor();
+			Color brushColor = element.getBrushColor();
+			pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
+			pen.setWidth(element.getPenWidth());
+			brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
+			item->setPen(pen);
+			item->setBrush(brush);
+			graphicsView_->scene()->addItem(item);
+		}
+
 	private:
 		GView* graphicsView_;
 	};
diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
index d1d57a0..b5cfa7b 100644
--- a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
@@ -9,6 +9,7 @@
 #include <Swiften/Whiteboard/Elements/WhiteboardRectElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardTextElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardFreehandPathElement.h>
 #include <Swiften/Whiteboard/Elements/Color.h>
 #include <boost/optional.hpp>
@@ -168,6 +169,36 @@ namespace Swift {
 			} else if (element == "text") {
 				WhiteboardTextElement::ref whiteboardElement = boost::make_shared<WhiteboardTextElement>(0,0);
 				getPayloadInternal()->setElement(whiteboardElement);
+			} else if (element == "ellipse") {
+				int cx = 0;
+				int cy = 0;
+				int rx = 0;
+				int ry = 0;
+				try {
+					cx = boost::lexical_cast<int>(attributes.getAttributeValue("cx").get_value_or("0"));
+					cy = boost::lexical_cast<int>(attributes.getAttributeValue("cy").get_value_or("0"));
+					rx = boost::lexical_cast<int>(attributes.getAttributeValue("rx").get_value_or("0"));
+					ry = boost::lexical_cast<int>(attributes.getAttributeValue("ry").get_value_or("0"));
+				} catch (boost::bad_lexical_cast&) {
+				}
+
+				WhiteboardEllipseElement::ref whiteboardElement = boost::make_shared<WhiteboardEllipseElement>(cx, cy, rx, ry);
+
+				int penWidth = 1;
+				try {
+					penWidth = boost::lexical_cast<int>(attributes.getAttributeValue("stroke-width").get_value_or("1"));
+				} catch (boost::bad_lexical_cast&) {
+				}
+				whiteboardElement->setPenWidth(penWidth);
+
+				Color penColor(attributes.getAttributeValue("stroke").get_value_or("#000000"));
+				Color brushColor(attributes.getAttributeValue("fill").get_value_or("#000000"));
+				penColor.setAlpha(opacityToAlpha(attributes.getAttributeValue("opacity").get_value_or("1")));
+				brushColor.setAlpha(opacityToAlpha(attributes.getAttributeValue("fill-opacity").get_value_or("1")));
+				whiteboardElement->setPenColor(penColor);
+				whiteboardElement->setBrushColor(brushColor);
+
+				getPayloadInternal()->setElement(whiteboardElement);
 			}
 		}
 		++level_;
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
index 5ce8c20..a15d7ae 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
@@ -96,6 +96,23 @@ namespace Swift {
 		}
 	}
 
+ 	void WhiteboardElementSerializingVisitor::visit(WhiteboardEllipseElement& ellipse) {
+		element = boost::make_shared<XMLElement>("ellipse");
+		try {
+			element->setAttribute("cx", boost::lexical_cast<std::string>(ellipse.getCX()));
+			element->setAttribute("cy", boost::lexical_cast<std::string>(ellipse.getCY()));
+			element->setAttribute("rx", boost::lexical_cast<std::string>(ellipse.getRX()));
+			element->setAttribute("ry", boost::lexical_cast<std::string>(ellipse.getRY()));
+			element->setAttribute("id", ellipse.getID());
+			element->setAttribute("stroke", ellipse.getPenColor().toHex());
+			element->setAttribute("fill", ellipse.getBrushColor().toHex());;
+			element->setAttribute("stroke-width", boost::lexical_cast<std::string>(ellipse.getPenWidth()));
+			element->setAttribute("opacity", alphaToOpacity(ellipse.getPenColor().getAlpha()));
+			element->setAttribute("fill-opacity", alphaToOpacity(ellipse.getBrushColor().getAlpha()));
+		} catch (boost::bad_lexical_cast&) {
+		}
+	}
+
 	std::string WhiteboardElementSerializingVisitor::intToStr(const int t) const {
 		std::stringstream ss;
 		ss << t;
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
index 4251cca..cc25bd1 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
@@ -12,6 +12,7 @@
 #include <Swiften/Whiteboard/Elements/WhiteboardRectElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardTextElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h>
 #include <Swiften/Serializer/GenericPayloadSerializer.h>
 #include <Swiften/Serializer/XML/XMLElement.h>
@@ -24,6 +25,7 @@ namespace Swift {
 		void visit(WhiteboardRectElement& rect);
 		void visit(WhiteboardPolygonElement& polygon);
 		void visit(WhiteboardTextElement& text);
+		void visit(WhiteboardEllipseElement& ellipse);
 		XMLElement::ref getResult() const;
 
 	private:
diff --git a/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h b/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h
index 7244ad1..413d6cf 100644
--- a/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h
+++ b/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h
@@ -12,6 +12,7 @@ namespace Swift {
 	class WhiteboardRectElement;
 	class WhiteboardPolygonElement;
 	class WhiteboardTextElement;
+	class WhiteboardEllipseElement;
 
 	class WhiteboardElementVisitor {
 	public:
@@ -21,5 +22,6 @@ namespace Swift {
 		virtual void visit(WhiteboardRectElement& /*element*/) = 0;
 		virtual void visit(WhiteboardPolygonElement& /*element*/) = 0;
 		virtual void visit(WhiteboardTextElement& /*element*/) = 0;
+		virtual void visit(WhiteboardEllipseElement& /*element*/) = 0;
 	};
 }
diff --git a/Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h b/Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h
new file mode 100644
index 0000000..8c74561
--- /dev/null
+++ b/Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Whiteboard/Elements/WhiteboardElement.h>
+#include <Swiften/Whiteboard/Elements/Color.h>
+
+namespace Swift {
+	class WhiteboardEllipseElement : public WhiteboardElement {
+	public:
+		typedef boost::shared_ptr<WhiteboardEllipseElement> ref;
+	public:
+		WhiteboardEllipseElement(int cx, int cy, int rx, int ry) {
+			cx_ = cx;
+			cy_ = cy;
+			rx_ = rx;
+			ry_ = ry;
+		}
+
+		int getCX() const {
+			return cx_;
+		}
+
+		int getCY() const {
+			return cy_;
+		}
+
+		int getRX() const {
+			return rx_;
+		}
+
+		int getRY() const {
+			return ry_;
+		}
+
+		const Color& getPenColor() const {
+			return penColor_;
+		}
+
+		void setPenColor(const Color& color) {
+			penColor_ = color;
+		}
+
+		const Color& getBrushColor() const {
+			return brushColor_;
+		}
+
+		void setBrushColor(const Color& color) {
+			brushColor_ = color;
+		}
+
+		std::string getID() const {
+			return id_;
+		}
+
+		void setID(const std::string& id) {
+			id_ = id;
+		}
+
+		int getPenWidth() const {
+			return penWidth_;
+		}
+
+		void setPenWidth(const int penWidth) {
+			penWidth_ = penWidth;
+		}
+
+		void accept(WhiteboardElementVisitor& visitor) {
+			visitor.visit(*this);
+		}
+
+	private:
+		int cx_, cy_, rx_, ry_;
+		Color penColor_;
+		Color brushColor_;
+		int penWidth_;
+		std::string id_;
+	};
+}
-- 
cgit v0.10.2-6-g49f6