File indexing completed on 2024-05-12 04:39:28

0001 /*
0002     SPDX-FileCopyrightText: 2007 Aleix Pol <aleixpol@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "cmakecachemodel.h"
0008 #include <QFile>
0009 #include <KLocalizedString>
0010 
0011 #include "cmakecachereader.h"
0012 #include <debug.h>
0013 
0014 //4 columns: name, type, value, comment
0015 //name:type=value - comment
0016 CMakeCacheModel::CMakeCacheModel(QObject *parent, const KDevelop::Path &path)
0017     : QStandardItemModel(parent), m_filePath(path)
0018 {
0019     read();
0020 }
0021 
0022 void CMakeCacheModel::reset()
0023 {
0024     beginResetModel();
0025     clear();
0026     m_internal.clear();
0027     m_modifiedRows.clear();
0028     read();
0029     endResetModel();
0030 }
0031 
0032 void CMakeCacheModel::read()
0033 {
0034     // Set headers
0035     const QStringList labels{
0036         i18nc("@title:column", "Name"),
0037         i18nc("@title:column", "Type"),
0038         i18nc("@title:column", "Value"),
0039         i18nc("@title:column", "Comment"),
0040         i18nc("@title:column", "Advanced"),
0041         i18nc("@title:column", "Strings"),
0042     };
0043     setHorizontalHeaderLabels(labels);
0044 
0045     QFile file(m_filePath.toLocalFile());
0046     if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
0047     {
0048         qCDebug(CMAKE) << "error. Could not find the file";
0049         return;
0050     }
0051 
0052     int currentIdx=0;
0053     QStringList currentComment;
0054     QTextStream in(&file);
0055     QHash<QString, int> variablePos;
0056     while (!in.atEnd())
0057     {
0058         QString line = in.readLine().trimmed();
0059         if(line.startsWith(QLatin1String("//")))
0060         {
0061             line.remove(0, 2);
0062             currentComment += line;
0063         } else if(!line.isEmpty() && !line.startsWith(QLatin1Char('#'))) //it is a variable
0064         {
0065             CacheLine c;
0066             c.readLine(line);
0067 
0068             if(c.isCorrect())
0069             {
0070                 QString name=c.name(), flag=c.flag();
0071 
0072                 QString type=c.type();
0073                 QString value=c.value();
0074 
0075                 const QList<QStandardItem*> lineItems{
0076                     new QStandardItem(name),
0077                     new QStandardItem(type),
0078                     new QStandardItem(value),
0079                     new QStandardItem(currentComment.join(QLatin1Char('\n'))),
0080                 };
0081 
0082                 if(flag==QLatin1String("INTERNAL"))
0083                 {
0084                     m_internal.insert(name);
0085                 } else if(flag==QLatin1String("ADVANCED") || flag==QLatin1String("STRINGS"))
0086                 {
0087                     const auto posIt = variablePos.constFind(name);
0088                     if (posIt != variablePos.constEnd()) {
0089                         const int pos = *posIt;
0090                         
0091                         // if the flag is not ADVANCED, it's STRINGS.
0092                         // The latter is stored in column 5
0093                         int column = flag==QLatin1String("ADVANCED") ? 4 : 5;
0094                         QStandardItem *p = item(pos, column);
0095                         if(!p)
0096                         {
0097                             p=new QStandardItem(value);
0098                             setItem(pos, column, p);
0099                         }
0100                         else
0101                         {
0102                             p->setText(value);
0103                         }
0104                     }
0105                     else
0106                     {
0107                         qCDebug(CMAKE) << "Flag for an unknown variable";
0108                     }
0109                 }
0110 
0111                 if(!flag.isEmpty())
0112                 {
0113                     lineItems[0]->setText(lineItems[0]->text() + QLatin1Char('-') + flag);
0114                 }
0115                 insertRow(currentIdx, lineItems);
0116                 if (!variablePos.contains(name)) {
0117                     variablePos[name]=currentIdx;
0118                 }
0119                 currentIdx++;
0120                 currentComment.clear();
0121             }
0122         }
0123         else if(line.startsWith(QLatin1Char('#')) && line.contains(QLatin1String("INTERNAL")))
0124         {
0125             m_internalBegin=currentIdx;
0126 //                 qCDebug(CMAKE) << "Comment: " << line << " -.- " << currentIdx;
0127         }
0128     }
0129 }
0130 
0131 bool CMakeCacheModel::setData(const QModelIndex& index, const QVariant& value, int role)
0132 {
0133     bool ret = QStandardItemModel::setData(index, value, role);
0134     if (ret) {
0135         const auto i = index.row();
0136         m_modifiedRows.insert(i);
0137         emit valueChanged(item(i, 0)->text(), item(i, 2)->text());
0138     }
0139     return ret;
0140 }
0141 
0142 QVariantMap CMakeCacheModel::changedValues() const
0143 {
0144     QVariantMap ret;
0145     for(int i=0; i<rowCount(); i++)
0146     {
0147         if (!m_modifiedRows.contains(i))
0148             continue;
0149 
0150         QStandardItem* name = item(i, 0);
0151         QStandardItem* type = item(i, 1);
0152         QStandardItem* valu = item(i, 2);
0153 //         QStandardItem* comment = item(i, 3);
0154         ret.insert(name->text()+QLatin1Char(':')+type->text(), valu->text());
0155 
0156     }
0157     return ret;
0158 }
0159 
0160 QString CMakeCacheModel::value(const QString & varName) const
0161 {
0162     for(int i=0; i<rowCount(); i++)
0163     {
0164         QStandardItem* name = item(i, 0);
0165         if(name->text()==varName) {
0166             QStandardItem* valu = item(i, 2);
0167             return valu->text();
0168         }
0169     }
0170     return QString();
0171 }
0172 
0173 bool CMakeCacheModel::isAdvanced(int i) const
0174 {
0175     QStandardItem *p=item(i, 4);
0176     bool isAdv= (p!=nullptr) || i>m_internalBegin;
0177     if(!isAdv)
0178     {
0179         p=item(i, 1);
0180         isAdv = p->text()==QLatin1String("INTERNAL") || p->text()==QLatin1String("STATIC");
0181     }
0182 
0183     return isAdv || m_internal.contains(item(i,0)->text());
0184 }
0185 
0186 bool CMakeCacheModel::isInternal(int i) const
0187 {
0188     bool isInt= i>m_internalBegin;
0189     return isInt;
0190 }
0191 
0192 QList< QModelIndex > CMakeCacheModel::persistentIndices() const
0193 {
0194     QList< QModelIndex > ret;
0195     for(int i=0; i<rowCount(); i++)
0196     {
0197         QStandardItem* type = item(i, 1);
0198         if(type->text()==QLatin1String("BOOL"))
0199         {
0200             QStandardItem* valu = item(i, 2);
0201             ret.append(valu->index());
0202         }
0203     }
0204     return ret;
0205 }
0206 
0207 KDevelop::Path CMakeCacheModel::filePath() const
0208 {
0209     return m_filePath;
0210 }
0211 
0212 #include "moc_cmakecachemodel.cpp"