All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions | Static Public Attributes | Protected Member Functions
GeopsyCore::SignalDB Class Reference

#include <SignalDB.h>

Inheritance diagram for GeopsyCore::SignalDB:
GeopsyCore::SubSignalPool QGpCoreTools::XMLClass QGpCoreTools::XMLContext

List of all members.

Public Member Functions

void addFile (SignalFile *file)
void addMetaData (MetaData *d)
void addSignal (Signal *sig)
Signalat (int index) const
void clear ()
bool contains (Signal *sig) const
int count () const
bool exists () const
SignalFilePoolfilePool ()
AbstractSignalGroupfindGroup (QString name) const
bool isModified ()
MasterSignalGroupmasterGroup () const
MetaDatametaData (int id)
const MetaDatametaData (int id) const
QString name () const
QDir newFilePath () const
bool open (QString fileName=QString::null)
void removeFile (SignalFile *f)
void removeMetaData (int id)
void removeSignal (Signal *sig)
MetaDataresolveMetaData (int index)
void save ()
void saveAs (QString fileName=QString::null)
void setName (const QString &n)
Signalsignal (int id) const
 SignalDB ()
void signalDeleted (Signal *sig)
const SubSignalPoolsubPool () const
int uniqueId (int requestedId)
int version () const
virtual const QString & xml_tagName () const
 ~SignalDB ()

Static Public Attributes

static const QString xmlSignalDBTag = "SignalDB"

Protected Member Functions

virtual XMLMember xml_member (XML_MEMBER_ARGS)
void xml_polish (XML_POLISH_ARGS)
virtual bool xml_setProperty (XML_SETPROPERTY_ARGS)
virtual void xml_writeChildren (XML_WRITECHILDREN_ARGS) const
virtual void xml_writeProperties (XML_WRITEPROPERTIES_ARGS) const

Constructor & Destructor Documentation

References GeopsyCore::AbstractSignalGroup::setComments(), GeopsyCore::AbstractSignalGroup::setModified(), GeopsyCore::AbstractSignalGroup::setName(), SIGNALDB_CURRENT_VERSION, QGpCoreTools::tr(), and TRACE.

Referenced by open().

                   : _files(this)
{
  TRACE;
  _newId=0;
  _version=SIGNALDB_CURRENT_VERSION;
  _masterGroup=new MasterSignalGroup(this);
  _masterGroup->setName("/");
  _masterGroup->setComments(tr("Root folder of all groups"));
  _masterGroup->setModified(false);
  _allSharedMetaData=0;
}

References GeopsyCore::SubSignalPool::begin(), GeopsyCore::SubSignalPool::end(), and TRACE.

{
  TRACE;
  delete _masterGroup;
  // Prepare all signals for delete
  for(const_iterator it=begin(); it!=end(); ++it) {
    (*it)->setDatabase(0);  /* avoid removal from internal list upon deletion
                                 (this will be done by SubSignalPool destructor).*/
  }
  ASSERT(!_allSharedMetaData);
}

Member Function Documentation

References GeopsyCore::SignalFile::database(), and TRACE.

Referenced by GeopsyCore::SignalFile::SignalFile().

{
  TRACE;
  ASSERT(file->database()==this);
  _files.append(file);
}
{_permanentSharedMetaData.add(d);}

This is the only one function to add new signals to database. It is automatically called by all constructors of Signal. Signal::id() is set uniquely here.

Reimplemented from GeopsyCore::SubSignalPool.

References GeopsyCore::Signal::database(), GeopsyCore::Signal::setId(), and TRACE.

Referenced by GeopsyCore::Signal::Signal().

{
  TRACE;
  ASSERT(sig->database()==this);
  sig->setId(-1);
  SubSignalPool::addSignal(sig);
}
Signal* GeopsyCore::SignalDB::at ( int  index) const [inline]

Reimplemented from GeopsyCore::SubSignalPool.

References GeopsyCore::SubSignalPool::at().

{return SubSignalPool::at(index);}

References GeopsyCore::MasterSignalGroup::clear(), GeopsyCore::MetaDataMap::clear(), GeopsyCore::SubSignalPool::removeAll(), setName(), and TRACE.

{
  TRACE;
  removeAll();
  setName(QString::null);
  _files.clear();
  _permanentSharedMetaData.clear();
  _masterGroup->clear();
}
bool GeopsyCore::SignalDB::contains ( Signal sig) const [inline]

References contains().

{return SubSignalPool::contains(sig);}
int GeopsyCore::SignalDB::count ( ) const [inline]
bool GeopsyCore::SignalDB::exists ( ) const [inline]

Return true if samples, header or groups are touched since last save or open Also return true if there are temporary files

References GeopsyCore::SignalFilePool::at(), GeopsyCore::SubSignalPool::begin(), GeopsyCore::SignalFilePool::count(), GeopsyCore::SubSignalPool::end(), GeopsyCore::SignalFile::format(), GeopsyCore::SignalFileFormat::id(), GeopsyCore::SubSignalPool::isHeaderModified(), GeopsyCore::AbstractSignalGroup::isModified(), GeopsyCore::SignalFileFormat::Temporary, and TRACE.

Referenced by GeopsyMainWindow::warnBeforeClear(), GeopsyCore::XMLSignal::xml_writeBinaryData(), and GeopsyCore::XMLSignal::xml_writeProperties().

{
  TRACE;
  //App::stream() << tr("Checking state of database:") << endl;
  if(isHeaderModified()) return true;
  //App::stream() << tr("  No header modified") << endl;
  if(_masterGroup->isModified()) return true;
  //App::stream() << tr("  No group modified") << endl;
  // scan for temporary files
  for(int i=0; i < _files.count(); ++i) {
    SignalFile * fsig=_files.at(i);
    if(fsig->format().id()==SignalFileFormat::Temporary) return true;
  }
  //App::stream() << tr("  No temporary files") << endl;
  // scan for temporary signals
  for(iterator it=begin(); it!=end(); ++it) {
    if( !(*it)->file()) return true;
  }
  //App::stream() << tr("  No temporary signals") << endl;
  return false;
}

References GeopsyCore::MetaData::data().

{return _permanentSharedMetaData.data(id);}
const MetaData* GeopsyCore::SignalDB::metaData ( int  id) const [inline]

References GeopsyCore::MetaData::data().

{return _permanentSharedMetaData.data(id);}
QString GeopsyCore::SignalDB::name ( ) const [inline]

Returns the directory where to save new files generated by Geopsy (signals, results,...).

References exists(), name(), and TRACE.

{
  TRACE;
  if(exists()) {
    QFileInfo fi(name());
    QString fileBaseName=fi.baseName()+".files";
    QDir d(fi.absolutePath());
    if(!d.exists(fileBaseName)) {
      d.mkdir(fileBaseName);
    }
    d.cd(fileBaseName);
    return d;
  } else {
    return QDir();
  }
}
bool GeopsyCore::SignalDB::open ( QString  fileName = QString::null)

References GeopsyCore::SubSignalPool::_name, count(), QGpCoreTools::endl(), QGpCoreTools::XMLClass::ErrorEndTagNotFound, QGpCoreTools::XMLClass::ErrorNoDocType, QGpCoreTools::XMLClass::ErrorNoVersion, fileName, MSG_ID, QGpCoreTools::XMLClass::NoError, open(), SignalDB(), QGpCoreTools::tr(), TRACE, and QGpCoreTools::XMLHeader::xml_restoreFile().

Referenced by GeopsyCore::GeopsyCoreEngine::database(), loadSignals(), main(), modeGroupList(), open(), and GeopsyMainWindow::openDB().

{
  TRACE;
  if(fileName.isEmpty()) {
    fileName=Message::getOpenFileName(tr("Open a database"),  tr("Geopsy database (*.gpy *.sdb)"));
  } else {
    QFileInfo fi(fileName);
    fileName=fi.absoluteFilePath();
  }
  if(fileName.isEmpty()) return false;

  if(count()>0) {
    if(Message::warning(MSG_ID, tr("Open database"),
                        tr("The current database already contains signals, Do you want to add signals from another database?"),
                        Message::yes(), Message::no())==Message::Answer1) {
      return false;
    }
    SignalDB * newDB=new SignalDB;
    if(!newDB->open(fileName)) {
      delete newDB;
      return false;
    } else { // New database opened successfully, merge it with current one
      add(newDB);
      delete newDB;
      // Set name as empty to force saveAs()
      _name=QString::null;
      return true;
    }
  } else {
    _name=fileName;
  }

  MessageContext mc;

  XMLHeader hdr(this);
  createAllSharedMetaData();
  XMLClass::Error err=hdr.xml_restoreFile(fileName, this);
  releaseAllSharedMetaData();
  bool ret;
  switch (err) {
  case ErrorNoDocType:
  case ErrorNoVersion:
  case ErrorEndTagNotFound: // Apparently not an XML file, hence try old formats
    App::stream() << tr("Trying with an old geopsy database format...") << endl;
    ret=openDBFileV12(fileName);
    openGroupsV12();  // in any case, try to open groups
    break;
  default:
    ret=(err==NoError);
    break;
  }

  if(!ret) {
    Message::warning(MSG_ID, tr( "Opening Database ..." ),
                     tr( "Errors occured while opening database, for more details read log." ),
                     Message::ok());
    // Set name as empty to force saveAs()
    _name=QString::null;
  }
  return ret;
}

Removes file f from database and delete its signals.

References GeopsyCore::SubSignalPool::addFile(), GeopsyCore::SubSignalPool::begin(), GeopsyCore::SubSignalPool::end(), GeopsyCore::SignalFile::removeFile(), GeopsyCore::AbstractSignalGroup::removeSignal(), and TRACE.

Referenced by GeopsyGui::SignalFileItem::remove(), and Process::run().

{
  TRACE;
  SubSignalPool subpool;
  subpool.addFile(f);
  for(SubSignalPool::iterator it=subpool.begin(); it!=subpool.end(); ++it) {
    Signal * sig=*it;
    remove(sig);
    _masterGroup->removeSignal(sig);
  }
  f->removeFile();
  _files.remove(f);
}
void GeopsyCore::SignalDB::removeMetaData ( int  id) [inline]
{_permanentSharedMetaData.remove(id);}
void GeopsyCore::SignalDB::removeSignal ( Signal sig) [inline]

Removes one signal from database and delete it through reference mechanism.

References GeopsyCore::SubSignalPool::remove().

Referenced by Process::run().

References QGpCoreTools::endl(), QGpCoreTools::tr(), and TRACE.

Referenced by xml_member(), and GeopsyCore::Signal::xml_member().

{
  TRACE;
  if(index<0 || index>=_allSharedMetaData->count()) {
    App::stream() << tr("Cannot resolve link to shared meta data: index %1 does not exist.").arg(index) << endl;
    return 0;
  } else {
    return _allSharedMetaData->at(index);
  }
}

References GeopsyCore::SubSignalPool::_name, exists(), MSG_ID, saveAs(), GeopsyCore::SubSignalPool::setHeaderModified(), GeopsyCore::AbstractSignalGroup::setModified(), SIGNALDB_CURRENT_VERSION, QGpCoreTools::tr(), TRACE, and QGpCoreTools::XMLHeader::xml_saveFile().

Referenced by saveAs(), and GeopsyMainWindow::saveDB().

{
  TRACE;
  if(!exists()) {
    saveAs ();
    return ;
  }
  MessageContext mc;
  if(_version<SIGNALDB_CURRENT_VERSION) {
    if(_version<3) {
      Message::information(MSG_ID, tr("Converting an old Geopsy or Sardine database"),
                               tr("Groups are no longer saved in separate files, after conversion, you can "
                               "safely remove all files .group, .grouplist and .sdb. The new database is saved "
                               "in a .gpy file which include all signal and group information. This is in fact a "
                               " .tar.gz that you can unpack to access its XML contents."));
      saveAs();
      return;
    } else {
      Message::information(MSG_ID, tr("Converting an old Geopsy database"),
                               tr("Signal database internal format has changed and the saved file will "
                                  "not be readable with old Geopsy releases."));
      saveAs();
      return;
    }
  }
  // Here, database may not yet exist on the disk but exist() returns always true.
  // Saving temporary files and signals and modified samples
  if(!saveTemporaryFiles()) return;
  if(!saveTemporarySignals()) return;
  // Saving database file
  XMLHeader hdr(this);
  collectAllSharedMetaData();
  XMLClass::Error err=hdr.xml_saveFile(_name);
  releaseAllSharedMetaData();
  if(err!=XMLClass::NoError) return;
  setHeaderModified(false);
  _masterGroup->setModified(false);
}
void GeopsyCore::SignalDB::saveAs ( QString  fileName = QString::null)

References GeopsyCore::SubSignalPool::_name, fileName, save(), SIGNALDB_CURRENT_VERSION, QGpCoreTools::tr(), and TRACE.

Referenced by save(), and GeopsyMainWindow::saveDBAs().

{
  TRACE;
  if(fileName.isEmpty()) {
    fileName=Message::getSaveFileName(tr( "Save current database as ..." ), tr( "Geopsy database (*.gpy)" ));
  }
  if(!fileName.isEmpty()) {
    _name=fileName;
    _version=SIGNALDB_CURRENT_VERSION;
    save();
  }
}
void GeopsyCore::SignalDB::setName ( const QString &  n) [inline]
Signal * GeopsyCore::SignalDB::signal ( int  id) const

Returns pointer to signal with id or 0 if no signal has id.

References GeopsyCore::SubSignalPool::begin(), GeopsyCore::SubSignalPool::end(), GeopsyCore::Signal::id(), and TRACE.

Referenced by GeopsyCore::SubSignalPool::addSignal(), and GeopsyCore::XMLSignal::signal().

{
  TRACE;
  for(SubSignalPool::const_iterator it=begin(); it!=end(); ++it) {
    Signal * sig=*it;
    if(sig->id()==id) {
      return sig;
    }
  }
  return 0;
}

Removes sig from database. Do not call directly this function, it is automatically called from Signal::~Signal().

References GeopsyCore::SubSignalPool::indexOf(), GeopsyCore::SubSignalPool::removeAt(), and TRACE.

Referenced by GeopsyCore::Signal::~Signal().

const SubSignalPool& GeopsyCore::SignalDB::subPool ( ) const [inline]
int GeopsyCore::SignalDB::uniqueId ( int  resquestedId)

Returns a unique ID number for signal. This function is called automatically every time the ID of a signal is modified.

References QGpCoreTools::endl(), QGpCoreTools::tr(), and TRACE.

Referenced by GeopsyCore::Signal::setId().

{
  TRACE;
  if(resquestedId==-1)
    return ++_newId;
  else {
    /* In Signal::setId() the _id is set to -1, hence even if resquestedId is the same as the current
    id of the signal, countId() will return 0 if no other signal have the same id. */
    if(countId(resquestedId)>0) {
      _newId++;
      App::stream() << Message::severityString(Message::Warning)
                    << tr(" signal ID %1 changed to %2" ).arg(resquestedId).arg(_newId) << endl;
      return _newId;
    } else {
      if(resquestedId>_newId) {
        _newId=resquestedId;
      }
      return resquestedId;
    }
  }
}
int GeopsyCore::SignalDB::version ( ) const [inline]

Re-implement this function to offer XML restore (children and properties) support to your class.

From tag and map (with contains the attibute value) return a unique identifier under the format of a XMLMember. XMLMember is initialized with 3 types of contructors:

  • An integer: id number of a property
  • A XMLClass * : a child of this object identified by tag
  • Default constructor: error, unknow child or property

Map of attributes can be inspected in this way (can be achived also in xml_setProperty()):

    static const QString tmp("childrenName");
    XMLRestoreAttributeIterator it=map.find(tmp);
    if(it!=map.end()) {
      // found attribute "childrenName"
    }

If the map of attributes is not used:

    Q_UNUSED(attributes);
    if(tag=="x1") return XMLMember(0);
    else if(tag=="y1") return XMLMember(1);
    else if(tag=="x2") return XMLMember(2);
    else if(tag=="y2") return XMLMember(3);
    else return XMLMember(XMLMember::Unknown);

Arithmetic operations + and - apply to XMLMember to avoid confusion of property id numbers between inherited objects. Offset 3 corresponds to the number of properties defined in this object.

    if(tag=="anInteger") return XMLMember(0);
    else if(tag=="aString") return XMLMember(1);
    else if(tag=="aDouble") return XMLMember(2);
    return AbstractLine::xml_member(tag, attributes, context)+3;

For the arguments of this function use Macro XML_MEMBER_ARGS.

Reimplemented from QGpCoreTools::XMLClass.

References GeopsyCore::MetaDataMap::add(), QGpCoreTools::endl(), resolveMetaData(), QGpCoreTools::tr(), and QGpCoreTools::XMLClass::xml_tagName().

{
  Q_UNUSED(attributes);
  Q_UNUSED(context);
  switch (tag[0].unicode()) {
  case 'F':
    if(tag=="File") {
      SignalFile * f=new SignalFile(this);
      return XMLMember(f);
    }
    break;
  case 'M':
    if(tag=="MasterGroup") {
      return XMLMember(_masterGroup);
    }
    break;
  case 'G':
    if(tag=="Group") {               // Kept for compatibility
      return XMLMember(_masterGroup);
    }
    break;
  case 'S':
    if(tag=="SharedMetaData") {
      ASSERT(_allSharedMetaData);
      return XMLMember(_allSharedMetaData);
    }
    break;
  case 'v':
    if(tag=="version") {
      return XMLMember(0);
    }
    break;
  default: {
      // Probably a link to permanent shared meta data
      static QString indexAtt="index";
      XMLRestoreAttributeIterator it=attributes.find(indexAtt);
      if(it!=attributes.end()) { // It is a link to shared data
        MetaData * d=resolveMetaData(it.value().toInt());
        if(d) {
          if(tag==d->xml_tagName()) {
            _permanentSharedMetaData.add(d);
            return XMLMember(101);
          } else {
            App::stream() << tr("Mismatch resolving shared meta data index %1: expecting type %2, found %3.")
                .arg(it.value().toInt()).arg(tag.toString()).arg(d->xml_tagName()) << endl;
          }
        }
      }
    }
    break;
  }
  return XMLMember(XMLMember::Unknown);
}
void GeopsyCore::SignalDB::xml_polish ( XML_POLISH_ARGS  ) [protected, virtual]

Reimplemented from QGpCoreTools::XMLClass.

References GeopsyCore::SubSignalPool::begin(), GeopsyCore::AbstractSignalGroup::convertIds(), GeopsyCore::SubSignalPool::end(), GeopsyCore::Signal::id(), GeopsyCore::AbstractSignalGroup::setModified(), and TRACE.

{
  TRACE;
  Q_UNUSED(context);
  // Groups refers to signal through IDs. Before starting anything
  // We must convert those IDs into real pointers.
  QHash<int, Signal *> lookup;
  for(SubSignalPool::const_iterator it=begin(); it!=end(); ++it) {
    Signal * sig=*it;
    lookup.insert(sig->id(), sig);
  }
  _masterGroup->convertIds(lookup);
  _masterGroup->setModified(false);
}

Re-implement this function to offer XML restore properties support to your class.

From memberID set the corresponding property with value content. The map of attributes is given as a supplementary information (not useful in all cases).

For a general case:

  Q_UNUSED(attributes);
  double val=content.toDouble();
  switch (memberID) {
  case 0:
    _x1=val;
    return true;
  case 1:
    _y1=val;
    return true;
  case 2:
    _x2=val;
    return true;
  case 3:
    _y2=val;
    return true;
  default:
    return false;
  }

For classes inheriting other classes (see also xml_member())

  switch (memberID) {
  case 0:
    _anInteger=content.toString();
    return true;
  case 1:
    _aString=content.toInt();
    return true;
  case 2:
    _aDouble=content.toDouble();
    return true;
  default:
    return AbstractLine::xml_setProperty(memberID-3, map, content);

For the arguments of this function use Macro XML_SETPROPERTY_ARGS.

Reimplemented from QGpCoreTools::XMLClass.

References QGpCoreTools::endl(), SIGNALDB_CURRENT_VERSION, and QGpCoreTools::tr().

{
  Q_UNUSED(tag);
  Q_UNUSED(attributes);
  Q_UNUSED(context);
  switch (memberID) {
  case 0:
    _version=content.toInt();
    if(_version>SIGNALDB_CURRENT_VERSION) {
      App::stream() << tr("Database saved with a more recent release, upgrade yours.") << endl;
      return false;
    }
    return true;
  default:
    return false;
  }
}
virtual const QString& GeopsyCore::SignalDB::xml_tagName ( ) const [inline, virtual]

Implements QGpCoreTools::XMLClass.

{return xmlSignalDBTag;}
void GeopsyCore::SignalDB::xml_writeChildren ( XML_WRITECHILDREN_ARGS  ) const [protected, virtual]

Reimplemented from QGpCoreTools::XMLClass.

References GeopsyCore::SignalFilePool::begin(), GeopsyCore::SignalFilePool::end(), GeopsyCore::AbstractSignalGroup::setModified(), TRACE, and QGpCoreTools::XMLClass::xml_save().

{
  TRACE;
  // Save all shared meta data
  ASSERT(_allSharedMetaData);
  _allSharedMetaData->xml_save(s, context);
  // Save files and signals
  for(QList<SignalFile *>::const_iterator it=_files.begin(); it!=_files.end(); ++it) {
    (*it)->xml_save(s, context);
  }
  // Save user groups
  _masterGroup->xml_save(s, context);
  _masterGroup->setModified(false);
}

Reimplemented from QGpCoreTools::XMLClass.

References QGpCoreTools::SortedVector< Key, T >::at(), GeopsyCore::MetaDataMap::count(), GeopsyCore::MetaData::isStored(), GeopsyCore::MetaDataMap::vector(), QGpCoreTools::XMLClass::writeProperty(), and GeopsyCore::MetaData::xml_writeLink().

{
  Q_UNUSED(context);
  writeProperty(s, "version", _version);
  // Save links for permanent meta data
  ASSERT(_allSharedMetaData);
  int n=_permanentSharedMetaData.count();
  const SortedVector<int, MetaData>& v=_permanentSharedMetaData.vector();
  for(int i=0; i<n; i++) {
    const MetaData * d=v.at(i);
    if(d->isStored()) {
      d->xml_writeLink(s);
    }
  }
}

Member Data Documentation

const QString GeopsyCore::SignalDB::xmlSignalDBTag = "SignalDB" [static]

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines