ModelEditor: Export diagram as image, pdf or svg

Change-Id: I19be1de5f0c8414b4d76dbbbb68e71183b7ce08e
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Jochen Becher
2016-02-22 20:59:28 +01:00
parent 537125155d
commit bbba9ccae3
9 changed files with 119 additions and 9 deletions

View File

@@ -1,6 +1,8 @@
include(../../qtcreatorlibrary.pri)
QT += svg
DEFINES += QMT_LIBRARY
INCLUDEPATH += $$PWD $$PWD/qtserialization/inc

View File

@@ -9,7 +9,7 @@ QtcLibrary {
"./qtserialization/inc",
])
Depends { name: "Qt.widgets" }
Depends { name: "Qt"; submodules: ["widgets", "svg"] }
Depends { name: "Utils" }
Group {

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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,

View File

@@ -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;

View File

@@ -86,6 +86,8 @@ public:
void openParentDiagram();
void editProperties();
void editSelectedItem();
void exportDiagram();
qmt::MPackage *guessSelectedPackage() const;
private:

View File

@@ -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";