From 06bbc72598ece3e62b82471e474b0753d5439f00 Mon Sep 17 00:00:00 2001
From: Mateusz Piekos <mateuszpiekos@gmail.com>
Date: Sun, 24 Jun 2012 20:37:27 +0200
Subject: Added handling of rects and basic handling of polygons


diff --git a/Swift/QtUI/Whiteboard/GView.cpp b/Swift/QtUI/Whiteboard/GView.cpp
index 478dee0..e904b32 100644
--- a/Swift/QtUI/Whiteboard/GView.cpp
+++ b/Swift/QtUI/Whiteboard/GView.cpp
@@ -45,6 +45,10 @@ namespace Swift {
 		lastItem = 0;
 	}
 
+	QGraphicsItem* GView::getItem(const QString id) const {
+		return items_.value(id);
+	}
+
 	void GView::mouseMoveEvent(QMouseEvent* event)
 	{
 		if (!mousePressed) {
@@ -144,17 +148,19 @@ namespace Swift {
 			QPointF point = this->mapToScene(event->pos());
 			QGraphicsItem* item = scene()->addLine(point.x(), point.y(), point.x(), point.y(), pen);
 			QString id = QString::fromStdString(idGenerator.generateID());
+			items_.insert(id, item);
 			item->setZValue(zValue++);
 			item->setData(0, id);
-			items_.insert(id, item);
 			lastItem = item;
-
 		}
 		else if (mode == Rect) {
 			QPointF point = this->mapToScene(event->pos());
 			QGraphicsRectItem* item = scene()->addRect(point.x(), point.y(), 0, 0, pen, brush);
+			QString id = QString::fromStdString(idGenerator.generateID());
+			items_.insert(id, item);
 			item->setZValue(zValue++);
 			item->setData(0, point);
+			item->setData(1, id);
 			lastItem = item;
 		}
 		else if (mode == Rubber) {
@@ -172,16 +178,22 @@ namespace Swift {
 		else if (mode == Circle) {
 			QPointF point = this->mapToScene(event->pos());
 			QGraphicsPathItem* item = scene()->addPath(QPainterPath(), pen, brush);
+			QString id = QString::fromStdString(idGenerator.generateID());
+			items_.insert(id, item);
 			item->setZValue(zValue++);
 			item->setData(0, point);
+			item->setData(1, id);
 			lastItem = item;
 		}
 		else if (mode == HandLine) {
 			QPointF point = this->mapToScene(event->pos());
 			FreehandLineItem* item = new FreehandLineItem;
+			QString id = QString::fromStdString(idGenerator.generateID());
+			items_.insert(id, item);
 			item->setPen(pen);
 			item->setStartPoint(point);
 			item->setZValue(zValue++);
+			item->setData(0, id);
 			scene()->addItem(item);
 			lastItem = item;
 		}
@@ -189,19 +201,26 @@ namespace Swift {
 			QPointF point = this->mapToScene(event->pos());
 			QPainterPath path;
 			QGraphicsPathItem* item = scene()->addPath(path, pen, brush);
+			QString id = QString::fromStdString(idGenerator.generateID());
+			items_.insert(id, item);
 			item->setZValue(zValue++);
 			item->setData(0, point);
+			item->setData(1, id);
 			lastItem = item;
 		}
 		else if (mode == Text) {
 			QPointF point = this->mapToScene(event->pos());
 			QGraphicsTextItem* item = scene()->addText("");
+			QString id = QString::fromStdString(idGenerator.generateID());
+			items_.insert(id, item);
 			item->setZValue(zValue++);
+			item->setData(0, id);
 			item->setDefaultTextColor(pen.color());
 			textDialog = new TextDialog(item, this);
 			textDialog->setAttribute(Qt::WA_DeleteOnClose);
 			textDialog->show();
 			item->setPos(point);
+			lastItem = item;
 		}
 		else if (mode == Polygon) {
 			QPointF point = this->mapToScene(event->pos());
@@ -211,7 +230,10 @@ namespace Swift {
 				polygon.append(point);
 				polygon.append(point);
 				item = scene()->addPolygon(polygon, pen, brush);
+				QString id = QString::fromStdString(idGenerator.generateID());
+				items_.insert(id, item);
 				item->setZValue(zValue++);
+				item->setData(0, id);
 				lastItem = item;
 			}
 			else {
diff --git a/Swift/QtUI/Whiteboard/GView.h b/Swift/QtUI/Whiteboard/GView.h
index 74da7a4..1a4dc42 100644
--- a/Swift/QtUI/Whiteboard/GView.h
+++ b/Swift/QtUI/Whiteboard/GView.h
@@ -31,6 +31,7 @@ namespace Swift {
 		void mouseMoveEvent(QMouseEvent* event);
 		void mousePressEvent(QMouseEvent* event);
 		void mouseReleaseEvent(QMouseEvent* event);
+		QGraphicsItem* getItem(const QString id) const;
 
 	public slots:
 		void moveUpSelectedItem();
diff --git a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
index 0a1afe3..a53b0dd 100644
--- a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
+++ b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
@@ -14,6 +14,7 @@
 #include <Swiften/Whiteboard/WhiteboardSession.h>
 #include <Swiften/Elements/WhiteboardPayload.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardLineElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardRectElement.h>
 #include <Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h>
 
 #include <QMessageBox>
@@ -131,22 +132,6 @@ namespace Swift {
 	void QtWhiteboardWindow::handleWhiteboardElementReceive(const WhiteboardElement::ref element) {
 		WhiteboardElementDrawingVisitor visitor(graphicsView);
 		element->accept(visitor);
-/*
-		else if (mode == 'F') {
-			FreehandLineItem *freehandLineItem = new FreehandLineItem();
-			getline(stream, temp, ','); 
-			x1 = atoi(temp.c_str());
-			getline(stream, temp, ','); 
-			y1 = atoi(temp.c_str());
-			freehandLineItem->setStartPoint(QPointF(x1, y1));
-			while (getline(stream, temp, ',')) {
-				x1 = atoi(temp.c_str());
-				getline(stream, temp, ','); 
-				y1 = atoi(temp.c_str());
-				freehandLineItem->lineTo(QPointF(x1, y1));
-			}
- 			graphicsView->scene()->addItem(freehandLineItem);
-			}*/
 	}
 
 	void QtWhiteboardWindow::changeLineWidth(int i)
@@ -259,7 +244,56 @@ namespace Swift {
 
 			element->setID(freehandLineItem->data(0).toString().toStdString());
 			whiteboardSession_->sendElement(element);
+		}
+
+		QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+		if (rectItem != 0) {
+			QRectF rect = rectItem->rect();
+			WhiteboardRectElement::ref element = boost::make_shared<WhiteboardRectElement>(rect.x(), rect.y(), rect.width(), rect.height());
+			QColor penColor = rectItem->pen().color();
+			QColor brushColor = rectItem->brush().color();
+
+			element->setBrushColor(Color(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+			element->setPenColor(Color(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+			element->setPenWidth(rectItem->pen().width());
+
+			element->setID(rectItem->data(1).toString().toStdString());
+			whiteboardSession_->sendElement(element);
+		}
+
+		QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
+		if (textItem != 0) {
+			QPointF point = textItem->pos();
+			WhiteboardTextElement::ref element = boost::make_shared<WhiteboardTextElement>(point.x(), point.y());
+			element->setText(textItem->toPlainText().toStdString());
+
+			QColor color = textItem->defaultTextColor();
+			element->setColor(Color(color.red(), color.green(), color.blue(), color.alpha()));
+
+			element->setID(rectItem->data(0).toString().toStdString());
+			whiteboardSession_->sendElement(element);
+		}
 
+		QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
+		if (polygonItem) {
+			WhiteboardPolygonElement::ref element = boost::make_shared<WhiteboardPolygonElement>();
+			QPolygonF polygon = polygonItem->polygon();
+			std::vector<std::pair<int, int> > points;
+			QVector<QPointF>::const_iterator it = polygon.begin();
+			for (; it != polygon.end(); ++it) {
+				points.push_back(std::pair<int, int>(it->x(), it->y()));
+			}
+
+			element->setPoints(points);
+
+			QColor penColor = polygonItem->pen().color();
+			QColor brushColor = polygonItem->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(polygonItem->pen().width());
+
+			element->setID(polygonItem->data(0).toString().toStdString());
+			whiteboardSession_->sendElement(element);
 		}
 	}
 
diff --git a/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h b/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
index 3b144cc..ebc9045 100644
--- a/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
+++ b/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
@@ -8,6 +8,8 @@
 
 #include <Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardLineElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardTextElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardFreehandPathElement.h>
 #include <Swift/QtUI/Whiteboard/GView.h>
 
@@ -43,6 +45,47 @@ namespace Swift {
 			graphicsView_->scene()->addItem(item);
 		}
 
+		void visit(WhiteboardRectElement& element) {
+			QGraphicsRectItem* item = new QGraphicsRectItem(element.getX(), element.getY(), element.getWidth(), element.getHeight());
+			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);
+		}
+
+		void visit(WhiteboardPolygonElement& element) {
+			QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(graphicsView_->getItem(QString::fromStdString(element.getID())));
+			if (item == 0) {
+				item = new QGraphicsPolygonItem();
+				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);
+			}
+			QPolygonF polygon;
+			std::vector<std::pair<int, int> >::const_iterator it = element.getPoints().begin();
+			for (; it != element.getPoints().end(); ++it) {
+				polygon.append(QPointF(it->first, it->second));
+			}
+			item->setPolygon(polygon);
+		}
+
+		void visit(WhiteboardTextElement& element) {
+
+		}
+
 	private:
 		GView* graphicsView_;
 	};
diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
index 7182a8c..d1d57a0 100644
--- a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
@@ -6,6 +6,9 @@
 
 #include <Swiften/Parser/PayloadParsers/WhiteboardParser.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardLineElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardRectElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardTextElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardFreehandPathElement.h>
 #include <Swiften/Whiteboard/Elements/Color.h>
 #include <boost/optional.hpp>
@@ -33,16 +36,9 @@ namespace Swift {
 				} catch (boost::bad_lexical_cast&) {
 				}
 				WhiteboardLineElement::ref whiteboardElement = boost::make_shared<WhiteboardLineElement>(x1, y1, x2, y2);
-				Color color(attributes.getAttributeValue("stroke").get_value_or("#000000"));
 
-				std::string opacity = attributes.getAttributeValue("opacity").get_value_or("1");
-				if (opacity.find('.') != std::string::npos) {
-					opacity = opacity.substr(opacity.find('.')+1, 2);
-					try {
-						color.setAlpha(boost::lexical_cast<int>(opacity)*255/100);
-					} catch (boost::bad_lexical_cast&) {
-					}
-				} 
+				Color color(attributes.getAttributeValue("stroke").get_value_or("#000000"));
+				color.setAlpha(opacityToAlpha(attributes.getAttributeValue("opacity").get_value_or("1")));
 				whiteboardElement->setColor(color);
 
 				int penWidth = 1;
@@ -97,18 +93,81 @@ namespace Swift {
 				whiteboardElement->setPenWidth(penWidth);
 
 				Color color(attributes.getAttributeValue("stroke").get_value_or("#000000"));
+				color.setAlpha(opacityToAlpha(attributes.getAttributeValue("opacity").get_value_or("1")));
+				whiteboardElement->setColor(color);
 
-				std::string opacity = attributes.getAttributeValue("opacity").get_value_or("1");
-				if (opacity.find('.') != std::string::npos) {
-					opacity = opacity.substr(opacity.find('.')+1, 2);
-					try {
-						color.setAlpha(boost::lexical_cast<int>(opacity)*255/100);
-					} catch (boost::bad_lexical_cast&) {
+				getPayloadInternal()->setElement(whiteboardElement);
+			} else if (element == "rect") {
+				int x = 0;
+				int y = 0;
+				int width = 0;
+				int height = 0;
+				try {
+					x = boost::lexical_cast<int>(attributes.getAttributeValue("x").get_value_or("0"));
+					y = boost::lexical_cast<int>(attributes.getAttributeValue("y").get_value_or("0"));
+					width = boost::lexical_cast<int>(attributes.getAttributeValue("width").get_value_or("0"));
+					height = boost::lexical_cast<int>(attributes.getAttributeValue("height").get_value_or("0"));
+				} catch (boost::bad_lexical_cast&) {
+				}
+
+				WhiteboardRectElement::ref whiteboardElement = boost::make_shared<WhiteboardRectElement>(x, y, width, height);
+
+				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);
+			} else if (element == "polygon") {
+				WhiteboardPolygonElement::ref whiteboardElement = boost::make_shared<WhiteboardPolygonElement>();
+
+				std::string pointsData = attributes.getAttributeValue("points").get_value_or("");
+				std::vector<std::pair<int, int> > points;
+				int pos = 0;
+				int npos;
+				int x, y;
+				try {
+					while (pos < pointsData.size()) {
+						npos = pointsData.find(',', pos);
+						x = boost::lexical_cast<int>(pointsData.substr(pos, npos-pos));
+						pos = npos+1;
+						npos = pointsData.find(' ', pos);
+						y = boost::lexical_cast<int>(pointsData.substr(pos, npos-pos));
+						pos = npos+1;
+						points.push_back(std::pair<int, int>(x, y));
 					}
-				} 
-				whiteboardElement->setColor(color);
+				} catch (boost::bad_lexical_cast&) {
+				}			
+
+				whiteboardElement->setPoints(points);
+
+				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);
+			} else if (element == "text") {
+				WhiteboardTextElement::ref whiteboardElement = boost::make_shared<WhiteboardTextElement>(0,0);
+				getPayloadInternal()->setElement(whiteboardElement);
 			}
 		}
 		++level_;
@@ -136,4 +195,16 @@ namespace Swift {
 			return WhiteboardPayload::SessionTerminate;
 		}
 	}
+
+	int WhiteboardParser::opacityToAlpha(std::string opacity) const {
+		int value = 255;
+		if (opacity.find('.') != std::string::npos) {
+			opacity = opacity.substr(opacity.find('.')+1, 2);
+			try {
+				value = boost::lexical_cast<int>(opacity)*255/100;
+			} catch (boost::bad_lexical_cast&) {
+			}
+		}
+		return value;
+	}
 }
diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.h b/Swiften/Parser/PayloadParsers/WhiteboardParser.h
index 79d0f27..dfb2236 100644
--- a/Swiften/Parser/PayloadParsers/WhiteboardParser.h
+++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.h
@@ -21,6 +21,7 @@ namespace Swift {
 
 	private:
 		WhiteboardPayload::Type stringToType(const std::string& type) const;
+		int opacityToAlpha(std::string opacity) const;
 
 	private:
 		int level_;
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
index b5a4c49..5ce8c20 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
@@ -21,13 +21,7 @@ namespace Swift {
 			element->setAttribute("id", line.getID());
 			element->setAttribute("stroke", line.getColor().toHex());
 			element->setAttribute("stroke-width", boost::lexical_cast<std::string>(line.getPenWidth()));
-			int alpha = line.getColor().getAlpha();
-			int opacity = 100*alpha/254;
-			if (opacity == 100) {
-				element->setAttribute("opacity", "1");
-			} else {
-				element->setAttribute("opacity", "."+boost::lexical_cast<std::string>(opacity));
-			}
+			element->setAttribute("opacity", alphaToOpacity(line.getColor().getAlpha()));
 		} catch (boost::bad_lexical_cast&) {
 		}
 	}
@@ -38,13 +32,7 @@ namespace Swift {
 		element->setAttribute("stroke", path.getColor().toHex());
 		try {
 			element->setAttribute("stroke-width", boost::lexical_cast<std::string>(path.getPenWidth()));
-			int alpha = path.getColor().getAlpha();
-			int opacity = 100*alpha/254;
-			if (opacity == 100) {
-				element->setAttribute("opacity", "1");
-			} else {
-				element->setAttribute("opacity", "."+boost::lexical_cast<std::string>(opacity));
-			}
+			element->setAttribute("opacity", alphaToOpacity(path.getColor().getAlpha()));
 			std::string pathData;
 			if (path.getPoints().size() != 0) {
 				std::vector<std::pair<int, int> >::const_iterator it = path.getPoints().begin();
@@ -58,6 +46,56 @@ namespace Swift {
 		}
 	}
 
+	void WhiteboardElementSerializingVisitor::visit(WhiteboardRectElement& rect) {
+		element = boost::make_shared<XMLElement>("rect");
+		try {
+			element->setAttribute("x", boost::lexical_cast<std::string>(rect.getX()));
+			element->setAttribute("y", boost::lexical_cast<std::string>(rect.getY()));
+			element->setAttribute("width", boost::lexical_cast<std::string>(rect.getWidth()));
+			element->setAttribute("height", boost::lexical_cast<std::string>(rect.getHeight()));
+			element->setAttribute("id", rect.getID());
+			element->setAttribute("stroke", rect.getPenColor().toHex());
+			element->setAttribute("fill", rect.getBrushColor().toHex());;
+			element->setAttribute("stroke-width", boost::lexical_cast<std::string>(rect.getPenWidth()));
+			element->setAttribute("opacity", alphaToOpacity(rect.getPenColor().getAlpha()));
+			element->setAttribute("fill-opacity", alphaToOpacity(rect.getBrushColor().getAlpha()));
+		} catch (boost::bad_lexical_cast&) {
+		}
+	}
+
+	void WhiteboardElementSerializingVisitor::visit(WhiteboardPolygonElement& polygon) {
+		element = boost::make_shared<XMLElement>("polygon");
+		try {
+			element->setAttribute("id", polygon.getID());
+			element->setAttribute("stroke", polygon.getPenColor().toHex());
+			element->setAttribute("fill", polygon.getBrushColor().toHex());;
+			element->setAttribute("stroke-width", boost::lexical_cast<std::string>(polygon.getPenWidth()));
+			element->setAttribute("opacity", alphaToOpacity(polygon.getPenColor().getAlpha()));
+			element->setAttribute("fill-opacity", alphaToOpacity(polygon.getBrushColor().getAlpha()));
+			std::string points;
+			std::vector<std::pair<int, int> >::const_iterator it = polygon.getPoints().begin();
+			for (; it != polygon.getPoints().end(); ++it) {
+				points += boost::lexical_cast<std::string>(it->first)+","+boost::lexical_cast<std::string>(it->second)+" ";
+			}
+			element->setAttribute("points", points);
+		} catch (boost::bad_lexical_cast&) {
+		}
+	}
+
+	void WhiteboardElementSerializingVisitor::visit(WhiteboardTextElement& text) {
+		element = boost::make_shared<XMLElement>("text");
+		try {
+			element->setAttribute("x", boost::lexical_cast<std::string>(text.getX()));
+			element->setAttribute("y", boost::lexical_cast<std::string>(text.getY()));
+			element->setAttribute("font-size", boost::lexical_cast<std::string>(text.getSize()));
+			element->setAttribute("id", text.getID());
+			element->setAttribute("fill", text.getColor().toHex());
+			element->setAttribute("opacity", alphaToOpacity(text.getColor().getAlpha()));
+			element->addNode(boost::make_shared<XMLTextNode>(text.getText()));
+		} catch (boost::bad_lexical_cast&) {
+		}
+	}
+
 	std::string WhiteboardElementSerializingVisitor::intToStr(const int t) const {
 		std::stringstream ss;
 		ss << t;
@@ -68,6 +106,15 @@ namespace Swift {
 		return element;
 	}
 
+	std::string WhiteboardElementSerializingVisitor::alphaToOpacity(int alpha) const {
+		int opacity = 100*alpha/254;
+		if (opacity == 100) {
+			return "1";
+		} else {
+			return "."+boost::lexical_cast<std::string>(opacity);
+		}
+	}
+
 	std::string WhiteboardSerializer::serializePayload(boost::shared_ptr<WhiteboardPayload> payload) const {
 		XMLElement element("wb");
 		if (payload->getType() == WhiteboardPayload::Data) {
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
index 25642d0..4251cca 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
@@ -9,6 +9,9 @@
 #include <Swiften/Elements/WhiteboardPayload.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardLineElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardFreehandPathElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardRectElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h>
+#include <Swiften/Whiteboard/Elements/WhiteboardTextElement.h>
 #include <Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h>
 #include <Swiften/Serializer/GenericPayloadSerializer.h>
 #include <Swiften/Serializer/XML/XMLElement.h>
@@ -18,10 +21,14 @@ namespace Swift {
 	public:
 		void visit(WhiteboardLineElement& line);
 		void visit(WhiteboardFreehandPathElement& path);
+		void visit(WhiteboardRectElement& rect);
+		void visit(WhiteboardPolygonElement& polygon);
+		void visit(WhiteboardTextElement& text);
 		XMLElement::ref getResult() const;
 
 	private:
 		std::string intToStr(const int t) const;
+		std::string alphaToOpacity(int alpha) const;
 		
 		XMLElement::ref element;
 	};
diff --git a/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h b/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h
index d546e7f..7244ad1 100644
--- a/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h
+++ b/Swiften/Whiteboard/Elements/WhiteboardElementVisitor.h
@@ -9,11 +9,17 @@
 namespace Swift {
 	class WhiteboardLineElement;
 	class WhiteboardFreehandPathElement;
+	class WhiteboardRectElement;
+	class WhiteboardPolygonElement;
+	class WhiteboardTextElement;
 
 	class WhiteboardElementVisitor {
 	public:
 		virtual ~WhiteboardElementVisitor() {}
 		virtual void visit(WhiteboardLineElement& /*element*/) = 0;
 		virtual void visit(WhiteboardFreehandPathElement& /*element*/) = 0;
+		virtual void visit(WhiteboardRectElement& /*element*/) = 0;
+		virtual void visit(WhiteboardPolygonElement& /*element*/) = 0;
+		virtual void visit(WhiteboardTextElement& /*element*/) = 0;
 	};
 }
diff --git a/Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h b/Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h
new file mode 100644
index 0000000..1134b1a
--- /dev/null
+++ b/Swiften/Whiteboard/Elements/WhiteboardPolygonElement.h
@@ -0,0 +1,72 @@
+/*
+ * 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 WhiteboardPolygonElement : public WhiteboardElement {
+		typedef std::pair<int, int> Point;
+	public:
+		typedef boost::shared_ptr<WhiteboardPolygonElement> ref;
+	public:
+		WhiteboardPolygonElement() {
+		}
+
+		const std::vector<Point>& getPoints() const {
+			return points_;
+		}
+
+		void setPoints(const std::vector<Point>& points) {
+			points_ = points;
+		}
+
+		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:
+		std::vector<Point> points_;
+		Color penColor_;
+		Color brushColor_;
+		int penWidth_;
+		std::string id_;
+	};
+}
diff --git a/Swiften/Whiteboard/Elements/WhiteboardRectElement.h b/Swiften/Whiteboard/Elements/WhiteboardRectElement.h
new file mode 100644
index 0000000..313c3bd
--- /dev/null
+++ b/Swiften/Whiteboard/Elements/WhiteboardRectElement.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 WhiteboardRectElement : public WhiteboardElement {
+	public:
+		typedef boost::shared_ptr<WhiteboardRectElement> ref;
+	public:
+		WhiteboardRectElement(int x, int y, int width, int height) {
+			x_ = x;
+			y_ = y;
+			width_ = width;
+			height_ = height;
+		}
+
+		int getX() const {
+			return x_;
+		}
+
+		int getY() const {
+			return y_;
+		}
+
+		int getWidth() const {
+			return width_;
+		}
+
+		int getHeight() const {
+			return height_;
+		}
+
+		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 x_, y_, width_, height_;
+		Color penColor_;
+		Color brushColor_;
+		int penWidth_;
+		std::string id_;
+	};
+}
diff --git a/Swiften/Whiteboard/Elements/WhiteboardTextElement.h b/Swiften/Whiteboard/Elements/WhiteboardTextElement.h
new file mode 100644
index 0000000..d9fe58f
--- /dev/null
+++ b/Swiften/Whiteboard/Elements/WhiteboardTextElement.h
@@ -0,0 +1,73 @@
+/*
+ * 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 WhiteboardTextElement : public WhiteboardElement {
+	public:
+		typedef boost::shared_ptr<WhiteboardTextElement> ref;
+	public:
+		WhiteboardTextElement(int x, int y) {
+			x_ = x;
+			y_ = y;
+		}
+
+		void setText(const std::string text) {
+			text_ = text;
+		}
+
+		const std::string& getText() const {
+			return text_;
+		}
+
+		int getX() const {
+			return x_;
+		}
+
+		int getY() const {
+			return y_;
+		}
+
+		const Color& getColor() const {
+			return color_;
+		}
+
+		void setColor(const Color& color) {
+			color_ = color;
+		}
+
+		std::string getID() const {
+			return id_;
+		}
+
+		void setID(const std::string& id) {
+			id_ = id;
+		}
+
+		int getSize() const {
+			return size_;
+		}
+
+		void setSize(const int size) {
+			size_ = size;
+		}
+
+		void accept(WhiteboardElementVisitor& visitor) {
+			visitor.visit(*this);
+		}
+
+	private:
+		int x_, y_;
+		int size_;
+		std::string text_;
+		std::string id_;
+		Color color_;
+	};
+}
-- 
cgit v0.10.2-6-g49f6