diff --git a/diagram.cpp b/diagram.cpp index 11065de18..74a518ad1 100644 --- a/diagram.cpp +++ b/diagram.cpp @@ -127,7 +127,7 @@ void Diagram::keyReleaseEvent(QKeyEvent *e) { Exporte le schema vers une image @return Une QImage representant le schema */ -QImage Diagram::toImage(int width, int height, Qt::AspectRatioMode aspectRatioMode) { +bool Diagram::toPaintDevice(QPaintDevice &pix, int width, int height, Qt::AspectRatioMode aspectRatioMode) { // determine la zone source = contenu du schema + marges QRectF source_area; if (!use_border) { @@ -147,12 +147,9 @@ QImage Diagram::toImage(int width, int height, Qt::AspectRatioMode aspectRatioMo // si les dimensions ne sont pas precisees, l'image est exportee a l'echelle 1:1 QSize image_size = (width == -1 && height == -1) ? source_area.size().toSize() : QSize(width, height); - // initialise une image avec ces dimensions - QImage pix = QImage(image_size, QImage::Format_RGB32); - // prepare le rendu QPainter p; - if (!p.begin(&pix)) return(QImage()); + if (!p.begin(&pix)) return(false); // rendu antialiase p.setRenderHint(QPainter::Antialiasing, true); @@ -164,13 +161,13 @@ QImage Diagram::toImage(int width, int height, Qt::AspectRatioMode aspectRatioMo foreach (QGraphicsItem *qgi, selected_elmts) qgi -> setSelected(false); // effectue le rendu lui-meme - render(&p, pix.rect(), source_area, aspectRatioMode); + render(&p, QRect(QPoint(0, 0), image_size), source_area, aspectRatioMode); p.end(); // restaure les elements selectionnes foreach (QGraphicsItem *qgi, selected_elmts) qgi -> setSelected(true); - return(pix); + return(true); } /** diff --git a/diagram.h b/diagram.h index 8cbd1d049..c027187bf 100644 --- a/diagram.h +++ b/diagram.h @@ -67,7 +67,7 @@ class Diagram : public QGraphicsScene { void setDrawTerminals(bool); QRectF border() const; - QImage toImage(int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio); + bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio); QSize imageSize() const; void invalidateMovedElements(); diff --git a/exportdialog.cpp b/exportdialog.cpp index f93af86e8..0ad5bbec5 100644 --- a/exportdialog.cpp +++ b/exportdialog.cpp @@ -1,4 +1,6 @@ #include "exportdialog.h" +#include +#include /** Constructeur @@ -14,6 +16,9 @@ ExportDialog::ExportDialog(Diagram *dia, QWidget *parent) : QDialog(parent) { diagram_ratio = (qreal)diagram_size.width() / (qreal)diagram_size.height(); dontchangewidth = dontchangeheight = false; + // vecteur contenant 256 nuances de gris, pour exporter les images sans couleur + for (int i = 0 ; i < 256 ; ++ i) ColorTab << qRgb(i, i, i); + // la taille du dialogue est fixee setFixedSize(800, 360); setWindowTitle(tr("Exporter")); @@ -174,6 +179,7 @@ QWidget *ExportDialog::leftPart() { format -> addItem(tr("PNG (*.png)"), "PNG"); format -> addItem(tr("JPEG (*.jpg)"), "JPG"); format -> addItem(tr("Bitmap (*.bmp)"), "BMP"); + format -> addItem(tr("SVG (*.svg)"), "SVG"); vboxLayout -> addLayout(hboxLayout1); @@ -248,7 +254,7 @@ void ExportDialog::slot_chooseAFile() { this, tr("Exporter vers le fichier"), QDir::homePath(), - tr("Images (*.png *.bmp *.jpg)") + tr("Images (*.png *.bmp *.jpg *.svg)") ); if (user_file != "") { diagram_path = user_file; @@ -261,22 +267,11 @@ void ExportDialog::slot_chooseAFile() { @return l'image a exporter */ QImage ExportDialog::generateImage() { - // memorise les parametres relatifs au schema - bool state_drawBorder = diagram -> border_and_inset.borderIsDisplayed(); - bool state_drawColumns = diagram -> border_and_inset.columnsAreDisplayed(); - bool state_drawInset = diagram -> border_and_inset.insetIsDisplayed(); - bool state_drawGrid = diagram -> displayGrid(); - bool state_drawTerm = diagram -> drawTerminals(); - bool state_useBorder = diagram -> useBorder(); + saveReloadDiagramParameters(true); - // genere l'image - diagram -> setUseBorder(export_border -> isChecked()); - diagram -> setDrawTerminals(draw_terminals -> isChecked()); - diagram -> setDisplayGrid(draw_grid -> isChecked()); - diagram -> border_and_inset.displayBorder(draw_border -> isChecked()); - diagram -> border_and_inset.displayColumns(draw_columns -> isChecked()); - diagram -> border_and_inset.displayInset(draw_inset -> isChecked()); - QImage image = diagram -> toImage( + QImage image(width -> value(), height -> value(), QImage::Format_RGB32); + diagram -> toPaintDevice( + image, width -> value(), height -> value(), keep_aspect_ratio -> isChecked() ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio @@ -284,22 +279,79 @@ QImage ExportDialog::generateImage() { // convertit l'image en niveaux de gris si besoin if (!keep_colors -> isChecked()) { - QVector ColorTab; - for (int i = 0 ; i < 256 ; ++ i) ColorTab << qRgb(i, i, i); image = image.convertToFormat(QImage::Format_Indexed8, ColorTab, Qt::ThresholdDither); } - // restaure les parametres relatifs au schema - diagram -> border_and_inset.displayBorder(state_drawBorder); - diagram -> border_and_inset.displayColumns(state_drawColumns); - diagram -> border_and_inset.displayInset(state_drawInset); - diagram -> setDisplayGrid(state_drawGrid); - diagram -> setDrawTerminals(state_drawTerm); - diagram -> setUseBorder(state_useBorder); + saveReloadDiagramParameters(false); return(image); } +/** + Sauve ou restaure les parametres du schema + @param save true pour memoriser les parametres du schema et appliquer ceux + definis par le formulaire, false pour restaurer les parametres +*/ +void ExportDialog::saveReloadDiagramParameters(bool save) { + static bool state_drawBorder; + static bool state_drawColumns; + static bool state_drawInset; + static bool state_drawGrid; + static bool state_drawTerm; + static bool state_useBorder; + + if (save) { + // memorise les parametres relatifs au schema + state_drawBorder = diagram -> border_and_inset.borderIsDisplayed(); + state_drawColumns = diagram -> border_and_inset.columnsAreDisplayed(); + state_drawInset = diagram -> border_and_inset.insetIsDisplayed(); + state_drawGrid = diagram -> displayGrid(); + state_drawTerm = diagram -> drawTerminals(); + state_useBorder = diagram -> useBorder(); + + diagram -> setUseBorder(export_border -> isChecked()); + diagram -> setDrawTerminals(draw_terminals -> isChecked()); + diagram -> setDisplayGrid(draw_grid -> isChecked()); + diagram -> border_and_inset.displayBorder(draw_border -> isChecked()); + diagram -> border_and_inset.displayColumns(draw_columns -> isChecked()); + diagram -> border_and_inset.displayInset(draw_inset -> isChecked()); + } else { + // restaure les parametres relatifs au schema + diagram -> border_and_inset.displayBorder(state_drawBorder); + diagram -> border_and_inset.displayColumns(state_drawColumns); + diagram -> border_and_inset.displayInset(state_drawInset); + diagram -> setDisplayGrid(state_drawGrid); + diagram -> setDrawTerminals(state_drawTerm); + diagram -> setUseBorder(state_useBorder); + } +} + +/** + Exporte le schema en SVG + @param file Fichier dans lequel sera enregistre le code SVG +*/ +void ExportDialog::generateSvg(QFile &file) { + saveReloadDiagramParameters(true); + + // genere une QPicture a partir du schema + QPicture picture; + diagram -> toPaintDevice( + picture, + width -> value(), + height -> value(), + keep_aspect_ratio -> isChecked() ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio + ); + + // "joue" la QPicture sur un QSvgGenerator + QSvgGenerator svg_engine; + svg_engine.setSize(QSize(width -> value(), height -> value())); + svg_engine.setOutputDevice(&file); + QPainter svg_painter(&svg_engine); + picture.play(&svg_painter); + /// @todo gerer l'enlevement des couleurs + saveReloadDiagramParameters(false); +} + /** Slot effectuant les verifications necessaires apres la validation du dialogue. @@ -341,17 +393,19 @@ void ExportDialog::slot_check() { // ouvre le fichier QFile fichier(diagram_path); - QImage image = generateImage(); - // enregistre l'image dans le fichier - image.save(&fichier, format_acronym.toUtf8().data()); + if (format_acronym == "SVG") { + generateSvg(fichier); + } else { + QImage image = generateImage(); + image.save(&fichier, format_acronym.toUtf8().data()); + } fichier.close(); // fermeture du dialogue accept(); } - /** Slot appele lorsque l'utilisateur change la zone du schema qui doit etre exportee. Il faut alors calculer le nouveau ratio et corriger les diff --git a/exportdialog.h b/exportdialog.h index 17d8a3e8c..532f9174e 100644 --- a/exportdialog.h +++ b/exportdialog.h @@ -2,6 +2,7 @@ #define EXPORTDIALOG_H #include #include "diagram.h" +class QSvgGenerator; /** Cette classe represente le dialogue permettant d'exporter un schema sous forme d'image selon les desirs de l'utilisateur @@ -47,6 +48,7 @@ class ExportDialog : public QDialog { QSize diagram_size; QString diagram_path; qreal diagram_ratio; + QVector ColorTab; // methodes private: @@ -54,6 +56,8 @@ class ExportDialog : public QDialog { QWidget *rightPart(); QGroupBox *setupDimensionsGroupBox(); QGroupBox *setupOptionsGroupBox(); + void saveReloadDiagramParameters(bool = true); + void generateSvg(QFile &file); QImage generateImage(); public slots: diff --git a/qelectrotech.pro b/qelectrotech.pro index 5902f6a47..57bb19493 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -129,7 +129,7 @@ SOURCES += aboutqet.cpp \ RESOURCES += qelectrotech.qrc TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts RC_FILE = ico/windows_icon/application_icon/qelectrotech.rc -QT += xml +QT += xml svg CONFIG += debug_and_release CONFIG(debug, debug|release) { TARGET = qelectrotech