Warning, file /office/skrooge/skgbasegui/skggraphicsview.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /***************************************************************************
0002  * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
0003  * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  ***************************************************************************/
0006 /** @file
0007  * A Graphic view with more functionalities.
0008  *
0009  * @author Stephane MANKOWSKI / Guillaume DE BURE
0010  */
0011 #include "skggraphicsview.h"
0012 
0013 #include <qapplication.h>
0014 #include <qclipboard.h>
0015 #include <qdesktopservices.h>
0016 #include <qdom.h>
0017 #include <qfileinfo.h>
0018 #include <qgraphicssceneevent.h>
0019 #include <qheaderview.h>
0020 #include <qmath.h>
0021 #include <qmenu.h>
0022 #include <qprintdialog.h>
0023 #include <qprinter.h>
0024 #include <qsvggenerator.h>
0025 #include <qwidgetaction.h>
0026 
0027 #include "skgmainpanel.h"
0028 #include "skgservices.h"
0029 #include "skgtraces.h"
0030 
0031 SKGGraphicsView::SKGGraphicsView(QWidget* iParent)
0032     : QWidget(iParent), m_oscale(1), m_toolBarVisible(true)
0033 {
0034     ui.setupUi(this);
0035     setAntialiasing(true);
0036 
0037     ui.kGraphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0038     ui.kGraphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0039 
0040     graphicsView()->installEventFilter(this);
0041 
0042     // Set icons
0043     ui.kPrint->setIcon(SKGServices::fromTheme(QStringLiteral("printer")));
0044     ui.kCopy->setIcon(SKGServices::fromTheme(QStringLiteral("edit-copy")));
0045 
0046     // Build contextual menu
0047     graphicsView()->setContextMenuPolicy(Qt::CustomContextMenu);
0048 
0049     m_mainMenu = new QMenu(graphicsView());
0050 
0051     // Zoom in menu
0052     auto zoomMenu = new SKGZoomSelector(this);
0053     zoomMenu->setResetValue(ui.kZoom->resetValue());
0054     zoomMenu->setValue(ui.kZoom->value());
0055 
0056     auto zoomWidget = new QWidgetAction(this);
0057     zoomWidget->setDefaultWidget(zoomMenu);
0058     m_mainMenu->addAction(zoomWidget);
0059 
0060     connect(zoomMenu, &SKGZoomSelector::changed, this, [ = ](int val) {
0061         ui.kZoom->setValue(val);
0062     });
0063     connect(ui.kZoom, &SKGZoomSelector::changed, this, [ = ](int val) {
0064         zoomMenu->setValue(val);
0065     });
0066 
0067     m_actShowToolBar = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("show-menu")), i18nc("Noun, user action", "Show tool bar"));
0068     if (m_actShowToolBar != nullptr) {
0069         m_actShowToolBar->setCheckable(true);
0070         m_actShowToolBar->setChecked(true);
0071         connect(m_actShowToolBar, &QAction::triggered, this, &SKGGraphicsView::onSwitchToolBarVisibility);
0072     }
0073 
0074     m_mainMenu->addSeparator();
0075 
0076     QAction* actCopy = m_mainMenu->addAction(ui.kCopy->icon(), ui.kCopy->toolTip());
0077     connect(actCopy, &QAction::triggered, this, &SKGGraphicsView::onCopy);
0078 
0079     QAction* actPrint = m_mainMenu->addAction(ui.kPrint->icon(), ui.kPrint->toolTip());
0080     connect(actPrint, &QAction::triggered, this, &SKGGraphicsView::onPrint);
0081 
0082     QAction* actExport = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Noun, user action", "Export…"));
0083     connect(actExport, &QAction::triggered, this, &SKGGraphicsView::onExport);
0084 
0085     connect(graphicsView(), &QHeaderView::customContextMenuRequested, this, &SKGGraphicsView::showMenu);
0086 
0087     connect(ui.kPrint, &QToolButton::clicked, this, &SKGGraphicsView::onPrint);
0088     connect(ui.kCopy, &QToolButton::clicked, this, &SKGGraphicsView::onCopy);
0089     connect(ui.kZoom, &SKGZoomSelector::changed, this, &SKGGraphicsView::onZoom);
0090 
0091     // Timer to refresh
0092     m_timer.setSingleShot(true);
0093     connect(&m_timer, &QTimer::timeout, ui.kZoom, &SKGZoomSelector::initializeZoom, Qt::QueuedConnection);
0094 }
0095 
0096 SKGGraphicsView::~SKGGraphicsView()
0097 {
0098     m_actShowToolBar = nullptr;
0099     m_actZoomOriginal = nullptr;
0100     m_mainMenu = nullptr;
0101     m_actAntialiasing = nullptr;
0102 }
0103 
0104 void SKGGraphicsView::setScene(QGraphicsScene* iScene)
0105 {
0106     graphicsView()->setScene(iScene);
0107     if (iScene != nullptr) {
0108         iScene->installEventFilter(this);
0109     }
0110     onZoom();
0111 }
0112 
0113 QGraphicsView* SKGGraphicsView::graphicsView()
0114 {
0115     return ui.kGraphicsView;
0116 }
0117 
0118 QString SKGGraphicsView::getState() const
0119 {
0120     SKGTRACEINFUNC(10)
0121     QDomDocument doc(QStringLiteral("SKGML"));
0122     QDomElement root = doc.createElement(QStringLiteral("parameters"));
0123     doc.appendChild(root);
0124 
0125     root.setAttribute(QStringLiteral("isToolBarVisible"), isToolBarVisible() ? QStringLiteral("Y") : QStringLiteral("N"));
0126 
0127     return doc.toString();
0128 }
0129 
0130 void SKGGraphicsView::setState(const QString& iState)
0131 {
0132     SKGTRACEINFUNC(10)
0133     QDomDocument doc(QStringLiteral("SKGML"));
0134     doc.setContent(iState);
0135     QDomElement root = doc.documentElement();
0136     setToolBarVisible(root.attribute(QStringLiteral("isToolBarVisible")) != QStringLiteral("N"));
0137 }
0138 
0139 QMenu* SKGGraphicsView::getContextualMenu() const
0140 {
0141     return m_mainMenu;
0142 }
0143 
0144 void SKGGraphicsView::showMenu(const QPoint iPos)
0145 {
0146     if (m_mainMenu != nullptr) {
0147         m_mainMenu->popup(graphicsView()->mapToGlobal(iPos));
0148     }
0149 }
0150 
0151 void SKGGraphicsView::setToolBarVisible(bool iVisibility)
0152 {
0153     if (m_toolBarVisible != iVisibility) {
0154         m_toolBarVisible = iVisibility;
0155         ui.toolBar->setVisible(m_toolBarVisible);
0156         if (m_actShowToolBar != nullptr) {
0157             m_actShowToolBar->setChecked(m_toolBarVisible);
0158         }
0159         Q_EMIT toolBarVisiblyChanged();
0160     }
0161 }
0162 
0163 bool SKGGraphicsView::isToolBarVisible() const
0164 {
0165     return m_toolBarVisible;
0166 }
0167 
0168 void SKGGraphicsView::addToolbarWidget(QWidget* iWidget)
0169 {
0170     ui.layout->insertWidget(3, iWidget);
0171 }
0172 
0173 void SKGGraphicsView::onSwitchToolBarVisibility()
0174 {
0175     setToolBarVisible(!isToolBarVisible());
0176 }
0177 
0178 void SKGGraphicsView::setAntialiasing(bool iAntialiasing)
0179 {
0180     graphicsView()->setRenderHint(QPainter::Antialiasing, iAntialiasing);
0181 }
0182 
0183 bool SKGGraphicsView::eventFilter(QObject* iObject, QEvent* iEvent)
0184 {
0185     if (iObject == graphicsView()->scene() && (iEvent != nullptr) && iEvent->type() == QEvent::GraphicsSceneWheel) {
0186         auto* e = dynamic_cast<QGraphicsSceneWheelEvent*>(iEvent);
0187         if ((e != nullptr) && e->orientation() == Qt::Vertical && ((QApplication::keyboardModifiers() &Qt::ControlModifier) != 0u)) {
0188             int numDegrees = e->delta() / 8;
0189             int numTicks = numDegrees / 15;
0190 
0191             if (numTicks > 0) {
0192                 ui.kZoom->zoomIn();
0193             } else {
0194                 ui.kZoom->zoomOut();
0195             }
0196             e->setAccepted(true);
0197             return true;
0198         }
0199     } else if (iObject == graphicsView() && (iEvent != nullptr) && iEvent->type() == QEvent::Resize) {
0200         Q_EMIT resized();
0201         if (ui.kZoom->value() == ui.kZoom->resetValue()) {
0202             m_timer.start(300);
0203         }
0204     }
0205     return QWidget::eventFilter(iObject, iEvent);
0206 }
0207 
0208 void SKGGraphicsView::initializeZoom()
0209 {
0210     ui.kZoom->initializeZoom();
0211 }
0212 
0213 void SKGGraphicsView::onZoom()
0214 {
0215     _SKGTRACEINFUNC(10)
0216     int sliderValue = ui.kZoom->value();
0217     if (graphicsView()->scene() != nullptr) {
0218         if (sliderValue == -10) {
0219             graphicsView()->fitInView(graphicsView()->scene()->sceneRect(), Qt::KeepAspectRatio);
0220             m_oscale = 1;
0221         } else {
0222             qreal scale = qPow(qreal(1.5), (sliderValue + 10.0) / qreal(4));
0223             graphicsView()->scale(scale / m_oscale, scale / m_oscale);
0224             m_oscale = scale;
0225         }
0226     }
0227 }
0228 
0229 void SKGGraphicsView::onPrint()
0230 {
0231     _SKGTRACEINFUNC(10)
0232     QPrinter printer;
0233     QPointer<QPrintDialog> dialog = new QPrintDialog(&printer, this);
0234     if (dialog->exec() == QDialog::Accepted) {
0235         QPainter painter(&printer);
0236         graphicsView()->render(&painter);
0237         painter.end();
0238     }
0239 }
0240 
0241 void SKGGraphicsView::onExport()
0242 {
0243     _SKGTRACEINFUNC(10)
0244     QString fileName = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), QStringLiteral("application/pdf image/svg+xml image/png image/jpeg image/gif image/tiff"), this, nullptr);
0245     if (fileName.isEmpty()) {
0246         return;
0247     }
0248 
0249     exportInFile(fileName);
0250 
0251     QDesktopServices::openUrl(QUrl(fileName));
0252 }
0253 
0254 void SKGGraphicsView::exportInFile(const QString& iFileName)
0255 {
0256     _SKGTRACEINFUNC(10)
0257     QString extension = QFileInfo(iFileName).suffix().toUpper();
0258     if (extension == QStringLiteral("PDF")) {
0259         QPrinter printer;
0260         printer.setOutputFileName(iFileName);
0261         QPainter painter(&printer);
0262         graphicsView()->render(&painter);
0263         painter.end();
0264     } else if (extension == QStringLiteral("SVG")) {
0265         QSvgGenerator generator;
0266         generator.setFileName(iFileName);
0267         generator.setSize(QSize(200, 200));
0268         generator.setViewBox(QRect(0, 0, 200, 200));
0269         generator.setTitle(i18nc("Title of the content SVG export", "Skrooge SVG export"));
0270         generator.setDescription(i18nc("Description of the content SVG export", "A SVG drawing created by the Skrooge."));
0271 
0272         QPainter painter(&generator);
0273         graphicsView()->render(&painter);
0274         painter.end();
0275     } else {
0276         QImage image(graphicsView()->size(), QImage::Format_ARGB32);
0277         QPainter painter(&image);
0278         graphicsView()->render(&painter);
0279         painter.end();
0280         image.save(iFileName);
0281     }
0282 }
0283 
0284 void SKGGraphicsView::onCopy()
0285 {
0286     _SKGTRACEINFUNC(10)
0287     QClipboard* clipboard = QApplication::clipboard();
0288     if (clipboard != nullptr) {
0289         QImage image(graphicsView()->size(), QImage::Format_ARGB32);
0290         QPainter painter(&image);
0291         graphicsView()->render(&painter);
0292         painter.end();
0293         clipboard->setImage(image);
0294     }
0295 }
0296 
0297