Ajout de l'editeur d'elements

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@94 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet
2007-06-30 17:41:07 +00:00
parent 0472392977
commit 75ca8fd3f2
79 changed files with 3867 additions and 345 deletions

56
editor/circleeditor.cpp Normal file
View File

@@ -0,0 +1,56 @@
#include "circleeditor.h"
#include "partcircle.h"
CircleEditor::CircleEditor(PartCircle *circle, QWidget *parent) : QWidget(parent) {
part = circle;
x = new QLineEdit();
y = new QLineEdit();
r = new QLineEdit();
// QDoubleValidator *format = new QDoubleValidator(-1000.0, -1000.0, 4, this);
// x -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
// y -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
// h -> setValidator(new QDoubleValidator(0.0, 1000.0, 4, this));
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
grid -> addWidget(new QLabel(tr("Diam\350tre : ")), 2, 0);
grid -> addWidget(r, 2, 1);
updateForm();
connect(x, SIGNAL(editingFinished()), this, SLOT(updateCircle()));
connect(y, SIGNAL(editingFinished()), this, SLOT(updateCircle()));
connect(r, SIGNAL(editingFinished()), this, SLOT(updateCircle()));
}
CircleEditor::~CircleEditor() {
qDebug() << "~CircleEditor()";
}
void CircleEditor::updateCircle() {
qreal _x = x -> text().toDouble();
qreal _y = y -> text().toDouble();
qreal _d = r -> text().toDouble();
part -> setRect(
QRectF(
part -> mapFromScene(QPointF(_x - _d / 2.0, _y - _d / 2.0)),
QSizeF(_d, _d)
)
);
}
void CircleEditor::updateForm() {
qreal _d = part -> rect().width();
QPointF top_left(part -> sceneTopLeft());
x -> setText(QString("%1").arg(top_left.x() + _d / 2.0));
y -> setText(QString("%1").arg(top_left.y() + _d / 2.0));
r -> setText(QString("%1").arg(_d));
}

29
editor/circleeditor.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef CIRCLE_EDITOR_H
#define CIRCLE_EDITOR_H
#include <QtGui>
class PartCircle;
/**
Cette classe represente un editeur de cercle.
Elle permet d'editer a travers une interface graphique les
proprietes d'une cercle composant le dessin d'un element.
*/
class CircleEditor : public QWidget {
Q_OBJECT
// Constructeurs, destructeur
public:
CircleEditor(PartCircle *, QWidget * = 0);
virtual ~CircleEditor();
private:
CircleEditor(const CircleEditor &);
// attributs
private:
PartCircle *part;
QLineEdit *x, *y, *r;
// methodes
public slots:
void updateCircle();
void updateForm();
};
#endif

View File

@@ -0,0 +1,447 @@
#include "customelementeditor.h"
#include "editorscene.h"
#include "customelementpart.h"
#include "newelementwizard.h"
#include "qetapp.h"
CustomElementEditor::CustomElementEditor(QWidget *parent) :
QMainWindow(parent),
read_only(false),
min_title(tr("QElectroTech - \311diteur d'\351l\351ment")),
_filename(QString())
{
setMinimumWidth(700);
setMinimumHeight(450);
setWindowTitle(min_title);
setWindowIcon(QIcon(":/ico/qet.png"));
setupInterface();
setupActions();
setupMenus();
}
CustomElementEditor::~CustomElementEditor() {
qDebug() << "~CustomElementEditor()";
// recupere le layout
// QLayout *layout = tools_dock -> widget() -> layout();
//
// // enleve les widgets deja presents
// QLayoutItem *qli;
// while ((qli = layout -> takeAt(0)) != 0) {
// if (qli -> widget()) {
// layout -> removeWidget(qli -> widget());
// qli -> widget() -> setParent(0);
// }
// }
}
void CustomElementEditor::setupActions() {
new_element = new QAction(QIcon(":/ico/new.png"), tr("&Nouveau"), this);
open = new QAction(QIcon(":/ico/open.png"), tr("&Ouvrir"), this);
save = new QAction(QIcon(":/ico/save.png"), tr("&Enregistrer"), this);
save_as = new QAction(QIcon(":/ico/saveas.png"), tr("Enregistrer sous"), this);
quit = new QAction(QIcon(":/ico/exit.png"), tr("&Quitter"), this);
selectall = new QAction( tr("Tout s\351lectionner"), this);
deselectall = new QAction( tr("D\351s\351lectionner tout"), this);
inv_select = new QAction( tr("Inverser la s\351lection"), this);
edit_delete = new QAction(QIcon(":/ico/delete.png"), tr("&Supprimer"), this);
edit_size = new QAction( tr("Modifier la taille"), this);
edit_hotspot = new QAction( tr("Modifier le point de saisie"), this);
edit_names = new QAction( tr("\311diter les noms"), this);
edit_ori = new QAction(QIcon(":/ico/orientations.png"), tr("\311diter les orientations"), this);
move = new QAction(QIcon(":/ico/select.png"), tr("D\351placer un objet"), this);
add_line = new QAction(QIcon(":/ico/line.png"), tr("Ajouter une ligne"), this);
add_ellipse = new QAction(QIcon(":/ico/ellipse.png"), tr("Ajouter une ellipse"), this);
add_circle = new QAction(QIcon(":/ico/circle.png"), tr("Ajouter un cercle"), this);
add_polygon = new QAction(QIcon(":/ico/polygon.png"), tr("Ajouter un polygone"), this);
add_text = new QAction(QIcon(":/ico/text.png"), tr("Ajouter du texte"), this);
add_arc = new QAction(QIcon(":/ico/arc.png"), tr("Ajouter un arc de cercle"), this);
add_terminal = new QAction(QIcon(":/ico/terminal.png"), tr("Ajouter une borne"), this);
add_textfield = new QAction(QIcon(":/ico/textfield.png"), tr("Ajouter un champ de texte"), this);
edit_delete -> setEnabled(false);
edit_size -> setEnabled(false);
edit_hotspot -> setEnabled(false);
selectall -> setShortcut(QKeySequence::SelectAll);
deselectall -> setShortcut(QKeySequence(tr("Ctrl+Shift+A")));
inv_select -> setShortcut(QKeySequence(tr("Ctrl+I")));
edit_delete -> setShortcut(QKeySequence(tr("Ctrl+Suppr")));
connect(new_element, SIGNAL(triggered()), this, SLOT(slot_new()));
connect(open, SIGNAL(triggered()), this, SLOT(slot_open()));
connect(save, SIGNAL(triggered()), this, SLOT(slot_save()));
connect(save_as, SIGNAL(triggered()), this, SLOT(slot_saveAs()));
connect(quit, SIGNAL(triggered()), this, SLOT(slot_quit()));
connect(selectall, SIGNAL(triggered()), ce_scene, SLOT(slot_selectAll()));
connect(deselectall, SIGNAL(triggered()), ce_scene, SLOT(slot_deselectAll()));
connect(inv_select, SIGNAL(triggered()), ce_scene, SLOT(slot_invertSelection()));
connect(edit_delete, SIGNAL(triggered()), ce_scene, SLOT(slot_delete()));
connect(edit_size, SIGNAL(triggered()), ce_scene, SLOT(slot_editSize()));
connect(edit_hotspot, SIGNAL(triggered()), ce_scene, SLOT(slot_editHotSpot()));
connect(edit_names, SIGNAL(triggered()), ce_scene, SLOT(slot_editNames()));
connect(edit_ori, SIGNAL(triggered()), ce_scene, SLOT(slot_editOrientations()));
connect(move, SIGNAL(triggered()), ce_scene, SLOT(slot_move()));
connect(add_line, SIGNAL(triggered()), ce_scene, SLOT(slot_addLine()));
connect(add_ellipse, SIGNAL(triggered()), ce_scene, SLOT(slot_addEllipse()));
connect(add_circle, SIGNAL(triggered()), ce_scene, SLOT(slot_addCircle()));
connect(add_polygon, SIGNAL(triggered()), ce_scene, SLOT(slot_addPolygon()));
connect(add_text, SIGNAL(triggered()), ce_scene, SLOT(slot_addText()));
connect(add_arc, SIGNAL(triggered()), ce_scene, SLOT(slot_addArc()));
connect(add_terminal, SIGNAL(triggered()), ce_scene, SLOT(slot_addTerminal()));
connect(add_textfield, SIGNAL(triggered()), ce_scene, SLOT(slot_addTextField()));
connect(move, SIGNAL(triggered()), this, SLOT(slot_setRubberBandToView()));
connect(add_line, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_ellipse, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_circle, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_polygon, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_text, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_arc, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_terminal, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(add_textfield, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
connect(ce_scene, SIGNAL(needNormalMode()), this, SLOT(slot_setNormalMode()));
move -> setCheckable(true);
add_line -> setCheckable(true);
add_ellipse -> setCheckable(true);
add_circle -> setCheckable(true);
add_polygon -> setCheckable(true);
add_text -> setCheckable(true);
add_arc -> setCheckable(true);
add_terminal -> setCheckable(true);
add_textfield -> setCheckable(true);
parts = new QActionGroup(this);
parts -> addAction(move);
parts -> addAction(add_line);
parts -> addAction(add_ellipse);
parts -> addAction(add_circle);
parts -> addAction(add_polygon);
parts -> addAction(add_text);
parts -> addAction(add_arc);
parts -> addAction(add_textfield);
parts -> addAction(add_terminal);
parts -> setExclusive(true);
parts_toolbar = new QToolBar(tr("Parties"), this);
foreach (QAction *action, parts -> actions()) parts_toolbar -> addAction(action);
move -> setChecked(true);
parts_toolbar -> setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
QAction *xml_preview = new QAction(QIcon(":/ico/info.png"), tr("XML"), this);
connect(xml_preview, SIGNAL(triggered()), this, SLOT(xmlPreview()));
parts_toolbar -> addAction(xml_preview);
addToolBar(Qt::LeftToolBarArea, parts_toolbar);
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateInformations()));
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateMenus()));
}
void CustomElementEditor::setupMenus() {
file_menu = new QMenu(tr("Fichier"));
edit_menu = new QMenu(tr("\311dition"));
display_menu = new QMenu(tr("Affichage"));
tools_menu = new QMenu(tr("Outils"));
help_menu = new QMenu(tr("Aide"));
file_menu -> setTearOffEnabled(true);
edit_menu -> setTearOffEnabled(true);
display_menu -> setTearOffEnabled(true);
tools_menu -> setTearOffEnabled(true);
help_menu -> setTearOffEnabled(true);
file_menu -> addAction(new_element);
file_menu -> addAction(open);
file_menu -> addAction(save);
file_menu -> addAction(save_as);
file_menu -> addSeparator();
file_menu -> addAction(quit);
edit_menu -> addAction(selectall);
edit_menu -> addAction(deselectall);
edit_menu -> addAction(inv_select);
edit_menu -> addSeparator();
edit_menu -> addAction(edit_delete);
edit_menu -> addSeparator();
edit_menu -> addAction(edit_names);
edit_menu -> addAction(edit_size);
edit_menu -> addAction(edit_hotspot);
edit_menu -> addAction(edit_ori);
menuBar() -> addMenu(file_menu);
menuBar() -> addMenu(edit_menu);
menuBar() -> addMenu(display_menu);
menuBar() -> addMenu(tools_menu);
menuBar() -> addMenu(help_menu);
}
void CustomElementEditor::slot_updateMenus() {
edit_delete -> setEnabled(!ce_scene -> selectedItems().isEmpty());
}
void CustomElementEditor::setupInterface() {
// editeur
ce_scene = new EditorScene(this);
ce_scene -> slot_move();
ce_view = new QGraphicsView(ce_scene, this);
ce_view -> setInteractive(true);
ce_view -> setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
//ce_view -> setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
ce_view -> setResizeAnchor(QGraphicsView::AnchorUnderMouse);
//ce_view -> setSceneRect(QRectF(0.0, 0.0, 50.0, 200.0));
ce_view -> scale(4.0, 4.0);
slot_setRubberBandToView();
setCentralWidget(ce_view);
// widget par defaut dans le QDockWidget
default_informations = new QLabel();
// panel sur le cote
tools_dock = new QDockWidget(tr("Informations"), this);
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
tools_dock -> setMinimumWidth(285);
addDockWidget(Qt::RightDockWidgetArea, tools_dock);
QWidget *info_widget = new QWidget();
info_widget -> setLayout(new QVBoxLayout(info_widget));
tools_dock -> setWidget(info_widget);
slot_updateInformations();
// barre d'etat
statusBar() -> showMessage(tr("\311diteur d'\351l\351ments"));
}
void CustomElementEditor::slot_setRubberBandToView() {
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
}
void CustomElementEditor::slot_setNoDragToView() {
ce_view -> setDragMode(QGraphicsView::NoDrag);
}
void CustomElementEditor::slot_setNormalMode() {
if (!move -> isChecked()) move -> setChecked(true);
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
ce_scene -> slot_move();
}
void CustomElementEditor::slot_updateInformations() {
QList<QGraphicsItem *> selected_qgis = ce_scene -> selectedItems();
QList<CustomElementPart *> selected_parts;
foreach(QGraphicsItem *qgi, selected_qgis) {
if (CustomElementPart *cep = dynamic_cast<CustomElementPart *>(qgi)) {
selected_parts.append(cep);
}
}
// recupere le layout
QLayout *layout = tools_dock -> widget() -> layout();
// enleve les widgets deja presents
QLayoutItem *qli;
while ((qli = layout -> takeAt(0)) != 0) {
if (qli -> widget()) {
layout -> removeWidget(qli -> widget());
qli -> widget() -> setParent(0);
}
}
if (selected_parts.size() == 1) {
// recupere le premier CustomElementPart et en ajoute le widget d'edition
layout -> addWidget(selected_parts.first() -> elementInformations());
} else {
default_informations -> setText(
selected_parts.size() ?
QString("%1").arg(selected_parts.size()) + tr(" parties s\351lectionn\351es.") :
tr("Aucune partie s\351lectionn\351e.")
);
layout -> addWidget(default_informations);
}
}
void CustomElementEditor::xmlPreview() {
QMessageBox::information(
this,
"Export XML",
ce_scene -> toXml().toString(4)
);
}
void CustomElementEditor::fromFile(const QString &filepath) {
bool state = true;
QString error_message;
// le fichier doit exister
QFileInfo infos_file(filepath);
if (!infos_file.exists() || !infos_file.isFile()) {
state = false;
error_message = tr("Le fichier ") + filepath + tr(" n'existe pas.");
}
// le fichier doit etre lisible
QFile file(filepath);
if (state) {
if (!file.open(QIODevice::ReadOnly)) {
state = false;
error_message = tr("Impossible d'ouvrir le fichier ") + filepath + ".";
}
}
// le fichier doit etre un document XML
QDomDocument document_xml;
if (state) {
if (!document_xml.setContent(&file)) {
state = false;
error_message = tr("Ce fichier n'est pas un document XML valide");
}
file.close();
}
if (!state) {
QMessageBox::critical(this, tr("Erreur"), error_message);
return;
}
// chargement de l'element
ce_scene -> fromXml(document_xml);
// gestion de la lecture seule
if (!infos_file.isWritable()) {
QMessageBox::warning(
this,
tr("\311dition en lecture seule"),
tr("Vous n'avez pas les privil\350ges n\351cessaires pour modifier cet \351lement. Il sera donc ouvert en lecture seule.")
);
setReadOnly(true);
}
// memorise le fichier
_filename = filepath;
// modifie le titre de la fenetre
QString new_title = min_title + " - " + ce_scene -> names().name();
if (isReadOnly()) new_title += tr(" [lecture seule]");
setWindowTitle(new_title);
}
bool CustomElementEditor::toFile(const QString &fn) {
QFile file(fn);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Erreur"), tr("Impossible d'ecrire dans ce fichier"));
return(false);
}
QTextStream out(&file);
out.setCodec("UTF-8");
out << ce_scene -> toXml().toString(4);
file.close();
return(true);
}
/**
specifie si l'editeur d'element doit etre en mode lecture seule
@param ro true pour activer le mode lecture seule, false pour le desactiver
*/
void CustomElementEditor::setReadOnly(bool ro) {
read_only = ro;
// active / desactive les actions
foreach (QAction *action, parts -> actions()) action -> setEnabled(!ro);
// active / desactive les interactions avec la scene
ce_view -> setInteractive(!ro);
// active / desactive l'edition de la taille, du hotspot, des noms et des orientations
edit_size -> setEnabled(!ro);
edit_hotspot -> setEnabled(!ro);
edit_names -> setEnabled(!ro);
edit_ori -> setEnabled(!ro);
}
/**
@return true si l'editeur d'element est en mode lecture seule
*/
bool CustomElementEditor::isReadOnly() const {
return(read_only);
}
void CustomElementEditor::slot_new() {
NewElementWizard new_element_wizard;
new_element_wizard.exec();
}
void CustomElementEditor::slot_open() {
// demande un nom de fichier a ouvrir a l'utilisateur
QString user_filename = QFileDialog::getOpenFileName(
this,
tr("Ouvrir un fichier"),
QETApp::customElementsDir(),
tr("\311l\351ments QElectroTech (*.elmt);;Fichiers XML (*.xml);;Tous les fichiers (*)")
);
if (user_filename == "") return;
CustomElementEditor *cee = new CustomElementEditor();
cee -> fromFile(user_filename);
cee -> show();
}
bool CustomElementEditor::slot_save() {
// si on ne connait pas le nom du fichier en cours, enregistrer revient a enregistrer sous
if (_filename == QString()) return(slot_saveAs());
// sinon on enregistre dans le nom de fichier connu
return(toFile(_filename));
}
bool CustomElementEditor::slot_saveAs() {
// demande un nom de fichier a l'utilisateur pour enregistrer l'element
QString fn = QFileDialog::getSaveFileName(
this,
tr("Enregistrer sous"),
QETApp::customElementsDir(),
tr("\311l\351ments QElectroTech (*.elmt)")
);
// si aucun nom n'est entre, renvoie faux.
if (fn == "") return(false);
// si le nom ne se termine pas par l'extension .elmt, celle-ci est ajoutee
if (!fn.endsWith(".elmt", Qt::CaseInsensitive)) fn += ".elmt";
// tente d'enregistrer le fichier
bool result_save = toFile(fn);
// si l'enregistrement reussit, le nom du fichier est conserve
if (result_save) setFileName(fn);
// retourne un booleen representatif de la reussite de l'enregistrement
return(result_save);
}
void CustomElementEditor::slot_quit(QCloseEvent *event) {
if (close()) {
if (event != NULL) event -> accept();
delete(this);
} else if (event != NULL) event -> ignore();
}
bool CustomElementEditor::close() {
// demande d'abord a l'utilisateur s'il veut enregistrer l'element en cours
QMessageBox::StandardButton answer = QMessageBox::question(
this,
tr("Enregistrer l'\351l\351ment en cours ?"),
tr("Voulez-vous enregistrer l'\351l\351ment ") + ce_scene -> names().name() + tr(" ?"),
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
QMessageBox::Cancel
);
bool result;
switch(answer) {
case QMessageBox::Cancel: result = false; break; // l'utilisateur annule : echec de la fermeture
case QMessageBox::Yes: result = slot_save(); break; // l'utilisateur dit oui : la reussite depend de l'enregistrement
default: result = true; // l'utilisateur dit non ou ferme le dialogue: c'est reussi
}
return(result);
}
/**
Permet de quitter l'editeur lors de la fermeture de la fenetre principale
@param qce Le QCloseEvent correspondant a l'evenement de fermeture
*/
void CustomElementEditor::closeEvent(QCloseEvent *qce) {
slot_quit(qce);
}

View File

@@ -0,0 +1,128 @@
#ifndef CUSTOM_ELEMENT_EDITOR_H
#define CUSTOM_ELEMENT_EDITOR_H
#include <QtGui>
#include "editorscene.h"
#include "orientationset.h"
class CustomElementEditor : public QMainWindow {
Q_OBJECT
// constructeur, destructeur
public:
CustomElementEditor(QWidget * = 0);
virtual ~CustomElementEditor();
private:
CustomElementEditor(const CustomElementEditor &);
// attributs
private:
/// booleen indiquant si l'editeur est en mode "lecture seule" ou non
bool read_only;
/// menus
QMenu *file_menu, *edit_menu, *display_menu, *tools_menu, *help_menu;
/// vue sur la scene d'edition
QGraphicsView *ce_view;
/// scene d'edition
EditorScene *ce_scene;
/// container pour les widgets d'edition des parties
QDockWidget *tools_dock;
/// actions du menu fichier
QAction *new_element, *open, *save, *save_as, *quit;
/// actions du menu edition
QAction *selectall, *deselectall, *inv_select;
QAction *edit_delete, *edit_size, *edit_hotspot, *edit_names, *edit_ori;
/// barre d'outils
QToolBar *parts_toolbar;
/// actions de la barre d'outils
QActionGroup *parts;
QAction *move, *add_line, *add_circle, *add_ellipse, *add_polygon, *add_text;
QAction *add_arc, *add_terminal, *add_textfield;
/// label affiche lors de la selection de plusieurs elements
QLabel *default_informations;
/// titre minimal
QString min_title;
/// Nom de fichier
QString _filename;
// methodes
public:
void setSize(const QSize &);
QSize size() const;
void setHotspot(const QPoint &);
QPoint hotspot() const;
void setNames(const NamesList &);
void setOrientations(const OrientationSet &orientation_set);
OrientationSet orientations() const;
void setFileName(const QString &);
QString fileName() const;
void setReadOnly(bool);
bool isReadOnly() const;
void fromFile(const QString &);
bool toFile(const QString &);
protected:
void closeEvent(QCloseEvent *);
private:
void setupActions();
void setupMenus();
void setupInterface();
bool close();
public slots:
void slot_new();
void slot_open();
bool slot_save();
bool slot_saveAs();
void slot_quit(QCloseEvent * = NULL);
void slot_setRubberBandToView();
void slot_setNoDragToView();
void slot_setNormalMode();
void slot_updateInformations();
void slot_updateMenus();
void xmlPreview();
};
inline void CustomElementEditor::setSize(const QSize &siz) {
ce_scene -> setWidth(siz.width());
ce_scene -> setHeight(siz.height());
}
inline QSize CustomElementEditor::size() const {
return(
QSize(
ce_scene -> width(),
ce_scene -> height()
)
);
}
inline void CustomElementEditor::setHotspot(const QPoint &hs) {
ce_scene -> setHotspot(hs);
}
inline QPoint CustomElementEditor::hotspot() const {
return(ce_scene -> hotspot());
}
inline void CustomElementEditor::setNames(const NamesList &nameslist) {
ce_scene -> setNames(nameslist);
}
inline void CustomElementEditor::setOrientations(const OrientationSet &orientation_set) {
ce_scene -> setOrientations(orientation_set);
}
inline OrientationSet CustomElementEditor::orientations() const {
return(ce_scene -> orientations());
}
inline void CustomElementEditor::setFileName(const QString &fn) {
setWindowTitle(min_title + " - " + fn);
_filename = fn;
}
inline QString CustomElementEditor::fileName() const {
return(_filename);
}
#endif

View File

@@ -0,0 +1,133 @@
#include "customelementgraphicpart.h"
/**
Ecrit les attributs de style dans un element XML
@param qde L'element XML a modifier
*/
void CustomElementGraphicPart::stylesToXml(QDomElement &qde) const {
QString css_like_styles;
css_like_styles += "line-style:";
if (_linestyle == DashedStyle) css_like_styles += "dashed";
else if (_linestyle == NormalStyle) css_like_styles += "normal";
css_like_styles += ";line-weight:";
if (_lineweight == NoneWeight) css_like_styles += "none";
else if (_lineweight == ThinWeight) css_like_styles += "thin";
else if (_lineweight == NormalWeight) css_like_styles += "normal";
css_like_styles += ";filling:";
if (_filling == NoneFilling) css_like_styles += "none";
else if (_filling == BlackFilling) css_like_styles += "black";
else if (_filling == WhiteFilling) css_like_styles += "white";
css_like_styles += ";color:";
if (_color == WhiteColor) css_like_styles += "white";
else if (_color == BlackColor) css_like_styles += "black";
qde.setAttribute("style", css_like_styles);
qde.setAttribute("antialias", _antialiased ? "true" : "false");
}
/**
Lit les attributs de style depuis un element XML
@param qde L'element XML a analyser
*/
void CustomElementGraphicPart::stylesFromXml(const QDomElement &qde) {
resetStyles();
// recupere la liste des couples style / valeur
QStringList styles = qde.attribute("style").split(";", QString::SkipEmptyParts);
// analyse chaque couple
QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
foreach (QString style, styles) {
if (!rx.exactMatch(style)) continue;
QString style_name = rx.cap(1);
QString style_value = rx.cap(2);
if (style_name == "line-style") {
if (style_value == "dashed") _linestyle = DashedStyle;
else if (style_value == "normal") _linestyle = NormalStyle;
// il n'y a pas de else car les valeurs non conformes sont ignorees (idem par la suite)
} else if (style_name == "line-weight") {
if (style_value == "thin") _lineweight = ThinWeight;
else if (style_value == "normal") _lineweight = NormalWeight;
else if (style_value == "none") _lineweight = NoneWeight;
} else if (style_name == "filling") {
if (style_value == "white") _filling = WhiteFilling;
else if (style_value == "black") _filling = BlackFilling;
else if (style_value == "none") _filling = NoneFilling;
} else if (style_name == "color") {
if (style_value == "black") _color = BlackColor;
else if (style_value == "white") _color = WhiteColor;
}
}
// recupere l'antialiasing
_antialiased = qde.attribute("antialias") == "true";
// met a jour l'editeur de style
style_editor -> updateForm();
}
/**
Remet les styles par defaut
*/
void CustomElementGraphicPart::resetStyles() {
_linestyle = NormalStyle;
_lineweight = NormalWeight;
_filling = NoneFilling;
_color = BlackColor;
_antialiased = false;
}
/**
Applique les styles a un Qpainter
@param painter QPainter a modifier
*/
void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const {
// recupere le QPen et la QBrush du QPainter
QPen pen = painter.pen();
QBrush brush = painter.brush();
// applique le style de trait
if (_linestyle == DashedStyle) pen.setStyle(Qt::DashLine);
else if (_linestyle == NormalStyle) pen.setStyle(Qt::SolidLine);
// applique l'epaisseur de trait
if (_lineweight == NoneWeight) pen.setColor(QColor(0, 0, 0, 0));
else if (_lineweight == ThinWeight) pen.setWidth(0);
else if (_lineweight == NormalWeight) pen.setWidthF(1.0);
// applique le remplissage
if (_filling == NoneFilling) {
brush.setStyle(Qt::NoBrush);
} else if (_filling == BlackFilling) {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::black);
} else if (_filling == WhiteFilling) {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
}
// applique la couleur de trait
if (_color == WhiteColor) pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
else if (_color == BlackColor) pen.setColor(QColor( 0, 0, 0, pen.color().alpha()));
// applique l'antialiasing
painter.setRenderHint(QPainter::Antialiasing, _antialiased);
painter.setRenderHint(QPainter::TextAntialiasing, _antialiased);
painter.setRenderHint(QPainter::SmoothPixmapTransform, _antialiased);
painter.setPen(pen);
painter.setBrush(brush);
}
/**
@return Le widget permettant d'editer les styles
*/
QWidget *CustomElementGraphicPart::elementInformations() {
return(style_editor);
}

View File

@@ -0,0 +1,145 @@
#ifndef CUSTOM_ELEMENT_GRAPHIC_PART_H
#define CUSTOM_ELEMENT_GRAPHIC_PART_H
#include <QPainter>
#include "customelementpart.h"
#include "styleeditor.h"
/**
Cette classe represente une partie graphique d'element
Elle encapsule des methodes afin de gerer les attributs de style communs
a la plupart des parties d'elements
*/
typedef CustomElementGraphicPart CEGP;
class CustomElementGraphicPart : public CustomElementPart {
public:
enum LineStyle { NormalStyle, DashedStyle };
enum LineWeight { NormalWeight, ThinWeight, NoneWeight };
enum Filling { NoneFilling, BlackFilling, WhiteFilling };
enum Color { BlackColor, WhiteColor };
// constructeurs, destructeur
public:
CustomElementGraphicPart() :
_linestyle(NormalStyle),
_lineweight(NormalWeight),
_filling(NoneFilling),
_color(BlackColor),
_antialiased(false)
{
style_editor = new StyleEditor(this);
};
virtual ~CustomElementGraphicPart() {
qDebug() << "~CustomElementGraphicPart()";
delete style_editor;
};
// attributs
private:
LineStyle _linestyle;
LineWeight _lineweight;
Filling _filling ;
Color _color;
bool _antialiased;
protected:
StyleEditor *style_editor;
//methodes
public:
void setLineStyle(LineStyle);
void setLineWeight(LineWeight);
void setFilling(Filling);
void setColor(Color);
void setAntialiased(bool);
LineStyle lineStyle() const;
LineWeight lineWeight() const;
Filling filling() const;
Color color() const;
bool antialiased() const;
QWidget *elementInformations();
protected:
void stylesToXml(QDomElement &) const;
void stylesFromXml(const QDomElement &);
void resetStyles();
void applyStylesToQPainter(QPainter &) const;
};
/**
Change le style de trait
@param ls Le nouveau style de trait
*/
inline void CustomElementGraphicPart::setLineStyle(LineStyle ls) {
_linestyle = ls;
}
/**
Change l'epaisseur de trait
@param lw La nouvelle epaisseur de trait
*/
inline void CustomElementGraphicPart::setLineWeight(LineWeight lw) {
_lineweight = lw;
}
/**
Change la couleur de remplissage
@param f La nouvelle couleur de remplissage
*/
inline void CustomElementGraphicPart::setFilling(Filling f) {
_filling = f;
}
/**
Change la couleur de trait
@param c La nouvelle couleur de trait
*/
inline void CustomElementGraphicPart::setColor(Color c) {
_color = c;
}
/**
@return Le style de trait
*/
inline CustomElementGraphicPart::LineStyle CustomElementGraphicPart::lineStyle() const {
return(_linestyle);
}
/**
@return L'epaisseur de trait
*/
inline CustomElementGraphicPart::LineWeight CustomElementGraphicPart::lineWeight() const {
return(_lineweight);
}
/**
@return La couleur de remplissage
*/
inline CustomElementGraphicPart::Filling CustomElementGraphicPart::filling() const {
return(_filling);
}
/**
@return La couleur de trait
*/
inline CustomElementGraphicPart::Color CustomElementGraphicPart::color() const {
return(_color);
}
/**
Definit si la partie doit etre antialiasee ou non
@param aa True pour activer l'antialiasing, false pour le desactiver
*/
inline void CustomElementGraphicPart::setAntialiased(bool aa) {
_antialiased = aa;
}
/**
@return true si la partie est antialiasee, false sinon
*/
inline bool CustomElementGraphicPart::antialiased() const {
return(_antialiased);
}
#endif

View File

@@ -0,0 +1,6 @@
#include "customelementpart.h"
#include "customelement.h"
QPicture *CustomElementPart::getCustomElementQPicture(CustomElement &ce) const {
return(&(ce.dessin));
}

View File

@@ -0,0 +1,39 @@
#ifndef CUSTOM_ELEMENT_PART_H
#define CUSTOM_ELEMENT_PART_H
#include <QtGui>
#include <QtXml>
#include <QImage>
class CustomElement;
/**
Cette classe abstraite represente une partie de la representation graphique
d'un element de schema electrique. Les attributs et methodes qu'elle
encapsule ne sont pas integres directement dans la classe CustomElement
afin de ne pas alourdir celle-ci. Il est en effet inutile pour cette classe
de retenir sa conception graphique autrement que sous la forme d'une
QImage.
*/
class CustomElementPart {
// constructeurs, destructeur
public:
CustomElementPart() {};
virtual ~CustomElementPart() {
qDebug() << "~CustomElementPart()";
};
private:
CustomElementPart(const CustomElementPart &);
// attributs
private:
// methodes
public:
virtual void fromXml(const QDomElement &) = 0;
virtual const QDomElement toXml(QDomDocument &) const = 0;
virtual QWidget *elementInformations() = 0;
//virtual void renderToCustomElement(CustomElement &) const = 0;
//virtual void toEditorPart(const EditorPart &);
//virtual void fromEditorPart(const EditorPart &) = 0;
protected:
QPicture *getCustomElementQPicture(CustomElement &ce) const;
};
#endif

447
editor/editorscene.cpp Normal file
View File

@@ -0,0 +1,447 @@
#include "editorscene.h"
#include <cmath>
#include "partline.h"
#include "partellipse.h"
#include "partcircle.h"
#include "partpolygon.h"
#include "partterminal.h"
#include "parttext.h"
#define GRILLE_X 10
#define GRILLE_Y 10
EditorScene::EditorScene(QObject *parent) :
QGraphicsScene(parent),
_width(3),
_height(7),
_hotspot(15, 35)
{
current_polygon = NULL;
connect(this, SIGNAL(changed(const QList<QRectF> &)), this, SLOT(slot_checkSelectionChanged()));
}
EditorScene::~EditorScene() {
qDebug() << "~EditorScene()";
}
void EditorScene::slot_move() {
behavior = Normal;
}
void EditorScene::slot_addLine() {
behavior = Line;
}
void EditorScene::slot_addCircle() {
behavior = Circle;
}
void EditorScene::slot_addEllipse() {
behavior = Ellipse;
}
void EditorScene::slot_addPolygon() {
behavior = Polygon;
}
void EditorScene::slot_addText() {
behavior = Text;
}
void EditorScene::slot_addTerminal() {
behavior = Terminal;
}
void EditorScene::slot_addArc() {
behavior = Arc;
}
void EditorScene::slot_addTextField() {
behavior = TextField;
}
void EditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
QRectF temp_rect;
qreal radius;
QPointF temp_point;
QPolygonF temp_polygon;
if (e -> buttons() & Qt::LeftButton) {
switch(behavior) {
case Normal:
QGraphicsScene::mouseMoveEvent(e);
break;
case Line:
current_line -> setLine(QLineF(current_line -> line().p1(), e -> scenePos()));
break;
case Ellipse:
temp_rect = current_ellipse -> rect();
temp_rect.setBottomRight(e -> scenePos());
current_ellipse -> setRect(temp_rect);
break;
case Circle:
temp_rect = current_circle -> rect();
temp_point = e -> scenePos() - current_circle -> mapToScene(temp_rect.center());
radius = sqrt(pow(temp_point.x(), 2) + pow(temp_point.y(), 2));
temp_rect = QRectF(
temp_rect.center() - QPointF(radius, radius),
QSizeF(2.0 * radius, 2.0 * radius)
);
current_circle -> setRect(temp_rect);
break;
case Polygon:
if (current_polygon == NULL) break;
temp_polygon = current_polygon -> polygon();
temp_polygon.pop_back();
temp_polygon << e -> scenePos();
current_polygon -> setPolygon(temp_polygon);
break;
default:
QGraphicsScene::mouseMoveEvent(e);
}
} else if (behavior == Polygon && current_polygon != NULL) {
temp_polygon = current_polygon -> polygon();
temp_polygon.pop_back();
temp_polygon << e -> scenePos();
current_polygon -> setPolygon(temp_polygon);
} else QGraphicsScene::mouseMoveEvent(e);
}
void EditorScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
QPolygonF temp_polygon;
if (e -> button() & Qt::LeftButton) {
switch(behavior) {
case Normal:
QGraphicsScene::mousePressEvent(e);
break;
case Line:
current_line = new PartLine(0, this);
current_line -> setLine(QLineF(e -> scenePos(), e -> scenePos()));
break;
case Ellipse:
current_ellipse = new PartEllipse(0, this);
current_ellipse -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
break;
case Circle:
current_circle = new PartCircle(0, this);
current_circle -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
break;
case Polygon:
if (current_polygon == NULL) {
current_polygon = new PartPolygon(0, this);
temp_polygon = QPolygonF(0);
} else temp_polygon = current_polygon -> polygon();
// au debut, on insere deux points
if (!temp_polygon.count()) temp_polygon << e -> scenePos();
temp_polygon << e -> scenePos();
current_polygon -> setPolygon(temp_polygon);
break;
default:
QGraphicsScene::mousePressEvent(e);
}
} else QGraphicsScene::mousePressEvent(e);
}
void EditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
PartTerminal *terminal;
PartText *text;
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
if (e -> button() & Qt::LeftButton) {
switch(behavior) {
case Normal:
QGraphicsScene::mouseReleaseEvent(e);
break;
case Line:
break;
case Ellipse:
current_ellipse -> setRect(current_ellipse -> rect().normalized());
break;
case Circle:
current_circle -> setRect(current_circle -> rect().normalized());
break;
case Terminal:
terminal = new PartTerminal(0, this);
terminal -> setPos(e -> scenePos());
break;
case Text:
text = new PartText(0, this);
text -> setPos(e -> scenePos());
break;
default:
QGraphicsScene::mouseReleaseEvent(e);
}
} else if (e -> button() & Qt::RightButton) {
if (behavior == Polygon) {
behavior = Normal;
current_polygon = NULL;
emit(needNormalMode());
} else QGraphicsScene::mouseReleaseEvent(e);
} else QGraphicsScene::mouseReleaseEvent(e);
}
/**
Dessine l'arriere-plan de l'editeur, cad la grille.
@param p Le QPainter a utiliser pour dessiner
@param r Le rectangle de la zone a dessiner
*/
void EditorScene::drawBackground(QPainter *p, const QRectF &r) {
p -> save();
// desactive tout antialiasing, sauf pour le texte
p -> setRenderHint(QPainter::Antialiasing, false);
p -> setRenderHint(QPainter::TextAntialiasing, true);
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
// dessine un fond blanc
p -> setPen(Qt::NoPen);
p -> setBrush(Qt::white);
p -> drawRect(r);
// encadre la zone dessinable de l'element
QRectF drawable_area(-_hotspot.x(), -_hotspot.y(), width(), height());
p -> setPen(Qt::black);
p -> setBrush(Qt::NoBrush);
p -> drawRect(drawable_area);
if (r.width() < 2500 && r.height() < 2500) {
// dessine les points de la grille
p -> setPen(Qt::black);
p -> setBrush(Qt::NoBrush);
qreal limite_x = r.x() + r.width();
qreal limite_y = r.y() + r.height();
int g_x = (int)ceil(r.x());
while (g_x % GRILLE_X) ++ g_x;
int g_y = (int)ceil(r.y());
while (g_y % GRILLE_Y) ++ g_y;
for (int gx = g_x ; gx < limite_x ; gx += GRILLE_X) {
for (int gy = g_y ; gy < limite_y ; gy += GRILLE_Y) {
p -> drawPoint(gx, gy);
}
}
}
p -> restore();
}
/**
Dessine l'arriere-plan de l'editeur, cad l'indicateur de hotspotó.
@param p Le QPainter a utiliser pour dessiner
@param r Le rectangle de la zone a dessiner
*/
void EditorScene::drawForeground(QPainter *p, const QRectF &) {
p -> save();
// desactive tout antialiasing, sauf pour le texte
p -> setRenderHint(QPainter::Antialiasing, false);
p -> setRenderHint(QPainter::TextAntialiasing, true);
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
p -> setPen(Qt::red);
p -> setBrush(Qt::NoBrush);
p -> drawLine(QLineF(0.0, -_hotspot.y(), 0.0, height() - _hotspot.y()));
p -> drawLine(QLineF(-_hotspot.x(), 0.0, width() - _hotspot.x(), 0.0));
p -> restore();
}
const QDomDocument EditorScene::toXml() const {
// document XML
QDomDocument xml_document;
// racine du document XML
QDomElement root = xml_document.createElement("definition");
root.setAttribute("type", "element");
root.setAttribute("width", QString("%1").arg(_width * 10));
root.setAttribute("height", QString("%1").arg(_height * 10));
root.setAttribute("hotspot_x", QString("%1").arg(_hotspot.x()));
root.setAttribute("hotspot_y", QString("%1").arg(_hotspot.y()));
root.setAttribute("orientation", ori.toString());
// noms de l'element
root.appendChild(_names.toXml(xml_document));
QDomElement description = xml_document.createElement("description");
// description de l'element
foreach(QGraphicsItem *qgi, items()) {
if (CustomElementPart *ce = dynamic_cast<CustomElementPart *>(qgi)) {
description.appendChild(ce -> toXml(xml_document));
}
}
root.appendChild(description);
xml_document.appendChild(root);
return(xml_document);
}
void EditorScene::fromXml(const QDomDocument &xml_document) {
QString error_message;
bool state = true;
// la racine est supposee etre une definition d'element
QDomElement root = xml_document.documentElement();
if (root.tagName() != "definition" || root.attribute("type") != "element") {
state = false;
error_message = tr("Ce document XML n'est pas une definition d'\351l\351ment.");
}
// dimensions et hotspot
if (state) {
// ces attributs doivent etre presents et valides
int w, h, hot_x, hot_y;
if (
!QET::attributeIsAnInteger(root, QString("width"), &w) ||\
!QET::attributeIsAnInteger(root, QString("height"), &h) ||\
!QET::attributeIsAnInteger(root, QString("hotspot_x"), &hot_x) ||\
!QET::attributeIsAnInteger(root, QString("hotspot_y"), &hot_y)
) {
state = false;
error_message = tr("Les dimensions ou le point de saisie ne sont pas valides.");
} else {
setWidth(w);
setHeight(h);
setHotspot(QPoint(hot_x, hot_y));
}
}
// orientations
if (state) {
if (!ori.fromString(root.attribute("orientation"))) {
state = false;
error_message = tr("Les orientations ne sont pas valides.");
}
}
// extrait les noms de la definition XML
if (state) {
_names.fromXml(root);
}
// parcours des enfants de la definition : parties de l'element
if (state) {
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
QDomElement elmts = node.toElement();
if (elmts.isNull()) continue;
if (elmts.tagName() == "description") {
// gestion de la description graphique de l'element
// = parcours des differentes parties du dessin
int z = 1;
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
QDomElement qde = n.toElement();
if (qde.isNull()) continue;
CustomElementPart *cep;
if (qde.tagName() == "line") cep = new PartLine (0, this);
else if (qde.tagName() == "ellipse") cep = new PartEllipse (0, this);
else if (qde.tagName() == "circle") cep = new PartCircle (0, this);
else if (qde.tagName() == "polygon") cep = new PartPolygon (0, this);
else if (qde.tagName() == "terminal") cep = new PartTerminal(0, this);
else if (qde.tagName() == "text") cep = new PartText (0, this);
else continue;
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) qgi -> setZValue(z++);
cep -> fromXml(qde);
}
}
}
}
}
void EditorScene::slot_checkSelectionChanged() {
static QList<QGraphicsItem *> cache_selecteditems = QList<QGraphicsItem *>();
QList<QGraphicsItem *> selecteditems = selectedItems();
if (cache_selecteditems != selecteditems) emit(selectionChanged());
cache_selecteditems = selecteditems;
}
void EditorScene::slot_selectAll() {
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(true);
}
void EditorScene::slot_deselectAll() {
clearSelection();
}
void EditorScene::slot_invertSelection() {
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(!qgi -> isSelected());
}
void EditorScene::slot_delete() {
// verifie qu'il y a qqc de selectionne
QList<QGraphicsItem *> selected_items = selectedItems();
if (selected_items.isEmpty()) return;
// efface tout ce qui est selectionne
foreach(QGraphicsItem *qgi, selected_items) {
removeItem(qgi);
delete qgi;
}
}
void EditorScene::slot_editSize() {
}
void EditorScene::slot_editHotSpot() {
}
void EditorScene::slot_editOrientations() {
// cree un dialogue
QDialog dialog_ori;
dialog_ori.setModal(true);
dialog_ori.setFixedSize(400, 230);
dialog_ori.setWindowTitle(tr("\311diter les orientations"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_ori);
// ajoute un champ explicatif au dialogue
QLabel *information_label = new QLabel(tr("L'orientation par d\351faut est l'orientation dans laquelle s'effectue la cr\351ation de l'\351l\351ment."));
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
information_label -> setWordWrap(true);
dialog_layout -> addWidget(information_label);
// ajoute un OrientationSetWidget au dialogue
OrientationSetWidget *ori_widget = new OrientationSetWidget();
ori_widget -> setOrientationSet(ori);
dialog_layout -> addWidget(ori_widget);
// ajoute deux boutons au dialogue
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dialog_buttons);
connect(dialog_buttons, SIGNAL(accepted()), &dialog_ori, SLOT(accept()));
connect(dialog_buttons, SIGNAL(rejected()), &dialog_ori, SLOT(reject()));
// lance le dialogue
if (dialog_ori.exec() == QDialog::Accepted) ori = ori_widget -> orientationSet();
}
void EditorScene::slot_editNames() {
// cree un dialogue
QDialog dialog;
dialog.setModal(true);
dialog.setFixedSize(400, 330);
dialog.setWindowTitle(tr("\311diter les noms"));
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog);
// ajoute un champ explicatif au dialogue
QLabel *information_label = new QLabel(tr("Vous pouvez sp\351cifier le nom de l'\351l\351ment dans plusieurs langues."));
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
information_label -> setWordWrap(true);
dialog_layout -> addWidget(information_label);
// ajoute un NamesListWidget au dialogue
NamesListWidget *names_widget = new NamesListWidget();
names_widget -> setNames(_names);
dialog_layout -> addWidget(names_widget);
// ajoute deux boutons au dialogue
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog_layout -> addWidget(dialog_buttons);
connect(dialog_buttons, SIGNAL(accepted()), names_widget, SLOT(check()));
connect(names_widget, SIGNAL(inputChecked()), &dialog, SLOT(accept()));
connect(dialog_buttons, SIGNAL(rejected()), &dialog, SLOT(reject()));
// lance le dialogue
if (dialog.exec() == QDialog::Accepted) _names = names_widget -> names();
}

136
editor/editorscene.h Normal file
View File

@@ -0,0 +1,136 @@
#ifndef EDITOR_SCNE_H
#define EDITOR_SCNE_H
#include <QtGui>
#include <QtXml>
#include "nameslistwidget.h"
#include "orientationsetwidget.h"
class PartLine;
class PartEllipse;
class PartCircle;
class PartPolygon;
class EditorScene : public QGraphicsScene {
Q_OBJECT
// enum
enum Behavior { Normal, Line, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField };
// constructeurs, destructeur
public:
EditorScene(QObject * = 0);
virtual ~EditorScene();
private:
EditorScene(const EditorScene &);
// attributs
private:
/// longueur de l'element en dizaines de pixels
uint _width;
/// hauteur de l'element en dizaines de pixels
uint _height;
/// position du point de saisie
QPoint _hotspot;
/// Liste des noms de l'element
NamesList _names;
/// Liste des orientations de l'element
OrientationSet ori;
/// Variables relatives a la gestion du dessin des parties sur la scene
Behavior behavior;
PartLine *current_line;
PartEllipse *current_ellipse;
PartCircle *current_circle;
PartPolygon *current_polygon;
// methodes
public:
void setWidth(const uint& theValue);
uint width() const;
void setHeight(const uint& theValue);
uint height() const;
void setHotspot(const QPoint &);
QPoint hotspot() const;
void setNames(const NamesList);
NamesList names() const;
OrientationSet orientations();
void setOrientations(const OrientationSet &);
virtual const QDomDocument toXml() const;
virtual void fromXml(const QDomDocument &);
protected:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
virtual void drawBackground(QPainter *, const QRectF &);
virtual void drawForeground(QPainter *, const QRectF &);
public slots:
void slot_move();
void slot_addLine();
void slot_addCircle();
void slot_addEllipse();
void slot_addPolygon();
void slot_addText();
void slot_addArc();
void slot_addTerminal();
void slot_addTextField();
void slot_checkSelectionChanged();
void slot_selectAll();
void slot_deselectAll();
void slot_invertSelection();
void slot_delete();
void slot_editSize();
void slot_editHotSpot();
void slot_editNames();
void slot_editOrientations();
signals:
void selectionChanged();
void needNormalMode();
};
inline void EditorScene::setWidth(const uint &wid) {
_width = wid;
while (_width % 10) ++ _width;
_width /= 10;
}
inline uint EditorScene::width() const {
return(_width * 10);
}
inline void EditorScene::setHeight(const uint &hei) {
_height = hei;
while (_height % 10) ++ _height;
_height /= 10;
}
inline uint EditorScene::height() const {
return(_height * 10);
}
inline void EditorScene::setHotspot(const QPoint &hs) {
_hotspot = hs;
}
inline QPoint EditorScene::hotspot() const {
return(_hotspot);
}
inline void EditorScene::setNames(const NamesList nameslist) {
_names = nameslist;
}
inline NamesList EditorScene::names() const {
return(_names);
}
inline OrientationSet EditorScene::orientations() {
return(ori);
}
inline void EditorScene::setOrientations(const OrientationSet &orientation_set) {
ori = orientation_set;
}
#endif

66
editor/ellipseeditor.cpp Normal file
View File

@@ -0,0 +1,66 @@
#include "ellipseeditor.h"
#include "partellipse.h"
EllipseEditor::EllipseEditor(PartEllipse *ellipse, QWidget *parent) : QWidget(parent) {
part = ellipse;
x = new QLineEdit();
y = new QLineEdit();
h = new QLineEdit();
v = new QLineEdit();
// QDoubleValidator *format = new QDoubleValidator(-1000.0, -1000.0, 4, this);
// x -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
// y -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
// h -> setValidator(new QDoubleValidator(0.0, 1000.0, 4, this));
// v -> setValidator(new QDoubleValidator(0.0, 1000.0, 4, this));
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
grid -> addWidget(new QLabel(tr("Diam\350tres : ")), 2, 0);
grid -> addWidget(new QLabel(tr("horizontal :")), 3, 0);
grid -> addWidget(h, 3, 1);
grid -> addWidget(new QLabel(tr("vertical :")), 4, 0);
grid -> addWidget(v, 4, 1);
updateForm();
connect(x, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
connect(y, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
connect(h, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
connect(v, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
}
EllipseEditor::~EllipseEditor() {
qDebug() << "~EllipseEditor()";
}
void EllipseEditor::updateEllipse() {
qreal _x = x -> text().toDouble();
qreal _y = y -> text().toDouble();
qreal _h = h -> text().toDouble();
qreal _v = v -> text().toDouble();
_v = _v < 0 ? -_v : _v;
part -> setRect(
QRectF(
part -> mapFromScene(QPointF(_x - (_h / 2.0), _y - (_v / 2.0))),
QSizeF(_h, _v)
)
);
}
void EllipseEditor::updateForm() {
qreal _h = part -> rect().width();
qreal _v = part -> rect().height();
QPointF top_left(part -> sceneTopLeft());
x -> setText(QString("%1").arg(top_left.x() + (_h / 2.0)));
y -> setText(QString("%1").arg(top_left.y() + (_v / 2.0)));
h -> setText(QString("%1").arg(_h));
v -> setText(QString("%1").arg(_v));
}

24
editor/ellipseeditor.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef ELLIPSE_EDITOR_H
#define ELLIPSE_EDITOR_H
#include <QtGui>
class PartEllipse;
class EllipseEditor : public QWidget {
Q_OBJECT
//constructeurs, destructeur
public:
EllipseEditor(PartEllipse *, QWidget * = 0);
~EllipseEditor();
private:
EllipseEditor(const EllipseEditor &);
// attributs
private:
PartEllipse *part;
QLineEdit *x, *y, *h, *v;
// methodes
public slots:
void updateEllipse();
void updateForm();
};
#endif

57
editor/lineeditor.cpp Normal file
View File

@@ -0,0 +1,57 @@
#include "lineeditor.h"
#include "partline.h"
LineEditor::LineEditor(PartLine *line, QWidget *parent) : QWidget(parent) {
part = line;
x1 = new QLineEdit();
y1 = new QLineEdit();
x2 = new QLineEdit();
y2 = new QLineEdit();
QGridLayout *grid = new QGridLayout(this);
grid -> addWidget(new QLabel("x1"), 0, 0);
grid -> addWidget(x1, 0, 1);
grid -> addWidget(new QLabel("y1"), 0, 2);
grid -> addWidget(y1, 0, 3);
grid -> addWidget(new QLabel("x2"), 1, 0);
grid -> addWidget(x2, 1, 1);
grid -> addWidget(new QLabel("y2"), 1, 2);
grid -> addWidget(y2, 1, 3);
updateForm();
connect(x1, SIGNAL(editingFinished()), this, SLOT(updateLine()));
connect(y1, SIGNAL(editingFinished()), this, SLOT(updateLine()));
connect(x2, SIGNAL(editingFinished()), this, SLOT(updateLine()));
connect(y2, SIGNAL(editingFinished()), this, SLOT(updateLine()));
}
LineEditor::~LineEditor() {
qDebug() << "~LineEditor()";
}
void LineEditor::updateLine() {
part -> setLine(
QLineF(
part -> mapFromScene(
x1 -> text().toDouble(),
y1 -> text().toDouble()
),
part -> mapFromScene(
x2 -> text().toDouble(),
y2 -> text().toDouble()
)
)
);
}
void LineEditor::updateForm() {
QPointF p1(part -> sceneP1());
QPointF p2(part -> sceneP2());
x1 -> setText(QString("%1").arg(p1.x()));
y1 -> setText(QString("%1").arg(p1.y()));
x2 -> setText(QString("%1").arg(p2.x()));
y2 -> setText(QString("%1").arg(p2.y()));
}

24
editor/lineeditor.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef LINE_EDITOR_H
#define LINE_EDITOR_H
#include <QtGui>
class PartLine;
class LineEditor : public QWidget {
Q_OBJECT
//constructeurs, destructeur
public:
LineEditor(PartLine *, QWidget * = 0);
~LineEditor();
private:
LineEditor(const LineEditor &);
// attributs
private:
PartLine *part;
QLineEdit *x1, *y1, *x2, *y2;
// methodes
public slots:
void updateLine();
void updateForm();
};
#endif

77
editor/partcircle.cpp Normal file
View File

@@ -0,0 +1,77 @@
#include "partcircle.h"
#include "circleeditor.h"
PartCircle::PartCircle(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart() {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new CircleEditor(this);
style_editor -> appendWidget(informations);
}
void PartCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> drawEllipse(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
QPointF center = rect().center();
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
}
}
const QDomElement PartCircle::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("circle");
QPointF top_left(sceneTopLeft());
xml_element.setAttribute("x", top_left.x());
xml_element.setAttribute("y", top_left.y());
xml_element.setAttribute("diameter", rect().width());
stylesToXml(xml_element);
return(xml_element);
}
void PartCircle::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
qreal diameter = qde.attribute("diameter", "0").toDouble();
setRect(
QRectF(
mapFromScene(
qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()
),
QSizeF(
diameter,
diameter
)
)
);
}
QVariant PartCircle::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));
}
QPointF PartCircle::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}
QPointF PartCircle::sceneCenter() const {
return(mapToScene(rect().center()));
}
QRectF PartCircle::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsEllipseItem::boundingRect());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}

33
editor/partcircle.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef PART_CIRCLE_H
#define PART_CIRCLE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class CircleEditor;
class PartCircle : public QGraphicsEllipseItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartCircle(QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartCircle() {
qDebug() << "~PartCircle()";
}
private:
PartCircle(const PartCircle &);
// attributs
private:
CircleEditor *informations;
// methodes
public:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;
virtual QRectF boundingRect() const;
QPointF sceneCenter() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
#endif

66
editor/partellipse.cpp Normal file
View File

@@ -0,0 +1,66 @@
#include "partellipse.h"
#include "ellipseeditor.h"
PartEllipse::PartEllipse(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart() {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new EllipseEditor(this);
style_editor -> appendWidget(informations);
}
void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> drawEllipse(rect());
if (isSelected()) {
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
QPointF center = rect().center();
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
}
}
const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("ellipse");
QPointF top_left(sceneTopLeft());
xml_element.setAttribute("x", top_left.x());
xml_element.setAttribute("y", top_left.y());
xml_element.setAttribute("width", rect().width());
xml_element.setAttribute("height", rect().height());
stylesToXml(xml_element);
return(xml_element);
}
void PartEllipse::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
setRect(
QRectF(
mapFromScene(
qde.attribute("x", "0").toDouble(),
qde.attribute("y", "0").toDouble()
),
QSizeF(
qde.attribute("width", "0").toDouble(),
qde.attribute("height", "0").toDouble()
)
)
);
}
QVariant PartEllipse::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsEllipseItem::itemChange(change, value));
}
QPointF PartEllipse::sceneTopLeft() const {
return(mapToScene(rect().topLeft()));
}

31
editor/partellipse.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef PART_ELLIPSE_H
#define PART_ELLIPSE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class EllipseEditor;
class PartEllipse : public QGraphicsEllipseItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartEllipse(QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartEllipse() {
qDebug() << "~PartEllipse()";
}
private:
PartEllipse(const PartEllipse &);
// attributs
private:
EllipseEditor *informations;
// methodes
public:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneTopLeft() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
#endif

143
editor/partline.cpp Normal file
View File

@@ -0,0 +1,143 @@
#include "partline.h"
#include "lineeditor.h"
#include <cmath>
PartLine::PartLine(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsLineItem(parent, scene), CustomElementGraphicPart() {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new LineEditor(this);
style_editor -> appendWidget(informations);
}
void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem */*q*/, QWidget */*w*/) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
painter -> setBrush(Qt::NoBrush);
painter -> drawLine(line());
}
const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("line");
QPointF p1(sceneP1());
QPointF p2(sceneP2());
xml_element.setAttribute("x1", p1.x());
xml_element.setAttribute("y1", p1.y());
xml_element.setAttribute("x2", p2.x());
xml_element.setAttribute("y2", p2.y());
stylesToXml(xml_element);
return(xml_element);
}
void PartLine::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
setLine(
QLineF(
mapFromScene(
qde.attribute("x1", "0").toDouble(),
qde.attribute("y1", "0").toDouble()
),
mapFromScene(
qde.attribute("x2", "0").toDouble(),
qde.attribute("y2", "0").toDouble()
)
)
);
}
QVariant PartLine::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsLineItem::itemChange(change, value));
}
QPointF PartLine::sceneP1() const {
return(mapToScene(line().p1()));
}
QPointF PartLine::sceneP2() const {
return(mapToScene(line().p2()));
}
/*
*/
QPainterPath PartLine::shape() const {
QList<QPointF> points = fourShapePoints();
QPainterPath t;
t.setFillRule(Qt::WindingFill);
t.moveTo(points.at(0));
t.lineTo(points.at(1));
t.lineTo(points.at(2));
t.lineTo(points.at(3));
t.lineTo(points.at(0));
return(t);
}
/*
QRectF PartLine::boundingRect() const {
QList<QPointF> points = fourShapePoints();
qreal min_x = points.first().x();
qreal max_x = points.first().x();
qreal min_y = points.first().y();
qreal max_y = points.first().y();
foreach(QPointF p, points) {
if (p.x() > max_x) max_x = p.x();
if (p.x() < min_x) min_x = p.x();
if (p.y() > max_y) max_y = p.y();
if (p.y() < min_y) min_y = p.y();
}
QRectF r;
r.setCoords(min_x, min_y, max_x, max_y);
return(r);
}
*/
/**
@return une liste contenant les deux points de la droite + les 4 points entourant ces deux points
*/
QList<QPointF> PartLine::fourShapePoints() const {
// on a donc A(xa , ya) et B(xb, yb)
QPointF a = line().p1();
QPointF b = line().p2();
// on calcule le vecteur AB : (xb-xa, yb-ya)
QPointF v_ab = b - a;
// et la distance AB : racine des coordonnees du vecteur au carre
qreal ab = sqrt(pow(v_ab.x(), 2) + pow(v_ab.y(), 2));
// ensuite on definit le vecteur u(a, b) qui est egal au vecteur AB divise
// par sa longueur et multiplie par la longueur de la marge que tu veux
// laisser
QPointF u = v_ab / ab * 2.0;
// on définit le vecteur v(-b , a) qui est perpendiculaire à AB
QPointF v(-u.y(), u.x());
QPointF m = -u + v; // on a le vecteur M = -u + v
QPointF n = -u - v; // et le vecteur N=-u-v
QPointF h = a + m; // H = A + M
QPointF k = a + n; // K = A + N
QPointF i = b - n; // I = B - N
QPointF j = b - m; // J = B - M
QList<QPointF> result;
result << h << i << j << k;
return(result);
}
QRectF PartLine::boundingRect() const {
qreal adjust = 1.5;
QRectF r(QGraphicsLineItem::boundingRect());
r.adjust(-adjust, -adjust, adjust, adjust);
return(r);
}

37
editor/partline.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef PART_LINE_H
#define PART_LINE_H
#include <QtGui>
#include "customelementgraphicpart.h"
class LineEditor;
class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartLine(QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartLine() {
qDebug() << "~PartLine()";
}
private:
PartLine(const PartLine &);
// attributs
private:
LineEditor *informations;
// methodes
public:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
virtual const QDomElement toXml(QDomDocument &) const;
virtual void fromXml(const QDomElement &);
virtual QPointF sceneP1() const;
virtual QPointF sceneP2() const;
virtual QPainterPath shape() const;
virtual QRectF boundingRect() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
private:
QList<QPointF> fourShapePoints() const;
};
#endif

69
editor/partpolygon.cpp Normal file
View File

@@ -0,0 +1,69 @@
#include "partpolygon.h"
#include "qet.h"
#include "polygoneditor.h"
PartPolygon::PartPolygon(QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsPolygonItem(parent, scene),
CustomElementGraphicPart(),
closed(false)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptedMouseButtons(Qt::LeftButton);
informations = new PolygonEditor(this);
style_editor -> appendWidget(informations);
}
void PartPolygon::fromXml(const QDomElement &qde) {
stylesFromXml(qde);
int i = 1;
while(true) {
if (
QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
QET::attributeIsAReal(qde, QString("y%1").arg(i))
) ++ i;
else break;
}
QPolygonF temp_polygon;
for (int j = 1 ; j < i ; ++ j) {
temp_polygon << QPointF(
qde.attribute(QString("x%1").arg(j)).toDouble(),
qde.attribute(QString("y%1").arg(j)).toDouble()
);
}
setPolygon(temp_polygon);
closed = qde.attribute("closed") != "false";
}
const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("polygon");
int i = 1;
foreach(QPointF point, polygon()) {
xml_element.setAttribute(QString("x%1").arg(i), point.x());
xml_element.setAttribute(QString("y%1").arg(i), point.y());
++ i;
}
if (!closed) xml_element.setAttribute("closed", "false");
stylesToXml(xml_element);
return(xml_element);
}
void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem */*q*/, QWidget */*w*/) {
applyStylesToQPainter(*painter);
QPen t = painter -> pen();
if (isSelected()) {
t.setColor(Qt::red);
painter -> setPen(t);
}
if (closed) painter -> drawPolygon(polygon());
else painter -> drawPolyline(polygon());
}
QVariant PartPolygon::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsPolygonItem::itemChange(change, value));
}

61
editor/partpolygon.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef PART_POLYGON_H
#define PART_POLYGON_H
#include <QtGui>
#include "customelementgraphicpart.h"
class PolygonEditor;
class PartPolygon : public QGraphicsPolygonItem, public CustomElementGraphicPart {
// constructeurs, destructeur
public:
PartPolygon(QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartPolygon() {
qDebug() << "~PartPolygon()";
}
private:
PartPolygon(const PartPolygon &);
// attributs
private:
bool closed;
PolygonEditor *informations;
/**
constructeur
paint()
widget bidon pour l'edition
methode pour poser le polygone :
-mousePressEvent = pose un nouveau point
-mouseMoveEvent = deplace ce point
-mouveReleaseEvent = finalise ce point
utiliser QPolygonF ; memoriser le point en cours (tout comme le
partploygon en cours) et ne l'ajouter au qpolygonf que lors du
mouseReleaseEvent
*/
// methodes
public:
void fromXml(const QDomElement &);
const QDomElement toXml(QDomDocument &) const;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
void setClosed(bool c);
bool isClosed() const;
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
};
/**
Specifie si le polygone doit etre ferme
@param c true pour un polygone ferme, false sinon
*/
inline void PartPolygon::setClosed(bool c) {
closed = c;
}
/**
Indique si le polygone est ferme
@return true si le polygone est ferme, false sinon
*/
inline bool PartPolygon::isClosed() const {
return(closed);
}
#endif

117
editor/partterminal.cpp Normal file
View File

@@ -0,0 +1,117 @@
#include "partterminal.h"
#include "terminal.h"
#include "terminaleditor.h"
PartTerminal::PartTerminal(QGraphicsItem *parent, QGraphicsScene *scene) :
CustomElementPart(),
QGraphicsItem(parent, scene),
_orientation(QET::North)
{
informations = new TerminalEditor(this);
updateSecondPoint();
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setZValue(100000);
}
PartTerminal::~PartTerminal() {
qDebug() << "~PartTerminal()";
delete informations;
};
void PartTerminal::fromXml(const QDomElement &xml_elmt) {
// lit la position de la borne
qreal term_x = 0.0, term_y = 0.0;
QET::attributeIsAReal(xml_elmt, "x", &term_x);
QET::attributeIsAReal(xml_elmt, "y", &term_y);
setPos(QPointF(term_x, term_y));
// lit l'orientation de la borne
_orientation = QET::orientationFromString(xml_elmt.attribute("orientation"));
updateSecondPoint();
}
const QDomElement PartTerminal::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("terminal");
// ecrit la position de la borne
xml_element.setAttribute("x", QString("%1").arg(pos().x()));
xml_element.setAttribute("y", QString("%1").arg(pos().y()));
// ecrit l'orientation de la borne
xml_element.setAttribute("orientation", orientationToString(_orientation));
return(xml_element);
}
QWidget *PartTerminal::elementInformations() {
return(informations);
}
void PartTerminal::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) {
p -> save();
// annulation des renderhints
p -> setRenderHint(QPainter::Antialiasing, false);
p -> setRenderHint(QPainter::TextAntialiasing, false);
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
QPen t;
t.setWidthF(1.0);
// dessin de la borne en rouge
t.setColor(Qt::red);
p -> setPen(t);
p -> drawLine(QPointF(0.0, 0.0), second_point);
// dessin du point d'amarrage au conducteur en bleu
t.setColor(Terminal::couleur_neutre);
p -> setPen(t);
p -> setBrush(Terminal::couleur_neutre);
p -> drawPoint(QPointF(0.0, 0.0));
p -> restore();
}
QRectF PartTerminal::boundingRect() const {
QPointF p1, p2;
if (second_point.x() <= 0.0 && second_point.y() <= 0.0) {
p1 = second_point;
p2 = QPointF(0.0, 0.0);
} else {
p1 = QPointF(0.0, 0.0);
p2 = second_point;
}
QRectF br;
br.setTopLeft (p1 - QPointF(2.0, 2.0));
br.setBottomRight(p2 + QPointF(2.0, 2.0));
return(br);
}
QET::Orientation PartTerminal::orientation() const {
return(_orientation);
}
void PartTerminal::setOrientation(QET::Orientation ori) {
prepareGeometryChange();
_orientation = ori;
updateSecondPoint();
informations -> updateForm();
}
QVariant PartTerminal::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene()) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
informations -> updateForm();
}
}
return(QGraphicsItem::itemChange(change, value));
}
void PartTerminal::updateSecondPoint() {
qreal ts = 4.0; // terminal size
switch(_orientation) {
case QET::North: second_point = QPointF(0.0, ts); break;
case QET::East : second_point = QPointF(-ts, 0.0); break;
case QET::South: second_point = QPointF(0.0, -ts); break;
case QET::West : second_point = QPointF(ts, 0.0); break;
}
}

37
editor/partterminal.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef PART_TERMINAL_H
#define PART_TERMINAL_H
#include "customelementpart.h"
#include "qet.h"
#include <QtGui>
class TerminalEditor;
class PartTerminal : public CustomElementPart, public QGraphicsItem {
public:
// constructeurs, destructeur
PartTerminal(QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartTerminal();
private:
PartTerminal(const PartTerminal &);
// attributs
private:
QET::Orientation _orientation;
QPointF second_point;
TerminalEditor *informations;
// methodes
public:
virtual void fromXml(const QDomElement &);
virtual const QDomElement toXml(QDomDocument &) const;
virtual QWidget *elementInformations();
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
virtual QRectF boundingRect() const;
QET::Orientation orientation() const;
void setOrientation(QET::Orientation);
protected:
QVariant itemChange(GraphicsItemChange, const QVariant &);
private:
void updateSecondPoint();
};
#endif

104
editor/parttext.cpp Normal file
View File

@@ -0,0 +1,104 @@
#include "parttext.h"
#include "texteditor.h"
PartText::PartText(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsTextItem(parent, scene), CustomElementPart(), can_check_changes(true) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setPlainText(tr("T"));
infos = new TextEditor(this);
}
PartText::~PartText() {
qDebug() << "~PartText()";
delete infos;
}
void PartText::fromXml(const QDomElement &xml_element) {
bool ok;
int font_size = xml_element.attribute("size").toInt(&ok);
if (!ok || font_size < 1) font_size = 20;
setFont(QFont(QString("Sans Serif"), font_size));
setPlainText(xml_element.attribute("text"));
setPos(
xml_element.attribute("x").toDouble(),
xml_element.attribute("y").toDouble()
);
}
const QDomElement PartText::toXml(QDomDocument &xml_document) const {
QDomElement xml_element = xml_document.createElement("text");
xml_element.setAttribute("x", QString("%1").arg(pos().x()));
xml_element.setAttribute("y", QString("%1").arg(pos().y()));
xml_element.setAttribute("text", toPlainText());
xml_element.setAttribute("size", font().pointSize());
return(xml_element);
}
QWidget *PartText::elementInformations() {
return(infos);
}
/**
Retourne la position du texte, l'origine etant le point en bas a gauche du
texte (et pas du cadre)
@return la position du texte
*/
QPointF PartText::pos() const {
return(QGraphicsTextItem::pos() + margin());
}
void PartText::setPos(const QPointF &left_corner_pos) {
QGraphicsTextItem::setPos(left_corner_pos - margin());
}
void PartText::setPos(qreal x, qreal y) {
QGraphicsTextItem::setPos(QPointF(x, y) - margin());
}
/**
@return Les coordonnees du point situe en bas a gauche du texte.
*/
QPointF PartText::margin() const {
QFont used_font = font();
QFontMetrics qfm(used_font);
QPointF margin(
(boundingRect().width () - qfm.width(toPlainText())) / 2.0,
((boundingRect().height() - used_font.pointSizeF()) / 3.0) + used_font.pointSizeF()
);
return(margin);
}
/**
Permet a l'element texte de redevenir deplacable a la fin de l'edition de texte
@param e Le QFocusEvent decrivant la perte de focus
*/
void PartText::focusOutEvent(QFocusEvent *e) {
QGraphicsTextItem::focusOutEvent(e);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
Permet a l'element texte de devenir editable lorsqu'on double-clique dessus
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
*/
void PartText::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
setTextInteractionFlags(Qt::TextEditorInteraction);
QGraphicsTextItem::mouseDoubleClickEvent(e);
setFocus(Qt::MouseFocusReason);
}
QVariant PartText::itemChange(GraphicsItemChange change, const QVariant &value) {
if (scene() && can_check_changes) {
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
infos -> updateForm();
}
}
return(QGraphicsTextItem::itemChange(change, value));
}
QRectF PartText::boundingRect() const {
QRectF r = QGraphicsTextItem::boundingRect();
r.adjust(0.0, -2.0, 0.0, 0.0);
return(r);
}

39
editor/parttext.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef PART_TEXT
#define PART_TEXT
#include <QtGui>
#include "customelementgraphicpart.h"
class TextEditor;
class PartText : public QGraphicsTextItem, public CustomElementPart {
// constructeurs, destructeur
public:
PartText(QGraphicsItem * = 0, QGraphicsScene * = 0);
virtual ~PartText();
private:
PartText(const PartText &);
// attributs
TextEditor *infos;
// methodes
public:
void fromXml(const QDomElement &);
const QDomElement toXml(QDomDocument &) const;
QWidget *elementInformations();
QPointF pos() const;
void setPos(const QPointF &);
void setPos(qreal, qreal);
protected:
virtual void focusOutEvent(QFocusEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
QRectF boundingRect() const;
public:
bool can_check_changes;
private:
QPointF margin() const;
};
#endif

89
editor/polygoneditor.cpp Normal file
View File

@@ -0,0 +1,89 @@
#include "polygoneditor.h"
#include "partpolygon.h"
/**
Constructeur
@param p Le polygone a editer
@param parent le Widget parent
*/
PolygonEditor::PolygonEditor(PartPolygon *p, QWidget *parent) :
QWidget(parent),
points_list(this),
close_polygon(tr("Polygone ferm\351"), this)
{
part = p;
// prepare la liste de points
points_list.setColumnCount(2);
QStringList headers;
headers << tr("x") << tr("y");
points_list.setHeaderLabels(headers);
points_list.setRootIsDecorated(false);
updateForm();
// layout
QVBoxLayout *layout = new QVBoxLayout(this);
layout -> addWidget(new QLabel(tr("Points du polygone :")));
layout -> addWidget(&points_list);
layout -> addWidget(&close_polygon);
// connexions signaux/slots
connect(&close_polygon, SIGNAL(stateChanged(int)), this, SLOT(updatePolygonClosedState()));
connect(&points_list, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(validColumn(QTreeWidgetItem *, int)));
}
void PolygonEditor::updatePolygon() {
updatePolygonPoints();
updatePolygonClosedState();
}
void PolygonEditor::updatePolygonPoints() {
QVector<QPointF> points = getPointsFromTree();
if (points.count() < 2) {
QMessageBox::warning(
this,
tr("Erreur"),
tr("Le polygone doit comporter au moins deux points.")
);
return;
}
part -> setPolygon(points);
}
void PolygonEditor::updatePolygonClosedState() {
part -> setClosed(close_polygon.isChecked());
}
void PolygonEditor::updateForm() {
while(points_list.takeTopLevelItem(0));
foreach(QPointF point, part -> polygon()) {
point = part -> mapToScene(point);
QStringList qsl;
qsl << QString("%1").arg(point.x()) << QString("%1").arg(point.y());
QTreeWidgetItem *qtwi = new QTreeWidgetItem(qsl);
qtwi -> setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
points_list.addTopLevelItem(qtwi);
}
close_polygon.setChecked(part -> isClosed());
}
QVector<QPointF> PolygonEditor::getPointsFromTree() {
QVector<QPointF> points;
for(int i = 0 ; i < points_list.topLevelItemCount() ; ++ i) {
QTreeWidgetItem *qtwi = points_list.topLevelItem(i);
bool x_convert_ok, y_convert_ok;
qreal x = qtwi -> text(0).toDouble(&x_convert_ok);
qreal y = qtwi -> text(1).toDouble(&y_convert_ok);
if (!x_convert_ok || !y_convert_ok) continue;
points << part -> mapFromScene(QPointF(x, y));
}
return(points);
}
void PolygonEditor::validColumn(QTreeWidgetItem *qtwi, int column) {
bool convert_ok;
qtwi -> text(column).toDouble(&convert_ok);
if (convert_ok) {
points_list.closePersistentEditor(qtwi, column);
updatePolygonPoints();
} else points_list.openPersistentEditor(qtwi, column);
}

35
editor/polygoneditor.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef POLYGON_EDITOR_H
#define POLYGON_EDITOR_H
#include <QtGui>
class PartPolygon;
class PolygonEditor : public QWidget {
Q_OBJECT
// constructeurs, destructeur
public:
PolygonEditor(PartPolygon *, QWidget * = 0);
~PolygonEditor() {
qDebug() << "~PolygonEditor()";
}
private:
PolygonEditor(const PolygonEditor &);
// attributs
private:
PartPolygon *part;
QTreeWidget points_list;
QCheckBox close_polygon;
// methodes
private:
QVector<QPointF> getPointsFromTree();
public slots:
void updatePolygon();
void updatePolygonPoints();
void updatePolygonClosedState();
void updateForm();
void validColumn(QTreeWidgetItem *qtwi, int column);
};
#endif

125
editor/qet.cpp Normal file
View File

@@ -0,0 +1,125 @@
#include "qet.h"
/**
Permet de convertir une chaine de caracteres ("n", "s", "e" ou "w")
en orientation. Si la chaine fait plusieurs caracteres, seul le
premier est pris en compte. En cas d'incoherence, QET::North est
retourne.
@param s Chaine de caractere cense representer une orientation
@return l'orientation designee par la chaine de caractere
*/
QET::Orientation QET::orientationFromString(const QString &s) {
QChar c = s[0];
if (c == 'e') return(QET::East);
else if (c == 's') return(QET::South);
else if (c == 'w') return (QET::West);
else return(QET::North);
}
/**
@param o une orientation
@return une chaine de caractere representant l'orientation
*/
QString QET::orientationToString(QET::Orientation o) {
QString ret;
switch(o) {
case QET::North: ret = "n"; break;
case QET::East : ret = "e"; break;
case QET::South: ret = "s"; break;
case QET::West : ret = "w"; break;
}
return(ret);
}
/**
Indique si deux orientations de Borne sont sur le meme axe (Vertical / Horizontal).
@param a La premiere orientation de Borne
@param b La seconde orientation de Borne
@return Un booleen a true si les deux orientations de bornes sont sur le meme axe
*/
bool QET::surLeMemeAxe(QET::Orientation a, QET::Orientation b) {
if ((a == QET::North || a == QET::South) && (b == QET::North || b == QET::South)) return(true);
else if ((a == QET::East || a == QET::West) && (b == QET::East || b == QET::West)) return(true);
else return(false);
}
/**
Indique si une orientation de borne est horizontale (Est / Ouest).
@param a L'orientation de borne
@return True si l'orientation de borne est horizontale, false sinon
*/
bool QET::estHorizontale(QET::Orientation a) {
return(a == QET::East || a == QET::West);
}
/**
Indique si une orientation de borne est verticale (Nord / Sud).
@param a L'orientation de borne
@return True si l'orientation de borne est verticale, false sinon
*/
bool QET::estVerticale(QET::Orientation a) {
return(a == QET::North || a == QET::South);
}
/**
Permet de connaitre l'orientation suivante apres celle donnee en parametre.
Les orientations sont generalement presentees dans l'ordre suivant : Nord,
Est, Sud, Ouest.
@param o une orientation
@return l'orientation suivante
*/
QET::Orientation QET::nextOrientation(QET::Orientation o) {
if (o < 0 || o > 2) return(QET::North);
return((QET::Orientation)(o + 1));
}
/**
Permet de connaitre l'orientation precedant celle donnee en parametre.
Les orientations sont generalement presentees dans l'ordre suivant : Nord,
Est, Sud, Ouest.
@param o une orientation
@return l'orientation precedente
*/
QET::Orientation QET::previousOrientation(QET::Orientation o) {
if (o < 0 || o > 3) return(QET::North);
if (o == QET::North) return(QET::West);
return((QET::Orientation)(o - 1));
}
/**
Permet de savoir si l'attribut nom_attribut d'un element XML e est bien un
entier. Si oui, sa valeur est copiee dans entier.
@param e Element XML
@param nom_attribut Nom de l'attribut a analyser
@param entier Pointeur facultatif vers un entier
@return true si l'attribut est bien un entier, false sinon
*/
bool QET::attributeIsAnInteger(const QDomElement &e, QString nom_attribut, int *entier) {
// verifie la presence de l'attribut
if (!e.hasAttribute(nom_attribut)) return(false);
// verifie la validite de l'attribut
bool ok;
int tmp = e.attribute(nom_attribut).toInt(&ok);
if (!ok) return(false);
if (entier != NULL) *entier = tmp;
return(true);
}
/**
Permet de savoir si l'attribut nom_attribut d'un element XML e est bien un
reel. Si oui, sa valeur est copiee dans reel.
@param e Element XML
@param nom_attribut Nom de l'attribut a analyser
@param reel Pointeur facultatif vers un double
@return true si l'attribut est bien un reel, false sinon
*/
bool QET::attributeIsAReal(const QDomElement &e, QString nom_attribut, double *reel) {
// verifie la presence de l'attribut
if (!e.hasAttribute(nom_attribut)) return(false);
// verifie la validite de l'attribut
bool ok;
qreal tmp = e.attribute(nom_attribut).toDouble(&ok);
if (!ok) return(false);
if (reel != NULL) *reel = tmp;
return(true);
}

121
editor/styleeditor.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include "styleeditor.h"
#include "customelementgraphicpart.h"
StyleEditor::StyleEditor(CustomElementGraphicPart *p, QWidget *parent) : QWidget(parent), part(p) {
// couleur
color = new QButtonGroup(this);
color -> addButton(black_color = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackColor);
color -> addButton(white_color = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteColor);
connect(color, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
// style
style = new QButtonGroup(this);
style -> addButton(normal_style = new QRadioButton(tr("Normal")), CustomElementGraphicPart::NormalStyle);
style -> addButton(dashed_style = new QRadioButton(tr("Pointill\351")), CustomElementGraphicPart::DashedStyle);
style -> button(part -> lineStyle()) -> setChecked(true);
connect(style, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
// epaisseur
weight = new QButtonGroup(this);
weight -> addButton(none_weight = new QRadioButton(tr("Nulle")), CustomElementGraphicPart::NoneWeight);
weight -> addButton(thin_weight = new QRadioButton(tr("Fine")), CustomElementGraphicPart::ThinWeight);
weight -> addButton(normal_weight = new QRadioButton(tr("Normale")), CustomElementGraphicPart::NormalWeight);
connect(weight, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
// remplissage
filling = new QButtonGroup(this);
filling -> addButton(no_filling = new QRadioButton(tr("Aucun")), CustomElementGraphicPart::NoneFilling );
filling -> addButton(black_filling = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackFilling);
filling -> addButton(white_filling = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteFilling);
connect(filling, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
// antialiasing
antialiasing = new QCheckBox(tr("Antialiasing"));
connect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePart()));
updateForm();
main_layout = new QVBoxLayout();
main_layout -> addWidget(antialiasing);
main_layout -> addWidget(new QLabel("<u>" + tr("Trait :") + "</u> "));
QHBoxLayout *color_layout = new QHBoxLayout();
color_layout -> addWidget(new QLabel(tr("Couleur : ")));
color_layout -> addWidget(black_color);
color_layout -> addWidget(white_color);
color_layout -> addStretch();
main_layout -> addItem(color_layout);
QHBoxLayout *style_layout = new QHBoxLayout();
style_layout -> addWidget(new QLabel(tr("Style : ")));
style_layout -> addWidget(normal_style);
style_layout -> addWidget(dashed_style);
style_layout -> addStretch();
main_layout -> addItem(style_layout);
QHBoxLayout *weight_layout = new QHBoxLayout();
weight_layout -> addWidget(new QLabel(tr("\311paisseur : ")));
weight_layout -> addWidget(none_weight);
weight_layout -> addWidget(thin_weight);
weight_layout -> addWidget(normal_weight);
weight_layout -> addStretch();
main_layout -> addItem(weight_layout);
main_layout -> addWidget(new QLabel("<u>" + tr("Remplissage :") + "</u> "));
QHBoxLayout *filling_layout = new QHBoxLayout();
filling_layout -> addWidget(no_filling);
filling_layout -> addWidget(black_filling);
filling_layout -> addWidget(white_filling);
filling_layout -> addStretch();
main_layout -> addItem(filling_layout);
main_layout -> addStretch();
setLayout(main_layout);
}
StyleEditor::~StyleEditor() {
qDebug() << "~StyleEditor()";
}
void StyleEditor::updatePart() {
// applique l'antialiasing
part -> setAntialiased(antialiasing -> isChecked());
// applique la couleur
part -> setColor(static_cast<CEGP::Color>(color -> checkedId()));
// applique le style
part -> setLineStyle(static_cast<CEGP::LineStyle>(style -> checkedId()));
// applique l'epaisseur
part -> setLineWeight(static_cast<CEGP::LineWeight>(weight -> checkedId()));
// applique le remplissage
part -> setFilling(static_cast<CEGP::Filling>(filling -> checkedId()));
}
void StyleEditor::updateForm() {
// lit l'antialiasing : deconnexion du slot pour eviter l'appel a updatePart()
disconnect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePart()));
antialiasing -> setChecked(part -> antialiased());
connect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePart()));
// lit la couleur
color -> button(part -> color()) -> setChecked(true);
// lit le style
style -> button(part -> lineStyle()) -> setChecked(true);
// lit l'epaisseur
weight -> button(part -> lineWeight()) -> setChecked(true);
// lit le remplissage
filling -> button(part -> filling()) -> setChecked(true);
}
void StyleEditor::appendWidget(QWidget *w) {
main_layout -> insertWidget(7, w);
}

33
editor/styleeditor.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef STYLE_EDITOR_H
#define STYLE_EDITOR_H
#include <QtGui>
class CustomElementGraphicPart;
class StyleEditor : public QWidget {
Q_OBJECT
// constructeurs, destructeur
public:
StyleEditor(CustomElementGraphicPart *, QWidget * = 0);
virtual ~StyleEditor();
private:
StyleEditor(const StyleEditor &);
// attributs
private:
CustomElementGraphicPart *part;
QVBoxLayout *main_layout;
QButtonGroup *color, *style, *weight, *filling;
QRadioButton *black_color, *white_color, *normal_style, *dashed_style;
QRadioButton *none_weight, *thin_weight, *normal_weight, *no_filling;
QRadioButton *black_filling, *white_filling;
QCheckBox *antialiasing;
//methodes
public:
void appendWidget(QWidget *w);
public slots:
void updatePart();
void updateForm();
};
#endif

67
editor/terminaleditor.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include "terminaleditor.h"
#include "partterminal.h"
/**
Constructeur
@param term Borne a editer
@param parent QWidget parent de ce widget
*/
TerminalEditor::TerminalEditor(PartTerminal *term, QWidget *parent) : QWidget(parent) {
part = term;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
orientation = new QComboBox();
orientation -> addItem(QIcon(":/ico/north.png"), tr("Nord"), QET::North);
orientation -> addItem(QIcon(":/ico/east.png"), tr("Est"), QET::East);
orientation -> addItem(QIcon(":/ico/south.png"), tr("Sud"), QET::South);
orientation -> addItem(QIcon(":/ico/west.png"), tr("Ouest"), QET::West);
QVBoxLayout *main_layout = new QVBoxLayout();
main_layout -> addWidget(new QLabel(tr("Postion : ")));
QHBoxLayout *position = new QHBoxLayout();
position -> addWidget(new QLabel(tr("x : ")));
position -> addWidget(qle_x );
position -> addWidget(new QLabel(tr("y : ")));
position -> addWidget(qle_y );
main_layout -> addLayout(position);
QHBoxLayout *ori = new QHBoxLayout();
ori -> addWidget(new QLabel(tr("Orientation : ")));
ori -> addWidget(orientation );
main_layout -> addLayout(ori);
main_layout -> addStretch();
setLayout(main_layout);
connect(qle_x, SIGNAL(textEdited(const QString &)), this, SLOT(updateTerminal()));
connect(qle_y, SIGNAL(textEdited(const QString &)), this, SLOT(updateTerminal()));
connect(orientation, SIGNAL(activated(int)), this, SLOT(updateTerminal()));
updateForm();
}
/**
Destructeur
*/
TerminalEditor::~TerminalEditor() {
qDebug() << "~TerminalEditor()";
};
void TerminalEditor::updateTerminal() {
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
part -> setOrientation(
static_cast<QET::Orientation>(
orientation -> itemData(
orientation -> currentIndex()
).toInt()
)
);
}
void TerminalEditor::updateForm() {
qle_x -> setText(QString("%1").arg(part -> pos().x()));
qle_y -> setText(QString("%1").arg(part -> pos().y()));
orientation -> setCurrentIndex(static_cast<int>(part -> orientation()));
}

30
editor/terminaleditor.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef TERMINAL_EDITOR_H
#define TERMINAL_EDITOR_H
#include <QtGui>
class PartTerminal;
/**
Cette classe represente un editeur de borne.
Elle permet d'editer a travers une interface graphique les
proprietes d'une borne d'element.
*/
class TerminalEditor : public QWidget {
Q_OBJECT
// Constructeurs, destructeur
public:
TerminalEditor(PartTerminal *, QWidget * = 0);
virtual ~TerminalEditor();
private:
TerminalEditor(const TerminalEditor &);
// attributs
private:
PartTerminal *part;
QLineEdit *qle_x, *qle_y;
QComboBox *orientation;
// methodes
public slots:
void updateTerminal();
void updateForm();
};
#endif

68
editor/texteditor.cpp Normal file
View File

@@ -0,0 +1,68 @@
#include "texteditor.h"
#include "parttext.h"
/**
Constructeur
@param term Champ de texte a editer
@param parent QWidget parent de ce widget
*/
TextEditor::TextEditor(PartText *text, QWidget *parent) : QWidget(parent) {
part = text;
qle_x = new QLineEdit();
qle_y = new QLineEdit();
qle_text = new QLineEdit();
font_size = new QSpinBox();
font_size -> setRange(0, 144);
QVBoxLayout *main_layout = new QVBoxLayout();
main_layout -> addWidget(new QLabel(tr("Postion : ")));
QHBoxLayout *position = new QHBoxLayout();
position -> addWidget(new QLabel(tr("x : ")));
position -> addWidget(qle_x );
position -> addWidget(new QLabel(tr("y : ")));
position -> addWidget(qle_y );
main_layout -> addLayout(position);
QHBoxLayout *fs = new QHBoxLayout();
fs -> addWidget(new QLabel(tr("Taille : ")));
fs -> addWidget(font_size);
main_layout -> addLayout(fs);
QHBoxLayout *t = new QHBoxLayout();
t -> addWidget(new QLabel(tr("Texte : ")));
t -> addWidget(qle_text);
main_layout -> addLayout(t);
main_layout -> addStretch();
setLayout(main_layout);
connect(qle_x, SIGNAL(textEdited(const QString &)), this, SLOT(updateText()));
connect(qle_y, SIGNAL(textEdited(const QString &)), this, SLOT(updateText()));
connect(qle_text, SIGNAL(textEdited(const QString &)), this, SLOT(updateText()));
connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(updateText()));
//updateForm();
}
/**
Destructeur
*/
TextEditor::~TextEditor() {
qDebug() << "~TextEditor()";
}
void TextEditor::updateText() {
part -> can_check_changes = false;
part -> setFont(QFont(part -> font().family(), font_size -> value()));
part -> setPlainText(qle_text -> text());
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
part -> can_check_changes = true;
}
void TextEditor::updateForm() {
qle_x -> setText(QString("%1").arg(part -> pos().x()));
qle_y -> setText(QString("%1").arg(part -> pos().y()));
qle_text -> setText(part -> toPlainText());
font_size -> setValue(part -> font().pointSize());
}

30
editor/texteditor.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef TEXT_EDITOR_H
#define TEXT_EDITOR_H
#include <QtGui>
class PartText;
/**
Cette classe represente un editeur de champ de texte non editable
Elle permet d'editer a travers une interface graphique les
proprietes d'un champ de texte non editable.
*/
class TextEditor : public QWidget {
Q_OBJECT
// Constructeurs, destructeur
public:
TextEditor(PartText *, QWidget * = 0);
virtual ~TextEditor();
private:
TextEditor(const TextEditor &);
// attributs
private:
PartText *part;
QLineEdit *qle_x, *qle_y, *qle_text;
QSpinBox *font_size;
// methodes
public slots:
void updateText();
void updateForm();
};
#endif