forked from qt-creator/qt-creator
ModelEditor: Export diagram as image, pdf or svg
Change-Id: I19be1de5f0c8414b4d76dbbbb68e71183b7ce08e Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
|
||||
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";
|
||||
|
||||
Reference in New Issue
Block a user