From d847e6bf7929c8565bff4e17d9fd077b8e0ca74d Mon Sep 17 00:00:00 2001 From: Stefan Suhren Date: Mon, 8 Jun 2015 10:27:31 +0200 Subject: Add XML files for reading and writing --- GUI_SS2015.pro | 2 +- ellipse.cpp | 6 +++ ellipse.h | 6 ++- interactioncanvas.cpp | 127 +++++++++++++++++++++++++++++++++++++++++++------- interactioncanvas.h | 7 +++ line.cpp | 77 ++++++++++++++++++++++++++++-- line.h | 18 +++++-- mainwindow.cpp | 54 ++++++++++++++++++++- mainwindow.h | 13 ++++++ mainwindow.ui | 18 +++++++ polygon.cpp | 65 ++++++++++++++++++++++++-- polygon.h | 5 ++ rectangle.cpp | 53 +++++++++++++++++++-- rectangle.h | 4 ++ 14 files changed, 416 insertions(+), 39 deletions(-) diff --git a/GUI_SS2015.pro b/GUI_SS2015.pro index 49d6038..aa989cc 100644 --- a/GUI_SS2015.pro +++ b/GUI_SS2015.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += core gui +QT += core gui xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/ellipse.cpp b/ellipse.cpp index dc0f4f8..d3c924e 100644 --- a/ellipse.cpp +++ b/ellipse.cpp @@ -28,3 +28,9 @@ void Ellipse::draw(QPainter *painter) painter->drawEllipse(m_rectangle); } + + +QString Ellipse::className() +{ + return "Ellipse"; +} diff --git a/ellipse.h b/ellipse.h index 6d27c9b..617357f 100644 --- a/ellipse.h +++ b/ellipse.h @@ -9,9 +9,11 @@ class Ellipse : public Rectangle public: Ellipse(); - // Line interface -public: virtual void draw(QPainter *painter); + + // Line interface +protected: + virtual QString className(); }; #endif // ELLIPSE_H diff --git a/interactioncanvas.cpp b/interactioncanvas.cpp index 80a4317..3236be1 100644 --- a/interactioncanvas.cpp +++ b/interactioncanvas.cpp @@ -1,7 +1,7 @@ #include "interactioncanvas.h" InteractionCanvas::InteractionCanvas(QWidget *parent) - :QLabel(parent) + : QLabel(parent) { setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); @@ -9,19 +9,27 @@ InteractionCanvas::InteractionCanvas(QWidget *parent) m_SelectedLine = NULL; } -InteractionCanvas::~InteractionCanvas() +void InteractionCanvas::clearLines() { - for(int i = 0; i < m_Lines.size(); i++) + for (int i = 0; i < m_Lines.size(); i++) { delete m_Lines[i]; - m_Lines.removeAt(i); } - if(m_NewLine) + + m_Lines.clear(); +} + +InteractionCanvas::~InteractionCanvas() +{ + clearLines(); + + if (m_NewLine) { delete m_NewLine; m_NewLine = NULL; } - if(m_SelectedLine) + + if (m_SelectedLine) { delete m_SelectedLine; m_SelectedLine = NULL; @@ -66,22 +74,100 @@ void InteractionCanvas::addPolygon() changeSelectedLine(tmpLine); } +void InteractionCanvas::read(QFile *file) +{ + m_fileName.setContent(file, false); + + QDomElement root = m_fileName.documentElement(); + + if (root.tagName() == "geometric_objects") + { + QDomElement child = root.firstChildElement(); + + Line *line = NULL; + + clearLines(); + + while (!child.isNull()) + { + line = NULL; + + if (child.tagName() == "Line") + { + line = new Line(); + } + + if (child.tagName() == "Rectangle") + { + line = new Rectangle(); + } + + if (child.tagName() == "Ellipse") + { + line = new Ellipse(); + } + + if (child.tagName() == "Polygon") + { + line = new Polygon(); + } + + if (line != NULL) + { + line->fromDomElement(child); + line->setSelected(false); + m_Lines.append(line); + } + + child = child.nextSiblingElement(); + } + } +} + +void InteractionCanvas::write(QFile *file) +{ + const int IndentSize = 4; + + m_fileName.clear(); + + QDomElement root = m_fileName.createElement("geometric_objects"); + + m_fileName.appendChild(root); + + QListIterator childs(m_Lines); + + Line *child = NULL; + + while (childs.hasNext()) + { + child = childs.next(); + + root.appendChild(child->toDomElement(&m_fileName)); + } + + QTextStream out(file); + m_fileName.save(out, IndentSize); +} + void InteractionCanvas::mouseMoveEvent(QMouseEvent *mouseEvent) { qDebug() << "InteractionCanvas:" << mouseEvent->pos(); if (mouseEvent->buttons() == Qt::LeftButton) { - if(m_SelectedLine) + if (m_SelectedLine) { m_SelectedLine->move(m_LastMousePosition, mouseEvent->pos()); } - if(m_NewLine) + + if (m_NewLine) { m_NewLine->setP2(mouseEvent->pos()); } + update(); } + m_LastMousePosition = mouseEvent->pos(); } @@ -92,7 +178,7 @@ void InteractionCanvas::mousePressEvent(QMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::LeftButton) { - if(!m_SelectedLine) + if (!m_SelectedLine) { m_MousePressPoint = mouseEvent->pos(); m_LastMousePosition = m_MousePressPoint; @@ -105,14 +191,16 @@ void InteractionCanvas::mousePressEvent(QMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::RightButton) { changeSelectedLine(NULL); - for(int i = 0; i < m_Lines.size() && !m_SelectedLine; i++) + + for (int i = 0; i < m_Lines.size() && !m_SelectedLine; i++) { - if(m_Lines[i]->isHit(mouseEvent->pos())) + if (m_Lines[i]->isHit(mouseEvent->pos())) { changeSelectedLine(m_Lines[i]); } } } + update(); } @@ -122,7 +210,7 @@ void InteractionCanvas::mouseReleaseEvent(QMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::LeftButton) { - if(m_NewLine) + if (m_NewLine) { m_MouseReleasePoint = mouseEvent->pos(); m_NewLine->setP2(m_MouseReleasePoint); @@ -140,12 +228,14 @@ void InteractionCanvas::keyPressEvent(QKeyEvent *keyEvent) qDebug() << "InteractionCanvas: Key: pressed:" << keyEvent->key() << "(" << keyEvent->text() << ")" << (keyEvent->isAutoRepeat() ? "druck" : ""); - if(!m_Lines.isEmpty() && keyEvent->key() == Qt::Key_Z && keyEvent->modifiers() == Qt::ControlModifier) + if (!m_Lines.isEmpty() && keyEvent->key() == Qt::Key_Z && + keyEvent->modifiers() == Qt::ControlModifier) { - if(m_SelectedLine == m_Lines.last()) + if (m_SelectedLine == m_Lines.last()) { m_SelectedLine = NULL; } + delete m_Lines.last(); m_Lines.removeLast(); update(); @@ -155,7 +245,7 @@ void InteractionCanvas::keyPressEvent(QKeyEvent *keyEvent) void InteractionCanvas::keyReleaseEvent(QKeyEvent *keyEvent) { qDebug() << "InteractionCanvas: Key: released:" << keyEvent->key() << "(" << - keyEvent->text() << ")" << (keyEvent->isAutoRepeat() ? "druck" : ""); + keyEvent->text() << ")" << (keyEvent->isAutoRepeat() ? "druck" : ""); } /** @@ -165,12 +255,13 @@ void InteractionCanvas::keyReleaseEvent(QKeyEvent *keyEvent) */ void InteractionCanvas::changeSelectedLine(Line *newSelectedLine) { - if(m_SelectedLine) + if (m_SelectedLine) { m_SelectedLine->setSelected(false); m_SelectedLine = NULL; } - if(newSelectedLine) + + if (newSelectedLine) { m_SelectedLine = newSelectedLine; m_SelectedLine->setSelected(true); @@ -185,7 +276,7 @@ void InteractionCanvas::addNewLine(Line *newLine) m_NewLine = NULL; } - if(newLine) + if (newLine) { m_NewLine = new Line(); } diff --git a/interactioncanvas.h b/interactioncanvas.h index 397865d..d87165e 100644 --- a/interactioncanvas.h +++ b/interactioncanvas.h @@ -24,6 +24,10 @@ public: void addEllipse(); void addPolygon(); + //QDom methods + void read(QFile *file); + void write(QFile *file); + protected: void mouseMoveEvent(QMouseEvent *mouseEvent); void mousePressEvent(QMouseEvent *mouseEvent); @@ -34,6 +38,7 @@ protected: private: void changeSelectedLine(Line *newSelectedLine); void addNewLine(Line *newLine); + void clearLines(); QList m_Lines; Line *m_NewLine; @@ -42,6 +47,8 @@ private: QPoint m_MouseReleasePoint; QPoint m_LastMousePosition; + QDomDocument m_fileName; + protected: void paintEvent(QPaintEvent *paintEvent); }; diff --git a/line.cpp b/line.cpp index 5f7e171..2d19874 100644 --- a/line.cpp +++ b/line.cpp @@ -1,7 +1,7 @@ #include "line.h" Line::Line() - :QLine() + : QLine() { m_selected = true; } @@ -25,7 +25,7 @@ void Line::setSelected(bool selected) void Line::draw(QPainter *painter) { - if(m_selected) + if (m_selected) { QPen penTemp(Qt::DotLine); penTemp.setColor(Qt::red); @@ -47,15 +47,16 @@ void Line::draw(QPainter *painter) void Line::move(const QPoint &oldPoint, const QPoint &newPoint) { - if(m_selected) + if (m_selected) { QPoint offset = newPoint - oldPoint; QVector3D vecOld(oldPoint); - if(vecOld.distanceToPoint(QVector3D(p1())) < 5) + + if (vecOld.distanceToPoint(QVector3D(p1())) < 5) { setP1(p1() + offset); } - else if(vecOld.distanceToPoint(QVector3D(p2())) < 5) + else if (vecOld.distanceToPoint(QVector3D(p2())) < 5) { setP2(p2() + offset); } @@ -66,3 +67,69 @@ void Line::move(const QPoint &oldPoint, const QPoint &newPoint) } } } + +QDomElement Line::toDomElement(QDomDocument *doc) +{ + QDomElement e = doc->createElement(className()); + attributesToDom(doc, e); + return e; +} + +bool Line::attributesToDom(QDomDocument *doc, QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::attributesToDom Error: NULL element passed."; + return false; + } + else + { + e.setAttribute("x1", p1().rx()); + e.setAttribute("y1", p1().ry()); + e.setAttribute("x2", p2().rx()); + e.setAttribute("y2", p2().ry()); + + return true; + } +} + +bool Line::fromDomElement(const QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::fromQDomElement Error: NULL element passed."; + return false; + } + + if (className() != e.tagName()) + { + qDebug() << className() << "::fromQDomElement Error: Invalid element type: " << + e.tagName() << " instead of " << className(); + return false; + } + + return attributesFromDom(e); +} + +bool Line::attributesFromDom(const QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::attributesFromDom Error: NULL element passed."; + return false; + } + else + { + QPoint newP1(e.attribute("x1", "0").toInt(), e.attribute("y1", "0").toInt()); + QPoint newP2(e.attribute("x2", "0").toInt(), e.attribute("y2", "0").toInt()); + + setPoints(newP1, newP2); + + return true; + } +} + +QString Line::className() +{ + return "Line"; +} diff --git a/line.h b/line.h index ffdb5d7..115c1e8 100644 --- a/line.h +++ b/line.h @@ -4,18 +4,30 @@ #include #include #include +#include + +#include class Line : public QLine { public: Line(); - virtual bool isHit(const QPoint & clickPoint); + virtual bool isHit(const QPoint &clickPoint); void setSelected(bool selected); - virtual void draw(QPainter * painter); - virtual void move(const QPoint & oldPoint, const QPoint & newPoint); + virtual void draw(QPainter *painter); + virtual void move(const QPoint &oldPoint, const QPoint &newPoint); + + // QDOM methods + QDomElement toDomElement(QDomDocument *doc); + bool fromDomElement(const QDomElement &e); + protected: + virtual bool attributesToDom(QDomDocument *doc, QDomElement &e); + virtual bool attributesFromDom(const QDomElement &e); + virtual QString className(); + bool m_selected; }; diff --git a/mainwindow.cpp b/mainwindow.cpp index 656b8c9..5df38a5 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -6,6 +6,7 @@ MainWindow::MainWindow(QWidget *parent) : ui(new Ui::MainWindow) { ui->setupUi(this); + lastUsedFile = NULL; } MainWindow::~MainWindow() @@ -42,6 +43,57 @@ void MainWindow::on_actionPreferences_triggered() delete tmp; } +void MainWindow::on_actionLoad_triggered() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Load an XML file"), + QStandardPaths::standardLocations(QStandardPaths::HomeLocation).at(0), + tr("XML File (*.xml *.Xml *.XML)"), 0, QFileDialog::DontUseNativeDialog); + + if(lastUsedFile) + { + delete lastUsedFile; + lastUsedFile = NULL; + } + + lastUsedFile = new QFile(fileName); + + if (lastUsedFile->exists()) + { + ui->interactionCanvasPlaceholder->read(lastUsedFile); + } + +} + +void MainWindow::on_actionSave_triggered() +{ + if (!lastUsedFile) + { + on_actionSave_As_triggered(); + } + + lastUsedFile->open(QFile::ReadWrite | QFile::Truncate); + + ui->interactionCanvasPlaceholder->write(lastUsedFile); + + lastUsedFile->close(); +} + +void MainWindow::on_actionSave_As_triggered() +{ + QString fileName = QFileDialog::getSaveFileName(this, tr("Load an XML file"), + QStandardPaths::standardLocations(QStandardPaths::HomeLocation).at(0), + tr("XML File (*.xml *.Xml *.XML)"), 0, QFileDialog::DontUseNativeDialog); + + if (lastUsedFile) + { + delete lastUsedFile; + lastUsedFile = NULL; + } + + lastUsedFile = new QFile(fileName); + + on_actionSave_triggered(); +} void MainWindow::on_actionLanguage_triggered() { @@ -100,7 +152,7 @@ void MainWindow::mouseMoveEvent(QMouseEvent *mouseEvent) qDebug() << "MainWindow:" << mouseEvent->pos(); } -void MainWindow::loadLanguage(const QString& rLanguageFile) +void MainWindow::loadLanguage(const QString &rLanguageFile) { // remove the old translator qApp->removeTranslator(&m_translator); diff --git a/mainwindow.h b/mainwindow.h index 43dbb29..d855081 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -4,6 +4,13 @@ #include #include #include +#include +#include +#include + +#include +#include + #include "dlgpreferences.h" #include "interactioncanvas.h" #include "languagedialog.h" @@ -37,10 +44,16 @@ private slots: void on_actionDraw_Polygon_triggered(); void changeEvent(QEvent *event); +private slots: + void on_actionLoad_triggered(); + void on_actionSave_triggered(); + void on_actionSave_As_triggered(); + private: Ui::MainWindow *ui; QTranslator m_translator; // contains the translations for this application + QFile *lastUsedFile; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 9e55b3a..d551437 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -38,6 +38,9 @@ Fi&le + + + @@ -105,6 +108,21 @@ Draw P&olygon + + + L&oad + + + + + &Save + + + + + S&ave As + + diff --git a/polygon.cpp b/polygon.cpp index d8b71b7..c785e7b 100644 --- a/polygon.cpp +++ b/polygon.cpp @@ -38,19 +38,20 @@ void Polygon::draw(QPainter *painter) void Polygon::move(const QPoint &oldPoint, const QPoint &newPoint) { - if(m_selected) + if (m_selected) { QPoint offset = newPoint - oldPoint; QVector3D vecOld(oldPoint); - if(vecOld.distanceToPoint(QVector3D(m_polygon.point(0))) < 5) + + if (vecOld.distanceToPoint(QVector3D(m_polygon.point(0))) < 5) { m_polygon.replace(0, m_polygon.point(0) + offset); } - else if(vecOld.distanceToPoint(QVector3D(m_polygon.point(1))) < 5) + else if (vecOld.distanceToPoint(QVector3D(m_polygon.point(1))) < 5) { m_polygon.replace(1, m_polygon.point(1) + offset); } - else if(vecOld.distanceToPoint(QVector3D(m_polygon.point(2))) < 5) + else if (vecOld.distanceToPoint(QVector3D(m_polygon.point(2))) < 5) { m_polygon.replace(2, m_polygon.point(2) + offset); } @@ -62,3 +63,59 @@ void Polygon::move(const QPoint &oldPoint, const QPoint &newPoint) } } } + +bool Polygon::attributesToDom(QDomDocument *doc, QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::attributesToDom Error: NULL element passed."; + return false; + } + else + { + QDomElement tmp; + + foreach(QPoint point, m_polygon.toList()) + { + tmp = doc->createElement("Point"); + + tmp.setAttribute("x", point.rx()); + tmp.setAttribute("y", point.ry()); + + e.appendChild(tmp); + } + + return true; + } +} + +bool Polygon::attributesFromDom(const QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::attributesFromDom Error: NULL element passed."; + return false; + } + else + { + QDomElement child = e.firstChildElement("Point"); + + m_polygon.clear(); + + while(!child.isNull()) + { + QPoint tmp(child.attribute("x", "0").toInt(), child.attribute("y", "0").toInt()); + + m_polygon.append(tmp); + + child = child.nextSiblingElement("Point"); + } + + return true; + } +} + +QString Polygon::className() +{ + return "Polygon"; +} diff --git a/polygon.h b/polygon.h index 6b76300..0a40947 100644 --- a/polygon.h +++ b/polygon.h @@ -18,6 +18,11 @@ public: protected: QPolygon m_polygon; + + virtual bool attributesToDom(QDomDocument *doc, QDomElement &e); + virtual bool attributesFromDom(const QDomElement &e); + virtual QString className(); + }; #endif // POLYGON_H diff --git a/rectangle.cpp b/rectangle.cpp index 1a58add..edc8749 100644 --- a/rectangle.cpp +++ b/rectangle.cpp @@ -40,23 +40,24 @@ void Rectangle::draw(QPainter *painter) void Rectangle::move(const QPoint &oldPoint, const QPoint &newPoint) { - if(m_selected) + if (m_selected) { QPoint offset = newPoint - oldPoint; QVector3D vecOld(oldPoint); - if(vecOld.distanceToPoint(QVector3D(m_rectangle.topLeft())) < 5) + + if (vecOld.distanceToPoint(QVector3D(m_rectangle.topLeft())) < 5) { m_rectangle.setTopLeft(m_rectangle.topLeft() + offset); } - else if(vecOld.distanceToPoint(QVector3D(m_rectangle.topRight())) < 5) + else if (vecOld.distanceToPoint(QVector3D(m_rectangle.topRight())) < 5) { m_rectangle.setTopRight(m_rectangle.topRight() + offset); } - else if(vecOld.distanceToPoint(QVector3D(m_rectangle.bottomLeft())) < 5) + else if (vecOld.distanceToPoint(QVector3D(m_rectangle.bottomLeft())) < 5) { m_rectangle.setBottomLeft(m_rectangle.bottomLeft() + offset); } - else if(vecOld.distanceToPoint(QVector3D(m_rectangle.bottomRight())) < 5) + else if (vecOld.distanceToPoint(QVector3D(m_rectangle.bottomRight())) < 5) { m_rectangle.setBottomRight(m_rectangle.bottomRight() + offset); } @@ -67,3 +68,45 @@ void Rectangle::move(const QPoint &oldPoint, const QPoint &newPoint) } } } + + +bool Rectangle::attributesToDom(QDomDocument *doc, QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::attributesToDom Error: NULL element passed."; + return false; + } + else + { + e.setAttribute("x1", m_rectangle.topLeft().rx()); + e.setAttribute("y1", m_rectangle.topLeft().ry()); + e.setAttribute("x2", m_rectangle.bottomRight().rx()); + e.setAttribute("y2", m_rectangle.bottomRight().ry()); + + return true; + } +} + +bool Rectangle::attributesFromDom(const QDomElement &e) +{ + if (e.isNull()) + { + qDebug() << className() << "::attributesFromDom Error: NULL element passed."; + return false; + } + else + { + m_rectangle.setTopLeft(QPoint(e.attribute("x1", "0").toInt(), + e.attribute("y1", "0").toInt())); + m_rectangle.setBottomRight(QPoint(e.attribute("x2", "0").toInt(), + e.attribute("y2", "0").toInt())); + + return true; + } +} + +QString Rectangle::className() +{ + return "Rectangle"; +} diff --git a/rectangle.h b/rectangle.h index cf29bb4..2c9ce05 100644 --- a/rectangle.h +++ b/rectangle.h @@ -16,6 +16,10 @@ public: protected: QRect m_rectangle; + + virtual bool attributesToDom(QDomDocument *doc, QDomElement &e); + virtual bool attributesFromDom(const QDomElement &e); + virtual QString className(); }; #endif // RECTANGLE_H -- cgit v1.2.3-70-g09d2