Commit bbba9cca authored by Jochen Becher's avatar Jochen Becher

ModelEditor: Export diagram as image, pdf or svg

Change-Id: I19be1de5f0c8414b4d76dbbbb68e71183b7ce08e
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent 53712515
include(../../qtcreatorlibrary.pri)
QT += svg
DEFINES += QMT_LIBRARY
INCLUDEPATH += $$PWD $$PWD/qtserialization/inc
......
......@@ -9,7 +9,7 @@ QtcLibrary {
"./qtserialization/inc",
])
Depends { name: "Qt.widgets" }
Depends { name: "Qt"; submodules: ["widgets", "svg"] }
Depends { name: "Utils" }
Group {
......
......@@ -57,10 +57,9 @@
#include <QBuffer>
#include <QPdfWriter>
#include <QFile>
#ifdef USE_SVG_CLIPBOARD
#include <QtSvg/QSvgGenerator>
#endif
namespace qmt {
......@@ -372,6 +371,8 @@ void DiagramSceneModel::copyToClipboard()
#ifdef USE_SVG_CLIPBOARD
{
const double border = 5;
QBuffer svgBuffer;
QSvgGenerator svgGenerator;
svgGenerator.setOutputDevice(&svgBuffer);
......@@ -383,8 +384,8 @@ void DiagramSceneModel::copyToClipboard()
svgPainter.setRenderHint(QPainter::Antialiasing);
m_graphicsScene->render(&svgPainter,
QRectF(border, border,
painter.device()->width() - 2 * border,
painter.device()->height() - 2 * border),
svgPainter.device()->width() - 2 * border,
svgPainter.device()->height() - 2 * border),
sceneBoundingRect);
svgPainter.end();
mimeData->setData(QStringLiteral("image/svg+xml"), svgBuffer.buffer());
......@@ -414,8 +415,9 @@ void DiagramSceneModel::copyToClipboard()
}
}
bool DiagramSceneModel::exportPng(const QString &fileName)
bool DiagramSceneModel::exportImage(const QString &fileName)
{
// TODO support exporting selected elements only
removeExtraSceneItems();
QRectF sceneBoundingRect = m_graphicsScene->itemsBoundingRect();
......@@ -450,8 +452,9 @@ bool DiagramSceneModel::exportPng(const QString &fileName)
return success;
}
void DiagramSceneModel::exportPdf(const QString &fileName)
bool DiagramSceneModel::exportPdf(const QString &fileName)
{
// TODO support exporting selected elements only
removeExtraSceneItems();
QRectF sceneBoundingRect = m_graphicsScene->itemsBoundingRect();
......@@ -479,6 +482,39 @@ void DiagramSceneModel::exportPdf(const QString &fileName)
pdfPainter.end();
addExtraSceneItems();
// TODO how to know that file was successfully created?
return true;
}
bool DiagramSceneModel::exportSvg(const QString &fileName)
{
// TODO support exporting selected elements only
removeExtraSceneItems();
QRectF sceneBoundingRect = m_graphicsScene->itemsBoundingRect();
const double border = 5;
QSvgGenerator svgGenerator;
svgGenerator.setFileName(fileName);
QSize svgSceneSize = sceneBoundingRect.size().toSize();
svgGenerator.setSize(svgSceneSize);
svgGenerator.setViewBox(QRect(QPoint(0,0), svgSceneSize));
QPainter svgPainter;
svgPainter.begin(&svgGenerator);
svgPainter.setRenderHint(QPainter::Antialiasing);
m_graphicsScene->render(&svgPainter,
QRectF(border, border,
svgPainter.device()->width() - 2 * border,
svgPainter.device()->height() - 2 * border),
sceneBoundingRect);
svgPainter.end();
addExtraSceneItems();
// TODO how to know that file was successfully created?
return true;
}
void DiagramSceneModel::selectItem(QGraphicsItem *item, bool multiSelect)
......
......@@ -113,8 +113,9 @@ public:
void selectElement(DElement *element);
void editElement(DElement *element);
void copyToClipboard();
bool exportPng(const QString &fileName);
void exportPdf(const QString &fileName);
bool exportImage(const QString &fileName);
bool exportPdf(const QString &fileName);
bool exportSvg(const QString &fileName);
void selectItem(QGraphicsItem *item, bool multiSelect);
void moveSelectedItems(QGraphicsItem *grabbedItem, const QPointF &delta);
......
......@@ -36,6 +36,7 @@
#include <QAction>
#include <QShortcut>
#include <QMenu>
namespace ModelEditor {
namespace Internal {
......@@ -52,6 +53,7 @@ public:
QAction *deleteAction = 0;
QAction *selectAllAction = 0;
QAction *openParentDiagramAction = 0;
QAction *exportDiagramAction = 0;
};
ActionHandler::ActionHandler(const Core::Context &context, QObject *parent)
......@@ -111,6 +113,11 @@ QAction *ActionHandler::openParentDiagramAction() const
return d->openParentDiagramAction;
}
QAction *ActionHandler::exportDiagramAction() const
{
return d->exportDiagramAction;
}
void ActionHandler::createActions()
{
Core::ActionContainer *medit = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
......@@ -131,6 +138,18 @@ void ActionHandler::createActions()
medit->addAction(deleteCommand, Core::Constants::G_EDIT_COPYPASTE);
d->deleteAction = deleteCommand->action();
d->selectAllAction = registerCommand(Core::Constants::SELECTALL, [this]() { selectAll(); }, d->context)->action();
Core::ActionContainer *menuModelEditor = Core::ActionManager::createMenu(Constants::MENU_ID);
menuModelEditor->menu()->setTitle(tr("Model Editor"));
Core::ActionContainer *menuTools = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
menuTools->addMenu(menuModelEditor);
Core::Command *exportDiagramCommand = registerCommand(
Constants::EXPORT_DIAGRAM, [this]() { exportDiagram(); }, Core::Context(), true,
tr("Export Diagram..."));
menuModelEditor->addAction(exportDiagramCommand);
d->exportDiagramAction = exportDiagramCommand->action();
d->openParentDiagramAction = registerCommand(
Constants::OPEN_PARENT_DIAGRAM, [this]() { openParentDiagram(); }, Core::Context(), true,
tr("Open Parent Diagram"), QKeySequence(QStringLiteral("Ctrl+Shift+P")))->action();
......@@ -230,6 +249,13 @@ void ActionHandler::onEditItem()
editor->editSelectedItem();
}
void ActionHandler::exportDiagram()
{
auto editor = qobject_cast<ModelEditor *>(Core::EditorManager::currentEditor());
if (editor)
editor->exportDiagram();
}
Core::Command *ActionHandler::registerCommand(const Core::Id &id, const std::function<void()> &slot,
const Core::Context &context, bool scriptable, const QString &title,
const QKeySequence &keySequence)
......
......@@ -64,6 +64,7 @@ public:
QAction *deleteAction() const;
QAction *selectAllAction() const;
QAction *openParentDiagramAction() const;
QAction *exportDiagramAction() const;
void createActions();
......@@ -79,6 +80,7 @@ private slots:
void openParentDiagram();
void onEditProperties();
void onEditItem();
void exportDiagram();
private:
Core::Command *registerCommand(const Core::Id &id, const std::function<void()> &slot,
......
......@@ -76,11 +76,14 @@
#include <QComboBox>
#include <QDir>
#include <QEvent>
#include <QFileDialog>
#include <QFileInfo>
#include <QFrame>
#include <QHBoxLayout>
#include <QImageWriter>
#include <QLabel>
#include <QMap>
#include <QMessageBox>
#include <QPainter>
#include <QPixmap>
#include <QScrollArea>
......@@ -121,6 +124,7 @@ public:
QWidget *toolbar = 0;
QComboBox *diagramSelector = 0;
SelectedArea selectedArea = SelectedArea::Nothing;
QString lastExportDirPath;
};
ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandler, QWidget *parent)
......@@ -514,6 +518,41 @@ void ModelEditor::editSelectedItem()
onEditSelectedElement();
}
void ModelEditor::exportDiagram()
{
qmt::MDiagram *diagram = currentDiagram();
if (diagram) {
if (d->lastExportDirPath.isEmpty())
d->lastExportDirPath = d->document->filePath().toFileInfo().canonicalPath();
QString fileName = QFileDialog::getSaveFileName(
Core::ICore::dialogParent(),
tr("Export Diagram"), d->lastExportDirPath,
tr("Images (*.png *.jpeg *.jpg *.tif *.tiff);;PDF (*.pdf);;SVG (*.svg)"));
if (!fileName.isEmpty()) {
qmt::DocumentController *documentController = d->document->documentController();
qmt::DiagramSceneModel *sceneModel = documentController->diagramsManager()->diagramSceneModel(diagram);
bool success = false;
QString suffix = QFileInfo(fileName).suffix().toLower();
// TODO use QFileDialog::selectedNameFilter() as fallback if no suffix is given
if (suffix.isEmpty()) {
suffix = QStringLiteral(".png");
fileName += suffix;
}
if (suffix == QStringLiteral(".pdf"))
success = sceneModel->exportPdf(fileName);
else if (suffix == QStringLiteral(".svg"))
success = sceneModel->exportSvg(fileName);
else
success = sceneModel->exportImage(fileName);
if (success)
d->lastExportDirPath = QFileInfo(fileName).canonicalPath();
else
QMessageBox::critical(Core::ICore::dialogParent(), tr("Exporting Diagram Failed"),
tr("Exporting the diagram into file<br>\"%1\"<br>failed.").arg(fileName));
}
}
}
qmt::MPackage *ModelEditor::guessSelectedPackage() const
{
qmt::MPackage *package = 0;
......
......@@ -86,6 +86,8 @@ public:
void openParentDiagram();
void editProperties();
void editSelectedItem();
void exportDiagram();
qmt::MPackage *guessSelectedPackage() const;
private:
......
......@@ -35,6 +35,8 @@ const char MODEL_EDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors",
const char REMOVE_SELECTED_ELEMENTS[] = "ModelEditor.RemoveSelectedElements";
const char DELETE_SELECTED_ELEMENTS[] = "ModelEditor.DeleteSelectedElements";
const char OPEN_PARENT_DIAGRAM[] = "ModelEditor.OpenParentDiagram";
const char MENU_ID[] = "ModelEditor.Menu";
const char EXPORT_DIAGRAM[] = "ModelEditor.ExportDiagram";
const char ACTION_ADD_PACKAGE[] = "ModelEditor.Action.AddPackage";
const char ACTION_ADD_COMPONENT[] = "ModelEditor.Action.AddComponent";
const char ACTION_ADD_CLASS[] = "ModelEditor.Action.AddClass";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment