Reworked the way project saving is presented to users.

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@1907 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavier 2012-07-13 07:21:19 +00:00
parent aa87f823d0
commit 00d158856a
10 changed files with 787 additions and 195 deletions

View File

@ -0,0 +1,313 @@
/*
Copyright 2006-2012 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "closediagramsdialog.h"
#include "diagram.h"
#include "qeticons.h"
/**
Construct a dialog showing \a diagrams.
@param parent Parent QWidget
*/
CloseDiagramsDialog::CloseDiagramsDialog(const QList<Diagram *> &diagrams, QWidget *parent) :
QDialog(parent),
diagrams_list_(diagrams),
answer_(-1)
{
initWidgets();
initLayout();
}
/**
Destructor
*/
CloseDiagramsDialog::~CloseDiagramsDialog() {
}
/**
@return the user answer once the dialog has been executed.
*/
int CloseDiagramsDialog::answer() const {
return(answer_);
}
/**
@return what the user wants to do with \a diagram
@see CloseDiagramsDialog::Actions
*/
int CloseDiagramsDialog::actionForDiagram(Diagram *diagram) {
if (QCheckBox *checkbox = getCheckBoxForDiagram(diagram)) {
if (!diagram -> undoStack().isClean()) {
return(checkbox -> isChecked() ? Save : DoNotSave);
} else if (!diagram -> wasWritten()) {
return(checkbox -> isChecked() ? Save : Remove);
}
}
return(Unknown);
}
/**
@return the list of diagrams for which users have chosen the \a action
action.
*/
QList<Diagram *> CloseDiagramsDialog::diagramsByAction(Actions action) {
QList<Diagram *> diagrams;
foreach (Diagram *diagram, diagrams_list_) {
if (actionForDiagram(diagram) == action) {
diagrams << diagram;
}
}
return(diagrams);
}
/**
Initialize widgets.
*/
void CloseDiagramsDialog::initWidgets() {
setWindowTitle(tr("Fermer un projet", "window title"));
connect(&show_mapper_, SIGNAL(mapped(int)), this, SLOT(requireShowDiagram(int)));
// label when diagrams were modified
informative_label1_ = new QLabel(
tr(
"Les sch\351mas ci-dessous contiennent des modifications non "
"enregistr\351es. Faut-il les sauvegarder ?",
"informative label"
)
);
informative_label1_ -> setWordWrap(true);
// label when no diagrams were modified
informative_label2_ = new QLabel(tr("Voulez-vous enregistrer le projet ?", "informative label"));
informative_label2_ -> setWordWrap(true);
// header labels
QLabel *state_label = new QLabel(tr("\311tat", "column header"));
QLabel *title_label = new QLabel(tr("Sch\351ma", "column header"));
// header checkbox in order to check/uncheck all diagrams
all_checkbox_ = new QCheckBox(tr("Action", "column header"));
all_checkbox_ -> setChecked(true);
connect(all_checkbox_, SIGNAL(stateChanged(int)), this, SLOT(topCheckBoxChangedState(int)));
// spacers inserted in the header row
QSpacerItem *spacer1 = new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum);
QSpacerItem *spacer2 = new QSpacerItem(25, 10, QSizePolicy::Preferred, QSizePolicy::Minimum);
buttons_ = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel);
connect(buttons_, SIGNAL(clicked(QAbstractButton *)), this, SLOT(storeAnswer(QAbstractButton *)));
// widget layout
diagrams_list_layout_ = new QGridLayout();
diagrams_list_layout_ -> addWidget(state_label, 0, 1, 1, 1, Qt::AlignCenter);
diagrams_list_layout_ -> addItem(spacer1, 0, 2);
diagrams_list_layout_ -> addWidget(title_label, 0, 3, 1, 1, Qt::AlignCenter);
diagrams_list_layout_ -> addItem(spacer2, 0, 4);
diagrams_list_layout_ -> addWidget(all_checkbox_, 0, 5, 1, 1, Qt::AlignCenter);
// widget
diagrams_list_widget_ = new QWidget();
diagrams_list_widget_ -> setLayout(diagrams_list_layout_);
diagrams_list_widget_ -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
// scroll area
diagrams_list_area_ = new QScrollArea();
diagrams_list_area_ -> setWidgetResizable(true);
diagrams_list_area_ -> setFrameStyle(QFrame::Plain | QFrame::NoFrame);
loadDiagramsList();
diagrams_list_area_ -> setWidget(diagrams_list_widget_);
}
/**
Initialize layout.
*/
void CloseDiagramsDialog::initLayout() {
setMinimumSize(650, 340);
QVBoxLayout *vlayout0 = new QVBoxLayout();
vlayout0 -> addWidget(informative_label1_);
vlayout0 -> addWidget(informative_label2_);
vlayout0 -> addWidget(diagrams_list_area_);
vlayout0 -> addWidget(buttons_);
setLayout(vlayout0);
}
/**
Create a visual list of all modified diagrams.
*/
void CloseDiagramsDialog::loadDiagramsList() {
if (diagrams_list_.count()) {
int row_id = 1;
foreach (Diagram *diagram, diagrams_list_) {
addDiagram(diagram, row_id);
++ row_id;
}
informative_label2_ -> setVisible(false);
} else {
informative_label1_ -> setVisible(false);
diagrams_list_area_ -> setVisible(false);
}
}
/**
Add \a diagram to the \a row_id row of the visual list.
*/
void CloseDiagramsDialog::addDiagram(Diagram *diagram, int row_id) {
QLabel *diagram_title = new QLabel(diagramTitle(diagram));
QPushButton *diagram_show = new QPushButton(QET::Icons::ZoomOriginal, ""); // tr("Afficher ce sch\351ma", "button label")
show_mapper_.setMapping(diagram_show, row_id - 1);
connect(diagram_show, SIGNAL(released()), &show_mapper_, SLOT(map()));
QLabel *diagram_status = new QLabel(diagramStatus(diagram));
QCheckBox *diagram_checkbox = new QCheckBox(diagramAction(diagram));
diagram_checkbox -> setChecked(true);
connect(diagram_checkbox, SIGNAL(stateChanged(int)), this, SLOT(lambdaCheckBoxChangedState(int)));
diagrams_list_layout_ -> addWidget(diagram_show, row_id, 0, 1, 1, Qt::AlignCenter);
diagrams_list_layout_ -> addWidget(diagram_title, row_id, 1, 1, 1, Qt::AlignCenter);
diagrams_list_layout_ -> addWidget(diagram_status, row_id, 3, 1, 1, Qt::AlignCenter);
diagrams_list_layout_ -> addWidget(diagram_checkbox, row_id, 5, 1, 1, Qt::AlignCenter);
}
/**
@return the action checkbox for \a diagram, or 0 if no adequate checkbox could be found.
*/
QCheckBox *CloseDiagramsDialog::getCheckBoxForDiagram(Diagram *diagram) {
int diagram_index = diagrams_list_.indexOf(diagram);
if (diagram_index == -1) return(0);
// We add 1 because there is one row dedicated to column headers;
// 4 is the column containing checkboxes, see initWidgets().
QLayoutItem *item = diagrams_list_layout_ -> itemAtPosition(diagram_index + 1, 5);
if (!item) return(0);
QWidget *widget = item -> widget();
if (!widget) return(0);
return(static_cast<QCheckBox *>(widget));
}
/**
@return the title for \a diagram
*/
QString CloseDiagramsDialog::diagramTitle(Diagram *diagram) {
if (!diagram -> title().isEmpty()) {
return(diagram -> title());
}
return(tr("Sch\351ma sans titre", "fallback diagram title"));
}
/**
@return a string describing the status of \a diagram
*/
QString CloseDiagramsDialog::diagramStatus(Diagram *diagram) {
if (!diagram) return(QString());
if (!diagram -> undoStack().isClean()) {
return(tr("Modifi\351", "diagram status"));
} else if (!diagram -> wasWritten()) {
return(tr("Ajout\351, non modifi\351", "diagram status"));
} else {
return(QString());
}
}
/**
@return a string describing the effect of saving \a diagram (e.g. "Save" or
"Keep").
*/
QString CloseDiagramsDialog::diagramAction(Diagram *diagram) {
if (!diagram) return(QString());
if (!diagram -> undoStack().isClean()) {
return(tr("Enregistrer", "diagram action"));
} else if (!diagram -> wasWritten()) {
return(tr("Conserver", "diagram action"));
} else {
return(QString());
}
}
/**
Adjust the state of the header checkbox when a diagram checkbox was
switched to \a new_state.
*/
void CloseDiagramsDialog::lambdaCheckBoxChangedState(int new_state) {
bool state = new_state;
bool all_same_state = true;
foreach (Diagram *diagram, diagrams_list_) {
if (QCheckBox *checkbox = getCheckBoxForDiagram(diagram)) {
if (checkbox -> isChecked() != state) {
all_same_state = false;
break;
}
}
}
all_checkbox_ -> blockSignals(true);
if (all_same_state) {
all_checkbox_ -> setTristate(false);
all_checkbox_ -> setChecked(state);
} else {
all_checkbox_ -> setTristate(true);
all_checkbox_ -> setCheckState(Qt::PartiallyChecked);
}
all_checkbox_ -> blockSignals(false);
all_checkbox_ -> update();
}
/**
Adjust diagram checkboxes when the header checkbox was switched to \a
new_state.
*/
void CloseDiagramsDialog::topCheckBoxChangedState(int new_state) {
setCheckedAll((bool)new_state);
}
/**
Set all diagram checkboxes to the checked (true) or unchecked (false)
state.
*/
void CloseDiagramsDialog::setCheckedAll(bool checked) {
foreach (Diagram *diagram, diagrams_list_) {
if (QCheckBox *checkbox = getCheckBoxForDiagram(diagram)) {
if (checkbox -> isChecked() != checked) {
checkbox -> blockSignals(true);
checkbox -> setChecked(checked);
checkbox -> blockSignals(false);
}
}
}
}
/**
Find the diagram at \a diagram_index and emts the showDiagram() signal with
it.
*/
void CloseDiagramsDialog::requireShowDiagram(int diagram_index) {
Diagram *diagram = diagrams_list_.value(diagram_index);
if (!diagram) return;
emit(showDiagram(diagram));
}
/**
Store the user answer when the dialog is validated or rejected.
*/
void CloseDiagramsDialog::storeAnswer(QAbstractButton *button) {
answer_ = buttons_ -> buttonRole(button);
accept();
}

View File

@ -0,0 +1,92 @@
/*
Copyright 2006-2012 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLOSE_DIAGRAMS_DIALOG_H
#define CLOSE_DIAGRAMS_DIALOG_H
#include <QDialog>
#include <QSignalMapper>
class QAbstractButton;
class QDialogButtonBox;
class QCheckBox;
class QLabel;
class QPushButton;
class Diagram;
class QGridLayout;
class QScrollArea;
/**
This class represents a dialog asking users whether they want to save
their modified project when it is being closed and what they wish to save
in it.
*/
class CloseDiagramsDialog : public QDialog {
Q_OBJECT
public:
enum Actions {
Unknown,
Save,
DoNotSave,
Remove
};
// Constructors, destructor
public:
CloseDiagramsDialog(const QList<Diagram *> &diagrams, QWidget *parent = 0);
virtual ~CloseDiagramsDialog();
private:
CloseDiagramsDialog(const CloseDiagramsDialog &);
// methods
public:
int answer() const;
int actionForDiagram(Diagram *);
QList<Diagram *> diagramsByAction(Actions);
private:
void initWidgets();
void initLayout();
void loadDiagramsList();
void addDiagram(Diagram *, int);
QCheckBox *getCheckBoxForDiagram(Diagram *);
QString diagramTitle(Diagram *);
QString diagramStatus(Diagram *);
QString diagramAction(Diagram *);
signals:
void showDiagram(Diagram *);
private slots:
void lambdaCheckBoxChangedState(int);
void topCheckBoxChangedState(int);
void setCheckedAll(bool);
void requireShowDiagram(int);
void storeAnswer(QAbstractButton *);
// attributes
private:
QList<Diagram *> diagrams_list_; ///< List of (modified or newly added) diagrams displayed by the dialog
QLabel *informative_label1_; ///< Informative label when there are modified diagrams
QLabel *informative_label2_; ///< Informative label when there is no modified diagram
QCheckBox *all_checkbox_; ///< Header checkbox to check/uncheck all other checkboxes
QScrollArea *diagrams_list_area_; ///< Scroll area to make the diagrams visual list fit in the dialog
QWidget *diagrams_list_widget_; ///< Scrolled widget
QGridLayout *diagrams_list_layout_; ///< Layout used to list diagrams
QDialogButtonBox *buttons_; ///< Buttons for users to input their final choice
int answer_; ///< Reflects the user answer once the diagram has been executed
QSignalMapper show_mapper_; ///< Signal mapper for the "show diagram" buttons to work
};
#endif

View File

@ -18,6 +18,7 @@
#include "projectview.h" #include "projectview.h"
#include "qetproject.h" #include "qetproject.h"
#include "configdialog.h" #include "configdialog.h"
#include "closediagramsdialog.h"
#include "projectconfigpages.h" #include "projectconfigpages.h"
#include "diagramview.h" #include "diagramview.h"
#include "diagram.h" #include "diagram.h"
@ -93,6 +94,36 @@ QList<DiagramView *> ProjectView::diagrams() const {
return(diagrams_); return(diagrams_);
} }
/**
@return A list containing child diagrams matching provided \a options.
*/
QList<Diagram *> ProjectView::getDiagrams(ProjectSaveOptions options) {
QList<Diagram *> selection;
if ((options & AllDiagrams) == AllDiagrams) {
selection << project_ -> diagrams();
} else {
Diagram *current = 0;
if (DiagramView *view = currentDiagram()) {
current = view -> diagram();
}
if (options & CurrentDiagram) {
if (current) selection << current;
} else if (options & AllDiagramsButCurrent) {
selection = project_ -> diagrams();
selection.removeOne(current);
}
}
if (options & ModifiedDiagramsOnly) {
foreach (Diagram *diagram, selection) {
if (!diagram -> undoStack().isClean() || !diagram -> wasWritten()) continue;
selection.removeOne(diagram);
}
}
return(selection);
}
/** /**
@return le schema actuellement active @return le schema actuellement active
*/ */
@ -106,35 +137,7 @@ DiagramView *ProjectView::currentDiagram() const {
@param qce Le QCloseEvent decrivant l'evenement @param qce Le QCloseEvent decrivant l'evenement
*/ */
void ProjectView::closeEvent(QCloseEvent *qce) { void ProjectView::closeEvent(QCloseEvent *qce) {
// si la vue n'est pas liee a un projet, on ferme directement bool can_close_project = tryClosing();
if (!project_) {
qce -> accept();
emit(projectClosed(this));
return;
}
// si le projet est comme neuf et n'est pas enregistre, on ferme directement
if (!project_ -> projectWasModified() && project_ -> filePath().isEmpty()) {
qce -> accept();
emit(projectClosed(this));
return;
}
bool can_close_project = true;
if (!tryClosing()) {
// l'utilisateur a refuse la fermeture du projet - on arrete la
can_close_project = false;
} else {
// a ce stade, l'utilisateur a accepte la fermeture de tout le contenu du projet
if (!project_ -> filePath().isEmpty()) {
// si le projet a un chemin specifie, on l'enregistre et on le ferme
can_close_project = project_ -> write();
} else {
// l'utilisateur n'enregistre pas son projet
can_close_project = true;
}
}
if (can_close_project) { if (can_close_project) {
qce -> accept(); qce -> accept();
emit(projectClosed(this)); emit(projectClosed(this));
@ -152,34 +155,46 @@ void ProjectView::closeEvent(QCloseEvent *qce) {
@see tryClosingDiagrams() @see tryClosingDiagrams()
*/ */
bool ProjectView::tryClosing() { bool ProjectView::tryClosing() {
if (!project_) return(true);
// First step: require external editors closing -- users may either cancel
// the whole closing process or save (and therefore add) content into this
// project. Of course, they may also discard them.
if (!tryClosingElementEditors()) { if (!tryClosingElementEditors()) {
return(false); return(false);
} }
if (!tryClosingDiagrams()) { // Check how different the current situation is from a brand new, untouched project
return(false); if (project_ -> filePath().isEmpty() && !project_ -> projectWasModified()) {
}
// a ce stade, l'utilisateur a accepte de fermer tous les editeurs
// d'elements et tous les schemas
// on regarde s'il reste du contenu dans le projet
if (project_ -> projectWasModified() && project_ -> filePath().isEmpty()) {
// si oui, on propose a l'utilisateur d'enregistrer le projet
QMessageBox::StandardButton answer = QET::MessageBox::question(
this,
tr("Enregistrer le projet en cours ?", "message box title"),
QString(tr("Voulez-vous enregistrer le projet ?", "message box content")),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
QMessageBox::Cancel
);
if (answer == QMessageBox::Cancel) {
return(false);
} else if (answer == QMessageBox::Yes) {
return(save());
}
}
return(true); return(true);
}
// Second step: users are presented with a dialog that enables them to
// choose whether they want to:
// - cancel the closing process,
// - discard all modifications,
// - 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) {
return(false); // the closing process was cancelled
} else if (user_input == QDialogButtonBox::DestructiveRole) {
return(true); // all modifications were discarded
}
// Check how different the current situation is from a brand new, untouched project (yes , again)
if (project_ -> filePath().isEmpty() && !project_ -> projectWasModified()) {
return(true);
}
if (project_ -> filePath().isEmpty()) {
QString filepath = askUserForFilePath();
if (filepath.isEmpty()) return(false); // users may cancel the closing
}
QETResult result = project_ -> write();
updateWindowTitle();
if (!result.isOk()) emit(errorEncountered(result.errorMessage()));
return(result.isOk());
} }
/** /**
@ -215,49 +230,45 @@ bool ProjectView::tryClosingElementEditors() {
l'utilisateur s'il souhaite l'enlever. l'utilisateur s'il souhaite l'enlever.
@return true si tous les schemas peuvent etre fermes, false sinon @return true si tous les schemas peuvent etre fermes, false sinon
*/ */
bool ProjectView::tryClosingDiagrams() { int ProjectView::tryClosingDiagrams() {
if (!project_) return(true); if (!project_) return(QDialogButtonBox::DestructiveRole);
foreach(DiagramView *diagram_view, diagrams()) { QList<Diagram *> modified_diagrams = getDiagrams(AllDiagrams | ModifiedDiagramsOnly);
if (!diagram_view -> diagram() -> undoStack().isClean()) { if (!modified_diagrams.count() && !project_ -> filePath().isEmpty()) {
// ce schema a ete modifie - on demande a l'utilisateur s'il veut l'enregistrer // nothing was modified, and we have a filepath, i.e. everything was already
showDiagram(diagram_view -> diagram()); // saved, i.e we can close the project right now
QMessageBox::StandardButton answer = QET::MessageBox::question( return(QDialogButtonBox::DestructiveRole);
this, }
tr("Enregistrer le sch\351ma en cours ?", "message box title"),
QString(tr("Voulez-vous enregistrer le sch\351ma %1 ?", "message box content - %1 is a diagram title")).arg(diagram_view -> windowTitle()), CloseDiagramsDialog close_dialog(modified_diagrams, this);
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, if (!project_ -> title().isEmpty()) {
QMessageBox::Cancel close_dialog.setWindowTitle(
QString(
tr(
"Fermer le projet \"%1\"",
"project closing dialog title -- %1 is a project title"
)
).arg(project_ -> title())
); );
if (answer == QMessageBox::Cancel) { }
return(false); connect(&close_dialog, SIGNAL(showDiagram(Diagram*)), this, SLOT(showDiagram(Diagram*)));
} else if (answer == QMessageBox::Yes) { if (close_dialog.exec() == QDialog::Rejected) {
if (!save()) { return(QDialogButtonBox::RejectRole);
return(false); }
if (close_dialog.answer() == QDialogButtonBox::AcceptRole) {
// save diagrams the user marked as to be saved
QList<Diagram *> to_save = close_dialog.diagramsByAction(CloseDiagramsDialog::Save);
saveDiagrams(to_save);
// remove diagrams the user marked as to be removed
QList<Diagram *> to_close = close_dialog.diagramsByAction(CloseDiagramsDialog::Remove);
foreach (Diagram *diagram, to_close) {
removeDiagram(diagram);
} }
} }
} else if (!diagram_view -> diagram() -> wasWritten()) {
// ce schema a ete ajoute mais pas modifie - on demande a l'utilisateur s'il veut le conserver return(close_dialog.answer());
showDiagram(diagram_view -> diagram());
QMessageBox::StandardButton answer = QET::MessageBox::question(
this,
tr("Enregistrer le nouveau sch\351ma ?", "message box title"),
tr("Ce sch\351ma a \351t\351 ajout\351 mais n'a \351t\351 ni modifi\351 ni enregistr\351. Voulez-vous le conserver ?", "message box content"),
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
QMessageBox::Cancel
);
if (answer == QMessageBox::Cancel) {
return(false);
} else if (answer == QMessageBox::Yes) {
if (!save()) {
return(false);
}
} else if (answer == QMessageBox::No) {
removeDiagram(diagram_view);
}
}
}
return(true);
} }
/** /**
@ -290,6 +301,15 @@ QString ProjectView::askUserForFilePath(bool assign) {
return(filepath); return(filepath);
} }
/**
@return the QETResult object to be returned when it appears this project
view is not associated to any project.
*/
QETResult ProjectView::noProjectResult() const {
QETResult no_project(tr("aucun projet affich\351", "error message"), false);
return(no_project);
}
/** /**
Ajoute un nouveau schema au ProjectView Ajoute un nouveau schema au ProjectView
*/ */
@ -530,58 +550,78 @@ void ProjectView::exportProject() {
} }
/** /**
Enregistre le projet dans un fichier. Save project properties along with all modified diagrams.
@see filePath() @see filePath()
@see setFilePath() @see setFilePath()
@return true si l'enregistrement a reussi, false sinon @return a QETResult object reflecting the situation
*/ */
bool ProjectView::save() { QETResult ProjectView::save() {
bool result = false; return(doSave(AllDiagrams | ModifiedDiagramsOnly));
if (project_) { }
/**
Ask users for a filepath in order to save the project.
@param options May be used to specify what should be saved; defaults to
all modified diagrams.
@return a QETResult object reflecting the situation; note that a valid
QETResult object is returned if the operation was cancelled.
*/
QETResult ProjectView::saveAs(ProjectSaveOptions options) {
if (!project_) return(noProjectResult());
QString filepath = askUserForFilePath();
if (filepath.isEmpty()) return(QETResult());
return(doSave(options));
}
/**
Save the current diagram.
@return A QETResult object reflecting the situation.
*/
QETResult ProjectView::saveCurrentDiagram() {
return(doSave(CurrentDiagram));
}
/**
Save project content according to \a options, then write the project file. May
call saveAs if no filepath was provided before.
@param options May be used to specify what should be saved (e.g. modified
diagrams only).
@return a QETResult object reflecting the situation; note that a valid
QETResult object is returned if the operation was cancelled.
*/
QETResult ProjectView::doSave(ProjectSaveOptions options) {
if (!project_) return(noProjectResult());
if (project_ -> filePath().isEmpty()) { if (project_ -> filePath().isEmpty()) {
// le projet n'est pas encore enregistre dans un fichier // The project has not been saved to a file yet,
// save() equivaut alors a saveAs() // so save() actually means saveAs().
return(saveAs()); return(saveAs(options));
}
// on enregistre le schema en cours
if (DiagramView *current_view = currentDiagram()) {
if (Diagram *diagram = current_view -> diagram()) {
diagram -> write();
result = true;
}
} else {
// s'il n'y a pas de schema, on appelle directement la methode write()
result = project_ -> write();
}
} }
// look for diagrams matching the required save options
saveDiagrams(getDiagrams(options));
// write to file
QETResult result = project_ -> write();
updateWindowTitle(); updateWindowTitle();
return(result); return(result);
} }
/** /**
Save all diagrams in the project. Save \a diagrams without emitting the written() signal and without writing
@return False if something went wrong (no project, no filepath provided, write the project file itself.
error), true otherwise.
*/ */
bool ProjectView::saveAll() { void ProjectView::saveDiagrams(const QList<Diagram *> &diagrams) {
if (project_) { foreach (Diagram *diagram, diagrams) {
if (project_ -> filePath().isEmpty()) { // Diagram::write() emits the written() signal, which is connected
QString filepath = askUserForFilePath(); // to QETProject::write() through QETProject::componentWritten().
if (filepath.isEmpty()) return(false); // We do not want to write the project immediately, so we block
} // this signal.
foreach (Diagram *diagram, project_ -> diagrams()) {
// Diagram::write() emits the written() signal, which is connected to
// QETProject::write() through QETProject::componentWritten(). We do not want
// to write the project immediately, so we block this signal.
diagram -> blockSignals(true); diagram -> blockSignals(true);
diagram -> write(); diagram -> write();
diagram -> blockSignals(false); diagram -> blockSignals(false);
} }
bool writing = project_ -> write();
updateWindowTitle();
return(writing);
}
return(false);
} }
/** /**
@ -652,20 +692,6 @@ int ProjectView::cleanProject() {
return(clean_count); return(clean_count);
} }
/**
Demande un nom de fichier a l'utilisateur pour enregistrer le projet
Si aucun nom n'est entre, elle renvoie faux.
Si le nom ne se termine pas par l'extension .qet, celle-ci est ajoutee.
Si l'enregistrement reussit, le nom du fichier est conserve et la fonction renvoie true.
Sinon, faux est renvoye.
@return true si l'enregistrement a reussi, false sinon
*/
bool ProjectView::saveAs() {
QString filepath = askUserForFilePath();
if (filepath.isEmpty()) return(false);
return(save());
}
/** /**
Initialize actions for this widget. Initialize actions for this widget.
*/ */

View File

@ -19,6 +19,7 @@
#define PROJECT_VIEW_H #define PROJECT_VIEW_H
#include <QtGui> #include <QtGui>
#include "templatelocation.h" #include "templatelocation.h"
#include "qetresult.h"
class QETProject; class QETProject;
class DiagramView; class DiagramView;
class Diagram; class Diagram;
@ -29,6 +30,17 @@ class QETTabWidget;
*/ */
class ProjectView : public QWidget { class ProjectView : public QWidget {
Q_OBJECT Q_OBJECT
public:
enum ProjectSaveOption {
ModifiedDiagramsOnly = 1,
CurrentDiagram = 2,
AllDiagramsButCurrent = 4,
AllDiagrams = 6
};
Q_DECLARE_FLAGS(ProjectSaveOptions, ProjectSaveOption)
// constructeurs, destructeur // constructeurs, destructeur
public: public:
ProjectView(QETProject *, QWidget * = 0); ProjectView(QETProject *, QWidget * = 0);
@ -41,6 +53,7 @@ class ProjectView : public QWidget {
QETProject *project(); QETProject *project();
void setProject(QETProject *); void setProject(QETProject *);
QList<DiagramView *> diagrams() const; QList<DiagramView *> diagrams() const;
QList<Diagram *> getDiagrams(ProjectSaveOptions options);
DiagramView *currentDiagram() const; DiagramView *currentDiagram() const;
void closeEvent(QCloseEvent *); void closeEvent(QCloseEvent *);
@ -61,9 +74,11 @@ class ProjectView : public QWidget {
void moveDiagramDown(Diagram *); void moveDiagramDown(Diagram *);
void printProject(); void printProject();
void exportProject(); void exportProject();
bool save(); QETResult save();
bool saveAs(); QETResult saveAs(ProjectSaveOptions = ProjectSaveOptions(AllDiagrams | ModifiedDiagramsOnly));
bool saveAll(); QETResult saveCurrentDiagram();
QETResult doSave(ProjectSaveOptions);
void saveDiagrams(const QList<Diagram *> &);
int cleanProject(); int cleanProject();
void updateWindowTitle(); void updateWindowTitle();
void updateTabTitle(DiagramView *, const QString &); void updateTabTitle(DiagramView *, const QString &);
@ -77,6 +92,7 @@ class ProjectView : public QWidget {
void diagramActivated(DiagramView *); void diagramActivated(DiagramView *);
void diagramOrderChanged(ProjectView *, int, int); void diagramOrderChanged(ProjectView *, int, int);
void projectClosed(ProjectView *); void projectClosed(ProjectView *);
void errorEncountered(const QString &);
// relayed signals // relayed signals
void findElementRequired(const ElementsLocation &); void findElementRequired(const ElementsLocation &);
void editElementRequired(const ElementsLocation &); void editElementRequired(const ElementsLocation &);
@ -91,8 +107,9 @@ class ProjectView : public QWidget {
void rebuildDiagramsMap(); void rebuildDiagramsMap();
bool tryClosing(); bool tryClosing();
bool tryClosingElementEditors(); bool tryClosingElementEditors();
bool tryClosingDiagrams(); int tryClosingDiagrams();
QString askUserForFilePath(bool = true); QString askUserForFilePath(bool = true);
QETResult noProjectResult() const;
private slots: private slots:
void tabChanged(int); void tabChanged(int);
@ -113,4 +130,5 @@ class ProjectView : public QWidget {
QMap<int, DiagramView *> diagram_ids_; QMap<int, DiagramView *> diagram_ids_;
QList<DiagramView *> diagrams_; QList<DiagramView *> diagrams_;
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(ProjectView::ProjectSaveOptions)
#endif #endif

View File

@ -27,6 +27,7 @@
#include "qeticons.h" #include "qeticons.h"
#include "qetelementeditor.h" #include "qetelementeditor.h"
#include "qetmessagebox.h" #include "qetmessagebox.h"
#include "qetresult.h"
#include "genericpanel.h" #include "genericpanel.h"
/** /**
@ -179,8 +180,8 @@ void QETDiagramEditor::actions() {
open_file = new QAction(QET::Icons::DocumentOpen, tr("&Ouvrir"), this); open_file = new QAction(QET::Icons::DocumentOpen, tr("&Ouvrir"), this);
close_file = new QAction(QET::Icons::DocumentClose, tr("&Fermer"), this); close_file = new QAction(QET::Icons::DocumentClose, tr("&Fermer"), this);
save_file = new QAction(QET::Icons::DocumentSave, tr("&Enregistrer"), this); save_file = new QAction(QET::Icons::DocumentSave, tr("&Enregistrer"), this);
save_file_sous = new QAction(QET::Icons::DocumentSaveAs, tr("Enregistrer sous"), this); save_file_as = new QAction(QET::Icons::DocumentSaveAs, tr("Enregistrer sous"), this);
save_all = new QAction(QET::Icons::DocumentSaveAll, tr("&Enregistrer tous les sch\351mas"), this); save_cur_diagram = new QAction(QET::Icons::DocumentSaveAll, tr("&Enregistrer tous les sch\351mas"), this);
import_diagram = new QAction(QET::Icons::DocumentImport, tr("&Importer"), this); import_diagram = new QAction(QET::Icons::DocumentImport, tr("&Importer"), this);
export_diagram = new QAction(QET::Icons::DocumentExport, tr("E&xporter"), this); export_diagram = new QAction(QET::Icons::DocumentExport, tr("E&xporter"), this);
print = new QAction(QET::Icons::DocumentPrint, tr("Imprimer"), this); print = new QAction(QET::Icons::DocumentPrint, tr("Imprimer"), this);
@ -273,9 +274,9 @@ void QETDiagramEditor::actions() {
new_file -> setStatusTip(tr("Cr\351e un nouveau sch\351ma", "status bar tip")); new_file -> setStatusTip(tr("Cr\351e un nouveau sch\351ma", "status bar tip"));
open_file -> setStatusTip(tr("Ouvre un sch\351ma existant", "status bar tip")); open_file -> setStatusTip(tr("Ouvre un sch\351ma existant", "status bar tip"));
close_file -> setStatusTip(tr("Ferme le sch\351ma courant", "status bar tip")); close_file -> setStatusTip(tr("Ferme le sch\351ma courant", "status bar tip"));
save_file -> setStatusTip(tr("Enregistre le sch\351ma courant", "status bar tip")); save_file -> setStatusTip(tr("Enregistre le projet courant et tous ses sch\351mas", "status bar tip"));
save_file_sous -> setStatusTip(tr("Enregistre le sch\351ma courant avec un autre nom de fichier", "status bar tip")); save_file_as -> setStatusTip(tr("Enregistre le project courant avec un autre nom de fichier", "status bar tip"));
save_all -> setStatusTip(tr("Enregistre tous les sch\351mas du projet courant", "status bar tip")); save_cur_diagram -> setStatusTip(tr("Enregistre tous les sch\351mas du projet courant", "status bar tip"));
import_diagram -> setStatusTip(tr("Importe un sch\351ma dans le sch\351ma courant", "status bar tip")); import_diagram -> setStatusTip(tr("Importe un sch\351ma dans le sch\351ma courant", "status bar tip"));
export_diagram -> setStatusTip(tr("Exporte le sch\351ma courant dans un autre format", "status bar tip")); export_diagram -> setStatusTip(tr("Exporte le sch\351ma courant dans un autre format", "status bar tip"));
print -> setStatusTip(tr("Imprime le sch\351ma courant", "status bar tip")); print -> setStatusTip(tr("Imprime le sch\351ma courant", "status bar tip"));
@ -356,9 +357,9 @@ void QETDiagramEditor::actions() {
connect(zoom_reset, SIGNAL(triggered()), this, SLOT(slot_zoomReset()) ); connect(zoom_reset, SIGNAL(triggered()), this, SLOT(slot_zoomReset()) );
connect(print, SIGNAL(triggered()), this, SLOT(printDialog()) ); connect(print, SIGNAL(triggered()), this, SLOT(printDialog()) );
connect(export_diagram, SIGNAL(triggered()), this, SLOT(exportDialog()) ); connect(export_diagram, SIGNAL(triggered()), this, SLOT(exportDialog()) );
connect(save_file_sous, SIGNAL(triggered()), this, SLOT(saveAsDialog()) ); connect(save_file_as, SIGNAL(triggered()), this, SLOT(saveAs()) );
connect(save_file, SIGNAL(triggered()), this, SLOT(save()) ); connect(save_file, SIGNAL(triggered()), this, SLOT(save()) );
connect(save_all, SIGNAL(triggered()), this, SLOT(saveAll()) ); connect(save_cur_diagram, SIGNAL(triggered()), this, SLOT(saveCurrentDiagram()) );
connect(new_file, SIGNAL(triggered()), this, SLOT(newProject()) ); connect(new_file, SIGNAL(triggered()), this, SLOT(newProject()) );
connect(open_file, SIGNAL(triggered()), this, SLOT(openProject()) ); connect(open_file, SIGNAL(triggered()), this, SLOT(openProject()) );
connect(close_file, SIGNAL(triggered()), this, SLOT(closeCurrentProject()) ); connect(close_file, SIGNAL(triggered()), this, SLOT(closeCurrentProject()) );
@ -421,8 +422,8 @@ void QETDiagramEditor::menus() {
menu_fichier -> addMenu(QETApp::projectsRecentFiles() -> menu()); menu_fichier -> addMenu(QETApp::projectsRecentFiles() -> menu());
connect(QETApp::projectsRecentFiles(), SIGNAL(fileOpeningRequested(const QString &)), this, SLOT(openRecentFile(const QString &))); connect(QETApp::projectsRecentFiles(), SIGNAL(fileOpeningRequested(const QString &)), this, SLOT(openRecentFile(const QString &)));
menu_fichier -> addAction(save_file); menu_fichier -> addAction(save_file);
menu_fichier -> addAction(save_file_sous); menu_fichier -> addAction(save_file_as);
menu_fichier -> addAction(save_all); menu_fichier -> addAction(save_cur_diagram);
menu_fichier -> addAction(close_file); menu_fichier -> addAction(close_file);
menu_fichier -> addSeparator(); menu_fichier -> addSeparator();
//menu_fichier -> addAction(import_diagram); //menu_fichier -> addAction(import_diagram);
@ -504,8 +505,8 @@ void QETDiagramEditor::toolbar() {
main_bar -> addAction(new_file); main_bar -> addAction(new_file);
main_bar -> addAction(open_file); main_bar -> addAction(open_file);
main_bar -> addAction(save_file); main_bar -> addAction(save_file);
main_bar -> addAction(save_file_sous); main_bar -> addAction(save_file_as);
main_bar -> addAction(save_all); main_bar -> addAction(save_cur_diagram);
main_bar -> addAction(close_file); main_bar -> addAction(close_file);
main_bar -> addAction(print); main_bar -> addAction(print);
main_bar -> addSeparator(); main_bar -> addSeparator();
@ -561,45 +562,45 @@ void QETDiagramEditor::exportDialog() {
Methode enregistrant le schema dans le dernier nom de fichier connu. Methode enregistrant le schema dans le dernier nom de fichier connu.
@return true si l'enregistrement a reussi, false sinon @return true si l'enregistrement a reussi, false sinon
*/ */
bool QETDiagramEditor::save() { void QETDiagramEditor::save() {
if (ProjectView *project_view = currentProject()) { if (ProjectView *project_view = currentProject()) {
bool save_file = project_view -> save(); QETResult save_file = project_view -> save();
if (save_file) { if (save_file.isOk()) {
QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath()); QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath());
} else {
showError(save_file);
} }
return(save_file);
} }
return(false);
} }
/** /**
Cette methode demande un nom de fichier a l'utilisateur pour enregistrer le schema Cette methode demande un nom de fichier a l'utilisateur pour enregistrer le schema
@return true si l'enregistrement a reussi, false sinon @return true si l'enregistrement a reussi, false sinon
*/ */
bool QETDiagramEditor::saveAsDialog() { void QETDiagramEditor::saveAs() {
if (ProjectView *project_view = currentProject()) { if (ProjectView *project_view = currentProject()) {
bool save_file = project_view -> saveAs(); QETResult save_file = project_view -> saveAs();
if (save_file) { if (save_file.isOk()) {
QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath()); QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath());
} else {
showError(save_file);
} }
return(save_file);
} }
return(false);
} }
/** /**
Methode enregistrant tous les schemas. Methode enregistrant tous les schemas.
@return true si l'enregistrement a reussi, false sinon @return true si l'enregistrement a reussi, false sinon
*/ */
bool QETDiagramEditor::saveAll() { void QETDiagramEditor::saveCurrentDiagram() {
if (ProjectView *project_view = currentProject()) { if (ProjectView *project_view = currentProject()) {
bool save_file = project_view -> saveAll(); QETResult save_file = project_view -> saveCurrentDiagram();
if (save_file) { if (save_file.isOk()) {
QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath()); QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath());
} else {
showError(save_file);
} }
return(save_file);
} }
return(false);
} }
/** /**
@ -1044,8 +1045,8 @@ void QETDiagramEditor::slot_updateActions() {
// actions ayant juste besoin d'un document ouvert // actions ayant juste besoin d'un document ouvert
close_file -> setEnabled(opened_project); close_file -> setEnabled(opened_project);
save_file -> setEnabled(editable_project); save_file -> setEnabled(editable_project);
save_file_sous -> setEnabled(opened_project); save_file_as -> setEnabled(opened_project);
save_all -> setEnabled(editable_diagram); save_cur_diagram -> setEnabled(editable_diagram);
prj_edit_prop -> setEnabled(opened_project); prj_edit_prop -> setEnabled(opened_project);
prj_add_diagram -> setEnabled(editable_project); prj_add_diagram -> setEnabled(editable_project);
prj_del_diagram -> setEnabled(editable_project); prj_del_diagram -> setEnabled(editable_project);
@ -1197,6 +1198,9 @@ void QETDiagramEditor::addProjectView(ProjectView *project_view) {
QETApp::instance(), SLOT(openTitleBlockTemplate(TitleBlockTemplateLocation, bool)) QETApp::instance(), SLOT(openTitleBlockTemplate(TitleBlockTemplateLocation, bool))
); );
// display error messages sent by the project view
connect(project_view, SIGNAL(errorEncountered(QString)), this, SLOT(showError(const QString &)));
// affiche la fenetre // affiche la fenetre
if (maximise) project_view -> showMaximized(); if (maximise) project_view -> showMaximized();
else project_view -> show(); else project_view -> show();
@ -1686,6 +1690,22 @@ void QETDiagramEditor::editElementInEditor(const ElementsLocation &location) {
QETApp::instance() -> openElementLocations(QList<ElementsLocation>() << location); QETApp::instance() -> openElementLocations(QList<ElementsLocation>() << location);
} }
/**
Show the error message contained in \a result.
*/
void QETDiagramEditor::showError(const QETResult &result) {
if (result.isOk()) return;
showError(result.errorMessage());
}
/**
Show the \a error message.
*/
void QETDiagramEditor::showError(const QString &error) {
if (error.isEmpty()) return;
QET::MessageBox::critical(this, tr("Erreur", "message box title"), error);
}
/** /**
@return Les proprietes par defaut pour le cartouche d'un schema @return Les proprietes par defaut pour le cartouche d'un schema
*/ */

View File

@ -24,6 +24,7 @@
#include "titleblockproperties.h" #include "titleblockproperties.h"
#include "exportproperties.h" #include "exportproperties.h"
class QETProject; class QETProject;
class QETResult;
class ProjectView; class ProjectView;
class Diagram; class Diagram;
class DiagramView; class DiagramView;
@ -83,9 +84,9 @@ class QETDiagramEditor : public QETMainWindow {
public slots: public slots:
void printDialog(); void printDialog();
void exportDialog(); void exportDialog();
bool saveAsDialog(); void save();
bool save(); void saveAs();
bool saveAll(); void saveCurrentDiagram();
bool newProject(); bool newProject();
bool openProject(); bool openProject();
bool openRecentFile(const QString &); bool openRecentFile(const QString &);
@ -147,6 +148,8 @@ class QETDiagramEditor : public QETMainWindow {
void diagramWasRemoved(DiagramView *); void diagramWasRemoved(DiagramView *);
void findElementInPanel(const ElementsLocation &); void findElementInPanel(const ElementsLocation &);
void editElementInEditor(const ElementsLocation &); void editElementInEditor(const ElementsLocation &);
void showError(const QETResult &);
void showError(const QString &);
// attributs // attributs
public: public:
@ -160,9 +163,9 @@ class QETDiagramEditor : public QETMainWindow {
QAction *new_file; ///< Cree un nouveau schema QAction *new_file; ///< Cree un nouveau schema
QAction *open_file; ///< OUvre un fichier QAction *open_file; ///< OUvre un fichier
QAction *close_file; ///< Ferme le fichier QAction *close_file; ///< Ferme le fichier
QAction *save_file; ///< Enregistre le fichier QAction *save_file; ///< Save current project
QAction *save_file_sous; ///< Enregistrer le fichier sous un nom donne QAction *save_file_as; ///< Save current project as a specific file
QAction *save_all; ///< Enregistre tous les schemas QAction *save_cur_diagram; ///< Save current diagram of the current project only
QAction *import_diagram; ///< Importe un schema existant (non implemente) QAction *import_diagram; ///< Importe un schema existant (non implemente)
QAction *export_diagram; ///< Exporte le schema sous forme d'image QAction *export_diagram; ///< Exporte le schema sous forme d'image
QAction *print; ///< Imprime le schema QAction *print; ///< Imprime le schema

View File

@ -22,6 +22,7 @@
#include "elementscategory.h" #include "elementscategory.h"
#include "qetapp.h" #include "qetapp.h"
#include "qetdiagrameditor.h" #include "qetdiagrameditor.h"
#include "qetresult.h"
#include "integrationmoveelementshandler.h" #include "integrationmoveelementshandler.h"
#include "movetemplateshandler.h" #include "movetemplateshandler.h"
#include "basicmoveelementshandler.h" #include "basicmoveelementshandler.h"
@ -468,17 +469,15 @@ bool QETProject::close() {
@see setFilePath() @see setFilePath()
@return true si l'enregistrement a reussi, false sinon @return true si l'enregistrement a reussi, false sinon
*/ */
bool QETProject::write() { QETResult QETProject::write() {
// le chemin du fichier doit etre connu // this operation requires a filepath
if (file_path_.isEmpty()) { if (file_path_.isEmpty()) {
qDebug() << qPrintable(QString("QETProject::write() : called without a known filepath [%1]").arg(QET::pointerString(this))); return(QString("unable to save project to file: no filepath was specified"));
return(false);
} }
// si le projet a ete ouvert en mode lecture seule et que le fichier n'est pas accessible en ecriture, on n'effectue pas l'enregistrement // if the project was opened read-only and the file is still non-writable, do not save the project
if (isReadOnly() && !QFileInfo(file_path_).isWritable()) { if (isReadOnly() && !QFileInfo(file_path_).isWritable()) {
qDebug() << qPrintable(QString("QETProject::write() : the file %1 was opened read-only and thus will not be written. [%2]").arg(file_path_).arg(QET::pointerString(this))); return(QString("the file %1 was opened read-only and thus will not be written").arg(file_path_));
return(true);
} }
// realise l'export en XML du projet dans le document XML interne // realise l'export en XML du projet dans le document XML interne
@ -488,11 +487,11 @@ bool QETProject::write() {
QString error_message; QString error_message;
bool writing = QET::writeXmlFile(document_root_, file_path_, &error_message); bool writing = QET::writeXmlFile(document_root_, file_path_, &error_message);
if (!writing) { if (!writing) {
qDebug() << qPrintable(QString("QETProject::write() : %1 [%2]").arg(error_message).arg(QET::pointerString(this))); return(error_message);
} else {
setModified(false);
} }
return(writing);
setModified(false);
return(QETResult());
} }
/** /**
@ -1180,6 +1179,10 @@ bool QETProject::embeddedCollectionWasModified() {
return(true); return(true);
} }
// the integration category must be empty
if (integ_cat -> categories().count()) return(true);
if (integ_cat -> elements().count()) return(true);
return(false); return(false);
} }
@ -1205,7 +1208,7 @@ bool QETProject::diagramsWereModified() {
if (diagrams_.count() != 1) return(true); if (diagrams_.count() != 1) return(true);
// dont la pile d'annulation est "clean" // dont la pile d'annulation est "clean"
return(!(diagrams_[0] -> undoStack().isClean())); return(!(diagrams_[0] -> undoStack().isClean() && !diagrams_[0] -> wasWritten()));
} }
/** /**

View File

@ -30,6 +30,7 @@ class ElementsCollection;
class ElementsCategory; class ElementsCategory;
class ElementDefinition; class ElementDefinition;
class ElementsLocation; class ElementsLocation;
class QETResult;
class TitleBlockTemplate; class TitleBlockTemplate;
class XmlElementsCollection; class XmlElementsCollection;
class MoveElementsHandler; class MoveElementsHandler;
@ -98,7 +99,7 @@ class QETProject : public QObject {
void setDefaultConductorProperties(const ConductorProperties &); void setDefaultConductorProperties(const ConductorProperties &);
QDomDocument toXml(); QDomDocument toXml();
bool close(); bool close();
bool write(); QETResult write();
bool isReadOnly() const; bool isReadOnly() const;
void setReadOnly(bool); void setReadOnly(bool);
bool isEmpty() const; bool isEmpty() const;

70
sources/qetresult.cpp Normal file
View File

@ -0,0 +1,70 @@
/*
Copyright 2006-2012 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "qetresult.h"
/**
Construct a default "true" QET result without an error message.
*/
QETResult::QETResult() :
result_(true)
{
}
/**
Construct a QET result embedding \a error_message and \a result (defaults
to false).
*/
QETResult::QETResult(const QString &error_message, bool result) :
result_(result),
error_message_(error_message)
{
}
/**
Destructor
*/
QETResult::~QETResult() {
}
/**
@return the boolean value embedded within this result.
*/
bool QETResult::isOk() const {
return(result_);
}
/**
Embed \a result.
*/
void QETResult::setResult(bool result) {
result_ = result;
}
/**
@return the error message embedded within this result.
*/
QString QETResult::errorMessage() const {
return(error_message_);
}
/**
Embed \a error_message wihthin this result.
*/
void QETResult::setErrorMessage(const QString &error_message) {
error_message_ = error_message;
}

46
sources/qetresult.h Normal file
View File

@ -0,0 +1,46 @@
/*
Copyright 2006-2012 Xavier Guerrin
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QET_RESULT_H
#define QET_RESULT_H
#include <QString>
/**
This class represents the result of a lambda operation. Technically, it is
a mere boolean+error message pair.
*/
class QETResult {
// Constructor, destructor
public:
QETResult();
QETResult(const QString &error_message, bool = false);
virtual ~QETResult();
// methods
public:
bool isOk() const;
void setResult(bool);
QString errorMessage() const;
void setErrorMessage(const QString &);
// attributes
private:
bool result_; ///< Embedded boolean value
QString error_message_; ///< Embedded error message, typically used to explain what failed to users
};
#endif