From c65bb1f5f3074643b424b9d83edb0cd3cf1cf4cc Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Fri, 17 Jun 2011 16:45:19 +0200 Subject: [PATCH] refactor: new/close/save/saveAs/open file dialogs (user interactions) are handled in MainWidget, GraphWidget only saves and reads the data. --- graphwidget.cpp | 353 +++++++++--------------------------------------- graphwidget.h | 19 +-- mainwindow.cpp | 235 ++++++++++++++++++++++---------- mainwindow.h | 24 ++-- mainwindow.ui | 8 +- 5 files changed, 258 insertions(+), 381 deletions(-) diff --git a/graphwidget.cpp b/graphwidget.cpp index 7ae6729..7de1d23 100644 --- a/graphwidget.cpp +++ b/graphwidget.cpp @@ -33,283 +33,36 @@ GraphWidget::GraphWidget(MainWindow *parent) : setTransformationAnchor(AnchorUnderMouse); setMinimumSize(400, 400); -// Node *node1 = new Node(this); -// node1->setHtml(QString("")); -// m_scene->addItem(node1); -// node1->setPos(-10, -10); -// node1->setBorder(false); -// m_nodeList.append(node1); - - /* - Node *node2 = new Node(this); - node2->setHtml(QString("work: hup.hu")); - m_scene->addItem(node2); - node2->setPos(60, -10); - m_nodeList.append(node2); - - Node *node3 = new Node(this); - node3->setHtml(QString("read")); - m_scene->addItem(node3); - node3->setPos(-70, -10); - m_nodeList.append(node3); - - Node *node4 = new Node(this); - node4->setHtml(QString("pragmatic programmer")); - m_scene->addItem(node4); - node4->setPos(-120, -80); - m_nodeList.append(node4); - - Node *node5 = new Node(this); - node5->setHtml(QString("semmi kulonos")); - m_scene->addItem(node5); - node5->setPos(-10, 50); - m_nodeList.append(node5); - - Node *node6 = new Node(this); - node6->setHtml(QString("rape goats")); - m_scene->addItem(node6); - node6->setPos(-10, 100); - m_nodeList.append(node6); - - Node *node7 = new Node(this); - node7->setHtml(QString("node

important

shit")); - m_scene->addItem(node7); - node7->setPos(-200, 50); - m_nodeList.append(node7); - - Node *node8 = new Node(this); - node8->setHtml(QString("more than\none lins")); - m_scene->addItem(node8); - node8->setPos(50, -80); - m_nodeList.append(node8); - - Node *node9 = new Node(this); - node9->setHtml(QString("iam a bald and italian guy")); - m_scene->addItem(node9); - node9->setPos(90, 90); - m_nodeList.append(node9); - - Node *node10 = new Node(this); - node10->setHtml(QString("no joke
anotehr line")); - m_scene->addItem(node10); - node10->setPos(-160, -10); - m_nodeList.append(node10); - - Node *node11 = new Node(this); - node11->setHtml(QString("salalal")); - m_scene->addItem(node11); - node11->setPos(-120, -120); - m_nodeList.append(node11); - - Node *node12 = new Node(this); - node12->setHtml(QString("lalalala")); - m_scene->addItem(node12); - node12->setPos(170, -10); - m_nodeList.append(node12);; - node12->setTextInteractionFlags(Qt::TextEditable); - - m_scene->addItem(new Edge(node1, node2)); - m_scene->addItem(new Edge(node1, node3)); - m_scene->addItem(new Edge(node3, node4)); - m_scene->addItem(new Edge(node1, node5)); - m_scene->addItem(new Edge(node5, node6)); - m_scene->addItem(new Edge(node4, node11)); - m_scene->addItem(new Edge(node2, node12)); - m_scene->addItem(new Edge(node3, node10)); - m_scene->addItem(new Edge(node10, node7)); - m_scene->addItem(new Edge(node5, node7)); - m_scene->addItem(new Edge(node2, node8)); - m_scene->addItem(new Edge(node2, node9)); - */ - -// m_activeNode = m_nodeList.first(); -// m_activeNode->setActive(); - - //addFirstNode(); - - /// @todo open file somewhere + connect(m_scene, SIGNAL(changed(const QList &)), + m_parent, SLOT(contentChanged())); } -void GraphWidget::newFile() +void GraphWidget::newScene() { removeAllNodes(); - addFirstNode(); - this->show(); - - m_parent->enableCloseFile(true); - m_parent->enableSave(false); - m_parent->enableSaveAs(true); - m_parent->setTitle("untitled"); -} - -void GraphWidget::closeFile() -{ - m_contentChanged = true; - - if (m_contentChanged) - { - - int ret = QMessageBox::warning( - this, - tr("QtMindMap - The document has been modified"), - m_parent->getFileName(). - append("\n\n"). - append(tr("Do you want to save your changes?")), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, - QMessageBox::Save); - - switch (ret) { - case QMessageBox::Save: - // Save was clicked - { - QString fileName = QFileDialog::getSaveFileName( - this, - tr("Save File"), - QDir::homePath(), - tr("QtMindMap (*.qmm)")); - - qDebug() << fileName; - - /// @todo save content to file - - break; - } - case QMessageBox::Discard: - // Don't Save was clicked - removeAllNodes(); - this->hide(); - break; - case QMessageBox::Cancel: - // Cancel was clicked - return; - default: - // should never be reached - break; - } - } - else - { - removeAllNodes(); - this->hide(); - } - - m_parent->enableCloseFile(false); - m_parent->enableSave(false); - m_parent->enableSaveAs(false); - m_parent->setTitle(""); -} - -void GraphWidget::saveFileAs() -{ - QFileDialog dialog(this, - tr("Save MindMap as"), - QDir::homePath(), - tr("QtMindMap (*.qmm)")); - dialog.setAcceptMode(QFileDialog::AcceptSave); - dialog.setDefaultSuffix("qmm"); - - if (dialog.exec()) - { - m_fileName = dialog.selectedFiles().first(); - saveFile(); - } } -void GraphWidget::saveFile() +void GraphWidget::closeScene() { - QDomDocument doc("QtMindMap"); - - QDomElement root = doc.createElement("qtmindmap"); - doc.appendChild( root ); - - // nodes - QDomElement nodes_root = doc.createElement("nodes"); - root.appendChild(nodes_root); - foreach(Node *node, m_nodeList) - { - QDomElement cn = doc.createElement("nodes"); - cn.setAttribute( "id", QString::number(m_nodeList.indexOf(node))); - cn.setAttribute( "x", QString::number(node->pos().x())); - cn.setAttribute( "y", QString::number(node->pos().y())); - cn.setAttribute( "htmlContent", node->toHtml()); - nodes_root.appendChild(cn); - } - - //edges - QDomElement edges_root = doc.createElement("edges"); - root.appendChild(edges_root); - foreach(Edge *edge, edges()) - { - QDomElement cn = doc.createElement("edge"); - cn.setAttribute( "source", QString::number(m_nodeList.indexOf(edge->sourceNode()))); - cn.setAttribute( "destination", QString::number(m_nodeList.indexOf(edge->destNode()))); - edges_root.appendChild(cn); - } - - QFile file(m_fileName); - if (!file.open(QIODevice::WriteOnly)) - { - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Couldn't open file to write."), - 3000); // millisec - return; - } - - QTextStream ts( &file ); - ts << doc.toString(); - file.close(); - - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Saved."), - 3000); // millisec - - m_parent->enableCloseFile(true); - m_parent->enableSave(true); - m_parent->enableSaveAs(true); - - m_parent->setTitle(m_fileName); -} - -void GraphWidget::openFile() -{ - qDebug() << __PRETTY_FUNCTION__; - - QFileDialog dialog(this, - tr("Open MindMap"), - QDir::homePath(), - tr("QtMindMap (*.qmm)")); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setDefaultSuffix("qmm"); - - if (dialog.exec()) - { - m_fileName = dialog.selectedFiles().first(); - openFile(m_fileName); - } + removeAllNodes(); + this->hide(); } -void GraphWidget::openFile(const QString &fileName) +void GraphWidget::readContentFromFile(const QString &fileName) { - m_fileName = fileName; - m_parent->enableCloseFile(true); - m_parent->enableSave(true); - m_parent->enableSaveAs(true); - - m_parent->setTitle(fileName); - QDomDocument doc("QtMindMap"); QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { - qDebug() << "faszom cannot read file"; + m_parent->statusBarMsg(tr("Couldn't read file.")); return; } if (!doc.setContent(&file)) { - qDebug() << "cannot parse file"; + m_parent->statusBarMsg(tr("Couldn't parse XML file")); file.close(); return; } @@ -352,6 +105,50 @@ void GraphWidget::openFile(const QString &fileName) this->show(); } +void GraphWidget::writeContentToFile(const QString &fileName) +{ + QDomDocument doc("QtMindMap"); + + QDomElement root = doc.createElement("qtmindmap"); + doc.appendChild( root ); + + // nodes + QDomElement nodes_root = doc.createElement("nodes"); + root.appendChild(nodes_root); + foreach(Node *node, m_nodeList) + { + QDomElement cn = doc.createElement("nodes"); +// cn.setAttribute( "id", QString::number(m_nodeList.indexOf(node))); + cn.setAttribute( "x", QString::number(node->pos().x())); + cn.setAttribute( "y", QString::number(node->pos().y())); + cn.setAttribute( "htmlContent", node->toHtml()); + nodes_root.appendChild(cn); + } + + //edges + QDomElement edges_root = doc.createElement("edges"); + root.appendChild(edges_root); + foreach(Edge *edge, edges()) + { + QDomElement cn = doc.createElement("edge"); + cn.setAttribute( "source", QString::number(m_nodeList.indexOf(edge->sourceNode()))); + cn.setAttribute( "destination", QString::number(m_nodeList.indexOf(edge->destNode()))); + edges_root.appendChild(cn); + } + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) + { + m_parent->statusBarMsg(tr("Couldn't open file to write.")); + return; + } + + QTextStream ts( &file ); + ts << doc.toString(); + file.close(); + + m_parent->statusBarMsg(tr("Saved.")); +} QGraphicsScene *GraphWidget::getScene() { @@ -388,9 +185,7 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) event->key() == Qt::Key_Left || event->key() == Qt::Key_Right)))) { - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("No active node."), - 3000); // millisec + m_parent->statusBarMsg(tr("No active node.")); return; } @@ -402,16 +197,12 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) if (m_edgeAdding) { m_edgeAdding = false; - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Edge adding cancelled"), - 3000); // millisec + m_parent->statusBarMsg(tr("Edge adding cancelled")); } else if (m_edgeDeleting) { m_edgeDeleting = false; - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Edge deleting cancelled"), - 3000); // millisec + m_parent->statusBarMsg(tr("Edge deleting cancelled")); } else if(m_showingNodeNumbers) { @@ -517,9 +308,7 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) if (m_nodeList.size()==1) { - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Last node cannot be deleted."), - 3000); // millisec + m_parent->statusBarMsg(tr("Last node cannot be deleted.")); break; } @@ -537,25 +326,14 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) // add edge to active node case Qt::Key_A: - - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Add edge: select destination node"), - 4000); // millisec - + m_parent->statusBarMsg(tr("Add edge: select destination node.")); m_edgeAdding = true; - break; // add edge to active node case Qt::Key_D: - - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("Delete edge: select other end-node"), - 4000); // millisec - + m_parent->statusBarMsg(tr("Delete edge: select other end-node.")); m_edgeDeleting = true; - - break; default: @@ -699,18 +477,11 @@ void GraphWidget::nodeSelected(Node *node) } } -//int GraphWidget::nodeId(Node *node) -//{ -// return m_nodeList.indexOf(node); -//} - void GraphWidget::addEdge(Node *source, Node *destination) { if (source->isConnected(destination)) { - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("There is already an edge between these two nodes."), - 5000); // millisec + m_parent->statusBarMsg(tr("There is already an edge between these two nodes.")); } else { @@ -722,9 +493,7 @@ void GraphWidget::removeEdge(Node *source, Node *destination) { if (!source->isConnected(destination)) { - dynamic_cast(m_parent)->getStatusBar()->showMessage( - tr("There no edge between these two nodes."), - 3000); // millisec + m_parent->statusBarMsg(tr("There no edge between these two nodes.")); } else { diff --git a/graphwidget.h b/graphwidget.h index bf4c178..d8e865e 100644 --- a/graphwidget.h +++ b/graphwidget.h @@ -26,14 +26,17 @@ public: // int nodeId(Node *node); QList edges() const; -public slots: - - void newFile(); - void closeFile(); - void saveFile(); - void saveFileAs(); - void openFile(const QString &fileName); - void openFile(); +//public slots: + + void newScene(); + void closeScene(); + void readContentFromFile(const QString &fileName); + void writeContentToFile(const QString &fileName); + +// void savetoFile(); +// void saveFileAs(); +// void openFile(const QString &fileName); +// void openFile(); protected: diff --git a/mainwindow.cpp b/mainwindow.cpp index 8ebb228..81b49a9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -5,49 +5,27 @@ #include #include -//#include - -/// QPixmap: It is not safe to use pixmaps outside the GUI thread -/// tr is messy -/* -extern void exportScaneToPng(QGraphicsScene *scene, - const QString &fileName, - Ui::MainWindow *ui) -{ - // start export in a diff thread - QImage img(scene->sceneRect().width(), - scene->sceneRect().height(), - QImage::Format_ARGB32_Premultiplied); - QPainter painter(&img); - painter.setRenderHint(QPainter::Antialiasing); - scene->render(&painter); - painter.end(); - - img.save(fileName); - ui->statusBar->showMessage(tr("MindMap exported as ") + fileName, - 5000); // millisec -} -*/ - - MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), - m_ui(new Ui::MainWindow) + m_ui(new Ui::MainWindow), + m_graphicsView(0), + m_fileName(""), + m_contentChanged(false) { m_graphicsView = new GraphWidget(this); m_ui->setupUi(this); connect(m_ui->actionNew, SIGNAL(activated()), - m_graphicsView, SLOT(newFile())); + this, SLOT(newFile())); connect(m_ui->actionOpen, SIGNAL(activated()), - m_graphicsView, SLOT(openFile())); + this, SLOT(openFile())); connect(m_ui->actionSave, SIGNAL(activated()), - m_graphicsView, SLOT(saveFile())); + this, SLOT(saveFile())); connect(m_ui->actionSaveAs, SIGNAL(activated()), - m_graphicsView, SLOT(saveFileAs())); - + this, SLOT(saveFileAs())); connect(m_ui->actionClose, SIGNAL(activated()), - m_graphicsView, SLOT(closeFile())); + this, SLOT(closeFile())); + connect(m_ui->actionExport, SIGNAL(activated()), this, SLOT(exportScene())); connect(m_ui->actionQuit, SIGNAL(activated()), @@ -64,6 +42,150 @@ MainWindow::~MainWindow() delete m_ui; } +//QStatusBar * MainWindow::getStatusBar() +//{ +// return m_ui->statusBar; +//} + +void MainWindow::statusBarMsg(const QString &msg) +{ + m_ui->statusBar->showMessage(msg, 5000); +} + +void MainWindow::contentChanged(const bool& changed) +{ + if (m_contentChanged == false && changed == true) + { + setWindowTitle(windowTitle().prepend("* ")); + m_contentChanged = true; + m_ui->actionSave->setEnabled(true); + } + else if (m_contentChanged == true && changed == false) + { + setWindowTitle(windowTitle().remove(0,2)); + m_contentChanged = false; + m_ui->actionSave->setEnabled(false); + } +} + +void MainWindow::newFile() +{ + closeFile(); + + m_graphicsView->newScene(); + + m_ui->actionSave->setEnabled(false); + m_ui->actionSaveAs->setEnabled(true); + m_ui->actionClose->setEnabled(true); + + m_fileName = "untitled"; + setTitle(m_fileName); + contentChanged(false); +} + +void MainWindow::openFile(const QString &fileName) +{ + closeFile(); + + if (fileName.isEmpty()) + { + QFileDialog dialog(this, + tr("Open MindMap"), + QDir::homePath(), + tr("QtMindMap (*.qmm)")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setDefaultSuffix("qmm"); + + if (dialog.exec()) + { + m_fileName = dialog.selectedFiles().first(); + } + else + { + return; + } + } + else + { + m_fileName = fileName; + } + + m_graphicsView->readContentFromFile(m_fileName); + + m_ui->actionSave->setEnabled(true); + m_ui->actionSaveAs->setEnabled(true); + m_ui->actionClose->setEnabled(true); + + setTitle(m_fileName); + contentChanged(false); +} + +void MainWindow::saveFile() +{ + m_graphicsView->writeContentToFile(m_fileName); + contentChanged(false); +} + +void MainWindow::saveFileAs() +{ + QFileDialog dialog(this, + tr("Save MindMap as"), + QDir::homePath(), + tr("QtMindMap (*.qmm)")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setDefaultSuffix("qmm"); + + if (dialog.exec()) + { + m_fileName = dialog.selectedFiles().first(); + setTitle(m_fileName); + saveFile(); + } +} + +void 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.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); + + switch (ret) { + case QMessageBox::Save: + { + m_fileName.isEmpty() ? saveFileAs() : saveFile(); + + /// @todo handle cancel + + break; + } + case QMessageBox::Discard: + m_graphicsView->closeScene(); + m_fileName = ""; + setTitle(m_fileName); + m_contentChanged = false; + return; + case QMessageBox::Cancel: + return; + default: + return; + } + } + else + { + m_ui->actionSave->setEnabled(false); + m_ui->actionSaveAs->setEnabled(false); + m_ui->actionClose->setEnabled(false); + + setTitle(""); + m_graphicsView->closeScene(); + } +} + void MainWindow::exportScene() { QFileDialog dialog(this, @@ -78,12 +200,6 @@ void MainWindow::exportScene() { QStringList fileNames(dialog.selectedFiles()); - /// @note Shall I start the export in diff thread? -// QtConcurrent::run(exportScaneToPng, -// graphicsView->getScene(), -// fileNames.first(), -// ui); - QImage img(m_graphicsView->getScene()->sceneRect().width(), m_graphicsView->getScene()->sceneRect().height(), QImage::Format_ARGB32_Premultiplied); @@ -96,9 +212,10 @@ void MainWindow::exportScene() painter.end(); img.save(fileNames.first()); - m_ui->statusBar->showMessage(tr("MindMap exported as ") + fileNames.first(), - 5000); // millisec - +// m_ui->statusBar->showMessage(tr("MindMap exported as ") + +// fileNames.first(), +// 5000); + statusBarMsg(tr("MindMap exported as ") + fileNames.first()); } } @@ -113,31 +230,14 @@ void MainWindow::about() msgBox.exec(); } -QStatusBar * MainWindow::getStatusBar() -{ - return m_ui->statusBar; -} - -void MainWindow::openFile(QString fileName) -{ - m_fileName = fileName; - m_graphicsView->openFile(m_fileName); -} - -void MainWindow::enableSave(const bool &enable) -{ - m_ui->actionSave->setEnabled(enable); -} -void MainWindow::enableSaveAs(const bool &enable) -{ - m_ui->actionSaveAs->setEnabled(enable); -} -void MainWindow::enableCloseFile(const bool &enable) -{ - m_ui->actionClose->setEnabled(enable); -} +//void MainWindow::setModifiedTitle(const bool &modified) +//{ +// modified ? +// setWindowTitle(windowTitle().remove(0,2)) : +// setWindowTitle(windowTitle().prepend("* ")); +//} void MainWindow::setTitle(const QString &title) { @@ -152,10 +252,3 @@ void MainWindow::setTitle(const QString &title) setWindowTitle(t); } } - -//void MainWindow::setModifiedTitle(const bool &modified) -//{ -// modified ? -// setWindowTitle(windowTitle().remove(0,2)) : -// setWindowTitle(windowTitle().prepend("* ")); -//} diff --git a/mainwindow.h b/mainwindow.h index 0be0876..595b22d 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -7,7 +7,7 @@ #include "graphwidget.h" namespace Ui { - class MainWindow; +class MainWindow; } class MainWindow : public QMainWindow @@ -15,27 +15,33 @@ class MainWindow : public QMainWindow Q_OBJECT public: + explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - QStatusBar * getStatusBar(); - QString getFileName() { return m_fileName; } - void openFile(QString fileName); - void enableSave(const bool &enable = true); - void enableSaveAs(const bool &enable = true); - void enableCloseFile(const bool &enable = true); - void setTitle(const QString &title); -// void setModifiedTitle(const bool &modified = true); +// QStatusBar * getStatusBar(); /// rewrite as a message slot? + void statusBarMsg(const QString &msg); public slots: + void contentChanged(const bool &changed = true); + + void newFile(); + void openFile(const QString &fileName = ""); + void saveFile(); + void saveFileAs(); + void closeFile(); + void exportScene(); void about(); private: + void setTitle(const QString &title); + Ui::MainWindow *m_ui; GraphWidget *m_graphicsView; QString m_fileName; + bool m_contentChanged; }; diff --git a/mainwindow.ui b/mainwindow.ui index b07afbd..074dd55 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -13,6 +13,10 @@ QtMindMap + + + :/heart.svg:/heart.svg + @@ -136,7 +140,9 @@ - + + + cica()