From 1a83a7f2aafd811a7027774e4786e159eeb0ff0f Mon Sep 17 00:00:00 2001 From: blacksun Date: Sun, 5 Jan 2014 15:00:46 +0000 Subject: [PATCH] remove undo stack by diagram, and add single undo stack for project git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@2706 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- sources/diagram.cpp | 8 ++-- sources/diagram.h | 4 +- sources/diagramview.cpp | 15 +------- sources/projectview.cpp | 74 +++++++++++++----------------------- sources/qetdiagrameditor.cpp | 28 +++++++------- sources/qetdiagrameditor.h | 1 + sources/qetproject.cpp | 10 +++++ sources/qetproject.h | 4 ++ 8 files changed, 63 insertions(+), 81 deletions(-) diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 388528951..9528abeb3 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -53,7 +53,6 @@ Diagram::Diagram(QObject *parent) : read_only_(false), diagram_qet_version_(-1) { - undo_stack_ = new QUndoStack(); qgi_manager_ = new QGIManager(this); setBackgroundBrush(Qt::white); conductor_setter_ = new QGraphicsLineItem(0, 0); @@ -83,8 +82,8 @@ Diagram::Diagram(QObject *parent) : Destructeur */ Diagram::~Diagram() { - // suppression de la liste des annulations - l'undo stack fait appel au qgimanager pour supprimer certains elements - delete undo_stack_; + // clear undo stack to prevent errors, because contains pointers to this diagram and is elements. + undoStack().clear(); // suppression du QGIManager - tous les elements qu'il connait sont supprimes delete qgi_manager_; // remove of conductor setter @@ -651,7 +650,6 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf void Diagram::write() { qDebug() << qPrintable(QString("Diagram::write() : saving changes from diagram \"%1\" [%2]").arg(title()).arg(QET::pointerString(this))); write(toXml().documentElement()); - undoStack().setClean(); } /** @@ -828,7 +826,7 @@ void Diagram::titleChanged(const QString &title) { */ void Diagram::diagramTextChanged(DiagramTextItem *text_item, const QString &old_text, const QString &new_text) { if (!text_item) return; - undo_stack_ -> push(new ChangeDiagramTextCommand(text_item, old_text, new_text)); + undoStack().push(new ChangeDiagramTextCommand(text_item, old_text, new_text)); } /** diff --git a/sources/diagram.h b/sources/diagram.h index b66f580bd..7f1247937 100644 --- a/sources/diagram.h +++ b/sources/diagram.h @@ -25,6 +25,7 @@ #include "exportproperties.h" #include "qgimanager.h" #include "numerotationcontext.h" +#include "qetproject.h" class Conductor; class CustomElement; @@ -86,7 +87,6 @@ class Diagram : public QGraphicsScene { bool draw_grid_; bool use_border_; QGIManager *qgi_manager_; - QUndoStack *undo_stack_; bool draw_terminals_; bool draw_colored_conductors_; QDomDocument xml_document_; @@ -323,7 +323,7 @@ inline Diagram::BorderOptions Diagram::borderOptions() { /// @return the diagram undo stack inline QUndoStack &Diagram::undoStack() { - return(*undo_stack_); + return *(project()->undoStack()); } /// @return the diagram graphics item manager diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 0d7e9b465..0b498170d 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -88,7 +88,6 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : QGraphicsView(pare connect(&(scene -> border_and_titleblock), SIGNAL(borderChanged(QRectF, QRectF)), this, SLOT(adjustSceneRect())); connect(&(scene -> border_and_titleblock), SIGNAL(displayChanged()), this, SLOT(adjustSceneRect())); connect(&(scene -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle())); - connect(&(scene -> undoStack()), SIGNAL(cleanChanged(bool)), this, SLOT(updateWindowTitle())); connect(diagram, SIGNAL(editElementRequired(ElementsLocation)), this, SIGNAL(editElementRequired(ElementsLocation))); connect(diagram, SIGNAL(findElementRequired(ElementsLocation)), this, SIGNAL(findElementRequired(ElementsLocation))); @@ -772,19 +771,7 @@ void DiagramView::adjustSceneRect() { Met a jour le titre du widget */ void DiagramView::updateWindowTitle() { - QString view_title(title()); - - // verifie si le document a ete modifie - bool modified_diagram = !(scene -> undoStack().isClean()); - - // specifie le titre du widget - setWindowTitle(view_title + " [*]"); - setWindowModified(modified_diagram); - - // emet le signal titleChanged en ajoutant manuellement [*] si le schema a ete modifie - QString emitted_title = view_title; - if (modified_diagram) emitted_title += " [*]"; - emit(titleChanged(this, emitted_title)); + emit(titleChanged(this, title())); } /** diff --git a/sources/projectview.cpp b/sources/projectview.cpp index 13795d437..ee614463e 100644 --- a/sources/projectview.cpp +++ b/sources/projectview.cpp @@ -176,9 +176,9 @@ bool ProjectView::tryClosing() { // - or specify what is to be saved, i.e. they choose whether they wants to // save/give up/remove diagrams considered as modified. int user_input = tryClosingDiagrams(); - if (user_input == QDialogButtonBox::RejectRole) { + if (user_input == QMessageBox::Cancel) { return(false); // the closing process was cancelled - } else if (user_input == QDialogButtonBox::DestructiveRole) { + } else if (user_input == QMessageBox::Discard) { return(true); // all modifications were discarded } @@ -222,55 +222,34 @@ bool ProjectView::tryClosingElementEditors() { } /** - Un projet comporte 0 a n schemas. - Cette methode parcourt les schemas et demande a l'utilisateur s'il veut - enregistrer les schemas modifies afin de les fermer. L'utilisateur peut - refuser la fermeture d'un schema. - Si un schema a ete ajoute sans jamais etre modifie, cette methode demande a - l'utilisateur s'il souhaite l'enlever. - @return true si tous les schemas peuvent etre fermes, false sinon -*/ + * @brief ProjectView::tryClosingDiagrams + * try to close this project, if diagram or project option are changed + * a dialog ask if user want to save the modification. + * @return the answer of dialog or discard if no change. + */ int ProjectView::tryClosingDiagrams() { - if (!project_) return(QDialogButtonBox::DestructiveRole); - - bool project_modified = project_ -> projectOptionsWereModified(); - QList modified_diagrams = getDiagrams(AllDiagrams | ModifiedDiagramsOnly); - bool has_filepath = !project_ -> filePath().isEmpty(); - if (!project_modified && !modified_diagrams.count() && has_filepath) { + if (!project_) return(QMessageBox::Discard); + + if (!project()->projectOptionsWereModified() && + project()->undoStack()->isClean() && + !project()->filePath().isEmpty()) { // nothing was modified, and we have a filepath, i.e. everything was already // saved, i.e we can close the project right now - return(QDialogButtonBox::DestructiveRole); + return(QMessageBox::Discard); + } + + int close_dialog = QMessageBox::question(this, project()->title(), + tr("Le projet \340 \351t\351 modifi\351.\n" + "Voulez-vous enregistrer les modifications ?"), + QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel, + QMessageBox::Save); + + if (close_dialog == QMessageBox::Save) { + saveDiagrams(project()->diagrams()); } - CloseDiagramsDialog close_dialog(modified_diagrams, this); - if (!project_ -> title().isEmpty()) { - close_dialog.setWindowTitle( - QString( - tr( - "Fermer le projet \"%1\"", - "project closing dialog title -- %1 is a project title" - ) - ).arg(project_ -> title()) - ); - } - connect(&close_dialog, SIGNAL(showDiagram(Diagram*)), this, SLOT(showDiagram(Diagram*))); - if (close_dialog.exec() == QDialog::Rejected) { - return(QDialogButtonBox::RejectRole); - } - - if (close_dialog.answer() == QDialogButtonBox::AcceptRole) { - // save diagrams the user marked as to be saved - QList to_save = close_dialog.diagramsByAction(CloseDiagramsDialog::Save); - saveDiagrams(to_save); - - // remove diagrams the user marked as to be removed - QList to_close = close_dialog.diagramsByAction(CloseDiagramsDialog::Remove); - foreach (Diagram *diagram, to_close) { - removeDiagram(diagram); - } - } - - return(close_dialog.answer()); + return(close_dialog); } /** @@ -558,7 +537,7 @@ void ProjectView::exportProject() { @return a QETResult object reflecting the situation */ QETResult ProjectView::save() { - return(doSave(AllDiagrams | ModifiedDiagramsOnly)); + return(doSave(AllDiagrams)); } /** @@ -607,6 +586,7 @@ QETResult ProjectView::doSave(ProjectSaveOptions options) { // write to file QETResult result = project_ -> write(); updateWindowTitle(); + if (options == AllDiagrams) project()->undoStack()->clear(); return(result); } diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index f9f883c2b..c436f51cb 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -119,7 +119,7 @@ QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) : // connexions signaux / slots pour une interface sensee connect(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(slot_updateWindowsMenu())); - connect(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(slot_updateActions())); + connect(&workspace, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(slot_updateUndoStack())); connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slot_updatePasteAction())); // lecture des parametres @@ -1158,23 +1158,24 @@ void QETDiagramEditor::slot_updateActions() { prj_nomenclature -> setVisible(false); #endif - // affiche les actions correspondant au diagram view en cours - if (dv) { - if (can_update_actions) { - undo_group.setActiveStack(&(dv -> diagram() -> undoStack())); - undo -> setEnabled(undo_group.canUndo()); - redo -> setEnabled(undo_group.canRedo()); - } - } else { - undo -> setEnabled(false); - redo -> setEnabled(false); - } - slot_updateModeActions(); slot_updatePasteAction(); slot_updateComplexActions(); } +/** + * @brief QETDiagramEditor::slot_updateUndoStack + * Update the undo stack view + */ +void QETDiagramEditor::slot_updateUndoStack() { + ProjectView *pv = currentProject(); + if (pv && can_update_actions) { + undo_group.setActiveStack(pv->project()->undoStack()); + undo -> setEnabled(undo_group.canUndo()); + redo -> setEnabled(undo_group.canRedo()); + } +} + /** gere les actions ayant des besoins precis pour etre active ou non Cette methode ne fait rien si aucun document n'est ouvert @@ -1821,6 +1822,7 @@ void QETDiagramEditor::diagramIsAboutToBeRemoved(DiagramView *dv) { void QETDiagramEditor::diagramWasRemoved(DiagramView *dv) { Q_UNUSED(dv); can_update_actions = true; + slot_updateUndoStack(); } /** diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index fc1de253d..7f43f50da 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -111,6 +111,7 @@ class QETDiagramEditor : public QETMainWindow { void slot_setSelectionMode(); void slot_setVisualisationMode(); void slot_updateActions(); + void slot_updateUndoStack(); void slot_updateModeActions(); void slot_updateComplexActions(); void slot_updatePasteAction(); diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index 473ea2f7f..9d3fb2453 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -62,6 +62,9 @@ QETProject::QETProject(int diagrams, QObject *parent) : // une categorie dediee aux elements integres automatiquement ensureIntegrationCategoryExists(); setupTitleBlockTemplatesCollection(); + + undo_stack_ = new QUndoStack(); + connect(undo_stack_, SIGNAL(cleanChanged(bool)), this, SLOT(undoStackChanged(bool))); } /** @@ -102,6 +105,9 @@ QETProject::QETProject(const QString &path, QObject *parent) : if (!project_file_info.isWritable()) { setReadOnly(true); } + + undo_stack_ = new QUndoStack(); + connect(undo_stack_, SIGNAL(cleanChanged(bool)), this, SLOT(undoStackChanged(bool))); } /** @@ -123,6 +129,9 @@ QETProject::QETProject(const QDomElement &xml_element, QObject *parent) : readProjectXml(); setupTitleBlockTemplatesCollection(); + + undo_stack_ = new QUndoStack(); + connect(undo_stack_, SIGNAL(cleanChanged(bool)), this, SLOT(undoStackChanged(bool))); } /** @@ -145,6 +154,7 @@ QETProject::~QETProject() { delete diagram; } // qDebug() << diagrams_; + delete undo_stack_; } /** diff --git a/sources/qetproject.h b/sources/qetproject.h index 8098b1a72..e8359dd93 100644 --- a/sources/qetproject.h +++ b/sources/qetproject.h @@ -118,6 +118,7 @@ class QETProject : public QObject { bool diagramsWereModified(); DiagramContext projectProperties(); void setProjectProperties(const DiagramContext &); + QUndoStack* undoStack() {return undo_stack_;} public slots: void componentWritten(); @@ -143,6 +144,7 @@ class QETProject : public QObject { void updateDiagramsTitleBlockTemplate(TitleBlockTemplatesCollection *, const QString &); void removeDiagramsTitleBlockTemplate(TitleBlockTemplatesCollection *, const QString &); void usedTitleBlockTemplateChanged(const QString &); + void undoStackChanged (bool a) {if (!a) setModified(true);} private: void setupTitleBlockTemplatesCollection(); @@ -193,6 +195,8 @@ class QETProject : public QObject { TitleBlockTemplatesProjectCollection titleblocks_; /// project-wide variables that will be made available to child diagrams DiagramContext project_properties_; + /// undo stack for this project + QUndoStack *undo_stack_; }; Q_DECLARE_METATYPE(QETProject *) #endif