File indexing completed on 2024-12-22 04:17:50
0001 /*************************************************************************** 0002 * * 0003 * copyright : (C) 2007 The University of Toronto * 0004 * netterfield@astro.utoronto.ca * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 ***************************************************************************/ 0012 0013 #include "basicplugin.h" 0014 0015 #include <stdlib.h> 0016 0017 #include <QXmlStreamWriter> 0018 0019 #ifndef Q_OS_WIN32 0020 #include <unistd.h> 0021 #endif 0022 0023 0024 0025 #include "debug.h" 0026 #include "dialoglauncher.h" 0027 #include "datacollection.h" 0028 #include "objectstore.h" 0029 #include "dataobjectplugin.h" 0030 #include "dataobjectscriptinterface.h" 0031 0032 namespace Kst { 0033 0034 const QString BasicPlugin::staticTypeString = "Plugin"; 0035 const QString BasicPlugin::staticTypeTag = "plugin"; 0036 0037 BasicPlugin::BasicPlugin(ObjectStore *store) 0038 : DataObject(store) { 0039 _typeString = "Plugin"; 0040 _type = "Plugin"; 0041 0042 _initializeShortName(); 0043 } 0044 0045 0046 BasicPlugin::~BasicPlugin() { 0047 } 0048 0049 void BasicPlugin::_initializeShortName() { 0050 _shortName = 'U'+QString::number(_pluginnum); 0051 if (_pluginnum>max_pluginnum) 0052 max_pluginnum = _pluginnum; 0053 _pluginnum++; 0054 0055 } 0056 0057 0058 ScriptInterface* BasicPlugin::createScriptInterface() { 0059 return new PluginSI(this); 0060 } 0061 0062 0063 void BasicPlugin::setPluginName(const QString &pluginName) { 0064 _pluginName = pluginName; 0065 } 0066 0067 0068 DataObjectPtr BasicPlugin::makeDuplicate() const { 0069 #if 0 0070 BasicPluginPtr plugin = kst_cast<BasicPlugin>(DataObject::createPlugin(propertyString())); 0071 0072 // use same inputs 0073 for (VectorMap::ConstIterator iter = _inputVectors.begin(); iter != _inputVectors.end(); ++iter) { 0074 plugin->inputVectors().insert(iter.key(), iter.value()); 0075 } 0076 for (ScalarMap::ConstIterator iter = _inputScalars.begin(); iter != _inputScalars.end(); ++iter) { 0077 plugin->inputScalars().insert(iter.key(), iter.value()); 0078 } 0079 for (StringMap::ConstIterator iter = _inputStrings.begin(); iter != _inputStrings.end(); ++iter) { 0080 plugin->inputStrings().insert(iter.key(), iter.value()); 0081 } 0082 0083 // create new outputs 0084 for (VectorMap::ConstIterator iter = outputVectors().begin(); iter != outputVectors().end(); ++iter) { 0085 KstWriteLocker blockVectorUpdates(&vectorList.lock()); 0086 VectorPtr v = new Vector(ObjectTag(iter.value()->tag().tag() + "'", iter.value()->tag().context()), 0, plugin.data()); // FIXME: unique tag generation 0087 plugin->outputVectors().insert(iter.key(), v); 0088 } 0089 for (ScalarMap::ConstIterator iter = outputScalars().begin(); iter != outputScalars().end(); ++iter) { 0090 ScalarPtr s = new Scalar(ObjectTag(iter.value()->tag().tag() + "'", iter.value()->tag().context()), plugin.data()); // FIXME: unique tag generation 0091 plugin->outputScalars().insert(iter.key(), s); 0092 } 0093 for (StringMap::ConstIterator iter = outputStrings().begin(); iter != outputStrings().end(); ++iter) { 0094 StringPtr s = new String(ObjectTag(iter.value()->tag().tag() + "'", iter.value()->tag().context()), plugin.data()); // FIXME: unique tag generation 0095 plugin->outputStrings().insert(iter.key(), s); 0096 } 0097 0098 // set the same plugin 0099 plugin->setTagName(ObjectTag(tag().tag() + "'", tag().context())); // FIXME: unique tag generation method 0100 map.insert(this, DataObjectPtr(plugin)); 0101 return DataObjectPtr(plugin); 0102 #endif 0103 // FIXME: implement this 0104 return 0L; 0105 } 0106 0107 void BasicPlugin::showNewDialog() { 0108 DialogLauncher::self()->showBasicPluginDialog(_pluginName); 0109 } 0110 0111 0112 void BasicPlugin::showEditDialog() { 0113 DialogLauncher::self()->showBasicPluginDialog(_pluginName, this); 0114 } 0115 0116 0117 VectorPtr BasicPlugin::inputVector(const QString& vector) const { 0118 VectorMap::ConstIterator i = _inputVectors.constFind(vector); 0119 if (i != _inputVectors.constEnd()) 0120 return *i; 0121 else 0122 return 0; 0123 } 0124 0125 0126 ScalarPtr BasicPlugin::inputScalar(const QString& scalar) const { 0127 ScalarMap::ConstIterator i = _inputScalars.constFind(scalar); 0128 if (i != _inputScalars.constEnd()) 0129 return *i; 0130 else 0131 return 0; 0132 } 0133 0134 0135 StringPtr BasicPlugin::inputString(const QString& string) const { 0136 StringMap::ConstIterator i = _inputStrings.constFind(string); 0137 if (i != _inputStrings.constEnd()) 0138 return *i; 0139 else 0140 return 0; 0141 } 0142 0143 0144 void BasicPlugin::setOutputVector(const QString &type, const QString &name) { 0145 QString txt = !name.isEmpty() ? name : type; 0146 Q_ASSERT(store()); 0147 VectorPtr v = store()->createObject<Vector>(); 0148 v->setProvider(this); 0149 v->setSlaveName(txt); 0150 _outputVectors.insert(type, v); 0151 } 0152 0153 0154 void BasicPlugin::setOutputScalar(const QString &type, const QString &name) { 0155 QString txt = !name.isEmpty() ? name : type; 0156 Q_ASSERT(store()); 0157 ScalarPtr s = store()->createObject<Scalar>(); 0158 s->setProvider(this); 0159 s->setSlaveName(txt); 0160 _outputScalars.insert(type, s); 0161 } 0162 0163 0164 void BasicPlugin::setOutputString(const QString &type, const QString &name) { 0165 QString txt = !name.isEmpty() ? name : type; 0166 Q_ASSERT(store()); 0167 StringPtr s = store()->createObject<String>(); 0168 s->setProvider(this); 0169 s->setSlaveName(txt); 0170 s->setOrphan(false); 0171 _outputStrings.insert(type, s); 0172 } 0173 0174 0175 void BasicPlugin::internalUpdate() { 0176 0177 //Make sure we have all the necessary inputs 0178 if (!inputsExist()) 0179 return; 0180 0181 writeLockInputsAndOutputs(); 0182 0183 //Call the plugins algorithm to operate on the inputs 0184 //and produce the outputs 0185 if ( !algorithm() ) { 0186 Debug::self()->log(tr("There is an error in the %1 algorithm.").arg(propertyString()), Debug::Error); 0187 unlockInputsAndOutputs(); 0188 return; 0189 } 0190 0191 // Register that the outputs have been recalculated. 0192 updateOutput(); 0193 0194 createScalars(); 0195 0196 unlockInputsAndOutputs(); 0197 0198 return; 0199 } 0200 0201 0202 // If a plugin provides a Parameters Vector, then scalars will be created, as well as a label. 0203 void BasicPlugin::createScalars() { 0204 // Assumes that this is called with a write lock in place on this object 0205 Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); 0206 0207 if (hasParameterVector()) { 0208 VectorPtr vectorParam = _outputVectors["Parameters Vector"]; 0209 if (vectorParam) { 0210 QString paramName; 0211 int i = 0; 0212 int length = vectorParam->length(); 0213 0214 Q_ASSERT(store()); 0215 for (paramName = parameterName(i); 0216 !paramName.isEmpty() && i < length; 0217 paramName = parameterName(++i)) { 0218 double scalarValue = vectorParam->value(i); 0219 if (!_outputScalars.contains(paramName)) { 0220 ScalarPtr s = store()->createObject<Scalar>(); 0221 s->setProvider(this); 0222 s->setSlaveName(paramName); 0223 s->setValue(scalarValue); 0224 s->writeLock(); 0225 _outputScalars.insert(paramName, s); 0226 } else { 0227 _outputScalars[paramName]->setValue(scalarValue); 0228 } 0229 } 0230 } 0231 } 0232 } 0233 0234 0235 QString BasicPlugin::parameterName(int /*index*/) const { 0236 return QString(); 0237 } 0238 0239 0240 QString BasicPlugin::label(int precision) const { 0241 Q_UNUSED(precision) 0242 QString label; 0243 QString paramName; 0244 0245 VectorPtr yVector = outputVectors().value(outputVectorList().first()); 0246 0247 label = yVector->labelInfo().name; 0248 0249 if (hasParameterVector()) { 0250 VectorPtr vectorParam = _outputVectors["Parameters Vector"]; 0251 int length = vectorParam->length(); 0252 int i=0; 0253 for (paramName = parameterName(i); 0254 !paramName.isEmpty() && i < length; 0255 paramName = parameterName(++i)) { 0256 if (_outputScalars.contains(paramName)) { 0257 label += QString("\n%1: [%2]").arg(paramName).arg(_outputScalars[paramName]->Name()); 0258 } 0259 } 0260 } 0261 0262 return label; 0263 } 0264 0265 0266 template<class T, class V> 0267 static void writeVectors(T& vectors, const QString& element, QXmlStreamWriter& stream, QString (V::* name)() const) { 0268 for (QStringList::iterator it = vectors.ordered.begin(); it != vectors.ordered.end(); ++it) { 0269 typename T::iterator i = vectors.find(*it); 0270 stream.writeStartElement(element); 0271 stream.writeAttribute("type", i.key()); 0272 stream.writeAttribute("tag", (i.value()->*name)()); 0273 stream.writeEndElement(); 0274 } 0275 } 0276 0277 0278 void BasicPlugin::save(QXmlStreamWriter &stream) { 0279 stream.writeStartElement(staticTypeTag); 0280 stream.writeAttribute("type", _pluginName); 0281 saveNameInfo(stream, VECTORNUM|PLUGINNUM|SCALARNUM); 0282 saveProperties(stream); 0283 writeVectors(_inputVectors, "inputvector", stream, &NamedObject::Name); 0284 writeVectors(_inputScalars, "inputscalar", stream, &NamedObject::Name); 0285 writeVectors(_inputStrings, "inputstring", stream, &NamedObject::Name); 0286 writeVectors(_outputVectors, "outputvector", stream, &Primitive::slaveName); 0287 writeVectors(_outputScalars, "outputscalar", stream, &Primitive::slaveName); 0288 writeVectors(_outputStrings, "outputstring", stream, &Primitive::slaveName); 0289 0290 stream.writeEndElement(); 0291 } 0292 0293 0294 void BasicPlugin::saveProperties(QXmlStreamWriter &s) { 0295 Q_UNUSED(s); 0296 } 0297 0298 0299 //TODO Could use some templates perhaps... 0300 bool BasicPlugin::inputsExist() const { 0301 //First, check the inputVectors... 0302 QStringList iv = inputVectorList(); 0303 QStringList::ConstIterator ivI = iv.constBegin(); 0304 for (; ivI != iv.constEnd(); ++ivI) { 0305 if (!inputVector(*ivI)) 0306 return false; 0307 } 0308 0309 //Now, check the inputScalars... 0310 QStringList is = inputScalarList(); 0311 QStringList::ConstIterator isI = is.constBegin(); 0312 for (; isI != is.constEnd(); ++isI) { 0313 if (!inputScalar(*isI)) 0314 return false; 0315 } 0316 0317 //Finally, check the inputStrings... 0318 QStringList istr = inputStringList(); 0319 QStringList::ConstIterator istrI = istr.constBegin(); 0320 for (; istrI != istr.constEnd(); ++istrI) { 0321 if (!inputString(*istrI)) 0322 return false; 0323 } 0324 return true; 0325 } 0326 0327 0328 // Register that the outputs have been recalculated. 0329 void BasicPlugin::updateOutput() const { 0330 //output vectors... 0331 //FIXME: _outputVectors should be used, not this string list! 0332 QStringList ov = outputVectorList(); 0333 QStringList::ConstIterator ovI = ov.constBegin(); 0334 for (; ovI != ov.constEnd(); ++ovI) { 0335 if (VectorPtr o = outputVector(*ovI)) { 0336 Q_ASSERT(o->myLockStatus() == KstRWLock::WRITELOCKED); 0337 //vectorRealloced(o, o->value(), o->length()); // why here? 0338 o->setNewAndShift(o->length(), o->numShift()); 0339 } 0340 } 0341 } 0342 0343 QString BasicPlugin::descriptionTip() const { 0344 return tr("Plugin: %1").arg(Name()); 0345 } 0346 0347 } 0348 // vim: ts=2 sw=2 et