File indexing completed on 2024-04-14 05:36:41
0001 /*************************************************************************** 0002 * Copyright (C) 2004-2005 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "subcircuits.h" 0012 #include "circuitdocument.h" 0013 #include "ecsubcircuit.h" 0014 #include "itemdocumentdata.h" 0015 #include "itemlibrary.h" 0016 #include "itemselector.h" 0017 0018 #include <KConfigGroup> 0019 #include <KLocalizedString> 0020 #include <KSharedConfig> 0021 0022 #include <QDir> 0023 #include <QFile> 0024 #include <QStandardPaths> 0025 #include <QTextStream> 0026 0027 #include <ktechlab_debug.h> 0028 0029 Subcircuits::Subcircuits() 0030 : QObject() 0031 { 0032 connect(ComponentSelector::self(), &ComponentSelector::itemRemoved, this, &Subcircuits::slotItemRemoved); 0033 } 0034 0035 Subcircuits::~Subcircuits() 0036 { 0037 } 0038 0039 static QList<int> asIntList(const QString &string) 0040 { 0041 QList<QByteArray> entries = string.toLatin1().split(','); 0042 QList<int> list; 0043 for (const QByteArray &s : entries) 0044 list << s.toInt(); 0045 return list; 0046 } 0047 0048 void Subcircuits::initECSubcircuit(int subcircuitId, ECSubcircuit *ecSubcircuit) 0049 { 0050 const QString fileName = genFileName(subcircuitId); 0051 if (!QFile::exists(fileName)) { 0052 qCDebug(KTL_LOG) << "Subcircuits::createSubcircuit: Subcircuit \"" << fileName << "\" was not found."; 0053 return; 0054 } 0055 0056 SubcircuitData subcircuit; 0057 if (!subcircuit.loadData(QUrl::fromLocalFile(genFileName(subcircuitId)))) 0058 return; 0059 0060 subcircuit.initECSubcircuit(ecSubcircuit); 0061 } 0062 0063 ECSubcircuit *Subcircuits::createSubcircuit(int id, CircuitDocument *circuitDocument, bool newItem, const char *newId) 0064 { 0065 // I pass finishCreation = false here because the subcircuit was getting 0066 // finished twice, causing a segfault in CircuitDocument::assignCircuits() 0067 //--electronerd 0068 ECSubcircuit *ecSubcircuit = static_cast<ECSubcircuit *>(itemLibrary()->createItem("ec/subcircuit", circuitDocument, newItem, newId, false)); 0069 ecSubcircuit->property("id")->setValue(id); 0070 return ecSubcircuit; 0071 } 0072 0073 void Subcircuits::loadSubcircuits() 0074 { 0075 // KConfig *config = kapp->config(); 0076 KSharedConfigPtr config = KSharedConfig::openConfig(); 0077 // config->setGroup("Subcircuits"); 0078 KConfigGroup configGrSubcirc = config->group("Subcircuits"); 0079 0080 QList<int> idList = asIntList(configGrSubcirc.readEntry<QString>(QString("Ids"), QString())); 0081 const QList<int>::iterator idListEnd = idList.end(); 0082 for (QList<int>::iterator it = idList.begin(); it != idListEnd; ++it) { 0083 QFile file(genFileName(*it)); 0084 if (file.open(QIODevice::ReadOnly) == false) { 0085 // File has mysteriously disappeared.... 0086 *it = -1; 0087 } else { 0088 KConfigGroup configGrSubcNr = config->group("Subcircuit_" + QString::number(*it)); 0089 updateComponentSelector(*it, configGrSubcNr.readEntry("Name")); 0090 } 0091 file.close(); 0092 } 0093 idList.removeAll(-1); 0094 0095 // Update the config file if any ids have been removed 0096 // config->setGroup("Subcircuits"); 0097 configGrSubcirc.writeEntry("Ids", idList); 0098 } 0099 0100 QString Subcircuits::genFileName(const int nextId) 0101 { 0102 return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/subcircuit_" + QString::number(nextId) + ".circuit"; 0103 } 0104 0105 void Subcircuits::updateComponentSelector(int id, const QString &name) 0106 { 0107 if (name.isEmpty()) 0108 return; 0109 0110 ComponentSelector::self()->addItem(name, "sc/" + QString::number(id), i18n("Subcircuits"), QIcon::fromTheme("application-x-circuit"), true); 0111 } 0112 0113 void Subcircuits::addSubcircuit(const QString &name, const QString &subcircuitXml) 0114 { 0115 // KConfig *config = kapp->config(); 0116 KSharedConfigPtr config = KSharedConfig::openConfig(); 0117 KConfigGroup subcircGroup = config->group("Subcircuits"); 0118 0119 int nextId = subcircGroup.readEntry<int>("NextId", 0); 0120 0121 // ensure dir exists 0122 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); 0123 while (QFile::exists(genFileName(nextId))) { 0124 nextId++; 0125 } 0126 0127 const int id = nextId; 0128 0129 const QString fileName = genFileName(id); 0130 QFile file(fileName); 0131 0132 if (file.open(QIODevice::WriteOnly) == false) { 0133 qCCritical(KTL_LOG) << "Subcircuits::addSubcircuit: couldn't open subcircuit save file: " << fileName; 0134 return; 0135 } 0136 0137 QTextStream stream(&file); 0138 stream << subcircuitXml; 0139 file.close(); 0140 0141 QList<int> idList = asIntList(subcircGroup.readEntry<QString>(QString("Ids"), QString())); 0142 idList += id; 0143 subcircGroup.writeEntry("Ids", idList); 0144 subcircGroup.writeEntry("NextId", ++nextId); 0145 0146 KConfigGroup grSubcircNr = config->group("Subcircuit_" + QString::number(id)); 0147 grSubcircNr.writeEntry("Name", name); 0148 0149 // It's important that we write the configuration *now*, lest the subcircuits be lost 0150 grSubcircNr.sync(); 0151 0152 updateComponentSelector(id, name); 0153 } 0154 0155 void Subcircuits::slotItemRemoved(const QString &id) 0156 { 0157 if (!id.startsWith("sc/")) { 0158 return; 0159 } 0160 0161 QString temp = id; 0162 temp.remove("sc/"); 0163 const int id_num = temp.toInt(); 0164 const QString fileName = genFileName(id_num); 0165 QFile file(fileName); 0166 file.remove(); 0167 0168 // KConfig *config = kapp->config(); 0169 KSharedConfigPtr config = KSharedConfig::openConfig(); 0170 KConfigGroup grSc = config->group("Subcircuits"); 0171 QList<int> idList = asIntList(grSc.readEntry<QString>(QString("Ids"), QString())); 0172 idList.removeAll(id_num); 0173 grSc.writeEntry("Ids", idList); 0174 } 0175 0176 #include "moc_subcircuits.cpp"