logic: implemented exporting graph as .svg (issue #596)

This commit is contained in:
mlangkabel
2018-07-10 14:31:39 +02:00
parent ee3bf41a27
commit 98f4ec62ec
7 changed files with 78 additions and 33 deletions
+8 -4
View File
@@ -212,12 +212,13 @@ else()
set(Qt5Widgets_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5Widgets") set(Qt5Widgets_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5Widgets")
set(Qt5PrintSupport_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5PrintSupport") set(Qt5PrintSupport_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5PrintSupport")
set(Qt5Network_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5Network") set(Qt5Network_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5Network")
set(Qt5WinExtras_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5WinExtras") set(Qt5Svg_DIR "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5Svg")
endif() endif()
find_package(Qt5Widgets) find_package(Qt5Widgets)
find_package(Qt5PrintSupport) find_package(Qt5PrintSupport)
find_package(Qt5Network) find_package(Qt5Network)
find_package(Qt5Svg)
if (WIN32) if (WIN32)
find_package(Qt5WinExtras) find_package(Qt5WinExtras)
@@ -418,9 +419,9 @@ add_custom_target(
add_library(${LIB_GUI_PROJECT_NAME} ${LIB_GUI_FILES} ${CMAKE_BINARY_DIR}/src/lib_gui/version.h) add_library(${LIB_GUI_PROJECT_NAME} ${LIB_GUI_FILES} ${CMAKE_BINARY_DIR}/src/lib_gui/version.h)
if(UNIX) if(UNIX)
target_link_libraries(${LIB_GUI_PROJECT_NAME} ${LIB_UTILITY_PROJECT_NAME} Qt5::Widgets Qt5::Network) target_link_libraries(${LIB_GUI_PROJECT_NAME} ${LIB_UTILITY_PROJECT_NAME} Qt5::Widgets Qt5::Network Qt5::Svg)
else() else()
target_link_libraries(${LIB_GUI_PROJECT_NAME} ${LIB_UTILITY_PROJECT_NAME} Qt5::Widgets Qt5::Network Qt5::WinExtras) target_link_libraries(${LIB_GUI_PROJECT_NAME} ${LIB_UTILITY_PROJECT_NAME} Qt5::Widgets Qt5::Network Qt5::Svg Qt5::WinExtras)
endif() endif()
# command for versioning script # command for versioning script
@@ -630,7 +631,10 @@ if (APPLE)
get_property(QT_NETWORK_PATH TARGET ${Qt5Network_LIBRARIES} PROPERTY LOCATION) get_property(QT_NETWORK_PATH TARGET ${Qt5Network_LIBRARIES} PROPERTY LOCATION)
get_filename_component(QT_NETWORK_PATH ${QT_NETWORK_PATH} REALPATH) get_filename_component(QT_NETWORK_PATH ${QT_NETWORK_PATH} REALPATH)
list(APPEND MACOSX_QT_FRAMEWORKS ${QT_CORE_PATH} ${QT_GUI_PATH} ${QT_WIDGETS_PATH} ${QT_PRINT_PATH} ${QT_NETWORK_PATH}) get_property(QT_SVG_PATH TARGET ${Qt5Svg_LIBRARIES} PROPERTY LOCATION)
get_filename_component(QT_SVG_PATH ${QT_SVG_PATH} REALPATH)
list(APPEND MACOSX_QT_FRAMEWORKS ${QT_CORE_PATH} ${QT_GUI_PATH} ${QT_WIDGETS_PATH} ${QT_PRINT_PATH} ${QT_NETWORK_PATH} ${QT_SVG_PATH})
string(REPLACE ";" " " MACOSX_QT_FRAMEWORKS "${MACOSX_QT_FRAMEWORKS}") string(REPLACE ";" " " MACOSX_QT_FRAMEWORKS "${MACOSX_QT_FRAMEWORKS}")
set(MACOSX_QT_DIR "$ENV{QT_DIR}") set(MACOSX_QT_DIR "$ENV{QT_DIR}")
+1
View File
@@ -42,6 +42,7 @@ function(InstallQt qtversion)
InstallQtModule(XcbQpa ${qtversion}) InstallQtModule(XcbQpa ${qtversion})
InstallQtModule(Widgets ${qtversion}) InstallQtModule(Widgets ${qtversion})
InstallQtModule(DBus ${qtversion}) InstallQtModule(DBus ${qtversion})
InstallQtModule(Svg ${qtversion})
endfunction(InstallQt) endfunction(InstallQt)
function(AddSharedToComponent) function(AddSharedToComponent)
@@ -45,6 +45,10 @@
<File Id='qt5networkDLL' Name='Qt5Network.dll' DiskId='1' Source='$(var.PlatformSourceFolder)/Qt5Network.dll' KeyPath='yes' /> <File Id='qt5networkDLL' Name='Qt5Network.dll' DiskId='1' Source='$(var.PlatformSourceFolder)/Qt5Network.dll' KeyPath='yes' />
</Component> </Component>
<Component Id='Qt5SvgDll' Guid='*' Win64="$(var.Win64)">
<File Id='qt5svgDll' Name='Qt5Svg.dll' DiskId='1' Source='$(var.PlatformSourceFolder)/Qt5Svg.dll' KeyPath='yes' />
</Component>
<Component Id='Qt5WidgetsDll' Guid='*' Win64="$(var.Win64)"> <Component Id='Qt5WidgetsDll' Guid='*' Win64="$(var.Win64)">
<File Id='qt5widgetsDLL' Name='Qt5Widgets.dll' DiskId='1' Source='$(var.PlatformSourceFolder)/Qt5Widgets.dll' KeyPath='yes' /> <File Id='qt5widgetsDLL' Name='Qt5Widgets.dll' DiskId='1' Source='$(var.PlatformSourceFolder)/Qt5Widgets.dll' KeyPath='yes' />
</Component> </Component>
@@ -174,6 +174,7 @@
<ComponentRef Id='Qt5CoreDll'/> <ComponentRef Id='Qt5CoreDll'/>
<ComponentRef Id='Qt5GuiDll'/> <ComponentRef Id='Qt5GuiDll'/>
<ComponentRef Id='Qt5NetworkDll'/> <ComponentRef Id='Qt5NetworkDll'/>
<ComponentRef Id='Qt5SvgDll'/>
<ComponentRef Id='Qt5WidgetsDll'/> <ComponentRef Id='Qt5WidgetsDll'/>
<ComponentRef Id='Qt5WinExtrasDll'/> <ComponentRef Id='Qt5WinExtrasDll'/>
+1
View File
@@ -72,6 +72,7 @@ if [ $PLATFORM == "Windows" ]; then
cp -u -r ${QT_DIR}/bin/Qt5Core$SUFFIX.dll build/win$1/$2/$3 cp -u -r ${QT_DIR}/bin/Qt5Core$SUFFIX.dll build/win$1/$2/$3
cp -u -r ${QT_DIR}/bin/Qt5Gui$SUFFIX.dll build/win$1/$2/$3 cp -u -r ${QT_DIR}/bin/Qt5Gui$SUFFIX.dll build/win$1/$2/$3
cp -u -r ${QT_DIR}/bin/Qt5Network$SUFFIX.dll build/win$1/$2/$3 cp -u -r ${QT_DIR}/bin/Qt5Network$SUFFIX.dll build/win$1/$2/$3
cp -u -r ${QT_DIR}/bin/Qt5Svg$SUFFIX.dll build/win$1/$2/$3
cp -u -r ${QT_DIR}/bin/Qt5Widgets$SUFFIX.dll build/win$1/$2/$3 cp -u -r ${QT_DIR}/bin/Qt5Widgets$SUFFIX.dll build/win$1/$2/$3
cp -u -r ${QT_DIR}/bin/Qt5WinExtras$SUFFIX.dll build/win$1/$2/$3 cp -u -r ${QT_DIR}/bin/Qt5WinExtras$SUFFIX.dll build/win$1/$2/$3
cp -u -r ${QT_DIR}/plugins/platforms/qwindows$SUFFIX.dll build/win$1/$2/$3/platforms cp -u -r ${QT_DIR}/plugins/platforms/qwindows$SUFFIX.dll build/win$1/$2/$3/platforms
+5 -5
View File
@@ -196,27 +196,27 @@ size_t GraphViewStyle::getFontSizeOfGroupNode()
std::string GraphViewStyle::getFontNameForDataNode() std::string GraphViewStyle::getFontNameForDataNode()
{ {
return s_fontName; return s_fontName + ", consolas, monospace, sans-serif";
} }
std::string GraphViewStyle::getFontNameOfAccessNode() std::string GraphViewStyle::getFontNameOfAccessNode()
{ {
return "Fira Sans"; return "Fira Sans, sans-serif";
} }
std::string GraphViewStyle::getFontNameOfExpandToggleNode() std::string GraphViewStyle::getFontNameOfExpandToggleNode()
{ {
return "Fira Sans"; return "Fira Sans, sans-serif";
} }
std::string GraphViewStyle::getFontNameOfTextNode() std::string GraphViewStyle::getFontNameOfTextNode()
{ {
return "Fira Sans"; return "Fira Sans, sans-serif";
} }
std::string GraphViewStyle::getFontNameOfGroupNode() std::string GraphViewStyle::getFontNameOfGroupNode()
{ {
return s_fontName; return s_fontName + ", consolas, monospace, sans-serif";
} }
GraphViewStyle::NodeMargins GraphViewStyle::getMarginsForDataNode(NodeType::StyleType type, bool hasIcon, bool hasChildren) GraphViewStyle::NodeMargins GraphViewStyle::getMarginsForDataNode(NodeType::StyleType type, bool hasIcon, bool hasChildren)
+49 -15
View File
@@ -9,6 +9,7 @@
#include <QClipboard> #include <QClipboard>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QParallelAnimationGroup> #include <QParallelAnimationGroup>
#include <QSvgGenerator>
#include "qt/element/QtIconButton.h" #include "qt/element/QtIconButton.h"
#include "qt/view/graphElements/QtGraphEdge.h" #include "qt/view/graphElements/QtGraphEdge.h"
@@ -108,7 +109,6 @@ void QtGraphicsView::setAppZoomFactor(float appZoomFactor)
void QtGraphicsView::setSceneRect(const QRectF& rect) void QtGraphicsView::setSceneRect(const QRectF& rect)
{ {
QGraphicsView::setSceneRect(rect); QGraphicsView::setSceneRect(rect);
scene()->setSceneRect(rect); scene()->setSceneRect(rect);
} }
@@ -441,10 +441,42 @@ void QtGraphicsView::stopTimer()
void QtGraphicsView::exportGraph() void QtGraphicsView::exportGraph()
{ {
QString fileName = QtFileDialog::showSaveFileDialog( const QString exportNotice = "Exported from Sourcetrail";
nullptr, "Save image", FilePath(), "PNG (*.png);;JPEG (*.JPEG);;BMP Files (*.bmp)"); const int margin = 10;
if (!fileName.isNull()) FilePath filePath(QtFileDialog::showSaveFileDialog(
nullptr, "Save image", FilePath(), "PNG (*.png);;JPEG (*.JPEG);;BMP Files (*.bmp);;SVG (*.svg)"
).toStdWString());
if (filePath.extension() == L".svg")
{
QSvgGenerator svgGen;
svgGen.setFileName(QString::fromStdWString(filePath.wstr()));
svgGen.setSize(scene()->sceneRect().size().toSize());
svgGen.setViewBox(QRect(QPoint(0, 0), scene()->sceneRect().size().toSize()));
svgGen.setTitle(QString::fromStdWString(filePath.withoutExtension().fileName()));
svgGen.setDescription(QString("Graph exported from Sourcetrail") + QChar(0x00AE));
QPainter painter(&svgGen);
scene()->render(&painter);
{
QFont font("Fira Sans, sans-serif");
font.setPixelSize(8);
painter.setFont(font);
}
{
QRect boundingRect;
painter.drawText(
QRect(margin, margin, svgGen.size().width() - 2 * margin, svgGen.size().height() - 2 * margin),
Qt::AlignBottom | Qt::AlignHCenter,
exportNotice + ' ' + QChar(0x00AE),
&boundingRect
);
}
}
else if (!filePath.empty())
{ {
QImage image(scene()->sceneRect().size().toSize() * 2, QImage::Format_ARGB32); QImage image(scene()->sceneRect().size().toSize() * 2, QImage::Format_ARGB32);
image.fill(Qt::transparent); image.fill(Qt::transparent);
@@ -453,21 +485,19 @@ void QtGraphicsView::exportGraph()
painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::Antialiasing);
scene()->render(&painter); scene()->render(&painter);
// different approach: only currently visible part
// QPixmap pixMap = grab();
// pixMap.save(fileName);
{
const int margin = 10;
{ {
QFont font = painter.font(); QFont font = painter.font();
font.setPixelSize(14); font.setPixelSize(14);
painter.setFont(font); painter.setFont(font);
} }
{
QRect boundingRect; QRect boundingRect;
painter.drawText(QRect(margin, margin, image.size().width() - 2 * margin, image.size().height() - 2 * margin), Qt::AlignBottom | Qt::AlignHCenter, "Exported from Sourcetrail", &boundingRect); painter.drawText(
QRect(margin, margin, image.size().width() - 2 * margin, image.size().height() - 2 * margin),
Qt::AlignBottom | Qt::AlignHCenter,
exportNotice,
&boundingRect
);
{ {
QFont font = painter.font(); QFont font = painter.font();
@@ -475,10 +505,14 @@ void QtGraphicsView::exportGraph()
painter.setFont(font); painter.setFont(font);
} }
painter.drawText(boundingRect.right() + boundingRect.height() / 5, boundingRect.top() + boundingRect.height() / 2, QChar(0x00AE)); painter.drawText(
boundingRect.right() + boundingRect.height() / 5,
boundingRect.top() + boundingRect.height() / 2,
QChar(0x00AE)
);
} }
image.save(fileName); image.save(QString::fromStdWString(filePath.wstr()));
} }
} }