File indexing completed on 2022-09-27 12:24:07

0001 /*
0002     SPDX-FileCopyrightText: 2004, 2005, 2006, 2007 Carsten Niehaus <cniehaus@kde.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "detailedgraphicaloverview.h"
0007 
0008 #include "kalziumdataobject.h"
0009 #include "kalziumutils.h"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include "kalzium_debug.h"
0014 #include <QFile>
0015 #include <QFileInfo>
0016 #include <QFontDatabase>
0017 #include <QPainter>
0018 #include <QRect>
0019 #include <QStandardPaths>
0020 #include <QSvgRenderer>
0021 
0022 #include "prefs.h"
0023 #include <element.h>
0024 
0025 DetailedGraphicalOverview::DetailedGraphicalOverview(QWidget *parent)
0026     : QWidget(parent)
0027 {
0028     setAttribute(Qt::WA_OpaquePaintEvent, true);
0029 
0030     setMinimumSize(300, 200);
0031 
0032     // Set Hydrogen as initial element.
0033     setElement(1);
0034 }
0035 
0036 void DetailedGraphicalOverview::setElement(int el)
0037 {
0038     m_element = KalziumDataObject::instance()->element(el);
0039     setBackgroundColor(KalziumElementProperty::instance()->getElementColor(el));
0040     update();
0041 }
0042 
0043 void DetailedGraphicalOverview::setBackgroundColor(QColor bgColor)
0044 {
0045     if (bgColor == Qt::transparent) {
0046         bgColor = palette().window().color();
0047     }
0048 
0049     // add a gradient
0050     QLinearGradient grad(QPointF(0, 0), QPointF(0, height()));
0051     grad.setColorAt(0, bgColor);
0052 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0053     qreal h, s, v, a;
0054 #else
0055     float h, s, v, a;
0056 #endif
0057     bgColor.getHsvF(&h, &s, &v, &a);
0058     bgColor.setHsvF(h, s, v * 0.6, a);
0059     grad.setColorAt(1, bgColor);
0060 
0061     m_backgroundBrush = QBrush(grad);
0062 }
0063 
0064 void DetailedGraphicalOverview::paintEvent(QPaintEvent *)
0065 {
0066     qreal dpr = devicePixelRatioF();
0067     qreal dprWidth = dpr * width();
0068     qreal dprHeight = dpr * height();
0069     QRect rect(0, 0, dprWidth, dprHeight);
0070 
0071     QPixmap pm(dprWidth, dprHeight);
0072     pm.setDevicePixelRatio(dpr);
0073 
0074     QPainter p;
0075     p.begin(&pm);
0076 
0077     p.setBrush(Qt::SolidPattern);
0078 
0079     if (!m_element) {
0080         pm.fill(palette().window().color());
0081         p.drawText(0, 0, width(), height(), Qt::AlignCenter | Qt::TextWordWrap, i18n("No element selected"));
0082     } else if (Prefs::colorschemebox() == 2) { // The iconic view is the 3rd view (0,1,2,...)
0083         pm.fill(palette().window().color());
0084 
0085         QString pathname = QStandardPaths::locate(QStandardPaths::AppLocalDataLocation, QStringLiteral("data/iconsets/"), QStandardPaths::LocateDirectory);
0086 
0087         int enumii = m_element->dataAsVariant(ChemicalDataObject::atomicNumber).toInt();
0088 
0089         QString filename = pathname + "school" + '/' + QString::number(enumii) + ".svg";
0090 
0091         QSvgRenderer svgrenderer;
0092         if (QFile::exists(filename) && svgrenderer.load(filename)) {
0093             QSize size = svgrenderer.defaultSize();
0094             size.scale(width(), height(), Qt::KeepAspectRatio);
0095 
0096             QRect bounds(QPoint(0, 0), size);
0097             bounds.moveCenter(QPoint(width() / 2, height() / 2));
0098             svgrenderer.render(&p, bounds);
0099         } else {
0100             p.drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("No graphic found"));
0101         }
0102     } else {
0103         const int h_t = 20; // height of the texts
0104 
0105         p.setBrush(m_backgroundBrush);
0106         p.drawRect(rect);
0107         p.setBrush(Qt::black);
0108         p.setBrush(Qt::NoBrush);
0109 
0110         QFont fA = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
0111         QFont fB = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
0112         QFont fC = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
0113 
0114         fA.setPointSize(fA.pointSize() + 20); // Huge font
0115         fA.setBold(true);
0116         fB.setPointSize(fB.pointSize() + 6); // Big font
0117         fC.setPointSize(fC.pointSize() + 4); // Big font
0118         fC.setBold(true);
0119         QFontMetrics fmA = QFontMetrics(fA);
0120         QFontMetrics fmB = QFontMetrics(fB);
0121 
0122         // coordinates for element symbol: near the center
0123         int xA = 4 * width() / 10;
0124         int yA = height() / 2;
0125 
0126         // coordinates for the atomic number: offset from element symbol to the upper left
0127         int xB = xA - fmB.boundingRect(m_element->dataAsString(ChemicalDataObject::atomicNumber)).width();
0128         int yB = yA + fmB.height() / 2;
0129 
0130         // Element Symbol
0131         p.setFont(fA);
0132         p.drawText(xA, yA, m_element->dataAsString(ChemicalDataObject::symbol));
0133 
0134         // Atomic number
0135         p.setFont(fB);
0136         p.drawText(xB, yB, m_element->dataAsString(ChemicalDataObject::atomicNumber));
0137 
0138         // Name and other data
0139         fC.setPointSize(h_t);
0140         p.setFont(fC);
0141 
0142         // Name
0143         p.drawText(1, 0, width(), height(), Qt::AlignLeft, m_element->dataAsString(ChemicalDataObject::name));
0144 
0145         // TODO Oxidationstates -> not there yet
0146 
0147         // Mass
0148         QString massString = i18nc("For example '1.0079u', the mass of an element in units", "%1 u", m_element->dataAsString(ChemicalDataObject::mass));
0149         int size3 = KalziumUtils::maxSize(massString, rect, fC, &p);
0150         fC.setPointSize(size3);
0151         p.setFont(fC);
0152         int offset = KalziumUtils::StringHeight(massString, fC, &p);
0153         p.drawText(0, height() - offset, width(), offset, Qt::AlignRight, massString);
0154     }
0155 
0156     p.end();
0157 
0158     p.begin(this);
0159     p.drawPixmap(0, 0, pm);
0160     p.end();
0161 }