From 4a038a8bf07fb65ab5b5be2a8f8f3632366beeb0 Mon Sep 17 00:00:00 2001 From: blacksun Date: Thu, 4 Apr 2013 16:57:15 +0000 Subject: [PATCH] add class for auto numerotation (for the time, only same potential) git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@2087 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- sources/conductor.cpp | 57 ++++++++ sources/conductor.h | 4 + sources/conductorautonumerotation.cpp | 104 ++++++++++++++ sources/conductorautonumerotation.h | 49 +++++++ sources/conductorautonumerotationwidget.cpp | 144 ++++++++++++++++++++ sources/conductorautonumerotationwidget.h | 38 ++++++ sources/diagramcommands.cpp | 59 ++++++++ sources/diagramcommands.h | 32 +++++ sources/terminal.cpp | 1 + 9 files changed, 488 insertions(+) create mode 100644 sources/conductorautonumerotation.cpp create mode 100644 sources/conductorautonumerotation.h create mode 100644 sources/conductorautonumerotationwidget.cpp create mode 100644 sources/conductorautonumerotationwidget.h diff --git a/sources/conductor.cpp b/sources/conductor.cpp index 5d0bfea4a..d0a143f58 100644 --- a/sources/conductor.cpp +++ b/sources/conductor.cpp @@ -23,6 +23,7 @@ #include "element.h" #include "diagram.h" #include "diagramcommands.h" +#include "conductorautonumerotation.h" #define PR(x) qDebug() << #x " = " << x; bool Conductor::pen_and_brush_initialized = false; @@ -1247,6 +1248,15 @@ void Conductor::setHighlighted(Conductor::Highlight hl) { update(); } +/** + * @brief Conductor::autoText + *lance l'autoNumerotation sur ce conducteur + */ +void Conductor::autoText() { + ConductorAutoNumerotation can(this); + can.numerate(); +} + /** Met a jour les proprietes du conducteur apres modification du champ de texte affiche */ @@ -1278,6 +1288,53 @@ QSet Conductor::relatedConductors() const { return(other_conductors); } +/** + * @param t_list terminaux a ne pas inclure dans la recherche + * @return les conducteurs avec lesquels ce conducteur partage + * le meme potentiel electrique a l'exception de lui même + */ +QSet Conductor::relatedPotentialConductors(QList *t_list) { + if (t_list == 0) + t_list = new QList ; + + QSet other_conductors; + //renvoie tous les conducteurs du terminal 1 + if (t_list->contains(terminal1) == false) { + t_list->append(terminal1); + QList other_conductors_list_t1 = terminal1 -> conductors(); + other_conductors_list_t1.removeAll(this); + //recherche les conducteurs connecté au conducteur déjà trouvé + foreach (Conductor *c, other_conductors_list_t1) { + other_conductors += c -> relatedPotentialConductors(t_list); + } + other_conductors += other_conductors_list_t1.toSet(); + } + //renvoie tous les conducteurs du terminal 2 + if (t_list->contains(terminal2) == false) { + t_list->append(terminal2); + QList other_conductors_list_t2 = terminal2 -> conductors(); + other_conductors_list_t2.removeAll(this); + //recherche les conducteurs connecté au conducteur déjà trouvé + foreach (Conductor *c, other_conductors_list_t2) { + other_conductors += c -> relatedPotentialConductors(t_list); + } + other_conductors += other_conductors_list_t2.toSet(); + } + other_conductors.remove(const_cast(this)); + return(other_conductors); +} + +/** + * @return l'editeur de schemas parent ou 0 + */ +QETDiagramEditor* Conductor::diagramEditor() const { + QWidget *w = const_cast(diagram() -> views().at(0)); + while (w -> parentWidget() && !w -> isWindow()) { + w = w -> parentWidget(); + } + return(qobject_cast(w)); +} + /** @param a reel @param b reel diff --git a/sources/conductor.h b/sources/conductor.h index 47f10de3f..cbd645a6a 100644 --- a/sources/conductor.h +++ b/sources/conductor.h @@ -21,6 +21,7 @@ #include "terminal.h" #include "conductorprofile.h" #include "conductorproperties.h" +#include "qetdiagrameditor.h" class ConductorSegment; class ConductorTextItem; class Element; @@ -92,6 +93,9 @@ class Conductor : public QObject, public QGraphicsPathItem { void adjustTextItemPosition(); virtual Highlight highlight() const; virtual void setHighlighted(Highlight); + void autoText(); + QSet relatedPotentialConductors(QList *t_list=0); + QETDiagramEditor* diagramEditor() const; public slots: void displayedTextChanged(); diff --git a/sources/conductorautonumerotation.cpp b/sources/conductorautonumerotation.cpp new file mode 100644 index 000000000..5071b7aab --- /dev/null +++ b/sources/conductorautonumerotation.cpp @@ -0,0 +1,104 @@ +#include +#include "conductorautonumerotation.h" +#include "conductorautonumerotationwidget.h" +#include "diagram.h" +#include "qetdiagrameditor.h" +#include "QGraphicsView" + +/** + * Constructor + */ +ConductorAutoNumerotation::ConductorAutoNumerotation() : +conductor_ (0), +diagram_ (0), +strategy_(0) +{} + +/** + *Constructor + * @param c le conducteur a appliquer une numerotation + */ +ConductorAutoNumerotation::ConductorAutoNumerotation(Conductor *c) : + conductor_ (c), + diagram_ (c -> diagram()), + strategy_(0), + conductor_list(c -> relatedPotentialConductors()) +{} + +/** + *destructor + */ +ConductorAutoNumerotation::~ConductorAutoNumerotation() { + delete strategy_; +} + +/** + * @param c le conducteur a appliquer une numerotation + */ +void ConductorAutoNumerotation::setConductor(Conductor *c) { + conductor_ = c; + diagram_ = c -> diagram(); + strategy_ = 0; + conductor_list = c -> relatedPotentialConductors(); +} + +/** + * @brief ConductorAutoNumerotation::numerate + *execute la numerotation automatique du conducteur + */ +void ConductorAutoNumerotation::numerate() { + if (conductor_ == 0) return; + //ce conducteur est sur un potentiel existant + if (conductor_list.size() >= 1) { + setNumStrategy(new SamePotential); + strategy_ -> createNumerotation(conductor_, diagram_); + } + //ce conducteur est le premier d'un nouveau potentiel + else if (conductor_list.size() == 0) { + } +} + +/** + * @brief ConductorAutoNumerotation::setNumStrategy + *applique la strategy adéquate à la situation + * @param strategy la class de la strategy à appliquer + */ +void ConductorAutoNumerotation::setNumStrategy(NumStrategy *strategy) { + if (strategy_ != 0) + delete strategy_; + strategy_ = strategy; +} + +NumStrategy::NumStrategy () {} +NumStrategy::~NumStrategy() {} + +/** + * @brief SamePotential::createNumerotation + *crée la numerotation pour le conducteur @c connecté sur un potentiel deja existant + */ +void SamePotential::createNumerotation(Conductor *c, Diagram *d) { + QSet cl; + QStringList strl; + + cl = c -> relatedPotentialConductors(); + foreach (const Conductor *cc, cl) strl<<(cc->text()); + //tout les textes sont identique + if (eachIsEqual(strl)) { + ConductorProperties cp; + cp.text = strl.at(0); + c -> setProperties(cp); + c -> setText(strl.at(0)); + } + //les textes ne sont pas identique + else { + ConductorAutoNumerotationWidget canw (c, cl, c -> diagramEditor()); + canw.exec(); + } +} + +bool eachIsEqual (const QStringList &qsl) { + foreach (const QString t, qsl) { + if (qsl.at(0) != t) return false; + } + return true; +} diff --git a/sources/conductorautonumerotation.h b/sources/conductorautonumerotation.h new file mode 100644 index 000000000..d5c1ea3cc --- /dev/null +++ b/sources/conductorautonumerotation.h @@ -0,0 +1,49 @@ +#ifndef CONDUCTORAUTONUMEROTATION_H +#define CONDUCTORAUTONUMEROTATION_H + +#include + +class NumStrategy; + +class ConductorAutoNumerotation +{ + public: + //constructors & destructor + ConductorAutoNumerotation (); + ConductorAutoNumerotation(Conductor *); + ~ConductorAutoNumerotation(); + + //methods + void setConductor(Conductor *); + void numerate(); + + protected: + //methods + void setNumStrategy (NumStrategy *); + + //attributes + Conductor *conductor_; + Diagram *diagram_; + QSet conductor_list; + NumStrategy *strategy_; +}; + + +class NumStrategy +{ + public: + NumStrategy (); + virtual ~NumStrategy (); + virtual void createNumerotation(Conductor *, Diagram *) = 0; //cree la numerotation en fonction de la strategie utilisé + +}; + + +class SamePotential: public NumStrategy +{ + virtual void createNumerotation(Conductor *, Diagram *); +}; + +bool eachIsEqual (const QStringList &); + +#endif // CONDUCTORAUTONUMEROTATION_H diff --git a/sources/conductorautonumerotationwidget.cpp b/sources/conductorautonumerotationwidget.cpp new file mode 100644 index 000000000..4db05a51e --- /dev/null +++ b/sources/conductorautonumerotationwidget.cpp @@ -0,0 +1,144 @@ +#include "conductorautonumerotationwidget.h" +#include "conductorproperties.h" +#include "diagramcommands.h" +#include "diagram.h" + +ConductorAutoNumerotationWidget::ConductorAutoNumerotationWidget(Conductor *c, QSet cl, QWidget *parent) : + conductor_(c), + c_list(cl), + QDialog (parent) +{ +#ifdef Q_WS_MAC + setWindowFlags(Qt::Sheet); +#endif + buildInterface(); +} + +void ConductorAutoNumerotationWidget::buildInterface() { + QVBoxLayout *mainlayout = new QVBoxLayout; + QGroupBox *potential_groupbox = new QGroupBox(tr("Textes de potentiel"), this); + QVBoxLayout *vlayout = new QVBoxLayout; + + QLabel *label= new QLabel(tr("Les textes de ce potentiel \351lectrique ne sont pas identiques.\n" + "Appliquer un texte \340 l'ensemble de ces conducteurs?"), this); + vlayout -> addWidget(label); + + //map the signal for each radio button create in buildRadioList + sm_ = new QSignalMapper(this); + connect(sm_, SIGNAL(mapped(QString)), this, SLOT(setText(QString))); + vlayout -> addLayout(buildRadioList()); + + potential_groupbox -> setLayout(vlayout); + mainlayout -> addWidget(potential_groupbox); + + QDialogButtonBox *dbb = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Yes, Qt::Horizontal, this); + connect(dbb, SIGNAL(rejected()), + this, SLOT(reject())); + connect(dbb, SIGNAL(accepted()), + this, SLOT(accept())); + + mainlayout->addWidget(dbb); + setLayout(mainlayout); +} + +/** + * @brief ConductorAutoNumerotationWidget::buildRadioList + *construit toute la partie de l'interface contenant les boutons radio permetant le choix du texte a appliquer + * @return un layout contenant les boutons radio + */ +QVBoxLayout* ConductorAutoNumerotationWidget::buildRadioList() { + QVBoxLayout *radioLayout = new QVBoxLayout; + QHBoxLayout *otherLayout = new QHBoxLayout; + + //create a new radio button for each text of @conductorList + QMultiMap conductorlist = conductorsTextToMap(c_list); + for (QMultiMap::ConstIterator it = conductorlist.constEnd()-1; it != conductorlist.constBegin()-1; --it) { + QRadioButton *rb= new QRadioButton(it.value() + tr(" : est pr\351sent ") + QString::number(it.key()) + tr(" fois."), this); + if (it == conductorlist.constEnd()-1) { + rb -> setChecked(true); + text_ = it.value(); + } + //connect the button to mapper @sm_ + connect(rb, SIGNAL(clicked()), + sm_, SLOT(map())); + sm_ -> setMapping(rb, it.value()); + radioLayout -> addWidget(rb); + } + + //create the "other" radio button and is text field + QRadioButton *other= new QRadioButton(tr("Autre"), this); + text_field = new QLineEdit(this); + text_field -> setEnabled(false); + connect(other, SIGNAL(toggled(bool)), text_field, SLOT(setEnabled(bool))); + otherLayout -> addWidget(other); + otherLayout -> addWidget(text_field); + radioLayout -> addLayout(otherLayout); + return radioLayout; +} + +/** + * @param csl liste des conducteurs a analyser + * @return QMultiMap avec le nombre de conducteurs possedant le même texte en clee et le texte en question comme valeur + */ +QMultiMap ConductorAutoNumerotationWidget::conductorsTextToMap(QSet csl) { + QStringList textList; + foreach(Conductor *c, csl) textList << c -> text(); + + QMultiMap conductorlist; + while (!textList.size() == 0) { + QString t = textList.at(0); + int n = textList.count(t); + textList.removeAll(t); + conductorlist.insert(n, t); + } + return conductorlist; +} + +/** + * @brief ConductorAutoNumerotationWidget::applyText + *applique le texte selectionne @text_ a tout les conducteur de @c_list et a @conducteur_ + */ +void ConductorAutoNumerotationWidget::applyText() { + QList old_properties, new_properties; + ConductorProperties cp; + foreach (Conductor *c, c_list) { + old_properties << c -> properties(); + cp = c -> properties(); + cp.text = text_; + c -> setProperties(cp); + new_properties << c -> properties(); + c -> setText(text_); + } + // initialise l'objet UndoCommand correspondant + ChangeSeveralConductorsPropertiesCommand *cscpc = new ChangeSeveralConductorsPropertiesCommand(c_list); + cscpc -> setOldSettings(old_properties); + cscpc -> setNewSettings(new_properties); + conductor_ -> diagram() -> undoStack().push(cscpc); + + cp = conductor_ -> properties(); + cp.text = text_; + conductor_ -> setProperties(cp); + conductor_ -> setText(text_); +} + +/** + * @brief ConductorAutoNumerotationWidget::setText + * enregistre le texte @t passé en parametre + */ +void ConductorAutoNumerotationWidget::setText(QString t) { + text_ = t; +} + +/** + * @brief ConductorAutoNumerotationWidget::accept + *action executé lors de l'appuis sur le bouton 'oui' + */ +void ConductorAutoNumerotationWidget::accept() { + if (text_field -> isEnabled()) { + text_ = text_field -> text(); + applyText(); + } + else + applyText(); + close(); +} diff --git a/sources/conductorautonumerotationwidget.h b/sources/conductorautonumerotationwidget.h new file mode 100644 index 000000000..6c7f03d74 --- /dev/null +++ b/sources/conductorautonumerotationwidget.h @@ -0,0 +1,38 @@ +#ifndef CONDUCTORAUTONUMEROTATIONWIDGET_H +#define CONDUCTORAUTONUMEROTATIONWIDGET_H + +#include +#include +#include +#include +#include +#include "conductor.h" + +class ConductorAutoNumerotationWidget : public QDialog +{ + Q_OBJECT + public: + explicit ConductorAutoNumerotationWidget(Conductor *, QSet , QWidget *parent = 0); + QMultiMap conductorsTextToMap (QSet ); + + public slots: + void setText (QString); + void accept(); + + private: + //methods + void buildInterface(); + QVBoxLayout* buildRadioList(); + void applyText(); + + //attributes + QSet c_list; //liste des conducteurs au même potentiel + Conductor *conductor_; + QList *radio_List; + QLineEdit *text_field; + QString text_; + QSignalMapper *sm_; + +}; + +#endif // CONDUCTORAUTONUMEROTATIONWIDGET_H diff --git a/sources/diagramcommands.cpp b/sources/diagramcommands.cpp index e8d8df4df..4612c4d98 100644 --- a/sources/diagramcommands.cpp +++ b/sources/diagramcommands.cpp @@ -936,3 +936,62 @@ void ChangeConductorPropertiesCommand::redo() { conductor -> update(); } } + +/** + Constructeur + @param c La liste des conducteurs dont on modifie les proprietes + @param parent QUndoCommand parent +*/ +ChangeSeveralConductorsPropertiesCommand::ChangeSeveralConductorsPropertiesCommand(QSetc, QUndoCommand *parent) : + QUndoCommand(QObject::tr("modifier les propri\351t\351s de plusieurs conducteurs", "undo caption"), parent), + conductors(c), + old_settings_set(false), + new_settings_set(false) +{ +} + +/// Destructeur +ChangeSeveralConductorsPropertiesCommand::~ChangeSeveralConductorsPropertiesCommand() { +} + +/// definit l'ancienne configuration +void ChangeSeveralConductorsPropertiesCommand::setOldSettings(const QList &properties) { + old_properties = properties; + old_settings_set = true; +} + +/// definit la nouvelle configuration +void ChangeSeveralConductorsPropertiesCommand::setNewSettings(const QList &properties) { + new_properties = properties; + new_settings_set = true; +} + +/** + Annule les changements - Attention : les anciens et nouveaux parametres + doivent avoir ete definis a l'aide de setNewSettings et setOldSettings +*/ +void ChangeSeveralConductorsPropertiesCommand::undo() { + if (old_settings_set && new_settings_set) { + int i=0; + foreach(Conductor *c, conductors) { + c -> setProperties(old_properties.at(i)); + c -> update(); + i++; + } + } +} + +/** + Refait les changements - Attention : les anciens et nouveaux parametres + doivent avoir ete definis a l'aide de setNewSettings et setOldSettings +*/ +void ChangeSeveralConductorsPropertiesCommand::redo() { + if (old_settings_set && new_settings_set) { + int i=0; + foreach(Conductor *c, conductors) { + c -> setProperties(new_properties.at(0)); + c -> update(); + i++; + } + } +} diff --git a/sources/diagramcommands.h b/sources/diagramcommands.h index 9f7a45907..2e2f6fd0e 100644 --- a/sources/diagramcommands.h +++ b/sources/diagramcommands.h @@ -495,4 +495,36 @@ class ChangeConductorPropertiesCommand : public QUndoCommand { /// track whether post-change properties were set bool new_settings_set; }; + +/** + This command changes the properties for several conductors. +*/ +class ChangeSeveralConductorsPropertiesCommand : public QUndoCommand { + // constructors, destructor + public: + ChangeSeveralConductorsPropertiesCommand(QSet, QUndoCommand * = 0); + virtual ~ChangeSeveralConductorsPropertiesCommand(); + private: + ChangeSeveralConductorsPropertiesCommand(const ChangeSeveralConductorsPropertiesCommand &); + + // methods + public: + virtual void undo(); + virtual void redo(); + virtual void setOldSettings(const QList &); + virtual void setNewSettings(const QList &); + + // attributes + private: + /// modified conductor + QSet conductors; + /// properties before the change + QList old_properties; + /// properties after the change + QList new_properties; + /// track whether pre-change properties were set + bool old_settings_set; + /// track whether post-change properties were set + bool new_settings_set; +}; #endif diff --git a/sources/terminal.cpp b/sources/terminal.cpp index f5e36ac85..e442b0675 100644 --- a/sources/terminal.cpp +++ b/sources/terminal.cpp @@ -368,6 +368,7 @@ void Terminal::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { Conductor *new_conductor = new Conductor(this, other_terminal); new_conductor -> setProperties(d -> defaultConductorProperties); d -> undoStack().push(new AddConductorCommand(d, new_conductor)); + new_conductor -> autoText(); } }