File indexing completed on 2024-05-19 15:27:49

0001 /* This file is part of KGraphViewer.
0002    Copyright (C) 2007 Gael de Chalendar <kleag@free.fr>
0003 
0004    KGraphViewer is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation, version 2.
0007 
0008    This program is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    General Public License for more details.
0012 
0013    You should have received a copy of the GNU General Public License
0014    along with this program; if not, write to the Free Software
0015    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0016    02110-1301, USA
0017 */
0018 
0019 #include "graphelement.h"
0020 #include "canvaselement.h"
0021 #include "dotdefaults.h"
0022 #include "kgraphviewerlib_debug.h"
0023 
0024 #include <math.h>
0025 
0026 #include <QDebug>
0027 
0028 #include <qregularexpression.h>
0029 #include <graphviz/gvc.h>
0030 
0031 namespace KGraphViewer
0032 {
0033 const QString GraphElement::KEY_ID = QLatin1String("id");
0034 const QString GraphElement::KEY_STYLE = QLatin1String("style");
0035 const QString GraphElement::KEY_LABEL = QLatin1String("label");
0036 const QString GraphElement::KEY_SHAPE = QLatin1String("shape");
0037 const QString GraphElement::KEY_SHAPEFILE = QLatin1String("shapefile");
0038 const QString GraphElement::KEY_COLOR = QLatin1String("color");
0039 const QString GraphElement::KEY_BGCOLOR = QLatin1String("bgcolor");
0040 const QString GraphElement::KEY_URL = QLatin1String("URL");
0041 const QString GraphElement::KEY_FONTSIZE = QLatin1String("fontsize");
0042 const QString GraphElement::KEY_FONTNAME = QLatin1String("fontname");
0043 const QString GraphElement::KEY_FONTCOLOR = QLatin1String("fontcolor");
0044 const QString GraphElement::KEY_FILLCOLOR = QLatin1String("fillcolor");
0045 
0046 GraphElement::GraphElement()
0047     : QObject()
0048     , m_attributes()
0049     , m_originalAttributes()
0050     , m_ce(nullptr)
0051     , m_z(1.0)
0052     , m_renderOperations()
0053     , m_renderOperationsRevision(0)
0054     , m_selected(false)
0055 {
0056     /*  label("");
0057       id("");
0058       style(DOT_DEFAULT_STYLE);
0059       shape(DOT_DEFAULT_SHAPE);
0060       lineColor(DOT_DEFAULT_LINECOLOR);
0061       backColor(DOT_DEFAULT_BACKCOLOR);
0062       fontName(DOT_DEFAULT_FONTNAME);
0063       fontColor(DOT_DEFAULT_FONTCOLOR);
0064       url("");
0065       shapeFile("");*/
0066     setFontSize(DOT_DEFAULT_FONTSIZE);
0067 }
0068 
0069 GraphElement::GraphElement(const GraphElement &element)
0070     : QObject()
0071     , m_attributes()
0072     , m_originalAttributes()
0073     , m_ce(element.m_ce)
0074     , m_z(element.m_z)
0075     , m_renderOperations()
0076     , m_renderOperationsRevision(0)
0077     , m_selected(element.m_selected)
0078 {
0079     updateWithElement(element);
0080 }
0081 
0082 void GraphElement::setRenderOperations(const DotRenderOpVec &drov)
0083 {
0084     m_renderOperations = drov;
0085     ++m_renderOperationsRevision;
0086 }
0087 
0088 void GraphElement::updateWithElement(const GraphElement &element)
0089 {
0090     qCDebug(KGRAPHVIEWERLIB_LOG) << element.id();
0091     bool modified = false;
0092     if (element.z() != m_z) {
0093         m_z = element.z();
0094         modified = true;
0095     }
0096     QMap<QString, QString>::const_iterator it = element.attributes().constBegin();
0097     for (; it != element.attributes().constEnd(); it++) {
0098         const QString &attrib = it.key();
0099         if ((!m_attributes.contains(attrib)) || (m_attributes[attrib] != it.value())) {
0100             m_attributes[attrib] = it.value();
0101             if (attrib == "z") {
0102                 bool ok;
0103                 setZ(m_attributes[attrib].toDouble(&ok));
0104             }
0105             modified = true;
0106         }
0107     }
0108     if (modified) {
0109         qCDebug(KGRAPHVIEWERLIB_LOG) << "modified: update render operations";
0110         setRenderOperations(element.m_renderOperations);
0111         /*    foreach (DotRenderOp op, m_renderOperations)
0112             {
0113               QString msg;
0114               QTextStream dd(&msg);
0115               dd << "an op: " << op.renderop << " ";
0116               foreach (int i, op.integers)
0117               {
0118                 dd << i << " ";
0119               }
0120               dd << op.str;
0121               qCDebug(KGRAPHVIEWERLIB_LOG) << msg;
0122             }
0123             g() << "modified: emiting changed";*/
0124         emit changed();
0125     }
0126     qCDebug(KGRAPHVIEWERLIB_LOG) << "done" << m_renderOperations.size();
0127 }
0128 
0129 QString GraphElement::backColor() const
0130 {
0131     if (m_attributes.find(KEY_FILLCOLOR) != m_attributes.end()) {
0132         return m_attributes[KEY_FILLCOLOR];
0133     } else if ((m_attributes.find(KEY_COLOR) != m_attributes.end()) && (m_attributes[KEY_STYLE] == QLatin1String("filled"))) {
0134         return m_attributes[KEY_COLOR];
0135     } else {
0136         return DOT_DEFAULT_NODE_BACKCOLOR;
0137     }
0138 }
0139 
0140 void GraphElement::removeAttribute(const QString &attribName)
0141 {
0142     qCDebug(KGRAPHVIEWERLIB_LOG) << attribName;
0143     m_attributes.remove(attribName);
0144     emit changed();
0145 }
0146 
0147 void GraphElement::exportToGraphviz(void *element) const
0148 {
0149     QMap<QString, QString>::const_iterator it, it_end;
0150     it = attributes().begin();
0151     it_end = attributes().end();
0152     for (; it != it_end; it++) {
0153         if (!it.value().isEmpty()) {
0154             if (it.key() == "label") {
0155                 QString label = it.value();
0156                 if (label != "label") {
0157                     label.replace(QRegularExpression("\n"), "\\n");
0158                                qCDebug(KGRAPHVIEWERLIB_LOG) << it.key() << "=\"" << label << "\",";
0159                     agsafeset(element, it.key().toUtf8().data(), label.toUtf8().data(), QString().toUtf8().data());
0160                 }
0161             } else if (it.key() == "_draw_" || it.key() == "_ldraw_") {
0162             } else if (originalAttributes().isEmpty() || originalAttributes().contains(it.key())) {
0163                 //         qCDebug(KGRAPHVIEWERLIB_LOG) << it.key() << it.value();
0164 
0165                 agsafeset(element, it.key().toUtf8().data(), it.value().toUtf8().data(), QString().toUtf8().data());
0166             }
0167         }
0168     }
0169 }
0170 
0171 QTextStream &operator<<(QTextStream &s, const GraphElement &n)
0172 {
0173     QMap<QString, QString>::const_iterator it, it_end;
0174     bool firstAttr = true;
0175     it = n.attributes().begin();
0176     it_end = n.attributes().end();
0177     for (; it != it_end; it++) {
0178         if (!it.value().isEmpty()) {
0179             if (it.key() == "label") {
0180                 QString label = it.value();
0181                 if (label != "label") {
0182                     label.replace(QRegularExpression("\n"), "\\n");
0183                                qCDebug(KGRAPHVIEWERLIB_LOG) << it.key() << "=\"" << label << "\",";
0184                     if (firstAttr)
0185                         firstAttr = false;
0186                     else
0187                         s << ',';
0188                     s << it.key() << "=\"" << label << '"';
0189                 }
0190             } else if (it.key() == "_draw_" || it.key() == "_ldraw_") {
0191             } else if (n.originalAttributes().isEmpty() || n.originalAttributes().contains(it.key())) {
0192                 //         qCDebug(KGRAPHVIEWERLIB_LOG) << it.key() << it.value();
0193 
0194                 if (firstAttr)
0195                     firstAttr = false;
0196                 else
0197                     s << ',';
0198                 s << it.key() << "=\"" << it.value() << '"';
0199             }
0200         }
0201     }
0202     return s;
0203 }
0204 
0205 }
0206 
0207 #include "moc_graphelement.cpp"