]> git.zarvox.org Git - shareboard.git/commitdiff
Near-complete implementation of actions, a shell menu, and basic network connections.
authorDrew Fisher <drew.m.fisher@gmail.com>
Tue, 5 Oct 2010 05:57:48 +0000 (22:57 -0700)
committerDrew Fisher <drew.m.fisher@gmail.com>
Tue, 5 Oct 2010 05:57:48 +0000 (22:57 -0700)
A number of things are still stubbed out while we work out network protocol specifics.

action.cpp [new file with mode: 0644]
action.h [new file with mode: 0644]
connectionmanager.cpp [new file with mode: 0644]
connectionmanager.h [new file with mode: 0644]
connectwidget.cpp [new file with mode: 0644]
connectwidget.h [new file with mode: 0644]
main.cpp [new file with mode: 0644]
mainwindow.cpp [new file with mode: 0644]
mainwindow.h [new file with mode: 0644]
shareboard.pro [new file with mode: 0644]

diff --git a/action.cpp b/action.cpp
new file mode 100644 (file)
index 0000000..fe82a21
--- /dev/null
@@ -0,0 +1,92 @@
+#include "action.h"
+
+Action::Action() {
+       type = INVALID;
+       id = 0;
+       approved = false;
+}
+
+Action::Action(Type t) {
+       type = t;
+       id = 0;
+       approved = false;
+}
+
+Action::~Action() {
+}
+
+//
+UserJoinAction::UserJoinAction() : Action(Action::UserJoin) {
+}
+UserJoinAction::~UserJoinAction() {
+}
+
+//
+UserPartAction::UserPartAction() : Action(Action::UserPart) {
+}
+UserPartAction::~UserPartAction() {
+}
+
+//
+MouseMoveAction::MouseMoveAction() : Action(Action::MouseMove) {
+}
+MouseMoveAction::~MouseMoveAction() {
+}
+
+//
+DrawLineAction::DrawLineAction() : Action(Action::DrawLine) {
+       color = Qt::black;
+       width = 1;
+}
+DrawLineAction::~DrawLineAction() {
+}
+
+QTextStream& operator<<(QTextStream& out, const Action& action) {
+       out << "0 " << action.id << " 0 " << static_cast<quint16>(action.type) ; // mesgID, userID, timestamp, mesgType
+       switch(action.type) {
+               case Action::INVALID: break;
+               case Action::UserJoin:
+                       {
+                               const UserJoinAction* a = static_cast<const UserJoinAction*>(&action);
+                               out << " " << a->username;
+                       } break;
+               case Action::UserPart:
+                       break; // UserPart doesn't have any special data
+               case Action::MouseMove:
+                       {
+                               const MouseMoveAction* a = static_cast<const MouseMoveAction*>(&action);
+                               out << " " << a->pos.x() << " " << a->pos.y();
+                       } break;
+               case Action::DrawLine:
+                       {
+                               const DrawLineAction* a = static_cast<const DrawLineAction*>(&action);
+                               const QColor& c = a->color;
+                               out << " " << c.red() << " " << c.green() << " " << c.blue() << " " << a->width;
+                               foreach(QPointF p, a->points) {
+                                       out << " " << p.x() << " " << p.y();
+                               }
+                       } break;
+               case Action::AddImage:
+                       {
+                               const AddImageAction* a = static_cast<const AddImageAction*>(&action);
+                               // TODO: unbackburner this
+                               //out << " " << a->topLeft << a->image;
+                       } break;
+               case Action::UserChat:
+                       {
+                               const UserChatAction* a = static_cast<const UserChatAction*>(&action);
+                               out << " " << a->text;
+                       } break;
+       }
+       out << "\n";
+       return out;
+}
+
+/*QTextStream& operator>>(QTextStream& in, Action& action){
+       quint16 k;
+       in >> k >> action.id >> action.approved >> action.when;
+       action.type = static_cast<Action::Type>(k);
+       return in;
+}*/
+
+
diff --git a/action.h b/action.h
new file mode 100644 (file)
index 0000000..3f2baf2
--- /dev/null
+++ b/action.h
@@ -0,0 +1,83 @@
+#ifndef __ACTION_H__
+#define __ACTION_H__
+
+#include <QDateTime>
+#include <QPointF>
+#include <QTextStream>
+#include <QColor>
+#include <QVector>
+#include <QString>
+#include <QImage>
+
+class Action {
+public:
+       enum Type {
+               INVALID,
+               UserJoin,
+               UserPart,
+               MouseMove,
+               DrawLine,
+               AddImage,
+               UserChat
+       };
+
+       Action();
+       Action(Type t);
+       virtual ~Action();
+
+       Type type;
+       // UUID uuid; // Unique id for this 
+       int id; // Which user does this refer to?
+       bool approved; // Has the server approved this event yet?
+       QDateTime when; // Time at which the server made this event official
+
+};
+
+class UserJoinAction : public Action {
+public:
+       UserJoinAction();
+       ~UserJoinAction();
+       QString username; // What's their username?
+};
+
+class UserPartAction : public Action {
+public:
+       UserPartAction();
+       ~UserPartAction();
+};
+
+class MouseMoveAction : public Action {
+public:
+       MouseMoveAction();
+       ~MouseMoveAction();
+       QPointF pos;
+};
+
+class DrawLineAction : public Action {
+public:
+       DrawLineAction();
+       ~DrawLineAction();
+       QColor color;
+       int width;
+       QVector<QPointF> points;
+       
+};
+
+class AddImageAction : public Action {
+public:
+       AddImageAction();
+       ~AddImageAction();
+       QPointF topLeft;
+       QImage image;
+};
+
+class UserChatAction : public Action {
+public:
+       UserChatAction();
+       ~UserChatAction();
+       QString text;
+};
+
+QTextStream& operator<<(QTextStream& out, const Action& action);
+
+#endif //__ACTION_H__
diff --git a/connectionmanager.cpp b/connectionmanager.cpp
new file mode 100644 (file)
index 0000000..3ad8525
--- /dev/null
@@ -0,0 +1,49 @@
+#include "connectionmanager.h"
+#include <QDebug>
+#include <QTcpSocket>
+#include <QTextStream>
+#include "action.h"
+
+ConnectionManager::ConnectionManager(QObject* parent) : QObject(parent) {
+       sock = new QTcpSocket();
+       textStream = new QTextStream(sock);
+       QObject::connect(sock, SIGNAL(connected()), this, SLOT(onConnect()));
+       QObject::connect(sock, SIGNAL(readyRead()), this, SLOT(haveData()));
+}
+
+ConnectionManager::~ConnectionManager() {
+       if (sock) delete sock;
+}
+
+void ConnectionManager::joinServer(QString _username, QString host) {
+       username = _username;
+       quint16 port = 4260;
+       sock->connectToHost(host, port);
+       qDebug() << "Connecting to " << host << "as " << _username;
+}
+
+void ConnectionManager::sendAction(Action* action) {
+       switch(action->type) { // Handle serializing all actions
+               default:
+                       break;
+       }
+       
+}
+void ConnectionManager::haveData() {
+       data.append(sock->readAll());
+       // Check if we have a full action waiting, if so, dispatch
+       // Event structure:
+       // uint32 num_bytes (we don't support things larger than 4GB, kthx
+       // uint16 type
+       // char approved
+       // QDateTime when
+       // [rest of details]
+       qDebug() << data.size() << " bytes read so far";
+}
+
+void ConnectionManager::onConnect() {
+       qDebug() << "connection established";
+       emit connected();
+       (*textStream) << "0 0 0 2 " << username << endl;
+       qDebug() << "sent JoinAction";
+}
diff --git a/connectionmanager.h b/connectionmanager.h
new file mode 100644 (file)
index 0000000..d9bc4e5
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __CONNECTIONMANAGER_H__
+#define __CONNECTIONMANAGER_H__
+
+#include <QObject>
+#include <QByteArray>
+#include <QString>
+#include <QTextStream>
+
+class Action;
+class QTcpSocket;
+
+class ConnectionManager : public QObject{
+       Q_OBJECT
+       public:
+               ConnectionManager(QObject* parent = 0);
+               ~ConnectionManager();
+       signals:
+               //void readData();
+               //void actionRecieved(Action* act); // act is freed by recipient of signal
+               void connected();
+       public slots:
+               void joinServer(QString _username, QString host);
+               void sendAction(Action* action);
+       private:
+               QString username;
+               QByteArray data;
+               QTcpSocket* sock;
+               QTextStream* textStream;
+       private slots:
+               void haveData();
+               void onConnect();
+};
+
+#endif // __CONNECTIONMANAGER_H__
+
diff --git a/connectwidget.cpp b/connectwidget.cpp
new file mode 100644 (file)
index 0000000..9933701
--- /dev/null
@@ -0,0 +1,49 @@
+#include "connectwidget.h"
+
+#include <QGridLayout>
+#include <QVBoxLayout>
+#include <QLineEdit>
+#include <QLabel>
+#include <QPushButton>
+
+
+ConnectWidget::ConnectWidget(QWidget* parent) : QWidget(parent) {
+       layout = new QVBoxLayout();
+       grid = new QGridLayout();
+       userEdit = new QLineEdit("guest", this);
+       hostEdit = new QLineEdit("kraken.zarvox.org", this);
+       userLabel = new QLabel("Pick a username:", this);
+       userLabel->setAlignment(Qt::AlignRight);
+       hostLabel = new QLabel("Server to connect to:", this);
+       hostLabel->setAlignment(Qt::AlignRight);
+       goButton = new QPushButton("Connect!");
+
+       grid->addWidget(userLabel, 0,0);
+       grid->addWidget(userEdit, 0,1);
+       grid->addWidget(hostLabel, 1,0);
+       grid->addWidget(hostEdit, 1,1);
+       layout->addStretch();
+       layout->addLayout(grid);
+       layout->addWidget(goButton);
+       layout->addStretch();
+       
+       setLayout(layout);
+       QObject::connect(goButton, SIGNAL(clicked()), this, SLOT(connect()));
+}
+
+ConnectWidget::~ConnectWidget() {
+}
+
+void ConnectWidget::connect() {
+       QString username = userEdit->text().replace(" ", "_");
+       QString host = hostEdit->text();
+       emit connectToServer(username, host);
+}
+
+QString ConnectWidget::user() {
+       return userEdit->text();
+}
+
+QString ConnectWidget::host() {
+       return hostEdit->text();
+}
diff --git a/connectwidget.h b/connectwidget.h
new file mode 100644 (file)
index 0000000..39dca00
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __CONNECTWIDGET_H__
+#define __CONNECTWIDGET_H__
+
+#include <QWidget>
+
+class QGridLayout;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QVBoxLayout;
+
+class ConnectWidget : public QWidget {
+       Q_OBJECT
+       public:
+               ConnectWidget(QWidget* parent=0);
+               ~ConnectWidget();
+               QString user();
+               QString host();
+       public slots:
+               void connect();
+       signals:
+               void connectToServer(QString username, QString host);
+       private:
+               QVBoxLayout* layout;
+               QGridLayout* grid;
+               QLineEdit* userEdit;
+               QLineEdit* hostEdit;
+               QLabel* userLabel;
+               QLabel* hostLabel;
+               QPushButton* goButton;
+};
+
+#endif // __CONNECTWIDGET_H__
diff --git a/main.cpp b/main.cpp
new file mode 100644 (file)
index 0000000..5f29b1c
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,9 @@
+#include <QApplication>
+#include "mainwindow.h"
+
+int main(int argc, char** argv) {
+       QApplication* app = new QApplication(argc, argv);
+       MainWindow* win = new MainWindow();
+       win->show();
+       return app->exec();
+}
diff --git a/mainwindow.cpp b/mainwindow.cpp
new file mode 100644 (file)
index 0000000..b45c8cd
--- /dev/null
@@ -0,0 +1,89 @@
+#include "mainwindow.h"
+#include <QAction>
+#include <QApplication>
+#include <QFile>
+#include <QFileDialog>
+#include <QLabel>
+#include <QMenuBar>
+#include <QStatusBar>
+
+#include "connectwidget.h"
+#include "connectionmanager.h"
+
+MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
+       createActions();
+       createMenus();
+
+       prompt = new ConnectWidget();
+       setCentralWidget(prompt);
+
+       connMan = new ConnectionManager(this);
+       QObject::connect(prompt, SIGNAL(connectToServer(QString, QString)), connMan, SLOT(joinServer(QString, QString)));
+
+       statusBar()->showMessage("Ready");
+}
+
+MainWindow::~MainWindow() {
+
+}
+
+void MainWindow::load() {
+       QString fileName = QFileDialog::getOpenFileName(this, "Load saved board:", ".", "Shareboards (*.board)");
+       if(fileName.isEmpty()) {
+               statusBar()->showMessage("Cancelled loading board.");
+               return;
+       }
+       QFile file(fileName);
+       QDataStream in(&file);
+       // Load all history from that file
+       statusBar()->showMessage(QString("Successfully loaded ").append(fileName));
+}
+
+void MainWindow::save() {
+       QString fileName = QFileDialog::getSaveFileName(this, "Save board history as:", ".", "Shareboards (*.board)");
+       if(fileName.isEmpty()) {
+               statusBar()->showMessage("Cancelled saving board.");
+               return;
+       }
+       if(!fileName.endsWith(".board"))
+               fileName = fileName.append(".board");
+       QFile file(fileName);
+       QDataStream out(&file);
+       // Output all history to that file
+       statusBar()->showMessage(QString("Successfully saved ").append(fileName));
+}
+
+void MainWindow::quit() {
+       // If we want, we can add some annoying dialog that says "Quit now?" and throws the user off
+       qApp->quit();
+}
+
+void MainWindow::switchToBoard() {
+       // Here, we set the central widget to be the as-of-yet unimplemented Shareboard widget
+}
+
+void MainWindow::switchToConnect() {
+       setCentralWidget(prompt);
+}
+
+void MainWindow::createActions() {
+       //joinAction = new QAction("Joi&n a board online", this);
+       loadPastAction = new QAction("&Open a board", this);
+       saveAction = new QAction("&Save board", this);
+       quitAction = new QAction("&Quit", this);
+       QObject::connect(loadPastAction, SIGNAL(triggered()), this, SLOT(load()));
+       QObject::connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
+       QObject::connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));
+}
+
+void MainWindow::createMenus() {
+
+       fileMenu = menuBar()->addMenu("&File");
+       //fileMenu->addAction(joinAction);
+       fileMenu->addAction(loadPastAction);
+       fileMenu->addAction(saveAction);
+       fileMenu->addSeparator();
+       fileMenu->addAction(quitAction);
+
+}
+
diff --git a/mainwindow.h b/mainwindow.h
new file mode 100644 (file)
index 0000000..44cda15
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef __MAINWINDOW_H__
+#define __MAINWINDOW_H__
+
+#include <QMainWindow>
+
+class QMenu;
+class QAction;
+class ConnectWidget;
+class ConnectionManager;
+
+class MainWindow : public QMainWindow {
+       Q_OBJECT
+public:
+       MainWindow(QWidget* parent = 0);
+       ~MainWindow();
+public slots:
+//     void join();
+       void load();
+       void save();
+       void quit();
+       void switchToBoard();
+       void switchToConnect();
+private:
+       void createActions();
+       void createMenus();
+       QMenu* fileMenu;
+//     QAction* joinAction; // Removed in favor of central widget handling this.
+       QAction* loadPastAction;
+       QAction* saveAction;
+       QAction* quitAction;
+       ConnectionManager* connMan;
+//     HistoryManager* historyManager;
+//     Shareboard* board;
+       ConnectWidget* prompt;
+};
+
+#endif // __MAINWINDOW_H__
diff --git a/shareboard.pro b/shareboard.pro
new file mode 100644 (file)
index 0000000..2c4c6bf
--- /dev/null
@@ -0,0 +1,14 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Thu Sep 30 22:59:13 2010
+######################################################################
+
+TEMPLATE = app
+TARGET = shareboard
+CONFIG += qt
+QT += network
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+HEADERS += mainwindow.h action.h connectwidget.h connectionmanager.h
+SOURCES += main.cpp mainwindow.cpp action.cpp connectwidget.cpp connectionmanager.cpp