示例#1
0
bool KstChangeFileDialog::applyFileChange() {
  KstDataSourcePtr file;
  KST::dataSourceList.lock().writeLock();
  KstDataSourceList::Iterator it = KST::dataSourceList.findReusableFileName(_dataFile->url());
  QString invalidSources;
  int invalid = 0;

  if (it == KST::dataSourceList.end()) {
    file = KstDataSource::loadSource(_dataFile->url());
    if (!file || !file->isValid()) {
      KST::dataSourceList.lock().unlock();
      QMessageBox::warning(this, tr("Kst"), tr("The file could not be loaded."));
      return false;
    }
    if (file->isEmpty()) {
      KST::dataSourceList.lock().unlock();
      QMessageBox::warning(this, tr("Kst"), tr("The file does not contain data."));
      return false;
    }
    KST::dataSourceList.append(file);
  } else {
    file = *it;
  }
  KST::dataSourceList.lock().unlock();

  KstApp *app = KstApp::inst();
  KstRVectorList rvl = kstObjectSubList<KstVector,KstRVector>(KST::vectorList);
  KstRMatrixList rml = kstObjectSubList<KstMatrix,KstRMatrix>(KST::matrixList);
  int selected = 0;
  int handled = 0;

  int count = (int)ChangeFileCurveList->count();
  for (int i = 0; i < count; i++) {
    if (ChangeFileCurveList->isSelected(i)) {
      ++selected;
    }
  }

  // a map to keep track of which objects have been duplicated, and mapping
  // old object -> new object
  KstDataObjectDataObjectMap duplicatedMap;
  QMap<KstVectorPtr, KstVectorPtr> duplicatedVectors;
  QMap<KstMatrixPtr, KstMatrixPtr> duplicatedMatrices;

  KstDataSourceList oldSources;

  // go through the vectors
  for (int i = 0; i < (int)rvl.count(); i++) {
    if (ChangeFileCurveList->isSelected(i)) {
      KstRVectorPtr vector = rvl[i];
      vector->writeLock();
      file->readLock();
      bool valid = file->isValidField(vector->field());
      file->unlock();
      if (!valid) {
        if (invalid > 0) {
          invalidSources = tr("%1, %2").arg(invalidSources).arg(vector->field());
        } else {
          invalidSources = vector->field();
        }
        ++invalid;
      } else {
        if (_duplicateSelected->isChecked()) {
          // block vector updates until vector is setup properly
          KST::vectorList.lock().writeLock();

          // create a new vector
          KstRVectorPtr newVector = vector->makeDuplicate();
          if (!oldSources.contains(newVector->dataSource())) {
            oldSources << newVector->dataSource();
          }
          newVector->changeFile(file);

          KST::vectorList.lock().unlock();

          // duplicate dependents
          if (_duplicateDependents->isChecked()) {
            duplicatedVectors.insert(KstVectorPtr(vector), KstVectorPtr(newVector));
            KST::duplicateDependents(KstVectorPtr(vector), duplicatedMap, duplicatedVectors);
          }
        } else {
          if (!oldSources.contains(vector->dataSource())) {
            oldSources << vector->dataSource();
          }
          vector->changeFile(file);
        }
      }
      vector->unlock();
      app->slotUpdateProgress(selected, ++handled, tr("Updating vectors..."));
    }
  }

  // go through the matrices
  for (int i = (int)rvl.count(); i < (int)ChangeFileCurveList->count(); i++) {
    if (ChangeFileCurveList->isSelected(i)) {
      KstRMatrixPtr matrix = rml[i-rvl.count()];
      matrix->writeLock();
      file->readLock();
      bool valid = file->isValidMatrix(matrix->field());
      file->unlock();
      if (!valid) {
        if (invalid > 0) {
          invalidSources = tr("%1, %2").arg(invalidSources).arg(matrix->field());
        } else {
          invalidSources = matrix->field();
        }
        ++invalid;
      } else {
        if (_duplicateSelected->isChecked()) {
          // block matrix updates until matrix is setup properly
          KST::matrixList.lock().writeLock();

          // create a new matrix
          KstRMatrixPtr newMatrix = matrix->makeDuplicate();
          if (!oldSources.contains(newMatrix->dataSource())) {
            oldSources << newMatrix->dataSource();
          }
          newMatrix->changeFile(file);

          KST::matrixList.lock().unlock();

          // duplicate dependents
          if (_duplicateDependents->isChecked()) {
            duplicatedMatrices.insert(KstMatrixPtr(matrix), KstMatrixPtr(newMatrix));
            KST::duplicateDependents(KstMatrixPtr(matrix), duplicatedMap, duplicatedMatrices);
          }
        } else {
          if (!oldSources.contains(matrix->dataSource())) {
            oldSources << matrix->dataSource();
          }
          matrix->changeFile(file);
        }
      }
      matrix->unlock();
      app->slotUpdateProgress(selected, ++handled, tr("Updating matrices..."));
    }
  }

  app->slotUpdateProgress(0, 0, QString::null);
  file = 0L;

  // now add any curves and images to plots if they were duplicated
  if (_duplicateSelected->isChecked() && _duplicateDependents->isChecked()) { 
    KstApp *app = KstApp::inst();
    QList<QMdiSubWindow*> windows;
    QList<QMdiSubWindow*>::const_iterator i;
  
    windows = app->subWindowList( CreationOrder );

    for (i = windows.constBegin(); i != windows.constEnd(); ++i)
      KstViewWindow *viewWindow = dynamic_cast<KstViewWindow*>(*i);
      if (viewWindow) {
        KstTopLevelViewPtr view = kst_cast<KstTopLevelView>(viewWindow->view());
        if (view) {
          Kst2DPlotList plots = view->findChildrenType<Kst2DPlot>(true);

          for (Kst2DPlotList::Iterator plotIter = plots.begin(); plotIter != plots.end(); ++plotIter) {
            for (KstDataObjectDataObjectMap::ConstIterator iter = duplicatedMap.begin(); iter != duplicatedMap.end(); ++iter) {
              if (KstBaseCurvePtr curve = kst_cast<KstBaseCurve>(iter.data())) {
                if ((*plotIter)->Curves.contains(kst_cast<KstBaseCurve>(iter.key())) && !(*plotIter)->Curves.contains(kst_cast<KstBaseCurve>(curve))) {
                  (*plotIter)->addCurve(curve);
                }
              }
            }
          }
        }
      }
    }
  }
KstBindDataSourceCollection::KstBindDataSourceCollection(KJS::ExecState *exec, const KstDataSourceList& dataSources)
: KstBindCollection(exec, "DataSourceCollection", true) {
  _isGlobal = false;
  _sources = dataSources.fileNames();
}
bool KstChangeFileDialogI::applyFileChange() {
  KstDataSourcePtr file;
  KST::dataSourceList.lock().writeLock();
  KstDataSourceList::Iterator it = KST::dataSourceList.findReusableFileName(_dataFile->url());
  QString invalidSources;
  int invalid = 0;

  if (it == KST::dataSourceList.end()) {
    file = KstDataSource::loadSource(_dataFile->url());
    if (!file || !file->isValid()) {
      KST::dataSourceList.lock().unlock();
      KMessageBox::sorry(this, i18n("The file could not be loaded."));
      return false;
    }
    if (file->isEmpty()) {
      KST::dataSourceList.lock().unlock();
      KMessageBox::sorry(this, i18n("The file does not contain data."));
      return false;
    }
    KST::dataSourceList.append(file);
  } else {
    file = *it;
  }
  KST::dataSourceList.lock().unlock();

  KstApp *app = KstApp::inst();
  KstRVectorList rvl = kstObjectSubList<KstVector,KstRVector>(KST::vectorList);
  KstRMatrixList rml = kstObjectSubList<KstMatrix,KstRMatrix>(KST::matrixList);
  int selected = 0;
  int handled = 0;

  int count = (int)ChangeFileCurveList->count();
  for (int i = 0; i < count; i++) {
    if (ChangeFileCurveList->isSelected(i)) {
      ++selected;
    }
  }

  // a map to keep track of which objects have been duplicated, and mapping
  // old object -> new object
  KstDataObjectDataObjectMap duplicatedMap;
  QMap<KstVectorPtr, KstVectorPtr> duplicatedVectors;
  QMap<KstMatrixPtr, KstMatrixPtr> duplicatedMatrices;

  KstDataSourceList oldSources;
  
  // go through the vectors
  for (int i = 0; i < (int)rvl.count(); i++) {
    if (ChangeFileCurveList->isSelected(i)) {
      KstRVectorPtr vector = rvl[i];
      vector->writeLock();
      file->readLock();
      bool valid = file->isValidField(vector->field());
      file->unlock();
      if (!valid) {
        if (invalid > 0) {
          // FIXME: invalid list construction for i18n
          invalidSources = i18n("%1, %2").arg(invalidSources).arg(vector->field());
        } else {
          invalidSources = vector->field();
        }
        ++invalid;
      } else {
        if (_duplicateSelected->isChecked()) {
          // block vector updates until vector is setup properly
          KST::vectorList.lock().writeLock();

          // create a new vector
          KstRVectorPtr newVector = vector->makeDuplicate();
          if (!oldSources.contains(newVector->dataSource())) {
            oldSources << newVector->dataSource();
          }
          newVector->changeFile(file);

          KST::vectorList.lock().unlock();

          // duplicate dependents
          if (_duplicateDependents->isChecked()) {
            duplicatedVectors.insert(KstVectorPtr(vector), KstVectorPtr(newVector));
            KST::duplicateDependents(KstVectorPtr(vector), duplicatedMap, duplicatedVectors);
          }
        } else {
          if (!oldSources.contains(vector->dataSource())) {
            oldSources << vector->dataSource();
          }
          vector->changeFile(file);
        }
      }
      vector->unlock();
      app->slotUpdateProgress(selected, ++handled, i18n("Updating vectors..."));
    }
  }
  
  // go through the matrices
  for (int i = (int)rvl.count(); i < (int)ChangeFileCurveList->count(); i++) {
    if (ChangeFileCurveList->isSelected(i)) {
      KstRMatrixPtr matrix = rml[i-rvl.count()];
      matrix->writeLock();
      file->readLock();
      bool valid = file->isValidMatrix(matrix->field());
      file->unlock();
      if (!valid) {
        if (invalid > 0) {
          // FIXME: invalid list construction for i18n
          invalidSources = i18n("%1, %2").arg(invalidSources).arg(matrix->field());
        } else {
          invalidSources = matrix->field();
        }
        ++invalid;
      } else {
        if (_duplicateSelected->isChecked()) {
          // block matrix updates until matrix is setup properly
          KST::matrixList.lock().writeLock();

          // create a new matrix
          KstRMatrixPtr newMatrix = matrix->makeDuplicate();
          if (!oldSources.contains(newMatrix->dataSource())) {
            oldSources << newMatrix->dataSource();
          }
          newMatrix->changeFile(file);

          KST::matrixList.lock().unlock();

          // duplicate dependents
          if (_duplicateDependents->isChecked()) {
            duplicatedMatrices.insert(KstMatrixPtr(matrix), KstMatrixPtr(newMatrix));
            KST::duplicateDependents(KstMatrixPtr(matrix), duplicatedMap, duplicatedMatrices);
          }
        } else {
          if (!oldSources.contains(matrix->dataSource())) {
            oldSources << matrix->dataSource();
          }
          matrix->changeFile(file);
        }
      }
      matrix->unlock();
      app->slotUpdateProgress(selected, ++handled, i18n("Updating matrices..."));
    }
  }

  app->slotUpdateProgress(0, 0, QString::null);
  file = 0L;
  
  // now add any curves and images to plots if they were duplicated
  if (_duplicateSelected->isChecked() && _duplicateDependents->isChecked()) { 
    KstApp *app = KstApp::inst();
    KMdiIterator<KMdiChildView*> *it = app->createIterator();
    while (it->currentItem()) {
      KstViewWindow *w = dynamic_cast<KstViewWindow*>(it->currentItem());
      if (w) {
        KstTopLevelViewPtr view = kst_cast<KstTopLevelView>(w->view());
        if (view) {
          Kst2DPlotList plots = view->findChildrenType<Kst2DPlot>(true);
          for (Kst2DPlotList::Iterator plotIter = plots.begin(); plotIter != plots.end(); ++plotIter) {
            for (KstDataObjectDataObjectMap::ConstIterator iter = duplicatedMap.begin(); iter != duplicatedMap.end(); ++iter) {
              if (KstBaseCurvePtr curve = kst_cast<KstBaseCurve>(iter.data())) {
                if ((*plotIter)->Curves.contains(kst_cast<KstBaseCurve>(iter.key())) && !(*plotIter)->Curves.contains(kst_cast<KstBaseCurve>(curve))) {
                  (*plotIter)->addCurve(curve);
                }
              } 
            }
  
          }     
        }
      }
      it->next();
    }
    app->deleteIterator(it);
  }

  // clean up unused data sources
//  kstdDebug() << "cleaning up data sources" << endl;
  KST::dataSourceList.lock().writeLock();
  for (KstDataSourceList::Iterator it = oldSources.begin(); it != oldSources.end(); ++it) {
//    kstdDebug() << "DATA SOURCE: " << (*it)->tag().displayString() << " (" << (void*)(*it) << ") USAGE: " << (*it)->getUsage() << endl;
    if ((*it)->getUsage() == 1) {
//      kstdDebug() << "    -> REMOVED" << endl;
      KST::dataSourceList.remove((*it).data());
    }
  }
  KST::dataSourceList.lock().unlock();
  
  if (!invalidSources.isEmpty()) {
    if (invalid == 1) {
      KMessageBox::sorry(this, i18n("The following field is not defined for the requested file:\n%1").arg(invalidSources));
    } else {
      KMessageBox::sorry(this, i18n("The following fields are not defined for the requested file:\n%1").arg(invalidSources));
    }
  }

  emit docChanged();

  // force an update in case we're in paused mode
  KstApp::inst()->forceUpdate();
  return true;
}