diff --git a/edge.cpp b/edge.cpp index 09b2290..65b8d23 100644 --- a/edge.cpp +++ b/edge.cpp @@ -7,12 +7,12 @@ #include -static const double Pi = 3.14159265358979323846264338327950288419717; -static double TwoPi = 2.0 * Pi; +const double Edge::m_pi = 3.14159265358979323846264338327950288419717; +const double Edge::m_twoPi = 2.0 * Edge::m_pi; +const qreal Edge::m_arrowSize = 7; Edge::Edge(Node *sourceNode, Node *destNode) - : m_arrowSize(7), - m_angle(-1) + : m_angle(-1) { setAcceptedMouseButtons(0); m_sourceNode = sourceNode; @@ -62,6 +62,11 @@ QPointF firstNotContainedPoint(const QLineF &line, return QPoint(0,0); } +double Edge::getAngle() const +{ + return m_angle; +} + void Edge::adjust() { if (!m_sourceNode || !m_destNode) @@ -110,7 +115,7 @@ void Edge::paint(QPainter *painter, m_angle = ::acos(line.dx() / line.length()); if (line.dy() >= 0) - m_angle = TwoPi - m_angle; + m_angle = Edge::m_twoPi - m_angle; if (sourceNode()->collidesWithItem(destNode())) return; @@ -128,19 +133,14 @@ void Edge::paint(QPainter *painter, // Draw the arrows QPointF destArrowP1 = m_destPoint + - QPointF(sin(m_angle - Pi / 3) * m_arrowSize, - cos(m_angle - Pi / 3) * m_arrowSize); + QPointF(sin(m_angle - Edge::m_pi / 3) * m_arrowSize, + cos(m_angle - Edge::m_pi / 3) * m_arrowSize); QPointF destArrowP2 = m_destPoint + - QPointF(sin(m_angle - Pi + Pi / 3) * m_arrowSize, - cos(m_angle - Pi + Pi / 3) * m_arrowSize); + QPointF(sin(m_angle - Edge::m_pi + Edge::m_pi / 3) * m_arrowSize, + cos(m_angle - Edge::m_pi + Edge::m_pi / 3) * m_arrowSize); painter->setBrush(Qt::black); painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); } - -double Edge::getAngle() const -{ - return m_angle; -} diff --git a/edge.h b/edge.h index be8c564..9dfd831 100644 --- a/edge.h +++ b/edge.h @@ -21,7 +21,8 @@ public: protected: QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + void paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, QWidget *widget); private: @@ -31,8 +32,11 @@ private: QPointF m_sourcePoint; QPointF m_destPoint; - qreal m_arrowSize; double m_angle; + + static const qreal m_arrowSize; + static const double m_pi; + static const double m_twoPi; }; #endif diff --git a/graphwidget.cpp b/graphwidget.cpp index 6d82bed..d732660 100644 --- a/graphwidget.cpp +++ b/graphwidget.cpp @@ -33,8 +33,8 @@ GraphWidget::GraphWidget(MainWindow *parent) : setTransformationAnchor(AnchorUnderMouse); setMinimumSize(400, 400); - connect(m_scene, SIGNAL(changed(const QList &)), - m_parent, SLOT(contentChanged())); +// connect(m_scene, SIGNAL(changed(const QList &)), +// m_parent, SLOT(contentChanged())); } void GraphWidget::newScene() @@ -50,7 +50,7 @@ void GraphWidget::closeScene() this->hide(); } -void GraphWidget::readContentFromFile(const QString &fileName) +void GraphWidget::readContentFromXmlFile(const QString &fileName) { QDomDocument doc("QtMindMap"); QFile file(fileName); @@ -105,7 +105,7 @@ void GraphWidget::readContentFromFile(const QString &fileName) this->show(); } -void GraphWidget::writeContentToFile(const QString &fileName) +void GraphWidget::writeContentToXmlFile(const QString &fileName) { QDomDocument doc("QtMindMap"); @@ -150,11 +150,23 @@ void GraphWidget::writeContentToFile(const QString &fileName) m_parent->statusBarMsg(tr("Saved.")); } -QGraphicsScene *GraphWidget::getScene() +void GraphWidget::writeContentToPngFile(const QString &fileName) { - return m_scene; -} + QImage img(m_scene->sceneRect().width(), + m_scene->sceneRect().height(), + QImage::Format_ARGB32_Premultiplied); + QPainter painter(&img); + + painter.setRenderHint(QPainter::Antialiasing); + + /// @bug scene background is not rendered + m_scene->render(&painter); + painter.end(); + + img.save(fileName); + m_parent->statusBarMsg(tr("MindMap exported as ") + fileName); +} void GraphWidget::keyPressEvent(QKeyEvent *event) { @@ -174,16 +186,16 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) // certain actions need an active node if (!m_activeNode && - (event->key() == Qt::Key_Insert || // add new node + ( event->key() == Qt::Key_Insert || // add new node event->key() == Qt::Key_F2 || // edit node event->key() == Qt::Key_Delete || // delete node event->key() == Qt::Key_A || // add edge event->key() == Qt::Key_D || // remove edge ( event->modifiers() == Qt::ControlModifier && // moving node - ( event->key() == Qt::Key_Up || - event->key() == Qt::Key_Down || - event->key() == Qt::Key_Left || - event->key() == Qt::Key_Right)))) + ( event->key() == Qt::Key_Up || + event->key() == Qt::Key_Down || + event->key() == Qt::Key_Left || + event->key() == Qt::Key_Right)))) { m_parent->statusBarMsg(tr("No active node.")); return; @@ -224,6 +236,7 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) else if (event->key() == Qt::Key_Down) m_activeNode->moveBy(0, 20); else if (event->key() == Qt::Key_Left) m_activeNode->moveBy(-20, 0); else if (event->key() == Qt::Key_Right) m_activeNode->moveBy(20, 0); + contentChanged(); } else // move scene { @@ -255,6 +268,7 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) // insert new node case Qt::Key_Insert: insertNode(); + contentChanged(); if (m_showingNodeNumbers) showNodeNumbers(); @@ -318,6 +332,7 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) m_nodeList.removeAll(m_activeNode); delete m_activeNode; m_activeNode = 0; + contentChanged(); if (m_showingNodeNumbers) showNodeNumbers(); @@ -486,6 +501,7 @@ void GraphWidget::addEdge(Node *source, Node *destination) else { m_scene->addItem(new Edge(source, destination)); + contentChanged(); } } @@ -498,6 +514,7 @@ void GraphWidget::removeEdge(Node *source, Node *destination) else { source->removeEdge(destination); + contentChanged(); } } @@ -546,3 +563,8 @@ QList GraphWidget::edges() const return list; } + +void GraphWidget::contentChanged(const bool &changed) +{ + m_parent->contentChanged(changed); +} diff --git a/graphwidget.h b/graphwidget.h index d8e865e..2684428 100644 --- a/graphwidget.h +++ b/graphwidget.h @@ -18,7 +18,6 @@ class GraphWidget : public QGraphicsView public: GraphWidget(MainWindow *parent = 0); - QGraphicsScene *getScene(); void setActiveNode(Node *node); void insertNode(); void setActiveNodeEditable(); @@ -26,12 +25,15 @@ public: // int nodeId(Node *node); QList edges() const; + void contentChanged(const bool &changed = true); + //public slots: void newScene(); void closeScene(); - void readContentFromFile(const QString &fileName); - void writeContentToFile(const QString &fileName); + void readContentFromXmlFile(const QString &fileName); + void writeContentToXmlFile(const QString &fileName); + void writeContentToPngFile(const QString &fileName); // void savetoFile(); // void saveFileAs(); diff --git a/main.cpp b/main.cpp index 4cd75a7..0093094 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ #include // EXIT_SUCCESS -#include // cout +#include // cerr #include #include @@ -9,10 +9,6 @@ #include "systemtray.h" #include "argumentparser.h" - - - - int main(int argc, char *argv[]) { Q_INIT_RESOURCE(qtmindmap); @@ -49,8 +45,8 @@ int main(int argc, char *argv[]) if (!QSystemTrayIcon::isSystemTrayAvailable()) { QMessageBox::critical(0, - QObject::tr("QtMindMap Error"), - QObject::tr("I couldn't detect any system tray on this system.")); + QObject::tr("QtMindMap Error"), + QObject::tr("I couldn't detect any system tray on this system.")); return EXIT_FAILURE; } QApplication::setQuitOnLastWindowClosed(false); diff --git a/mainwindow.cpp b/mainwindow.cpp index b3e6828..6bbd34c 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -8,8 +8,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::MainWindow), - m_graphicsView(0), - m_fileName(""), m_contentChanged(false) { m_graphicsView = new GraphWidget(this); @@ -42,11 +40,6 @@ MainWindow::~MainWindow() delete m_ui; } -//QStatusBar * MainWindow::getStatusBar() -//{ -// return m_ui->statusBar; -//} - void MainWindow::statusBarMsg(const QString &msg) { m_ui->statusBar->showMessage(msg, 5000); @@ -58,7 +51,8 @@ void MainWindow::contentChanged(const bool& changed) { setWindowTitle(windowTitle().prepend("* ")); m_contentChanged = true; - m_ui->actionSave->setEnabled(true); + if (m_fileName != "untitled") + m_ui->actionSave->setEnabled(true); } else if (m_contentChanged == true && changed == false) { @@ -70,22 +64,23 @@ void MainWindow::contentChanged(const bool& changed) void MainWindow::newFile() { - closeFile(); + if (!closeFile()) + return; m_graphicsView->newScene(); m_ui->actionSave->setEnabled(false); m_ui->actionSaveAs->setEnabled(true); m_ui->actionClose->setEnabled(true); - + contentChanged(false); m_fileName = "untitled"; setTitle(m_fileName); - contentChanged(false); } void MainWindow::openFile(const QString &fileName) { - closeFile(); + if (!closeFile()) + return; if (fileName.isEmpty()) { @@ -110,23 +105,22 @@ void MainWindow::openFile(const QString &fileName) m_fileName = fileName; } - m_graphicsView->readContentFromFile(m_fileName); + m_graphicsView->readContentFromXmlFile(m_fileName); m_ui->actionSave->setEnabled(true); m_ui->actionSaveAs->setEnabled(true); m_ui->actionClose->setEnabled(true); - - setTitle(m_fileName); contentChanged(false); + setTitle(m_fileName); } void MainWindow::saveFile() { - m_graphicsView->writeContentToFile(m_fileName); + m_graphicsView->writeContentToXmlFile(m_fileName); contentChanged(false); } -void MainWindow::saveFileAs() +bool MainWindow::saveFileAs() { QFileDialog dialog(this, tr("Save MindMap as"), @@ -140,50 +134,58 @@ void MainWindow::saveFileAs() m_fileName = dialog.selectedFiles().first(); setTitle(m_fileName); saveFile(); + return true; + } + else + { + return false; // cancelled } } -void MainWindow::closeFile() +bool MainWindow::closeFile() { if (m_contentChanged) { QMessageBox msgBox(this); msgBox.setText("The document has been modified."); msgBox.setInformativeText("Do you want to save your changes?"); - msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setStandardButtons(QMessageBox::Save | + QMessageBox::Discard | + QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Save); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Save: { - m_fileName.isEmpty() ? saveFileAs() : saveFile(); - - /// @todo handle cancel + if (m_fileName == "untitled") + { + if (!saveFileAs()) + return false; + } + else + { + saveFile(); + } break; } case QMessageBox::Discard: - m_graphicsView->closeScene(); - m_fileName = ""; - setTitle(m_fileName); - m_contentChanged = false; - return; + break; case QMessageBox::Cancel: - return; + return false; default: - return; + break; } } - else - { - m_ui->actionSave->setEnabled(false); - m_ui->actionSaveAs->setEnabled(false); - m_ui->actionClose->setEnabled(false); - setTitle(""); - m_graphicsView->closeScene(); - } + m_ui->actionSave->setEnabled(false); + m_ui->actionSaveAs->setEnabled(false); + m_ui->actionClose->setEnabled(false); + m_contentChanged = false; + setTitle(""); + m_graphicsView->closeScene(); + return true; } void MainWindow::exportScene() @@ -195,27 +197,9 @@ void MainWindow::exportScene() dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setDefaultSuffix("png"); - if (dialog.exec()) { - QStringList fileNames(dialog.selectedFiles()); - - QImage img(m_graphicsView->getScene()->sceneRect().width(), - m_graphicsView->getScene()->sceneRect().height(), - QImage::Format_ARGB32_Premultiplied); - QPainter painter(&img); - - painter.setRenderHint(QPainter::Antialiasing); - - /// @bug scene background is not rendered - m_graphicsView->getScene()->render(&painter); - painter.end(); - - img.save(fileNames.first()); -// m_ui->statusBar->showMessage(tr("MindMap exported as ") + -// fileNames.first(), -// 5000); - statusBarMsg(tr("MindMap exported as ") + fileNames.first()); + m_graphicsView->writeContentToPngFile(dialog.selectedFiles().first()); } } @@ -224,21 +208,15 @@ void MainWindow::about() QMessageBox msgBox(this); msgBox.setWindowTitle(tr("About QtMindMap")); msgBox.setText(tr("MindMap software written in Qt.")); - msgBox.setInformativeText(tr("Homepage: https://gitorious.org/qtmindmap\n\nReport bugs to: denes.matetelki@gmail.com")); + msgBox.setInformativeText(tr("Homepage: "). + append("https://gitorious.org/qtmindmap\n\n"). + append(tr("Report bugs to: ")). + append("denes.matetelki@gmail.com")); QPixmap pixMap(":/qtmindmap.svg"); msgBox.setIconPixmap(pixMap.scaled(50,50)); msgBox.exec(); } - - -//void MainWindow::setModifiedTitle(const bool &modified) -//{ -// modified ? -// setWindowTitle(windowTitle().remove(0,2)) : -// setWindowTitle(windowTitle().prepend("* ")); -//} - void MainWindow::setTitle(const QString &title) { if (title.isEmpty()) diff --git a/mainwindow.h b/mainwindow.h index 595b22d..650f57a 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -18,18 +18,17 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); -// QStatusBar * getStatusBar(); /// rewrite as a message slot? + void statusBarMsg(const QString &msg); + void contentChanged(const bool &changed = true); public slots: - void contentChanged(const bool &changed = true); - void newFile(); void openFile(const QString &fileName = ""); void saveFile(); - void saveFileAs(); - void closeFile(); + bool saveFileAs(); + bool closeFile(); void exportScene(); void about(); diff --git a/node.cpp b/node.cpp index b08a642..5bcacad 100644 --- a/node.cpp +++ b/node.cpp @@ -94,8 +94,10 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) case ItemPositionHasChanged: + m_graph->contentChanged(); foreach (EdgeElement element, m_edgeList) element.edge->adjust(); break; + default: break; }; @@ -304,6 +306,7 @@ void Node::keyPressEvent(QKeyEvent *event) // not cursor movement: editing QGraphicsTextItem::keyPressEvent(event); + m_graph->contentChanged(); foreach (EdgeElement element, m_edgeList) element.edge->adjust(); }