summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMateusz Piekos <mateuszpiekos@gmail.com>2012-05-30 12:40:27 (GMT)
committerRemko Tronçon <git@el-tramo.be>2012-09-08 16:14:27 (GMT)
commitfe8a8aa031da734f3112184420b372021d9e10c7 (patch)
tree9f8e0b7d11d7612eb25a8682cf940fa647ca67f2 /Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
parent0174723efbc1f612433d45c6916a2ad4596b96ba (diff)
downloadswift-contrib-fe8a8aa031da734f3112184420b372021d9e10c7.zip
swift-contrib-fe8a8aa031da734f3112184420b372021d9e10c7.tar.bz2
Support whiteboarding.
License: This patch is BSD-licensed, see http://www.opensource.org/licenses/bsd-license.php
Diffstat (limited to 'Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp')
-rw-r--r--Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
new file mode 100644
index 0000000..50d7f54
--- /dev/null
+++ b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtWhiteboardWindow.h"
+
+#include <iostream>
+
+#include <boost/bind.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <Swiften/Whiteboard/WhiteboardSession.h>
+#include <Swiften/Elements/WhiteboardPayload.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardLineElement.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardRectElement.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardInsertOperation.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardUpdateOperation.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardDeleteOperation.h>
+#include <Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h>
+
+#include <QMessageBox>
+#include <QLabel>
+
+namespace Swift {
+ QtWhiteboardWindow::QtWhiteboardWindow(WhiteboardSession::ref whiteboardSession) : QWidget() {
+#ifndef Q_WS_MAC
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
+#endif
+ layout = new QVBoxLayout(this);
+ hLayout = new QHBoxLayout;
+ sidebarLayout = new QVBoxLayout;
+ toolboxLayout = new QGridLayout;
+
+ scene = new QGraphicsScene(this);
+ scene->setSceneRect(0, 0, 400, 400);
+
+ graphicsView = new GView(scene, this);
+ graphicsView->setMode(GView::Line);
+ connect(graphicsView, SIGNAL(lastItemChanged(QGraphicsItem*, int, GView::Type)), this, SLOT(handleLastItemChanged(QGraphicsItem*, int, GView::Type)));
+ connect(graphicsView, SIGNAL(itemDeleted(QString, int)), this, SLOT(handleItemDeleted(QString, int)));
+
+ widthBox = new QSpinBox(this);
+ connect(widthBox, SIGNAL(valueChanged(int)), this, SLOT(changeLineWidth(int)));
+ connect(graphicsView, SIGNAL(lineWidthChanged(int)), widthBox, SLOT(setValue(int)));
+ widthBox->setValue(1);
+
+ moveUpButton = new QPushButton("Move Up", this);
+ connect(moveUpButton, SIGNAL(clicked()), graphicsView, SLOT(moveUpSelectedItem()));
+
+ moveDownButton = new QPushButton("Move Down", this);
+ connect(moveDownButton, SIGNAL(clicked()), graphicsView, SLOT(moveDownSelectedItem()));
+
+ strokeLayout = new QHBoxLayout;
+ strokeColor = new ColorWidget;
+ strokeLayout->addWidget(new QLabel("Stroke:"));
+ strokeLayout->addWidget(strokeColor);
+ connect(strokeColor, SIGNAL(clicked()), this, SLOT(showColorDialog()));
+ connect(graphicsView, SIGNAL(lineColorChanged(QColor)), strokeColor, SLOT(setColor(QColor)));
+
+ fillLayout = new QHBoxLayout;
+ fillColor = new ColorWidget;
+ fillLayout->addWidget(new QLabel("Fill:"));
+ fillLayout->addWidget(fillColor);
+ connect(fillColor, SIGNAL(clicked()), this, SLOT(showBrushColorDialog()));
+ connect(graphicsView, SIGNAL(brushColorChanged(QColor)), fillColor, SLOT(setColor(QColor)));
+
+ rubberButton = new QToolButton(this);
+ rubberButton->setIcon(QIcon(":/icons/eraser.png"));
+ rubberButton->setCheckable(true);
+ rubberButton->setAutoExclusive(true);
+ connect(rubberButton, SIGNAL(clicked()), this, SLOT(setRubberMode()));
+
+ lineButton = new QToolButton(this);
+ lineButton->setIcon(QIcon(":/icons/line.png"));
+ lineButton->setCheckable(true);
+ lineButton->setAutoExclusive(true);
+ lineButton->setChecked(true);
+ connect(lineButton, SIGNAL(clicked()), this, SLOT(setLineMode()));
+
+ rectButton = new QToolButton(this);
+ rectButton->setIcon(QIcon(":/icons/rect.png"));
+ rectButton->setCheckable(true);
+ rectButton->setAutoExclusive(true);
+ connect(rectButton, SIGNAL(clicked()), this, SLOT(setRectMode()));
+
+ circleButton = new QToolButton(this);
+ circleButton->setIcon(QIcon(":/icons/circle.png"));
+ circleButton->setCheckable(true);
+ circleButton->setAutoExclusive(true);
+ connect(circleButton, SIGNAL(clicked()), this, SLOT(setCircleMode()));
+
+ handLineButton = new QToolButton(this);
+ handLineButton->setIcon(QIcon(":/icons/handline.png"));
+ handLineButton->setCheckable(true);
+ handLineButton->setAutoExclusive(true);
+ connect(handLineButton, SIGNAL(clicked()), this, SLOT(setHandLineMode()));
+
+ textButton = new QToolButton(this);
+ textButton->setIcon(QIcon(":/icons/text.png"));
+ textButton->setCheckable(true);
+ textButton->setAutoExclusive(true);
+ connect(textButton, SIGNAL(clicked()), this, SLOT(setTextMode()));
+
+ polygonButton = new QToolButton(this);
+ polygonButton->setIcon(QIcon(":/icons/polygon.png"));
+ polygonButton->setCheckable(true);
+ polygonButton->setAutoExclusive(true);
+ connect(polygonButton, SIGNAL(clicked()), this, SLOT(setPolygonMode()));
+
+ selectButton = new QToolButton(this);
+ selectButton->setIcon(QIcon(":/icons/cursor.png"));
+ selectButton->setCheckable(true);
+ selectButton->setAutoExclusive(true);
+ connect(selectButton, SIGNAL(clicked()), this, SLOT(setSelectMode()));
+
+ toolboxLayout->addWidget(rubberButton, 0, 0);
+ toolboxLayout->addWidget(selectButton, 0, 1);
+ toolboxLayout->addWidget(lineButton, 0, 2);
+ toolboxLayout->addWidget(circleButton, 1, 0);
+ toolboxLayout->addWidget(handLineButton, 1, 1);
+ toolboxLayout->addWidget(rectButton, 1, 2);
+ toolboxLayout->addWidget(textButton, 2, 0);
+ toolboxLayout->addWidget(polygonButton, 2, 1);
+
+ sidebarLayout->addLayout(toolboxLayout);
+ sidebarLayout->addSpacing(30);
+ sidebarLayout->addWidget(moveUpButton);
+ sidebarLayout->addWidget(moveDownButton);
+ sidebarLayout->addSpacing(40);
+ sidebarLayout->addWidget(widthBox);
+ sidebarLayout->addLayout(strokeLayout);
+ sidebarLayout->addLayout(fillLayout);
+ sidebarLayout->addStretch();
+ hLayout->addWidget(graphicsView);
+ hLayout->addLayout(sidebarLayout);
+ layout->addLayout(hLayout);
+ this->setLayout(layout);
+
+ setSession(whiteboardSession);
+ }
+
+ void QtWhiteboardWindow::handleWhiteboardOperationReceive(const WhiteboardOperation::ref operation) {
+ WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
+ if (insertOp) {
+ WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::New);
+ insertOp->getElement()->accept(visitor);
+ }
+
+ WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation);
+ if (updateOp) {
+ WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::Update);
+ updateOp->getElement()->accept(visitor);
+ if (updateOp->getPos() != updateOp->getNewPos()) {
+ graphicsView->move(graphicsView->getItem(P2QSTRING(updateOp->getElement()->getID())), updateOp->getNewPos());
+ }
+ }
+
+ WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation);
+ if (deleteOp) {
+ graphicsView->deleteItem(P2QSTRING(deleteOp->getElementID()));
+ }
+ }
+
+ void QtWhiteboardWindow::changeLineWidth(int i)
+ {
+ graphicsView->setLineWidth(i);
+ }
+
+ void QtWhiteboardWindow::showColorDialog()
+ {
+ QColor color = QColorDialog::getColor(graphicsView->getLineColor(), 0, "Select pen color", QColorDialog::ShowAlphaChannel);
+ if(color.isValid())
+ graphicsView->setLineColor(color);
+ }
+
+ void QtWhiteboardWindow::showBrushColorDialog()
+ {
+ QColor color = QColorDialog::getColor(graphicsView->getBrushColor(), 0, "Select brush color", QColorDialog::ShowAlphaChannel);
+ if(color.isValid())
+ graphicsView->setBrushColor(color);
+ }
+
+ void QtWhiteboardWindow::setRubberMode()
+ {
+ graphicsView->setMode(GView::Rubber);
+ }
+
+ void QtWhiteboardWindow::setLineMode()
+ {
+ graphicsView->setMode(GView::Line);
+ }
+
+ void QtWhiteboardWindow::setRectMode()
+ {
+ graphicsView->setMode(GView::Rect);
+ }
+
+ void QtWhiteboardWindow::setCircleMode()
+ {
+ graphicsView->setMode(GView::Circle);
+ }
+
+ void QtWhiteboardWindow::setHandLineMode()
+ {
+ graphicsView->setMode(GView::HandLine);
+ }
+
+ void QtWhiteboardWindow::setTextMode()
+ {
+ graphicsView->setMode(GView::Text);
+ }
+
+ void QtWhiteboardWindow::setPolygonMode()
+ {
+ graphicsView->setMode(GView::Polygon);
+ }
+
+ void QtWhiteboardWindow::setSelectMode()
+ {
+ graphicsView->setMode(GView::Select);
+ }
+
+ void QtWhiteboardWindow::show()
+ {
+ QWidget::show();
+ }
+
+ void QtWhiteboardWindow::setSession(WhiteboardSession::ref session) {
+ graphicsView->clear();
+ whiteboardSession_ = session;
+ whiteboardSession_->onOperationReceived.connect(boost::bind(&QtWhiteboardWindow::handleWhiteboardOperationReceive, this, _1));
+ whiteboardSession_->onRequestAccepted.connect(boost::bind(&QWidget::show, this));
+ whiteboardSession_->onSessionTerminated.connect(boost::bind(&QtWhiteboardWindow::handleSessionTerminate, this));
+ }
+
+ void QtWhiteboardWindow::activateWindow() {
+ QWidget::activateWindow();
+ }
+
+ void QtWhiteboardWindow::setName(const std::string& name) {
+ setWindowTitle(P2QSTRING(name));
+ }
+
+ void QtWhiteboardWindow::handleLastItemChanged(QGraphicsItem* item, int pos, GView::Type type) {
+ WhiteboardElement::ref el;
+ QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
+ if (lineItem != 0) {
+ QLine line = lineItem->line().toLine();
+ QColor color = lineItem->pen().color();
+ WhiteboardLineElement::ref element = boost::make_shared<WhiteboardLineElement>(line.x1()+lineItem->pos().x(), line.y1()+lineItem->pos().y(), line.x2()+lineItem->pos().x(), line.y2()+lineItem->pos().y());
+ element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
+ element->setPenWidth(lineItem->pen().width());
+
+ element->setID(lineItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ FreehandLineItem* freehandLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
+ if (freehandLineItem != 0) {
+ WhiteboardFreehandPathElement::ref element = boost::make_shared<WhiteboardFreehandPathElement>();
+ QColor color = freehandLineItem->pen().color();
+ std::vector<std::pair<int, int> > points;
+ QVector<QPointF>::const_iterator it = freehandLineItem->points().constBegin();
+ for ( ; it != freehandLineItem->points().constEnd(); ++it) {
+ points.push_back(std::pair<int, int>(it->x()+item->pos().x(), it->y()+item->pos().y()));
+ }
+
+ element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
+ element->setPenWidth(freehandLineItem->pen().width());
+ element->setPoints(points);
+
+ element->setID(freehandLineItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+ if (rectItem != 0) {
+ QRectF rect = rectItem->rect();
+ WhiteboardRectElement::ref element = boost::make_shared<WhiteboardRectElement>(rect.x()+item->pos().x(), rect.y()+item->pos().y(), rect.width(), rect.height());
+ QColor penColor = rectItem->pen().color();
+ QColor brushColor = rectItem->brush().color();
+
+ element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+ element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+ element->setPenWidth(rectItem->pen().width());
+
+ element->setID(rectItem->data(100).toString().toStdString());
+ el = 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());
+ element->setSize(textItem->font().pointSize());
+ QColor color = textItem->defaultTextColor();
+ element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
+
+ element->setID(textItem->data(100).toString().toStdString());
+ el = 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()+item->pos().x(), it->y()+item->pos().y()));
+ }
+
+ element->setPoints(points);
+
+ QColor penColor = polygonItem->pen().color();
+ QColor brushColor = polygonItem->brush().color();
+ element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+ element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+ element->setPenWidth(polygonItem->pen().width());
+
+ element->setID(polygonItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+ if (ellipseItem) {
+ QRectF rect = ellipseItem->rect();
+ int cx = rect.x()+rect.width()/2 + item->pos().x();
+ int cy = rect.y()+rect.height()/2 + item->pos().y();
+ 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(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+ element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+ element->setPenWidth(ellipseItem->pen().width());
+
+ element->setID(ellipseItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ if (type == GView::New) {
+ WhiteboardInsertOperation::ref insertOp = boost::make_shared<WhiteboardInsertOperation>();
+ insertOp->setPos(pos);
+ insertOp->setElement(el);
+ whiteboardSession_->sendOperation(insertOp);
+ } else {
+ WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>();
+ updateOp->setPos(pos);
+ if (type == GView::Update) {
+ updateOp->setNewPos(pos);
+ } else if (type == GView::MoveUp) {
+ updateOp->setNewPos(pos+1);
+ } else if (type == GView::MoveDown) {
+ updateOp->setNewPos(pos-1);
+ }
+ updateOp->setElement(el);
+ whiteboardSession_->sendOperation(updateOp);
+ }
+ }
+
+ void QtWhiteboardWindow::handleItemDeleted(QString id, int pos) {
+ WhiteboardDeleteOperation::ref deleteOp = boost::make_shared<WhiteboardDeleteOperation>();
+ deleteOp->setElementID(Q2PSTRING(id));
+ deleteOp->setPos(pos);
+ whiteboardSession_->sendOperation(deleteOp);
+ }
+
+ void QtWhiteboardWindow::handleSessionTerminate() {
+ hide();
+ }
+
+ void QtWhiteboardWindow::closeEvent(QCloseEvent* event) {
+ QMessageBox box(this);
+ box.setText(tr("Closing window is equivalent closing the session. Are you sure you want to do this?"));
+ box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ box.setIcon(QMessageBox::Question);
+ if (box.exec() == QMessageBox::Yes) {
+ whiteboardSession_->cancel();
+ } else {
+ event->ignore();
+ }
+ }
+}