void KstRWLock::unlock() const {
#ifndef ONE_LOCK_TO_RULE_THEM_ALL
  QMutexLocker lock(&_mutex);

#ifdef LOCKTRACE
  kstdDebug() << (void*)this << " KstRWLock::unlock() by tid=" << (int)QThread::currentThread() << endl;
#endif

  Qt::HANDLE me = QThread::currentThread();

  if (_readCount > 0) {
    QMap<Qt::HANDLE, int>::Iterator it = _readLockers.find(me);
    if (it == _readLockers.end()) {
      // read locked but not by me -- ERROR
      kstdFatal() << "Thread " << (int)QThread::currentThread() << " tried to unlock KstRWLock " << (void*)this << " (read locked) without holding the lock" << endl;
      return;
    } else {
      --_readCount;
      if (it.data() == 1) {
        _readLockers.remove(it);
      } else {
        --(it.data());
      }
    }
  } else if (_writeCount > 0) {
    if (_writeLocker != me) {
      // write locked but not by me -- ERROR
      kstdFatal() << "Thread " << (int)QThread::currentThread() << " tried to unlock KstRWLock " << (void*)this << " (write locked) without holding the lock" << endl;
      return;
    } else {
      --_writeCount;
    }
  } else if (_readCount == 0 && _writeCount == 0) {
    // not locked -- ERROR
    kstdFatal() << "Thread " << (int)QThread::currentThread() << " tried to unlock KstRWLock " << (void*)this << " (unlocked) without holding the lock" << endl;
    return;
  }

  if (_readCount == 0 && _writeCount == 0) {
    // no locks remaining
    if (_waitingWriters) {
      _writerWait.wakeOne();
    } else if (_waitingReaders) {
      _readerWait.wakeAll();
    }
  }

#ifdef LOCKTRACE
  kstdDebug() << (void*)this << " KstRWLock::unlock() done by tid=" << (int)QThread::currentThread() << endl;
#endif
#else
  _mutex.unlock();
#endif
}
void KstRWLock::writeLock() const {
#ifndef ONE_LOCK_TO_RULE_THEM_ALL
  QMutexLocker lock(&_mutex);

#ifdef LOCKTRACE
  kstdDebug() << (void*)this << " KstRWLock::writeLock() by tid=" << (int)QThread::currentThread() << endl;
//  kstdDebug() << kstdBacktrace(6) << endl;
#endif

  Qt::HANDLE me = QThread::currentThread();

  if (_readCount > 0) {
    QMap<Qt::HANDLE, int>::Iterator it = _readLockers.find(me);
    if (it != _readLockers.end() && it.data() > 0) {
      // cannot acquire a write lock if I already have a read lock -- ERROR
      kstdFatal() << "Thread " << (int)QThread::currentThread() << " tried to write lock KstRWLock " << (void*)this << " while holding a read lock" << endl;
      return;
    }
  }

  while (_readCount > 0 || (_writeCount > 0 && _writeLocker != me)) {
    ++_waitingWriters;
    _writerWait.wait(&_mutex);
    --_waitingWriters;
  }
  _writeLocker = me;
  ++_writeCount;

#ifdef LOCKTRACE
  kstdDebug() << (void*)this << " KstRWLock::writeLock() done by tid=" << (int)QThread::currentThread() << endl;
#endif
#else
  _mutex.lock();
#endif
}
Example #3
0
/* returns true if succesful */
bool KstCsdDialogI::newObject() {
    QString tag_name = _tagName->text();
    if (tag_name == defaultTag) {
        tag_name = KST::suggestCSDName(_w->_vector->selectedVector());
    }

    // verify that the curve name is unique
    if (KstData::self()->dataTagNameNotUnique(tag_name)) {
        _tagName->setFocus();
        return false;
    }

    if (_w->_vector->selectedVector().isEmpty()) {
        KMessageBox::sorry(this, i18n("New CSD not made: define vectors first."));
        return false;
    }

    KST::vectorList.lock().readLock();
    KstVectorPtr p = *KST::vectorList.findTag(_w->_vector->selectedVector());
    KST::vectorList.lock().unlock();
    if (!p) {
        kstdFatal() << "Bug in kst: the vector field in CSD dialog refers to "
                    << "a non existant vector...." << endl;
    }

    ApodizeFunction apodizeFxn = ApodizeFunction(_w->_kstFFTOptions->ApodizeFxn->currentItem());
    bool apodize = _w->_kstFFTOptions->Apodize->isChecked();
    double gaussianSigma = _w->_kstFFTOptions->Sigma->value();
    bool removeMean = _w->_kstFFTOptions->RemoveMean->isChecked();
    bool average = _w->_kstFFTOptions->Interleaved->isChecked();
    int windowSize = _w->_windowSize->value();
    int length = _w->_kstFFTOptions->FFTLen->value();
    double freq = _w->_kstFFTOptions->SampRate->text().toDouble();
    PSDType output = PSDType(_w->_kstFFTOptions->Output->currentItem());
    QString vectorUnits = _w->_kstFFTOptions->VectorUnits->text();
    QString rateUnits = _w->_kstFFTOptions->RateUnits->text();
    _w->_kstFFTOptions->synch();

    KstCSDPtr csd = new KstCSD(tag_name, p, freq, average, removeMean,
                               apodize, apodizeFxn, windowSize, length, gaussianSigma, output,
                               vectorUnits, rateUnits);
    //csd->setInterpolateHoles(_w->_kstFFTOptions->InterpolateHoles->isChecked());

    KstImagePtr image = createImage(csd);

    KST::dataObjectList.lock().writeLock();
    KST::dataObjectList.append(csd.data());
    KST::dataObjectList.append(image.data());
    KST::dataObjectList.lock().unlock();

    csd = 0L;
    emit modified();
    return true;
}
Example #4
0
bool KstEqDialogI::editSingleObject(KstEquationPtr eqPtr) {
  eqPtr->writeLock();
  if (!checkEntries()) {
    eqPtr->unlock();
    return false;
  }

  // update the vector only if it is dirty 
  KstVectorPtr vp;
  if (_xVectorsDirty) {
    KST::vectorList.lock().readLock();
    /* find *V */
    KstVectorList::Iterator i = KST::vectorList.findTag(_w->_xVectors->selectedVector());
    if (i == KST::vectorList.end()) {
      kstdFatal() << "Bug in kst: the Vector field (Eq) "
                  << "refers to a non existant vector..." << endl;
    }
    vp = *i;
  } else {
    vp = eqPtr->vX();
  }
  KST::vectorList.lock().unlock();
  
  // update the DoInterpolation only if it is dirty
  if (_doInterpolationDirty) {
    eqPtr->setExistingXVector(vp, _w->_doInterpolation->isChecked());
  } else {
    eqPtr->setExistingXVector(vp, eqPtr->doInterp());
  }
  
  if (_equationDirty) {
    eqPtr->setEquation(_w->_equation->text());
    if (!eqPtr->isValid()) {
      QString parseErrors;
      for (QStringList::ConstIterator i = Equation::errorStack.begin(); i != Equation::errorStack.end(); ++i) {
        parseErrors += *i;
        parseErrors += "\n";
      }
      KMessageBox::detailedSorry(this, i18n("There is an error in the equation you entered."), parseErrors);
      eqPtr->unlock();
      return false;
    }
  }
  eqPtr->unlock();
  return true;
}
Example #5
0
void KstHsDialogI::autoBin() {
  KstReadLocker ml(&KST::vectorList.lock());

  if (!KST::vectorList.isEmpty()) {
    KstVectorList::Iterator i = KST::vectorList.findTag(_w->_vector->selectedVector());
    double max, min;
    int n;

    if (i == KST::vectorList.end()) {
      kstdFatal() << "Bug in kst: the Vector field in hsdialog refers to "
                  << "a non existant vector..." << endl;
    }
    (*i)->readLock(); // Hmm should we really lock here?  AutoBin should I think
    KstHistogram::AutoBin(KstVectorPtr(*i), &n, &max, &min);
    (*i)->unlock();

    _w->N->setValue(n);
    _w->Min->setText(QString::number(min));
    _w->Max->setText(QString::number(max));
  }
}
KstObject::UpdateType KstCPlugin::update(int update_counter) {
  Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);

  if (!isValid()) {
    return setLastUpdateResult(NO_CHANGE);
  }

  if (recursed()) {
    return setLastUpdateResult(NO_CHANGE);
  }

  bool force = dirty();
  setDirty(false);

  if (KstObject::checkUpdateCounter(update_counter) && !force) {
    return lastUpdateResult();
  }

#define CLEANUP() do {\
  for (unsigned i = 0; i < _outStringCnt; ++i) { \
    if (_outStrings[i]) { \
      free(_outStrings[i]); \
      _outStrings[i] = 0L; \
    } \
  } \
  for (unsigned i = 0; i < _inStringCnt; ++i) { \
    if (_inStrings[i]) { \
      free(_inStrings[i]); \
      _inStrings[i] = 0L; \
    } \
  } \
  } while(0)


  writeLockInputsAndOutputs();

  const QValueList<Plugin::Data::IOValue>& itable = _plugin->data()._inputs;
  const QValueList<Plugin::Data::IOValue>& otable = _plugin->data()._outputs;
  int itcnt = 0, vitcnt = 0, sitcnt = 0;
  bool doUpdate = force;

  // Populate the input scalars and vectors
  for (QValueList<Plugin::Data::IOValue>::ConstIterator it = itable.begin(); it != itable.end(); ++it) {
    if ((*it)._type == Plugin::Data::IOValue::TableType) {
      if (!_inputVectors.contains((*it)._name)) {
        KstDebug::self()->log(i18n("Input vector [%1] for plugin %2 not found.  Unable to continue.").arg((*it)._name).arg(tagName()), KstDebug::Error);
        CLEANUP();
        return setLastUpdateResult(NO_CHANGE);
      }
      KstVectorPtr iv = _inputVectors[(*it)._name];
      if (!iv) {
        kstdFatal() << "Input vector \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl;
      }
      doUpdate = (UPDATE == iv->update(update_counter)) || doUpdate;
      _inVectors[vitcnt] = iv->value();
      _inArrayLens[vitcnt++] = iv->length();
    } else if ((*it)._type == Plugin::Data::IOValue::FloatType) {
      KstScalarPtr is = _inputScalars[(*it)._name];
      if (!is) {
        kstdFatal() << "Input scalar \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl;
      }
      doUpdate = (UPDATE == is->update(update_counter)) || doUpdate;
      _inScalars[itcnt++] = is->value();
    } else if ((*it)._type == Plugin::Data::IOValue::StringType) {
      KstStringPtr is = _inputStrings[(*it)._name];
      if (!is) {
        kstdFatal() << "Input string \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl;
      }
      doUpdate = (UPDATE == is->update(update_counter)) || doUpdate;
      // Maybe we should use UTF-8 instead?
      _inStrings[sitcnt++] = strdup(is->value().latin1());
    } else if ((*it)._type == Plugin::Data::IOValue::PidType) {
      _inScalars[itcnt++] = getpid();
    }
  }

  if (!doUpdate) {
    CLEANUP();
    unlockInputsAndOutputs();
    return setLastUpdateResult(NO_CHANGE);
  }

  vitcnt = 0;
  // Populate the output vectors
  for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin();
                                                         it != otable.end();
                                                                        ++it) {
    if ((*it)._type == Plugin::Data::IOValue::TableType) {
      if (!_outputVectors.contains((*it)._name)) {
        KstDebug::self()->log(i18n("Output vector [%1] for plugin %2 not found.  Unable to continue.").arg((*it)._name).arg(tagName()), KstDebug::Error);
        CLEANUP();
        unlockInputsAndOutputs();
        return setLastUpdateResult(NO_CHANGE);
      }
      _outVectors[vitcnt] = _outputVectors[(*it)._name]->value();
      _outArrayLens[vitcnt++] = _outputVectors[(*it)._name]->length();
    }
  }

  if (_outStringCnt > 0) {
    memset(_outStrings, 0, _outStringCnt*sizeof(char *));
  }

  int rc;
  if (_inStringCnt > 0 || _outStringCnt > 0) {
    if (_plugin->data()._localdata) {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars,
          const_cast<const char**>(_inStrings), _outStrings, &_localData);
    } else {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars,
          const_cast<const char**>(_inStrings), _outStrings);
    }
  } else {
    if (_plugin->data()._localdata) {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars, &_localData);
    } else {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars);
    }
  }

  if (rc == 0) {
    itcnt = 0;
    vitcnt = 0;
    sitcnt = 0;
    setLastUpdateResult(UPDATE); // make sure that provider callbacks work
    // Read back the output vectors and scalars
    for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin();
        it != otable.end();
        ++it) {
      if ((*it)._type == Plugin::Data::IOValue::TableType) {
        KstVectorPtr vp = _outputVectors[(*it)._name];
        vectorRealloced(vp, _outVectors[vitcnt], _outArrayLens[vitcnt]);
        vp->setDirty();
        // Inefficient, but do we have any other choice?  We don't really know
        // from the plugin how much of this vector is "new" or "shifted"
        vp->setNewAndShift(vp->length(), vp->numShift());
        vp->update(update_counter);
        vitcnt++;
      } else if ((*it)._type == Plugin::Data::IOValue::FloatType) {
        KstScalarPtr sp = _outputScalars[(*it)._name];
        sp->setValue(_outScalars[itcnt++]);
        sp->update(update_counter);
      } else if ((*it)._type == Plugin::Data::IOValue::StringType) {
        KstStringPtr sp = _outputStrings[(*it)._name];
        sp->setValue(_outStrings[sitcnt++]);
        sp->update(update_counter);
      }
    }

    // if we have a fit plugin then create the necessary scalars from the parameter vector
    createFitScalars();
    _lastError = QString::null;
  } else if (rc > 0) {
    if (_lastError.isEmpty()) {
      const char *err = _plugin->errorCode(rc);
      if (err && *err) {
        _lastError = err;
        KstDebug::self()->log(i18n("Plugin %1 produced error: %2.").arg(tagName()).arg(_lastError), KstDebug::Error);
      } else {
        _lastError = QString::null;
      }
    }
  } else {
    bool doSend = _lastError.isEmpty() ? true : false;

    switch (rc) {
      case -1:
        _lastError = i18n("Generic Error");
        break;
      case -2:
        _lastError = i18n("Input Error");
        break;
      case -3:
        _lastError = i18n("Memory Error");
        break;
      default:
        _lastError = i18n("Unknown Error");
        break;
    }

    if (doSend) {
      KstDebug::self()->log(i18n("Plugin %2 produced error: %1.").arg(_lastError).arg(tagName()), KstDebug::Error);
    }
  }

  unlockInputsAndOutputs();

  CLEANUP();
#undef CLEANUP
  return setLastUpdateResult(UPDATE);
}
Example #7
0
bool KstEqDialogI::newObject() {
  QString tag_name = _tagName->text();
  QString etext = _w->_equation->text();
  etext.remove(QRegExp("[^a-zA-Z0-9\\(\\)\\+\\-\\*/\\%\\^\\|\\&\\!<>=_.]"));
  if (etext.length() > 12) {
    etext.truncate(12);
    etext += "...";
  }

  if (tag_name == defaultTag) {
    tag_name = KST::suggestEQName(etext);
  }

  /* verify that the curve name is unique */
  if (KstData::self()->dataTagNameNotUnique(tag_name)) {
    _tagName->setFocus();
    return false;
  }

  if (!checkEntries()) {
    return false;
  }

  KST::vectorList.lock().readLock();
  /* find *V */
  KstVectorPtr vp = *KST::vectorList.findTag(_w->_xVectors->selectedVector());
  if (!vp) {
    kstdFatal() << "Bug in kst: the Vector field (Eq) "
                << "refers to a non-existent vector..." << endl;
  }
  KST::vectorList.lock().unlock();

  /** Create the equation here */
  vp->readLock();
  KstEquationPtr eq = new KstEquation(tag_name, _w->_equation->text(), vp, _w->_doInterpolation->isChecked());
  vp->unlock();

  if (!eq->isValid()) {
    eq = 0L;
    QString parseErrors;
    for (QStringList::ConstIterator i = Equation::errorStack.begin(); i != Equation::errorStack.end(); ++i) {
      parseErrors += *i;
      parseErrors += "\n";
    }

    KMessageBox::detailedSorry(this, i18n("There is an error in the equation you entered."), parseErrors);
    return false;
  }

  KstVCurvePtr vc = new KstVCurve(KST::suggestCurveName(tag_name, true), eq->vX(), eq->vY(), 0L, 0L, 0L, 0L, _w->_curveAppearance->color());
  vc->setHasPoints(_w->_curveAppearance->showPoints());
  vc->setHasLines(_w->_curveAppearance->showLines());
  vc->setHasBars(_w->_curveAppearance->showBars());
  vc->setLineWidth(_w->_curveAppearance->lineWidth());
  vc->setLineStyle(_w->_curveAppearance->lineStyle());
  vc->pointType = _w->_curveAppearance->pointType();
  vc->setPointDensity(_w->_curveAppearance->pointDensity());
  vc->setBarStyle(_w->_curveAppearance->barStyle());
  
  QString legend_text = _legendText->text();
  if (legend_text == defaultTag) {
    vc->setLegendText(QString(""));
  } else {
    vc->setLegendText(legend_text);
  }

  KstViewWindow *w = dynamic_cast<KstViewWindow*>(KstApp::inst()->findWindow(_w->_curvePlacement->_plotWindow->currentText()));
  if (!w) {
    QString n = KstApp::inst()->newWindow(KST::suggestWinName());
    w = dynamic_cast<KstViewWindow*>(KstApp::inst()->findWindow(n));
  }

  if (w) {
    Kst2DPlotPtr plot;
    if (_w->_curvePlacement->existingPlot()) {
      /* assign curve to plot */
      plot = kst_cast<Kst2DPlot>(w->view()->findChild(_w->_curvePlacement->plotName()));
      if (plot) {
        plot->addCurve(vc.data());
      }
    }

    if (_w->_curvePlacement->newPlot()) {
      /* assign curve to plot */
      QString name = w->createObject<Kst2DPlot>(KST::suggestPlotName());
      if (_w->_curvePlacement->reGrid()) {
        w->view()->cleanup(_w->_curvePlacement->columns());
      }
      plot = kst_cast<Kst2DPlot>(w->view()->findChild(name));
      if (plot) {
        _w->_curvePlacement->update();
        _w->_curvePlacement->setCurrentPlot(plot->tagName());
        plot->addCurve(vc.data());
        plot->generateDefaultLabels();
      }
    }
  }

  KST::dataObjectList.lock().writeLock();
  KST::dataObjectList.append(eq.data());
  KST::dataObjectList.append(vc.data());
  KST::dataObjectList.lock().unlock();

  eq = 0L; // drop the reference before we update
  vc = 0L;
  emit modified();
  return true;
}
Example #8
0
/* returns true if succesful */
bool KstPsdDialogI::newObject() {
  QString tag_name = _tagName->text();
  if (tag_name == defaultTag) {
    tag_name = KST::suggestPSDName(KstObjectTag::fromString(_w->_vector->selectedVector()));
  }

  // verify that the curve name is unique
  if (KstData::self()->dataTagNameNotUnique(tag_name)) {
    _tagName->setFocus();
    return false;
  }

  if (_w->_vector->selectedVector().isEmpty()) {
    KMessageBox::sorry(this, i18n("New PSD not made: define vectors first."));
    return false;
  }

  KST::vectorList.lock().readLock();
  KstVectorPtr p = *KST::vectorList.findTag(_w->_vector->selectedVector());
  KST::vectorList.lock().unlock();
  if (!p) {
    kstdFatal() << "Bug in kst: the vector field (PSD) refers to "
                << "a non existant vector...." << endl;
  }

  // create the psd curve
  if (!_w->_kstFFTOptions->checkValues()) {
    return false;
  } else {
    p->readLock();
    KstPSDPtr psd = new KstPSD(tag_name, p,
                            _w->_kstFFTOptions->SampRate->text().toDouble(),
                            _w->_kstFFTOptions->Interleaved->isChecked(),
                            _w->_kstFFTOptions->FFTLen->text().toInt(),
                            _w->_kstFFTOptions->Apodize->isChecked(),
                            _w->_kstFFTOptions->RemoveMean->isChecked(),
                            _w->_kstFFTOptions->VectorUnits->text(),
                            _w->_kstFFTOptions->RateUnits->text(),
                            ApodizeFunction(_w->_kstFFTOptions->ApodizeFxn->currentItem()),
                            _w->_kstFFTOptions->Sigma->value(),
                            PSDType(_w->_kstFFTOptions->Output->currentItem()));
    psd->setInterpolateHoles(_w->_kstFFTOptions->InterpolateHoles->isChecked());
    p->unlock();

    KstVCurvePtr vc = new KstVCurve(KST::suggestCurveName(psd->tag(),true), psd->vX(), psd->vY(), 0L, 0L, 0L, 0L, _w->_curveAppearance->color());
    vc->setHasPoints(_w->_curveAppearance->showPoints());
    vc->setHasLines(_w->_curveAppearance->showLines());
    vc->setHasBars(_w->_curveAppearance->showBars());
    vc->pointType = _w->_curveAppearance->pointType();
    vc->setLineWidth(_w->_curveAppearance->lineWidth());
    vc->setLineStyle(_w->_curveAppearance->lineStyle());
    vc->setBarStyle(_w->_curveAppearance->barStyle());
    vc->setPointDensity(_w->_curveAppearance->pointDensity());

    QString legend_text = _legendText->text();
    if (legend_text == defaultTag) {
      vc->setLegendText(QString::null);
    } else {
      vc->setLegendText(legend_text);
    }

    Kst2DPlotPtr plot;
    KstViewWindow *w = dynamic_cast<KstViewWindow*>(KstApp::inst()->findWindow(_w->_curvePlacement->_plotWindow->currentText()));
    if (!w) {
      QString n = KstApp::inst()->newWindow(KST::suggestWinName());
      w = static_cast<KstViewWindow*>(KstApp::inst()->findWindow(n));
    }
    if (w) {
      if (_w->_curvePlacement->existingPlot()) {
        // assign curve to plot
        plot = kst_cast<Kst2DPlot>(w->view()->findChild(_w->_curvePlacement->plotName()));
        if (plot) {
          plot->addCurve(vc.data());
        }
      }

      if (_w->_curvePlacement->newPlot()) {
        // assign curve to plot
        QString name = w->createObject<Kst2DPlot>(KST::suggestPlotName());
        if (_w->_curvePlacement->reGrid()) {
          w->view()->cleanup(_w->_curvePlacement->columns());
        }
        plot = kst_cast<Kst2DPlot>(w->view()->findChild(name));
        if (plot) {
          plot->setXAxisInterpretation(false, KstAxisInterpretation(), KstAxisDisplay());
          plot->setYAxisInterpretation(false, KstAxisInterpretation(), KstAxisDisplay());
          _w->_curvePlacement->update();
          _w->_curvePlacement->setCurrentPlot(plot->tagName());
          plot->addCurve(vc.data());
          plot->generateDefaultLabels();
        }
      }
    }
    KST::dataObjectList.lock().writeLock();
    KST::dataObjectList.append(psd.data());
    KST::dataObjectList.append(vc.data());
    KST::dataObjectList.lock().unlock();
    psd = 0L;
    vc = 0L;
    emit modified();
  }
  return true;
}
Example #9
0
bool KstHsDialogI::newObject() {
  QString tag_name = _tagName->text();
  if (tag_name == defaultTag) {
    tag_name = KST::suggestHistogramName(KstObjectTag::fromString(_w->_vector->selectedVector()));
  }

  // verify that the curve name is unique
  if (KstData::self()->dataTagNameNotUnique(tag_name)) {
    _tagName->setFocus();
    return false;
  }

  if (_w->_vector->selectedVector().isEmpty()) {
    KMessageBox::sorry(this, i18n("New Histogram not made: define vectors first."));
    return false;
  }

  // find max and min
  double new_min = _w->Min->text().toDouble();
  double new_max = _w->Max->text().toDouble();
  if (new_max < new_min) {
    double m = new_max;
    new_max = new_min;
    new_min = m;
  }

  if (new_max == new_min) {
    KMessageBox::sorry(this, i18n("Max and Min can not be equal."));
    return false;
  }

  int new_n_bins = _w->N->text().toInt();
  if (new_n_bins < 1) {
    KMessageBox::sorry(this, i18n("You must have one or more bins in a histogram."));
    return false;
  }

  KstHsNormType new_norm_mode;
  if (_w->NormIsPercent->isChecked()) {
    new_norm_mode = KST_HS_PERCENT;
  } else if (_w->NormIsFraction->isChecked()) {
    new_norm_mode = KST_HS_FRACTION;
  } else if (_w->PeakIs1->isChecked()) {
    new_norm_mode = KST_HS_MAX_ONE;
  } else {
    new_norm_mode = KST_HS_NUMBER;
  }

  KstHistogramPtr hs;

  KST::vectorList.lock().readLock();
  KstVectorPtr vp = *KST::vectorList.findTag(_w->_vector->selectedVector());
  KST::vectorList.lock().unlock();
  if (!vp) {
    kstdFatal() << "Bug in kst: the Vector field (Hs) refers to "
                << " a non existant vector..." << endl;
  }

  vp->readLock();
  hs = new KstHistogram(tag_name, vp, new_min, new_max,
                        new_n_bins, new_norm_mode);
  vp->unlock();
  hs->setRealTimeAutoBin(_w->_realTimeAutoBin->isChecked());

  KstVCurvePtr vc = new KstVCurve(KST::suggestCurveName(hs->tag(), true), hs->vX(), hs->vY(), 0L, 0L, 0L, 0L, _w->_curveAppearance->color());

  vc->setHasPoints(_w->_curveAppearance->showPoints());
  vc->setHasLines(_w->_curveAppearance->showLines());
  vc->setHasBars(_w->_curveAppearance->showBars());
  vc->pointType = _w->_curveAppearance->pointType();
  vc->setLineWidth(_w->_curveAppearance->lineWidth());
  vc->setLineStyle(_w->_curveAppearance->lineStyle());
  vc->setBarStyle(_w->_curveAppearance->barStyle());
  vc->setPointDensity(_w->_curveAppearance->pointDensity());

  QString legend_text = _legendText->text();
  if (legend_text == defaultTag) {
    vc->setLegendText(QString(""));
  } else {
    vc->setLegendText(legend_text);
  }

  KstViewWindow *w = dynamic_cast<KstViewWindow*>(KstApp::inst()->findWindow(_w->_curvePlacement->_plotWindow->currentText()));
  if (!w) {
    QString n = KstApp::inst()->newWindow(KST::suggestWinName());
    w = static_cast<KstViewWindow*>(KstApp::inst()->findWindow(n));
  }
  if (w) {
    Kst2DPlotPtr plot;
    if (_w->_curvePlacement->existingPlot()) {
      /* assign curve to plot */
      plot = kst_cast<Kst2DPlot>(w->view()->findChild(_w->_curvePlacement->plotName()));
      if (plot) {
        plot->addCurve(vc.data());
      }
    }

    if (_w->_curvePlacement->newPlot()) {
      /* assign curve to plot */
      QString name = w->createObject<Kst2DPlot>(KST::suggestPlotName());
      if (_w->_curvePlacement->reGrid()) {
        w->view()->cleanup(_w->_curvePlacement->columns());
      }
      plot = kst_cast<Kst2DPlot>(w->view()->findChild(name));
      if (plot) {
        _w->_curvePlacement->update();
        _w->_curvePlacement->setCurrentPlot(plot->tagName());
        plot->addCurve(vc.data());
        plot->generateDefaultLabels();
      }
    }
  }

  KST::dataObjectList.lock().writeLock();
  KST::dataObjectList.append(hs.data());
  KST::dataObjectList.append(vc.data());
  KST::dataObjectList.lock().unlock();

  hs = 0L;
  vc = 0L;
  emit modified();

  return true;
}