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