<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qtooltip.h>
#include <qframe.h>
#include <qpixmap.h>
#include <qlayout.h>
#include <qwidgetstack.h>
#include <qdatetime.h>
#include <qwhatsthis.h>

#include <kdebug.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <kinputdialog.h>
#include <kio/netaccess.h>
#include <kabc/addressee.h>

#include <libkdepim/designerfields.h>
#include <libkdepim/embeddedurlpage.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/incidence.h>
#include <libkcal/icalformat.h>

#include "koprefs.h"
#include "koglobals.h"
#include "koeditordetails.h"
#include "koeditorattachments.h"
#include "koeditoralarms.h"
#include "urihandler.h"
#include "koincidenceeditor.h"
#include "templatemanagementdialog.h"

KOIncidenceEditor::KOIncidenceEditor( const QString &caption,
                                      Calendar *calendar, QWidget *parent )
  : KDialogBase( Tabbed, caption, Ok | Apply | Cancel | Default, Ok,
                 parent, 0, false, false ),
    mDetails( 0 ), mAttachments( 0 )
{
  // Set this to be the group leader for all subdialogs - this means
  // modal subdialogs will only affect this dialog, not the other windows
  setWFlags( getWFlags() | WGroupLeader );

  mCalendar = calendar;

  if ( KOPrefs::instance()->mCompactDialogs ) {
    showButton( Apply, false );
    showButton( Default, false );
  } else {
    setButtonText( Default, i18n("&Templates...") );
  }

  connect( this, SIGNAL( defaultClicked() ), SLOT( slotManageTemplates() ) );
  connect( this, SIGNAL( finished() ), SLOT( delayedDestruct() ) );
}

KOIncidenceEditor::~KOIncidenceEditor()
{
}

void KOIncidenceEditor::setupAttendeesTab()
{
  QFrame *topFrame = addPage( i18n("Atte&ndees") );
  QWhatsThis::add( topFrame,
                   i18n("The Attendees tab allows you to Add or Remove "
                        "Attendees to/from this event or to-do.") );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  mDetails = new KOEditorDetails( spacingHint(), topFrame );
  topLayout->addWidget( mDetails );
}

void KOIncidenceEditor::setupAttachmentsTab()
{
  QFrame *topFrame = addPage( i18n("Attach&ments") );
  QWhatsThis::add( topFrame,
                   i18n("The Attachments tab allows you to add or remove "
                        "files, emails, contacts, and other items "
                        "associated with this event or to-do.") );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  mAttachments = new KOEditorAttachments( spacingHint(), topFrame );
  connect( mAttachments, SIGNAL( openURL( const KURL & ) ) ,
           this, SLOT( openURL( const KURL & ) ) );
  topLayout->addWidget( mAttachments );
}

void KOIncidenceEditor::slotApply()
{
  processInput();
}

void KOIncidenceEditor::slotOk()
{
  if ( processInput() ) accept();
}

void KOIncidenceEditor::updateCategoryConfig()
{
}

void KOIncidenceEditor::slotCancel()
{
  processCancel();
  reject();
}

void KOIncidenceEditor::cancelRemovedAttendees( Incidence *incidence )
{
  if ( !incidence ) return;

  // cancelAttendeeEvent removes all attendees from the incidence,
  // and then only adds those that need to be cancelled (i.e. a mail needs to be sent to them).
  if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
    Incidence *ev = incidence->clone();
    ev->registerObserver( 0 );
    mDetails->cancelAttendeeEvent( ev );
    if ( ev->attendeeCount() > 0 ) {
      emit deleteAttendee( ev );
    }
    delete( ev );
  }

}

void KOIncidenceEditor::slotManageTemplates()
{
  kdDebug(5850) << "KOIncidenceEditor::manageTemplates()" << endl;

  TemplateManagementDialog * const d = new TemplateManagementDialog( this, templates() );
  connect( d, SIGNAL( loadTemplate( const QString& ) ),
           this, SLOT( slotLoadTemplate( const QString& ) ) );
  connect( d, SIGNAL( templatesChanged( const QStringList& ) ),
           this, SLOT( slotTemplatesChanged( const QStringList& ) ) );
  connect( d, SIGNAL( saveTemplate( const QString& ) ),
           this, SLOT( slotSaveTemplate( const QString& ) ) );
  d->exec();
  return;
}

void KOIncidenceEditor::saveAsTemplate( Incidence *incidence,
                                        const QString &templateName )
{
  if ( !incidence || templateName.isEmpty() ) return;

  QString fileName = "templates/" + incidence->type();
  fileName.append( "/" + templateName );
  fileName = locateLocal( "data", "korganizer/" + fileName );

  CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
  cal.addIncidence( incidence );
  ICalFormat format;
  format.save( &cal, fileName );
}

void KOIncidenceEditor::slotLoadTemplate( const QString& templateName )
{
  CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
  QString fileName = locateLocal( "data", "korganizer/templates/" + type() + "/" +
      templateName );

  if ( fileName.isEmpty() ) {
    KMessageBox::error( this, i18n("Unable to find template '%1'.")
        .arg( fileName ) );
  } else {
    ICalFormat format;
    if ( !format.load( &cal, fileName ) ) {
      KMessageBox::error( this, i18n("Error loading template file '%1'.")
          .arg( fileName ) );
      return;
    }
  }
  loadTemplate( cal );
}

void KOIncidenceEditor::slotTemplatesChanged( const QStringList& newTemplates )
{
  templates() = newTemplates;
}

void KOIncidenceEditor::setupDesignerTabs( const QString &type )
{
  QStringList activePages = KOPrefs::instance()->activeDesignerFields();

  QStringList list = KGlobal::dirs()->findAllResources( "data",
    "korganizer/designer/" + type + "/*.ui", true, true );
  for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) {
    const QString &fn = (*it).mid( (*it).findRev('/') + 1 );
    if ( activePages.find( fn ) != activePages.end() ) {
      addDesignerTab( *it );
    }
  }
}

QWidget *KOIncidenceEditor::addDesignerTab( const QString &uifile )
{
  kdDebug(5850) << "Designer tab: " << uifile << endl;

  KPIM::DesignerFields *wid = new KPIM::DesignerFields( uifile, 0 );
  mDesignerFields.append( wid );

  QFrame *topFrame = addPage( wid->title() );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  wid->reparent( topFrame, 0, QPoint() );
  topLayout->addWidget( wid );
  mDesignerFieldForWidget[ topFrame ] = wid;

  return topFrame;
}

class KCalStorage : public KPIM::DesignerFields::Storage
{
  public:
    KCalStorage( Incidence *incidence )
      : mIncidence( incidence )
    {
    }

    QStringList keys()
    {
      QStringList keys;

      QMap<QCString, QString> props = mIncidence->customProperties();
      QMap<QCString, QString>::ConstIterator it;
      for( it = props.begin(); it != props.end(); ++it ) {
        QString customKey = it.key();
        QStringList parts = QStringList::split( "-", customKey );
        if ( parts.count() != 4 ) continue;
        if ( parts[ 2 ] != "KORGANIZER" ) continue;
        keys.append( parts[ 3 ] );
      }

      return keys;
    }

    QString read( const QString &key )
    {
      return mIncidence->customProperty( "KORGANIZER", key.utf8() );
    }

    void write( const QString &key, const QString &value )
    {
      mIncidence->setCustomProperty( "KORGANIZER", key.utf8(), value );
    }

  private:
    Incidence *mIncidence;
};

void KOIncidenceEditor::readDesignerFields( Incidence *i )
{
  KCalStorage storage( i );
  KPIM::DesignerFields *fields;
  for( fields = mDesignerFields.first(); fields;
       fields = mDesignerFields.next() ) {
    fields->load( &storage );
  }
}

void KOIncidenceEditor::writeDesignerFields( Incidence *i )
{
  kdDebug(5850) << "KOIncidenceEditor::writeDesignerFields()" << endl;

  KCalStorage storage( i );
  KPIM::DesignerFields *fields;
  for( fields = mDesignerFields.first(); fields;
       fields = mDesignerFields.next() ) {
    kdDebug(5850) << "Write Field " << fields->title() << endl;
    fields->save( &storage );
  }
}

void KOIncidenceEditor::setupEmbeddedURLPage( const QString &label,
                                 const QString &url, const QString &mimetype )
{
  kdDebug(5850) << "KOIncidenceEditor::setupEmbeddedURLPage()" << endl;
  kdDebug(5850) << "label=" << label << ", url=" << url << ", mimetype=" << mimetype << endl;
  QFrame *topFrame = addPage( label );
  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  KPIM::EmbeddedURLPage *wid = new KPIM::EmbeddedURLPage( url, mimetype,
                                                          topFrame );
  topLayout->addWidget( wid );
  mEmbeddedURLPages.append( topFrame );
  connect( wid, SIGNAL( openURL( const KURL & ) ) ,
           this, SLOT( openURL( const KURL & ) ) );
  // TODO: Call this method only when the tab is actually activated!
  wid->loadContents();
}

void KOIncidenceEditor::createEmbeddedURLPages( Incidence *i )
{
  kdDebug(5850) << "KOIncidenceEditor::createEmbeddedURLPages()" << endl;

  if ( !i ) return;
  if ( !mEmbeddedURLPages.isEmpty() ) {
    kdDebug(5850) << "mEmbeddedURLPages are not empty, clearing it!" << endl;
    mEmbeddedURLPages.setAutoDelete( true );
    mEmbeddedURLPages.clear();
    mEmbeddedURLPages.setAutoDelete( false );
  }
  if ( !mAttachedDesignerFields.isEmpty() ) {
    for ( QPtrList<QWidget>::Iterator it = mAttachedDesignerFields.begin();
          it != mAttachedDesignerFields.end(); ++it ) {
      if ( mDesignerFieldForWidget.contains( *it ) ) {
        mDesignerFields.remove( mDesignerFieldForWidget[ *it ] );
      }
    }
    mAttachedDesignerFields.setAutoDelete( true );
    mAttachedDesignerFields.clear();
    mAttachedDesignerFields.setAutoDelete( false );
  }

  Attachment::List att = i->attachments();
  for ( Attachment::List::Iterator it = att.begin(); it != att.end(); ++it ) {
    Attachment *a = (*it);
    kdDebug(5850) << "Iterating over the attachments " << endl;
    kdDebug(5850) << "label=" << a->label() << ", url=" << a->uri() << ", mimetype=" << a->mimeType() << endl;
    if ( a && a->showInline() && a->isUri() ) {
      // TODO: Allow more mime-types, but add security checks!
/*      if ( a->mimeType() == "application/x-designer" ) {
        QString tmpFile;
        if ( KIO::NetAccess::download( a->uri(), tmpFile, this ) ) {
          mAttachedDesignerFields.append( addDesignerTab( tmpFile ) );
          KIO::NetAccess::removeTempFile( tmpFile );
        }
      } else*/
      // TODO: Enable that check again!
      if ( a->mimeType() == "text/html" )
      {
        setupEmbeddedURLPage( a->label(), a->uri(), a->mimeType() );
      }
    }
  }
}

void KOIncidenceEditor::openURL( const KURL &url )
{
  QString uri = url.url();
  UriHandler::process( uri );
}

void KOIncidenceEditor::addAttachments( const QStringList &attachments,
                                        const QStringList &mimeTypes,
                                        bool inlineAttachments )
{
  QStringList::ConstIterator it;
  uint i = 0;
  for ( it = attachments.begin(); it != attachments.end(); ++it, ++i ) {
    QString mimeType;
    if ( mimeTypes.count() > i )
      mimeType = mimeTypes[ i ];
    mAttachments->addAttachment( *it, mimeType, !inlineAttachments );
  }
}

void KOIncidenceEditor::addAttendees( const QStringList &attendees )
{
  QStringList::ConstIterator it;
  for ( it = attendees.begin(); it != attendees.end(); ++it ) {
    QString name, email;
    KABC::Addressee::parseEmailAddress( *it, name, email );
    mDetails->insertAttendee( new Attendee( name, email ) );
  }
}

#include "koincidenceeditor.moc"
<commit_msg>Kolab issue 1784 (prokde35): catch another "/this/ is deleted while processInput() shows a non-modal-dialog"-case<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qtooltip.h>
#include <qframe.h>
#include <qguardedptr.h>
#include <qpixmap.h>
#include <qlayout.h>
#include <qwidgetstack.h>
#include <qdatetime.h>
#include <qwhatsthis.h>

#include <kdebug.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <kinputdialog.h>
#include <kio/netaccess.h>
#include <kabc/addressee.h>

#include <libkdepim/designerfields.h>
#include <libkdepim/embeddedurlpage.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/incidence.h>
#include <libkcal/icalformat.h>

#include "koprefs.h"
#include "koglobals.h"
#include "koeditordetails.h"
#include "koeditorattachments.h"
#include "koeditoralarms.h"
#include "urihandler.h"
#include "koincidenceeditor.h"
#include "templatemanagementdialog.h"

KOIncidenceEditor::KOIncidenceEditor( const QString &caption,
                                      Calendar *calendar, QWidget *parent )
  : KDialogBase( Tabbed, caption, Ok | Apply | Cancel | Default, Ok,
                 parent, 0, false, false ),
    mDetails( 0 ), mAttachments( 0 )
{
  // Set this to be the group leader for all subdialogs - this means
  // modal subdialogs will only affect this dialog, not the other windows
  setWFlags( getWFlags() | WGroupLeader );

  mCalendar = calendar;

  if ( KOPrefs::instance()->mCompactDialogs ) {
    showButton( Apply, false );
    showButton( Default, false );
  } else {
    setButtonText( Default, i18n("&Templates...") );
  }

  connect( this, SIGNAL( defaultClicked() ), SLOT( slotManageTemplates() ) );
  connect( this, SIGNAL( finished() ), SLOT( delayedDestruct() ) );
}

KOIncidenceEditor::~KOIncidenceEditor()
{
}

void KOIncidenceEditor::setupAttendeesTab()
{
  QFrame *topFrame = addPage( i18n("Atte&ndees") );
  QWhatsThis::add( topFrame,
                   i18n("The Attendees tab allows you to Add or Remove "
                        "Attendees to/from this event or to-do.") );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  mDetails = new KOEditorDetails( spacingHint(), topFrame );
  topLayout->addWidget( mDetails );
}

void KOIncidenceEditor::setupAttachmentsTab()
{
  QFrame *topFrame = addPage( i18n("Attach&ments") );
  QWhatsThis::add( topFrame,
                   i18n("The Attachments tab allows you to add or remove "
                        "files, emails, contacts, and other items "
                        "associated with this event or to-do.") );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  mAttachments = new KOEditorAttachments( spacingHint(), topFrame );
  connect( mAttachments, SIGNAL( openURL( const KURL & ) ) ,
           this, SLOT( openURL( const KURL & ) ) );
  topLayout->addWidget( mAttachments );
}

void KOIncidenceEditor::slotApply()
{
  processInput();
}

void KOIncidenceEditor::slotOk()
{
  // "this" can be deleted before processInput() returns (processInput() opens
  // a non-modal dialog when Kolab is used). So accept should only be executed
  // when "this" is still valid
  QGuardedPtr<QWidget> ptr( this );
  if ( processInput() && ptr ) accept();
}

void KOIncidenceEditor::updateCategoryConfig()
{
}

void KOIncidenceEditor::slotCancel()
{
  processCancel();
  reject();
}

void KOIncidenceEditor::cancelRemovedAttendees( Incidence *incidence )
{
  if ( !incidence ) return;

  // cancelAttendeeEvent removes all attendees from the incidence,
  // and then only adds those that need to be cancelled (i.e. a mail needs to be sent to them).
  if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
    Incidence *ev = incidence->clone();
    ev->registerObserver( 0 );
    mDetails->cancelAttendeeEvent( ev );
    if ( ev->attendeeCount() > 0 ) {
      emit deleteAttendee( ev );
    }
    delete( ev );
  }

}

void KOIncidenceEditor::slotManageTemplates()
{
  kdDebug(5850) << "KOIncidenceEditor::manageTemplates()" << endl;

  TemplateManagementDialog * const d = new TemplateManagementDialog( this, templates() );
  connect( d, SIGNAL( loadTemplate( const QString& ) ),
           this, SLOT( slotLoadTemplate( const QString& ) ) );
  connect( d, SIGNAL( templatesChanged( const QStringList& ) ),
           this, SLOT( slotTemplatesChanged( const QStringList& ) ) );
  connect( d, SIGNAL( saveTemplate( const QString& ) ),
           this, SLOT( slotSaveTemplate( const QString& ) ) );
  d->exec();
  return;
}

void KOIncidenceEditor::saveAsTemplate( Incidence *incidence,
                                        const QString &templateName )
{
  if ( !incidence || templateName.isEmpty() ) return;

  QString fileName = "templates/" + incidence->type();
  fileName.append( "/" + templateName );
  fileName = locateLocal( "data", "korganizer/" + fileName );

  CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
  cal.addIncidence( incidence );
  ICalFormat format;
  format.save( &cal, fileName );
}

void KOIncidenceEditor::slotLoadTemplate( const QString& templateName )
{
  CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
  QString fileName = locateLocal( "data", "korganizer/templates/" + type() + "/" +
      templateName );

  if ( fileName.isEmpty() ) {
    KMessageBox::error( this, i18n("Unable to find template '%1'.")
        .arg( fileName ) );
  } else {
    ICalFormat format;
    if ( !format.load( &cal, fileName ) ) {
      KMessageBox::error( this, i18n("Error loading template file '%1'.")
          .arg( fileName ) );
      return;
    }
  }
  loadTemplate( cal );
}

void KOIncidenceEditor::slotTemplatesChanged( const QStringList& newTemplates )
{
  templates() = newTemplates;
}

void KOIncidenceEditor::setupDesignerTabs( const QString &type )
{
  QStringList activePages = KOPrefs::instance()->activeDesignerFields();

  QStringList list = KGlobal::dirs()->findAllResources( "data",
    "korganizer/designer/" + type + "/*.ui", true, true );
  for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) {
    const QString &fn = (*it).mid( (*it).findRev('/') + 1 );
    if ( activePages.find( fn ) != activePages.end() ) {
      addDesignerTab( *it );
    }
  }
}

QWidget *KOIncidenceEditor::addDesignerTab( const QString &uifile )
{
  kdDebug(5850) << "Designer tab: " << uifile << endl;

  KPIM::DesignerFields *wid = new KPIM::DesignerFields( uifile, 0 );
  mDesignerFields.append( wid );

  QFrame *topFrame = addPage( wid->title() );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  wid->reparent( topFrame, 0, QPoint() );
  topLayout->addWidget( wid );
  mDesignerFieldForWidget[ topFrame ] = wid;

  return topFrame;
}

class KCalStorage : public KPIM::DesignerFields::Storage
{
  public:
    KCalStorage( Incidence *incidence )
      : mIncidence( incidence )
    {
    }

    QStringList keys()
    {
      QStringList keys;

      QMap<QCString, QString> props = mIncidence->customProperties();
      QMap<QCString, QString>::ConstIterator it;
      for( it = props.begin(); it != props.end(); ++it ) {
        QString customKey = it.key();
        QStringList parts = QStringList::split( "-", customKey );
        if ( parts.count() != 4 ) continue;
        if ( parts[ 2 ] != "KORGANIZER" ) continue;
        keys.append( parts[ 3 ] );
      }

      return keys;
    }

    QString read( const QString &key )
    {
      return mIncidence->customProperty( "KORGANIZER", key.utf8() );
    }

    void write( const QString &key, const QString &value )
    {
      mIncidence->setCustomProperty( "KORGANIZER", key.utf8(), value );
    }

  private:
    Incidence *mIncidence;
};

void KOIncidenceEditor::readDesignerFields( Incidence *i )
{
  KCalStorage storage( i );
  KPIM::DesignerFields *fields;
  for( fields = mDesignerFields.first(); fields;
       fields = mDesignerFields.next() ) {
    fields->load( &storage );
  }
}

void KOIncidenceEditor::writeDesignerFields( Incidence *i )
{
  kdDebug(5850) << "KOIncidenceEditor::writeDesignerFields()" << endl;

  KCalStorage storage( i );
  KPIM::DesignerFields *fields;
  for( fields = mDesignerFields.first(); fields;
       fields = mDesignerFields.next() ) {
    kdDebug(5850) << "Write Field " << fields->title() << endl;
    fields->save( &storage );
  }
}

void KOIncidenceEditor::setupEmbeddedURLPage( const QString &label,
                                 const QString &url, const QString &mimetype )
{
  kdDebug(5850) << "KOIncidenceEditor::setupEmbeddedURLPage()" << endl;
  kdDebug(5850) << "label=" << label << ", url=" << url << ", mimetype=" << mimetype << endl;
  QFrame *topFrame = addPage( label );
  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  KPIM::EmbeddedURLPage *wid = new KPIM::EmbeddedURLPage( url, mimetype,
                                                          topFrame );
  topLayout->addWidget( wid );
  mEmbeddedURLPages.append( topFrame );
  connect( wid, SIGNAL( openURL( const KURL & ) ) ,
           this, SLOT( openURL( const KURL & ) ) );
  // TODO: Call this method only when the tab is actually activated!
  wid->loadContents();
}

void KOIncidenceEditor::createEmbeddedURLPages( Incidence *i )
{
  kdDebug(5850) << "KOIncidenceEditor::createEmbeddedURLPages()" << endl;

  if ( !i ) return;
  if ( !mEmbeddedURLPages.isEmpty() ) {
    kdDebug(5850) << "mEmbeddedURLPages are not empty, clearing it!" << endl;
    mEmbeddedURLPages.setAutoDelete( true );
    mEmbeddedURLPages.clear();
    mEmbeddedURLPages.setAutoDelete( false );
  }
  if ( !mAttachedDesignerFields.isEmpty() ) {
    for ( QPtrList<QWidget>::Iterator it = mAttachedDesignerFields.begin();
          it != mAttachedDesignerFields.end(); ++it ) {
      if ( mDesignerFieldForWidget.contains( *it ) ) {
        mDesignerFields.remove( mDesignerFieldForWidget[ *it ] );
      }
    }
    mAttachedDesignerFields.setAutoDelete( true );
    mAttachedDesignerFields.clear();
    mAttachedDesignerFields.setAutoDelete( false );
  }

  Attachment::List att = i->attachments();
  for ( Attachment::List::Iterator it = att.begin(); it != att.end(); ++it ) {
    Attachment *a = (*it);
    kdDebug(5850) << "Iterating over the attachments " << endl;
    kdDebug(5850) << "label=" << a->label() << ", url=" << a->uri() << ", mimetype=" << a->mimeType() << endl;
    if ( a && a->showInline() && a->isUri() ) {
      // TODO: Allow more mime-types, but add security checks!
/*      if ( a->mimeType() == "application/x-designer" ) {
        QString tmpFile;
        if ( KIO::NetAccess::download( a->uri(), tmpFile, this ) ) {
          mAttachedDesignerFields.append( addDesignerTab( tmpFile ) );
          KIO::NetAccess::removeTempFile( tmpFile );
        }
      } else*/
      // TODO: Enable that check again!
      if ( a->mimeType() == "text/html" )
      {
        setupEmbeddedURLPage( a->label(), a->uri(), a->mimeType() );
      }
    }
  }
}

void KOIncidenceEditor::openURL( const KURL &url )
{
  QString uri = url.url();
  UriHandler::process( uri );
}

void KOIncidenceEditor::addAttachments( const QStringList &attachments,
                                        const QStringList &mimeTypes,
                                        bool inlineAttachments )
{
  QStringList::ConstIterator it;
  uint i = 0;
  for ( it = attachments.begin(); it != attachments.end(); ++it, ++i ) {
    QString mimeType;
    if ( mimeTypes.count() > i )
      mimeType = mimeTypes[ i ];
    mAttachments->addAttachment( *it, mimeType, !inlineAttachments );
  }
}

void KOIncidenceEditor::addAttendees( const QStringList &attendees )
{
  QStringList::ConstIterator it;
  for ( it = attendees.begin(); it != attendees.end(); ++it ) {
    QString name, email;
    KABC::Addressee::parseEmailAddress( *it, name, email );
    mDetails->insertAttendee( new Attendee( name, email ) );
  }
}

#include "koincidenceeditor.moc"
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "otbWrapperApplicationRegistry.h"

using otb::Wrapper::Application;
using otb::Wrapper::ApplicationRegistry;

int otbWrapperApplicationDocTest(int argc, char* argv[])
{
  if (argc < 2)
    {
    std::cerr << "Usage : " << argv[0] << " [MODULEPATH]" << std::endl;
    return EXIT_FAILURE;
    }

  // Get the module path list
  std::list<std::string> modulePathList;
  if (argc > 1)
    {
    std::copy(argv + 1, argv + argc, std::back_inserter(modulePathList));

    // Load the path in the environment
    std::list<std::string>::const_iterator it = modulePathList.begin();
    while( it != modulePathList.end() )
      {
      ApplicationRegistry::AddApplicationPath( *(it) );
      ++it;
      }
    }

  bool isOK = true;

  // Get list of available applications
  std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
  for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
    {
    std::cout << "Testing documentation for application "<< (*it) << " ..." << std::endl;
    // Create module
    Application::Pointer app = ApplicationRegistry::CreateApplication(*it);

    // Check application availability
    if( app.IsNull() )
      {
      std::cout<<"Unable to load "<<argv[1]<<" application."<<std::endl;
      isOK = false;
      continue;
      }

    // Check doc element...
    if( std::string(app->GetName()) == "" )
      {
      std::cout<<"Missing Name."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocName()) == "" )
      {
      std::cout<<"Missing Doc Name."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDescription()) == "" )
      {
      std::cout<<"Missing Description."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocLongDescription()) == "" )
      {
      std::cout<<"Missing DocLongDescription."<<std::endl;
      isOK = false;
      }
    else if( std::string(app->GetDocLongDescription()).size() < 30 )
      {
      std::cout<<"DocLongDescription too small..."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocAuthors()) == "" )
      {
      std::cout<<"Missing DocAuthors."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocLimitations()) == "" )
      {
      std::cout<<"Missing DocLimitations."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocSeeAlso()) == "" )
      {
      std::cout<<"Missing DocSeeAlso."<<std::endl;
      isOK = false;
      }
    if( app->GetDocTags().size() == 0 )
      {
      std::cout<<"Missing DocTags."<<std::endl;
      isOK = false;
      }

    // Check example data
    app->Init();
    otb::Wrapper::DocExampleStructure::Pointer doc = app->GetDocExample();
    if( doc->GetApplicationName() == "" )
      {
      std::cout<<"Error in doc example: no aaplication name found."<<std::endl;
      isOK = false;
      }
    if( doc->GetParameterList().size() == 0 )
      {
      std::cout<<"Error in doc example: the list of parameter is empty."<<std::endl;
      isOK = false;
      }
    else
      {
      bool hasValue = false;
      unsigned int count = 0;
      while ( count<doc->GetParameterList().size() && !hasValue )
        {
        if( doc->GetParameterValue(count) != "" )
          {
          hasValue = true;
          }
        count++;
        }

      if( !hasValue )
        {
        std::cout<<"Error in doc example: no value for the example found !!!"<<std::endl;
        isOK = false;
        }
      }
    }

  if( !isOK )
    return EXIT_FAILURE;

  return EXIT_SUCCESS;
}

<commit_msg>BUG: avoid dl-close by cleaning registry sooner<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "otbWrapperApplicationRegistry.h"

using otb::Wrapper::Application;
using otb::Wrapper::ApplicationRegistry;

int otbWrapperApplicationDocTest(int argc, char* argv[])
{
  if (argc < 2)
    {
    std::cerr << "Usage : " << argv[0] << " [MODULEPATH]" << std::endl;
    return EXIT_FAILURE;
    }

  // Get the module path list
  std::list<std::string> modulePathList;
  if (argc > 1)
    {
    std::copy(argv + 1, argv + argc, std::back_inserter(modulePathList));

    // Load the path in the environment
    std::list<std::string>::const_iterator it = modulePathList.begin();
    while( it != modulePathList.end() )
      {
      ApplicationRegistry::AddApplicationPath( *(it) );
      ++it;
      }
    }

  bool isOK = true;

  // Get list of available applications
  std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
  for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
    {
    std::cout << "Testing documentation for application "<< (*it) << " ..." << std::endl;
    // Create module
    Application::Pointer app = ApplicationRegistry::CreateApplication(*it);

    // Check application availability
    if( app.IsNull() )
      {
      std::cout<<"Unable to load "<<argv[1]<<" application."<<std::endl;
      isOK = false;
      continue;
      }

    // Check doc element...
    if( std::string(app->GetName()) == "" )
      {
      std::cout<<"Missing Name."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocName()) == "" )
      {
      std::cout<<"Missing Doc Name."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDescription()) == "" )
      {
      std::cout<<"Missing Description."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocLongDescription()) == "" )
      {
      std::cout<<"Missing DocLongDescription."<<std::endl;
      isOK = false;
      }
    else if( std::string(app->GetDocLongDescription()).size() < 30 )
      {
      std::cout<<"DocLongDescription too small..."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocAuthors()) == "" )
      {
      std::cout<<"Missing DocAuthors."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocLimitations()) == "" )
      {
      std::cout<<"Missing DocLimitations."<<std::endl;
      isOK = false;
      }
    if( std::string(app->GetDocSeeAlso()) == "" )
      {
      std::cout<<"Missing DocSeeAlso."<<std::endl;
      isOK = false;
      }
    if( app->GetDocTags().size() == 0 )
      {
      std::cout<<"Missing DocTags."<<std::endl;
      isOK = false;
      }

    // Check example data
    app->Init();
    otb::Wrapper::DocExampleStructure::Pointer doc = app->GetDocExample();
    if( doc->GetApplicationName() == "" )
      {
      std::cout<<"Error in doc example: no aaplication name found."<<std::endl;
      isOK = false;
      }
    if( doc->GetParameterList().size() == 0 )
      {
      std::cout<<"Error in doc example: the list of parameter is empty."<<std::endl;
      isOK = false;
      }
    else
      {
      bool hasValue = false;
      unsigned int count = 0;
      while ( count<doc->GetParameterList().size() && !hasValue )
        {
        if( doc->GetParameterValue(count) != "" )
          {
          hasValue = true;
          }
        count++;
        }

      if( !hasValue )
        {
        std::cout<<"Error in doc example: no value for the example found !!!"<<std::endl;
        isOK = false;
        }
      }
    }
  ApplicationRegistry::CleanRegistry();

  if( !isOK )
    return EXIT_FAILURE;

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSceneIOTestScenarioProvider.h"

#include "mitkPointSet.h"
#include "mitkImage.h"
#include "mitkImageGenerator.h"
#include "mitkSurface.h"

// --------------- SceneIOTestScenarioProvider::Scenario ---------------

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::Scenario::BuildDataStorage() const
{
  return (*m_ScenarioProvider.*m_ProviderMethod)(); // calls function
}

mitk::SceneIOTestScenarioProvider::Scenario::Scenario(const std::string& _key,
    const SceneIOTestScenarioProvider* _scenarioProvider,
    SceneIOTestScenarioProvider::BuilderMethodPointer _providerMethod,
    bool _isSerializable,
    const std::string& _referenceArchiveFilename,
    bool _isReferenceLoadable)
: key(_key)
, serializable(_isSerializable)
, referenceArchiveFilename(_referenceArchiveFilename)
, referenceArchiveLoadable(_isReferenceLoadable)
, m_ScenarioProvider(_scenarioProvider)
, m_ProviderMethod(_providerMethod)
{
}

// --------------- SceneIOTestScenarioProvider ---------------

mitk::SceneIOTestScenarioProvider::ScenarioList mitk::SceneIOTestScenarioProvider::GetAllScenarios() const
{
  return m_Scenarios;
}

void mitk::SceneIOTestScenarioProvider::AddScenario(const std::string& key,
                                                    BuilderMethodPointer creator,
                                                    bool isSerializable,
                                                    const std::string& referenceArchiveFilename,
                                                    bool isReferenceLoadable)
{
  Scenario newScenario(key, this, creator, isSerializable, referenceArchiveFilename, isReferenceLoadable);
  m_Scenarios.push_back(newScenario);
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::EmptyStorage() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();
  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::OneEmptyNode() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  mitk::DataNode::Pointer node = DataNode::New();
  storage->Add(node);

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::OneEmptyNamedNode() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  mitk::DataNode::Pointer node = DataNode::New();
  node->SetName("Urmel");
  storage->Add(node);

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::ManyTopLevelNodes() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  for ( auto i = 0; i < m_HowMuchIsMany; ++i ) {
    mitk::DataNode::Pointer node = DataNode::New();
    std::stringstream s;
    s << "Node #" << i;
    node->SetName(s.str());
    storage->Add(node);
  }

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::LineOfManyOnlyChildren() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  mitk::DataNode::Pointer parent;
  for ( auto i = 0; i < m_HowMuchIsMany; ++i ) {
    mitk::DataNode::Pointer node = DataNode::New();
    std::stringstream s;
    s << "Node #" << i;
    node->SetName(s.str());
    storage->Add(node, parent);
    parent = node;
  }

  return storage;
}

#define AddNode(name) \
  storage->Add(name);

#define DefineNode(name) \
  mitk::DataNode::Pointer name = mitk::DataNode::New(); \
  name->SetName( #name );

#define DefNode0(name) \
  DefineNode(name) \
  AddNode(name)

#define DefNode1(source, name) \
  DefineNode(name) \
  storage->Add(name, source);

#define DefNode2(source1, source2, name) \
  DefineNode(name) \
  { mitk::DataStorage::SetOfObjects::Pointer sources = mitk::DataStorage::SetOfObjects::New(); \
  sources->push_back(source1); \
  sources->push_back(source2); \
  storage->Add(name, sources); }

#define DefNode3(source1, source2, source3, name) \
  DefineNode(name) \
  { mitk::DataStorage::SetOfObjects::Pointer sources = mitk::DataStorage::SetOfObjects::New(); \
  sources->push_back(source1); \
  sources->push_back(source2); \
  sources->push_back(source3); \
  storage->Add(name, sources); }

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::ComplicatedFamilySituation() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  // constructing a hierarchy with multiple levels
  // and a couple of multiple parent relations.

  // Source image : http://4.bp.blogspot.com/_57lEz2uo9yw/TTGWNhjsWPI/AAAAAAAAA5M/yMauv61ULXc/s1600/web-technology-family-tree-large.jpg

  // The red tree

  // two real ones
  DefNode0(Cpp)
  DefNode0(Basic)

  // descendants
  DefNode1(Cpp, Java)
  DefNode1(Cpp, Perl)
  DefNode1(Cpp, CSharp)

  DefNode1(Java, JSP)

  DefNode1(Perl, PHP)
  DefNode1(Perl, Ruby)
  DefNode1(Perl, Python)

  DefNode1(PHP, OOPHP)
  DefNode1(PHP, PHPLibs)

  DefNode1(Ruby, RubyRails);

  DefNode1(Basic, VBNet)

  // interesting ones
  DefNode2(Basic, VBNet, VBScript)
  DefNode2(CSharp, VBNet, ASPNet)
  DefNode2(ASPNet, VBScript, ClassicASP)

  DefNode1(ClassicASP, SHTML_SSI)
  DefNode1(ASPNet, ATLAS)

  // some green items
  DefNode0(ECMAScript)
  DefNode0(XHTML)
  DefNode1(ECMAScript, JavaScript)
  DefNode1(JavaScript, DHTML)

  // finally
  DefNode3(DHTML, XHTML, RubyRails, Ajax)

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::BasicCoreTypes() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  { // Image of ints
    mitk::Image::Pointer image3Dints = mitk::ImageGenerator::GenerateRandomImage<int>(10, 5, 7, // dim
                                                                                1, 0.5, 0.5,// spacing
                                                                                1, // time steps
                                                                                3000, -1000); // random max / min
    mitk::DataNode::Pointer node = DataNode::New();
    node->SetName("Image-Int");
    node->SetData(image3Dints);
    storage->Add(node);
  }

  { // Image of doubles
    mitk::Image::Pointer image3Ddouble = mitk::ImageGenerator::GenerateRandomImage<double>(5, 10, 8, // dim
                                                                                1, 0.5, 0.5,// spacing
                                                                                2, // time steps
                                                                                3000, -1000); // random max / min
    mitk::DataNode::Pointer node = DataNode::New();
    node->SetName("Image-Double");
    node->SetData(image3Ddouble);
    storage->Add(node);
  }

  return storage;

  { // PointSet
    mitk::PointSet::Pointer ps = mitk::PointSet::New();
    mitk::PointSet::PointType p;
    mitk::FillVector3D(p, 1.0, -2.0, 33.0);
    ps->SetPoint(0, p);
    mitk::FillVector3D(p, 100.0, -200.0, 3300.0);
    ps->SetPoint(1, p);
    mitk::FillVector3D(p, 2.0, -3.0, 22.0);
    ps->SetPoint(2, p, mitk::PTCORNER); // add point spec

    mitk::DataNode::Pointer node = DataNode::New();
    node->SetName("PointSet");
    node->SetData(ps);
    storage->Add(node);
  }

  return storage;
}

<commit_msg>Activate a test case for PointSet - fails due to geometry<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSceneIOTestScenarioProvider.h"

#include "mitkPointSet.h"
#include "mitkImage.h"
#include "mitkImageGenerator.h"
#include "mitkSurface.h"

// --------------- SceneIOTestScenarioProvider::Scenario ---------------

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::Scenario::BuildDataStorage() const
{
  return (*m_ScenarioProvider.*m_ProviderMethod)(); // calls function
}

mitk::SceneIOTestScenarioProvider::Scenario::Scenario(const std::string& _key,
    const SceneIOTestScenarioProvider* _scenarioProvider,
    SceneIOTestScenarioProvider::BuilderMethodPointer _providerMethod,
    bool _isSerializable,
    const std::string& _referenceArchiveFilename,
    bool _isReferenceLoadable)
: key(_key)
, serializable(_isSerializable)
, referenceArchiveFilename(_referenceArchiveFilename)
, referenceArchiveLoadable(_isReferenceLoadable)
, m_ScenarioProvider(_scenarioProvider)
, m_ProviderMethod(_providerMethod)
{
}

// --------------- SceneIOTestScenarioProvider ---------------

mitk::SceneIOTestScenarioProvider::ScenarioList mitk::SceneIOTestScenarioProvider::GetAllScenarios() const
{
  return m_Scenarios;
}

void mitk::SceneIOTestScenarioProvider::AddScenario(const std::string& key,
                                                    BuilderMethodPointer creator,
                                                    bool isSerializable,
                                                    const std::string& referenceArchiveFilename,
                                                    bool isReferenceLoadable)
{
  Scenario newScenario(key, this, creator, isSerializable, referenceArchiveFilename, isReferenceLoadable);
  m_Scenarios.push_back(newScenario);
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::EmptyStorage() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();
  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::OneEmptyNode() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  mitk::DataNode::Pointer node = DataNode::New();
  storage->Add(node);

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::OneEmptyNamedNode() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  mitk::DataNode::Pointer node = DataNode::New();
  node->SetName("Urmel");
  storage->Add(node);

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::ManyTopLevelNodes() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  for ( auto i = 0; i < m_HowMuchIsMany; ++i ) {
    mitk::DataNode::Pointer node = DataNode::New();
    std::stringstream s;
    s << "Node #" << i;
    node->SetName(s.str());
    storage->Add(node);
  }

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::LineOfManyOnlyChildren() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  mitk::DataNode::Pointer parent;
  for ( auto i = 0; i < m_HowMuchIsMany; ++i ) {
    mitk::DataNode::Pointer node = DataNode::New();
    std::stringstream s;
    s << "Node #" << i;
    node->SetName(s.str());
    storage->Add(node, parent);
    parent = node;
  }

  return storage;
}

#define AddNode(name) \
  storage->Add(name);

#define DefineNode(name) \
  mitk::DataNode::Pointer name = mitk::DataNode::New(); \
  name->SetName( #name );

#define DefNode0(name) \
  DefineNode(name) \
  AddNode(name)

#define DefNode1(source, name) \
  DefineNode(name) \
  storage->Add(name, source);

#define DefNode2(source1, source2, name) \
  DefineNode(name) \
  { mitk::DataStorage::SetOfObjects::Pointer sources = mitk::DataStorage::SetOfObjects::New(); \
  sources->push_back(source1); \
  sources->push_back(source2); \
  storage->Add(name, sources); }

#define DefNode3(source1, source2, source3, name) \
  DefineNode(name) \
  { mitk::DataStorage::SetOfObjects::Pointer sources = mitk::DataStorage::SetOfObjects::New(); \
  sources->push_back(source1); \
  sources->push_back(source2); \
  sources->push_back(source3); \
  storage->Add(name, sources); }

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::ComplicatedFamilySituation() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  // constructing a hierarchy with multiple levels
  // and a couple of multiple parent relations.

  // Source image : http://4.bp.blogspot.com/_57lEz2uo9yw/TTGWNhjsWPI/AAAAAAAAA5M/yMauv61ULXc/s1600/web-technology-family-tree-large.jpg

  // The red tree

  // two real ones
  DefNode0(Cpp)
  DefNode0(Basic)

  // descendants
  DefNode1(Cpp, Java)
  DefNode1(Cpp, Perl)
  DefNode1(Cpp, CSharp)

  DefNode1(Java, JSP)

  DefNode1(Perl, PHP)
  DefNode1(Perl, Ruby)
  DefNode1(Perl, Python)

  DefNode1(PHP, OOPHP)
  DefNode1(PHP, PHPLibs)

  DefNode1(Ruby, RubyRails);

  DefNode1(Basic, VBNet)

  // interesting ones
  DefNode2(Basic, VBNet, VBScript)
  DefNode2(CSharp, VBNet, ASPNet)
  DefNode2(ASPNet, VBScript, ClassicASP)

  DefNode1(ClassicASP, SHTML_SSI)
  DefNode1(ASPNet, ATLAS)

  // some green items
  DefNode0(ECMAScript)
  DefNode0(XHTML)
  DefNode1(ECMAScript, JavaScript)
  DefNode1(JavaScript, DHTML)

  // finally
  DefNode3(DHTML, XHTML, RubyRails, Ajax)

  return storage;
}

mitk::DataStorage::Pointer mitk::SceneIOTestScenarioProvider::BasicCoreTypes() const
{
  mitk::DataStorage::Pointer storage = StandaloneDataStorage::New();

  { // Image of ints
    mitk::Image::Pointer image3Dints = mitk::ImageGenerator::GenerateRandomImage<int>(10, 5, 7, // dim
                                                                                1, 0.5, 0.5,// spacing
                                                                                1, // time steps
                                                                                3000, -1000); // random max / min
    mitk::DataNode::Pointer node = DataNode::New();
    node->SetName("Image-Int");
    node->SetData(image3Dints);
    storage->Add(node);
  }

  { // Image of doubles
    mitk::Image::Pointer image3Ddouble = mitk::ImageGenerator::GenerateRandomImage<double>(5, 10, 8, // dim
                                                                                1, 0.5, 0.5,// spacing
                                                                                2, // time steps
                                                                                3000, -1000); // random max / min
    mitk::DataNode::Pointer node = DataNode::New();
    node->SetName("Image-Double");
    node->SetData(image3Ddouble);
    storage->Add(node);
  }

  { // PointSet
    mitk::PointSet::Pointer ps = mitk::PointSet::New();
    mitk::PointSet::PointType p;
    mitk::FillVector3D(p, 1.0, -2.0, 33.0);
    ps->SetPoint(0, p);
    mitk::FillVector3D(p, 100.0, -200.0, 3300.0);
    ps->SetPoint(1, p);
    mitk::FillVector3D(p, 2.0, -3.0, 22.0);
    ps->SetPoint(2, p, mitk::PTCORNER); // add point spec

    mitk::DataNode::Pointer node = DataNode::New();
    node->SetName("PointSet");
    node->SetData(ps);
    storage->Add(node);
  }

  return storage;
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2022.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <iostream>

#include "Stroika/Foundation/Characters/String2Int.h"
#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Containers/Collection.h"
#include "Stroika/Foundation/Execution/CommandLine.h"
#include "Stroika/Foundation/IO/Network/DNS.h"

#include "Stroika/Frameworks/NetworkMonitor/Ping.h"
#include "Stroika/Frameworks/NetworkMonitor/Traceroute.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::IO::Network;
using namespace Stroika::Foundation::IO::Network::InternetProtocol;
using namespace Stroika::Foundation::Time;
using namespace Stroika::Frameworks;
using namespace Stroika::Frameworks::NetworkMonitor;

using Characters::String;
using Containers::Collection;
using Containers::Sequence;

int main (int argc, const char* argv[])
{
    Debug::TraceContextBumper ctx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"main", L"argv=%s", Characters::ToString (vector<const char*>{argv, argv + argc}).c_str ())};
    String                    targetAddress;
    enum class MajorOp {
        ePing,
        eTraceroute,
    };
    MajorOp               majorOp     = MajorOp::eTraceroute;
    unsigned int          maxHops     = Ping::Options::kDefaultMaxHops;
    unsigned int          sampleCount = 3;
    static const Duration kInterSampleTime_{"PT.1S"};
    size_t                packetSize = Ping::Options::kDefaultPayloadSize + sizeof (ICMP::V4::PacketHeader); // historically, the app ping has measured this including ICMP packet header, but not ip packet header size
    auto                  usage      = [] (const optional<String>& extraArg = {}) {
        if (extraArg) {
            cerr << extraArg->AsNarrowSDKString () << endl;
        }
        cerr << "traceroute [--ping][--traceroute][--packetSize NNN][--maxHops NNN][--sampleCount N]  target-address" << endl;
        cerr << "   if sampleCount is 1, exception details shown, otherwise just summary of number of exceptions" << endl;
    };
    {
        Sequence<String> args = Execution::ParseCommandLine (argc, argv);
        for (auto argi = args.begin (); argi != args.end (); ++argi) {
            if (Execution::MatchesCommandLineArgument (*argi, L"ping")) {
                majorOp = MajorOp::ePing;
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"traceroute")) {
                majorOp = MajorOp::eTraceroute;
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"packetSize")) {
                ++argi;
                if (argi != args.end ()) {
                    packetSize = Characters::String2Int<unsigned int> (*argi);
                }
                else {
                    usage (L"Expected arg to -packetSize");
                    return EXIT_FAILURE;
                }
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"maxHops")) {
                ++argi;
                if (argi != args.end ()) {
                    maxHops = Characters::String2Int<unsigned int> (*argi);
                }
                else {
                    usage (L"Expected arg to -maxHops");
                    return EXIT_FAILURE;
                }
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"sampleCount")) {
                ++argi;
                if (argi != args.end ()) {
                    sampleCount = Characters::String2Int<unsigned int> (*argi);
                }
                else {
                    usage (L"Expected arg to -sampleCount");
                    return EXIT_FAILURE;
                }
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"help") or Execution::MatchesCommandLineArgument (*argi, L"h")) {
                usage ();
                return EXIT_SUCCESS;
            }
            else if (argi->StartsWith (L"-")) {
                usage (L"unrecognized option: " + *argi);
                return EXIT_FAILURE;
            }
            else {
                targetAddress = *argi;
            }
        }
    }

    try {
        Collection<InternetAddress> addrList = IO::Network::DNS::kThe.GetHostAddresses (targetAddress);
        if (addrList.empty ()) {
            Execution::Throw (Execution::Exception{L"whoops no addrs"sv});
        }
        InternetAddress addr = addrList.Nth (0);

        switch (majorOp) {
            case MajorOp::ePing: {
                Ping::Options options{};
                options.fPacketPayloadSize = Ping::Options::kAllowedICMPPayloadSizeRange.Pin (packetSize - sizeof (ICMP::V4::PacketHeader));
                options.fMaxHops           = maxHops;
                //   options.fSampleInfo                   = Ping::Options::SampleInfo{kInterSampleTime_, sampleCount};
                NetworkMonitor::Ping::SampleResults t = NetworkMonitor::Ping::Sample (addr, Ping::SampleOptions{kInterSampleTime_, sampleCount}, options);
                cout << "Ping to " << addr.ToString ().AsNarrowSDKString () << ": " << Characters::ToString (t).AsNarrowSDKString () << endl;
            } break;
            case MajorOp::eTraceroute: {
                Traceroute::Options options{};
                options.fPacketPayloadSize = Traceroute::Options::kAllowedICMPPayloadSizeRange.Pin (packetSize - sizeof (ICMP::V4::PacketHeader));
                options.fMaxHops           = maxHops;

                cout << "Tracing Route to " << targetAddress.AsNarrowSDKString () << " [" << Characters::ToString (addr).AsNarrowSDKString () << "] over a maximum of " << maxHops << " hops." << endl;
                cout << endl;

                // quickie - weak attempt at formatting the output
                cout << "Hop\tTime\t\tAddress" << endl;

                Sequence<Traceroute::Hop> hops = Traceroute::Run (addr, options);
                unsigned int              hopIdx{1};
                for (Traceroute::Hop h : hops) {
                    String hopName = [=] () {
                        String addrStr = h.fAddress.As<String> ();
                        if (auto rdnsName = DNS::Default ().QuietReverseLookup (h.fAddress)) {
                            return *rdnsName + L" [" + addrStr + L"]";
                        }
                        else {
                            return addrStr;
                        }
                    }();
                    cout << hopIdx++ << "\t" << h.fTime.PrettyPrint ().AsNarrowSDKString () << "\t" << hopName.AsNarrowSDKString () << endl;
                }
            } break;
        }
    }
    catch (...) {
        String exceptMsg = Characters::ToString (current_exception ());
        cerr << "Exception - " << exceptMsg.AsNarrowSDKString () << " - terminating..." << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<commit_msg>fixed typo<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2022.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <iostream>

#include "Stroika/Foundation/Characters/String2Int.h"
#include "Stroika/Foundation/Characters/ToString.h"
#include "Stroika/Foundation/Containers/Collection.h"
#include "Stroika/Foundation/Execution/CommandLine.h"
#include "Stroika/Foundation/IO/Network/DNS.h"

#include "Stroika/Frameworks/NetworkMonitor/Ping.h"
#include "Stroika/Frameworks/NetworkMonitor/Traceroute.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::IO::Network;
using namespace Stroika::Foundation::IO::Network::InternetProtocol;
using namespace Stroika::Foundation::Time;
using namespace Stroika::Frameworks;
using namespace Stroika::Frameworks::NetworkMonitor;

using Characters::String;
using Containers::Collection;
using Containers::Sequence;

int main (int argc, const char* argv[])
{
    Debug::TraceContextBumper ctx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"main", L"argv=%s", Characters::ToString (vector<const char*>{argv, argv + argc}).c_str ())};
    String                    targetAddress;
    enum class MajorOp {
        ePing,
        eTraceroute,
    };
    MajorOp               majorOp     = MajorOp::eTraceroute;
    unsigned int          maxHops     = Ping::Options::kDefaultMaxHops;
    unsigned int          sampleCount = 3;
    static const Duration kInterSampleTime_{"PT.1S"};
    size_t                packetSize = Ping::Options::kDefaultPayloadSize + sizeof (ICMP::V4::PacketHeader); // historically, the app ping has measured this including ICMP packet header, but not ip packet header size
    auto                  usage      = [] (const optional<String>& extraArg = {}) {
        if (extraArg) {
            cerr << extraArg->AsNarrowSDKString () << endl;
        }
        cerr << "traceroute [--ping][--traceroute][--packetSize NNN][--maxHops NNN][--sampleCount N]  target-address" << endl;
        cerr << "   if sampleCount is 1, exception details shown, otherwise just summary of number of exceptions" << endl;
    };
    {
        Sequence<String> args = Execution::ParseCommandLine (argc, argv);
        for (auto argi = args.begin (); argi != args.end (); ++argi) {
            if (Execution::MatchesCommandLineArgument (*argi, L"ping")) {
                majorOp = MajorOp::ePing;
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"traceroute")) {
                majorOp = MajorOp::eTraceroute;
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"packetSize")) {
                ++argi;
                if (argi != args.end ()) {
                    packetSize = Characters::String2Int<unsigned int> (*argi);
                }
                else {
                    usage (L"Expected arg to -packetSize");
                    return EXIT_FAILURE;
                }
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"maxHops")) {
                ++argi;
                if (argi != args.end ()) {
                    maxHops = Characters::String2Int<unsigned int> (*argi);
                }
                else {
                    usage (L"Expected arg to -maxHops");
                    return EXIT_FAILURE;
                }
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"sampleCount")) {
                ++argi;
                if (argi != args.end ()) {
                    sampleCount = Characters::String2Int<unsigned int> (*argi);
                }
                else {
                    usage (L"Expected arg to -sampleCount");
                    return EXIT_FAILURE;
                }
            }
            else if (Execution::MatchesCommandLineArgument (*argi, L"help") or Execution::MatchesCommandLineArgument (*argi, L"h")) {
                usage ();
                return EXIT_SUCCESS;
            }
            else if (argi->StartsWith (L"-")) {
                usage (L"unrecognized option: " + *argi);
                return EXIT_FAILURE;
            }
            else {
                targetAddress = *argi;
            }
        }
    }

    try {
        Collection<InternetAddress> addrList = IO::Network::DNS::kThe.GetHostAddresses (targetAddress);
        if (addrList.empty ()) {
            Execution::Throw (Execution::Exception{L"whoops no addrs"sv});
        }
        InternetAddress addr = addrList.Nth (0);

        switch (majorOp) {
            case MajorOp::ePing: {
                Ping::Options options{};
                options.fPacketPayloadSize = Ping::Options::kAllowedICMPPayloadSizeRange.Pin (packetSize - sizeof (ICMP::V4::PacketHeader));
                options.fMaxHops           = maxHops;
                //   options.fSampleInfo                   = Ping::Options::SampleInfo{kInterSampleTime_, sampleCount};
                NetworkMonitor::Ping::SampleResults t = NetworkMonitor::Ping::Sample (addr, Ping::SampleOptions{kInterSampleTime_, sampleCount}, options);
                cout << "Ping to " << addr.ToString ().AsNarrowSDKString () << ": " << Characters::ToString (t).AsNarrowSDKString () << endl;
            } break;
            case MajorOp::eTraceroute: {
                Traceroute::Options options{};
                options.fPacketPayloadSize = Traceroute::Options::kAllowedICMPPayloadSizeRange.Pin (packetSize - sizeof (ICMP::V4::PacketHeader));
                options.fMaxHops           = maxHops;

                cout << "Tracing Route to " << targetAddress.AsNarrowSDKString () << " [" << Characters::ToString (addr).AsNarrowSDKString () << "] over a maximum of " << maxHops << " hops." << endl;
                cout << endl;

                // quickie - weak attempt at formatting the output
                cout << "Hop\tTime\t\tAddress" << endl;

                Sequence<Traceroute::Hop> hops = Traceroute::Run (addr, options);
                unsigned int              hopIdx{1};
                for (Traceroute::Hop h : hops) {
                    String hopName = [=] () {
                        String addrStr = h.fAddress.As<String> ();
                        if (auto rdnsName = DNS::kThe.QuietReverseLookup (h.fAddress)) {
                            return *rdnsName + L" [" + addrStr + L"]";
                        }
                        else {
                            return addrStr;
                        }
                    }();
                    cout << hopIdx++ << "\t" << h.fTime.PrettyPrint ().AsNarrowSDKString () << "\t" << hopName.AsNarrowSDKString () << endl;
                }
            } break;
        }
    }
    catch (...) {
        String exceptMsg = Characters::ToString (current_exception ());
        cerr << "Exception - " << exceptMsg.AsNarrowSDKString () << " - terminating..." << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/** \brief Checks the BSZ delivery database to find journals for which we have no reasonably new articles delivered.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018-2021 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctime>
#include <cstdlib>
#include "EmailSender.h"
#include "IniFile.h"
#include "SqlUtil.h"
#include "StringUtil.h"
#include "TextUtil.h"
#include "TimeUtil.h"
#include "UBTools.h"
#include "util.h"
#include "Zeder.h"
#include "ZoteroHarvesterConfig.h"
#include "ZoteroHarvesterUtil.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--min-log-level=log_level] [--default-update-window=no_of_days] sender_email_address notification_email_address");
}

bool MaxDeliveredAtSmallerThanUpdateWindow(const time_t &max_delivered_at, const unsigned &update_window) {
     if (max_delivered_at == TimeUtil::BAD_TIME_T)
         return false;
     return max_delivered_at < ::time(nullptr) - update_window * 86400;
}

void ProcessJournal(ZoteroHarvester::Util::UploadTracker * const upload_tracker, const std::string &journal_name,
                    const std::string &zeder_id, const std::string &zeder_instance, const unsigned update_window,
                    std::string * tardy_list)
{
    // Make sure articles stored as online first are retried after an update_window period
    upload_tracker->deleteOnlineFirstEntriesOlderThan(StringUtil::ToUnsigned(zeder_id), zeder_instance, update_window);

    const time_t max_delivered_at(upload_tracker->getLastUploadTime(StringUtil::ToUnsigned(zeder_id),
                                  Zeder::ParseFlavour(zeder_instance)));

    if (MaxDeliveredAtSmallerThanUpdateWindow(max_delivered_at, update_window))
        *tardy_list += journal_name + ": " + TimeUtil::TimeTToString(max_delivered_at) + "\n";
}

const unsigned DEFAULT_UPDATE_WINDOW(60); // days

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc < 4)
        Usage();

    unsigned default_update_window(DEFAULT_UPDATE_WINDOW);
    if (StringUtil::StartsWith(argv[1], "--default-update-window=")) {
        if (not StringUtil::ToUnsigned(argv[1] + __builtin_strlen("--default-update-window=")))
            LOG_ERROR("invalid default update window: \"" + std::string(argv[1] + __builtin_strlen("--default-update-window=")) + "\"!");
        --argc, ++argv;
    }

    if (argc != 4)
        Usage();

    const std::string sender_email_address(argv[2]), notification_email_address(argv[3]);
    ZoteroHarvester::Util::UploadTracker upload_tracker;

    IniFile ini_file(UBTools::GetTuelibPath() + "zotero-enhancement-maps/zotero_harvester.conf");
    std::string tardy_list;
    for (const auto &section : ini_file) {
        if (section.find("user_agent") != section.end())
            continue; // Not a journal section.

        const auto delivery_mode(section.getEnum("zotero_delivery_mode", ZoteroHarvester::Config::STRING_TO_UPLOAD_OPERATION_MAP,
                                                 ZoteroHarvester::Config::UploadOperation::NONE));
        if (delivery_mode != ZoteroHarvester::Config::UploadOperation::LIVE or section.getBool("zeder_newly_synced_entry", false))
            continue;

        const std::string journal_name(section.getSectionName());

        const std::string zeder_id(section.getString("zeder_id"));
        const std::string zeder_instance(TextUtil::UTF8ToLower(section.getString("zotero_group")));

        unsigned update_window;
        if (section.find("zotero_update_window") == section.end()) {
            LOG_WARNING("no update window found for \"" + journal_name + "\", using " + std::to_string(default_update_window) + "!");
            update_window = default_update_window;
        } else
            update_window = section.getUnsigned("zotero_update_window");
        LOG_WARNING("USING ZOTERO_UPDATE_WINDOW: " + std::to_string(update_window));

        ProcessJournal(&upload_tracker, journal_name, zeder_id, zeder_instance, update_window, &tardy_list);
    }

    if (not tardy_list.empty()) {
        if (EmailSender::SimplerSendEmail(sender_email_address, { notification_email_address }, "Überfällige Zeitschriften",
                                          "Letzte Lieferung ans BSZ\n" + tardy_list) > 299)
            LOG_ERROR("failed to send email notification!");
    }

    return EXIT_SUCCESS;
}
<commit_msg>Force OF deletion to shorter time spans<commit_after>/** \brief Checks the BSZ delivery database to find journals for which we have no reasonably new articles delivered.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018-2021 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctime>
#include <cstdlib>
#include "EmailSender.h"
#include "IniFile.h"
#include "SqlUtil.h"
#include "StringUtil.h"
#include "TextUtil.h"
#include "TimeUtil.h"
#include "UBTools.h"
#include "util.h"
#include "Zeder.h"
#include "ZoteroHarvesterConfig.h"
#include "ZoteroHarvesterUtil.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--min-log-level=log_level] [--default-update-window=no_of_days] sender_email_address notification_email_address");
}

bool MaxDeliveredAtSmallerThanUpdateWindow(const time_t &max_delivered_at, const unsigned &update_window) {
     if (max_delivered_at == TimeUtil::BAD_TIME_T)
         return false;
     return max_delivered_at < ::time(nullptr) - update_window * 86400;
}

void ProcessJournal(ZoteroHarvester::Util::UploadTracker * const upload_tracker, const std::string &journal_name,
                    const std::string &zeder_id, const std::string &zeder_instance, const unsigned update_window,
                    std::string * tardy_list)
{
     // Make sure articles stored as online first are retried after half an update_window period or at most 30 days
    upload_tracker->deleteOnlineFirstEntriesOlderThan(StringUtil::ToUnsigned(zeder_id), zeder_instance, std::min(update_window / 2 , static_cast<unsigned>(30)));

    const time_t max_delivered_at(upload_tracker->getLastUploadTime(StringUtil::ToUnsigned(zeder_id),
                                  Zeder::ParseFlavour(zeder_instance)));

    if (MaxDeliveredAtSmallerThanUpdateWindow(max_delivered_at, update_window))
        *tardy_list += journal_name + ": " + TimeUtil::TimeTToString(max_delivered_at) + "\n";
}

const unsigned DEFAULT_UPDATE_WINDOW(60); // days

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc < 4)
        Usage();

    unsigned default_update_window(DEFAULT_UPDATE_WINDOW);
    if (StringUtil::StartsWith(argv[1], "--default-update-window=")) {
        if (not StringUtil::ToUnsigned(argv[1] + __builtin_strlen("--default-update-window=")))
            LOG_ERROR("invalid default update window: \"" + std::string(argv[1] + __builtin_strlen("--default-update-window=")) + "\"!");
        --argc, ++argv;
    }

    if (argc != 4)
        Usage();

    const std::string sender_email_address(argv[2]), notification_email_address(argv[3]);
    ZoteroHarvester::Util::UploadTracker upload_tracker;

    IniFile ini_file(UBTools::GetTuelibPath() + "zotero-enhancement-maps/zotero_harvester.conf");
    std::string tardy_list;
    for (const auto &section : ini_file) {
        if (section.find("user_agent") != section.end())
            continue; // Not a journal section.

        const auto delivery_mode(section.getEnum("zotero_delivery_mode", ZoteroHarvester::Config::STRING_TO_UPLOAD_OPERATION_MAP,
                                                 ZoteroHarvester::Config::UploadOperation::NONE));
        if (delivery_mode != ZoteroHarvester::Config::UploadOperation::LIVE or section.getBool("zeder_newly_synced_entry", false))
            continue;

        const std::string journal_name(section.getSectionName());

        const std::string zeder_id(section.getString("zeder_id"));
        const std::string zeder_instance(TextUtil::UTF8ToLower(section.getString("zotero_group")));

        unsigned update_window;
        if (section.find("zotero_update_window") == section.end()) {
            LOG_WARNING("no update window found for \"" + journal_name + "\", using " + std::to_string(default_update_window) + "!");
            update_window = default_update_window;
        } else
            update_window = section.getUnsigned("zotero_update_window");
        LOG_WARNING("USING ZOTERO_UPDATE_WINDOW: " + std::to_string(update_window));

        ProcessJournal(&upload_tracker, journal_name, zeder_id, zeder_instance, update_window, &tardy_list);
    }

    if (not tardy_list.empty()) {
        if (EmailSender::SimplerSendEmail(sender_email_address, { notification_email_address }, "Überfällige Zeitschriften",
                                          "Letzte Lieferung ans BSZ\n" + tardy_list) > 299)
            LOG_ERROR("failed to send email notification!");
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: interfacecontainer.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <cppuhelper/interfacecontainer.hxx>
#include <cppuhelper/queryinterface.hxx>

#include <osl/diagnose.h>
#include <osl/mutex.hxx>

#include <hash_map>

#include <assert.h>

#include <com/sun/star/lang/XEventListener.hpp>

using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;

namespace cppu
{

//===================================================================
//===================================================================
//===================================================================
/**
 * Reallocate the sequence.
 */
static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
{
    Sequence< Reference< XInterface > > aNewSeq( nNewLen );
    Reference< XInterface > * pDest = aNewSeq.getArray();
    // getArray on a const sequence is faster
    const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
    for( sal_Int32 i = (nNewLen < rSeq.getLength() ? nNewLen : rSeq.getLength()) -1; i >= 0; i-- )
        pDest[i] = pSource[i];
    rSeq = aNewSeq;
}

/**
 * Remove an element from an interface sequence.
 */
static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
{
    sal_Int32 nNewLen = rSeq.getLength() - 1;

    Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
    // getArray on a const sequence is faster
    const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
    Reference< XInterface > * pDest = aDestSeq.getArray();
    sal_Int32 i = 0;
    for( ; i < index; i++ )
        pDest[i] = pSource[i];
    for( sal_Int32 j = i ; j < nNewLen; j++ )
        pDest[j] = pSource[j+1];
    rSeq = aDestSeq;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

#ifdef SAL_WNT
#pragma warning( disable: 4786 )
#endif

//===================================================================
//===================================================================
//===================================================================
OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
    : rCont( rCont_ )
{
    MutexGuard aGuard( rCont.rMutex );
    if( rCont.bInUse )
        // worst case, two iterators at the same time
        rCont.copyAndResetInUse();
    bIsList = rCont_.bIsList;
    pData = rCont_.pData;
    if( bIsList )
    {
        rCont.bInUse = sal_True;
        nRemain = ((Sequence< Reference< XInterface > >*)pData)->getLength();
    }
    else if( pData )
    {
        ((XInterface *)pData)->acquire();
        nRemain = 1;
    }
    else
        nRemain = 0;
}

OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
{
    sal_Bool bShared;
    {
    MutexGuard aGuard( rCont.rMutex );
    // bResetInUse protect the iterator against recursion
    bShared = pData == rCont.pData && rCont.bIsList;
    if( bShared )
    {
        OSL_ENSHURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
        rCont.bInUse = sal_False;
    }
    }

    if( !bShared )
    {
        if( bIsList )
            // Sequence owned by the iterator
            delete (Sequence< Reference< XInterface > >*)pData;
        else if( pData )
            // Interface is acquired by the iterator
            ((XInterface*)pData)->release();
    }
}

XInterface * OInterfaceIteratorHelper::next()
{
    if( nRemain )
    {
        nRemain--;
        if( bIsList )
            // typecase to const,so the getArray method is faster
            return ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get();
        else if( pData )
            return (XInterface*)pData;
    }
    // exception
    return 0;
}

//===================================================================
//===================================================================
//===================================================================

OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ )
    : rMutex( rMutex_ )
    , bInUse( sal_False )
    , bIsList( sal_False )
    , pData( 0 )
{
}

OInterfaceContainerHelper::~OInterfaceContainerHelper()
{
    OSL_ENSHURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
    if( bIsList )
        delete (Sequence< Reference< XInterface > >*)pData;
    else if( pData )
        ((XInterface*)pData)->release();
}

sal_Int32   OInterfaceContainerHelper::getLength() const
{
    MutexGuard aGuard( rMutex );
    if( bIsList )
        return ((Sequence< Reference< XInterface > >*)pData)->getLength();
    else if( pData )
        return 1;
    return 0;
}

Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
{
    MutexGuard aGuard( rMutex );
    if( bIsList )
        return *(Sequence< Reference< XInterface > >*)pData;
    else if( pData )
    {
        Reference<XInterface> x( (XInterface *)pData );
        return Sequence< Reference< XInterface > >( &x, 1 );
    }
    return Sequence< Reference< XInterface > >();
}

void OInterfaceContainerHelper::copyAndResetInUse()
{
    OSL_ENSHURE( bInUse, "OInterfaceContainerHelper not in use" );
    if( bInUse )
    {
        // this should be the worst case. If a iterator is active
        // and a new Listener is added.
        if( bIsList )
            pData = new Sequence< Reference< XInterface > >( *(Sequence< Reference< XInterface > >*)pData );
        else if( pData )
            ((XInterface*)pData)->acquire();

        bInUse = sal_False;
    }
}

sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener )
{
    assert( rListener.is() );
    MutexGuard aGuard( rMutex );
    if( bInUse )
        copyAndResetInUse();

    if( bIsList )
    {
        sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength();
        realloc( *(Sequence< Reference< XInterface > >*)pData, nLen +1 );
        ((Sequence< Reference< XInterface > >*)pData)->getArray()[ nLen ] = rListener;
        return nLen +1;
    }
    else if( pData )
    {
        Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
        Reference<XInterface> * pArray = pSeq->getArray();
        pArray[0] = (XInterface *)pData;
        pArray[1] = rListener;
        ((XInterface *)pData)->release();
        pData = pSeq;
        bIsList = sal_True;
        return 2;
    }
    else
    {
        pData = rListener.get();
        if( rListener.is() )
            rListener->acquire();
        return 1;
    }
}

sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener )
{
    assert( rListener.is() );
    MutexGuard aGuard( rMutex );
    if( bInUse )
        copyAndResetInUse();

    if( bIsList )
    {
        const Reference<XInterface> * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray();
        sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength();
        sal_Int32 i;
        for( i = 0; i < nLen; i++ )
        {
            // It is not valid to compare the Pointer direkt, but is is is much
            // more faster.
            if( pL[i].get() == rListener.get() )
            {
                sequenceRemoveElementAt( *(Sequence< Reference< XInterface > >*)pData, i );
                break;
            }
        }

        if( i == nLen )
        {
            // interface not found, use the correct compare method
            for( i = 0; i < nLen; i++ )
            {
                if( pL[i] == rListener )
                {
                    sequenceRemoveElementAt(*(Sequence< Reference< XInterface > >*)pData, i );
                    break;
                }
            }
        }

        if( ((Sequence< Reference< XInterface > >*)pData)->getLength() == 1 )
        {
            XInterface * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[0].get();
            pL->acquire();
            delete (Sequence< Reference< XInterface > >*)pData;
            pData = pL;
            bIsList = sal_False;
            return 1;
        }
        else
            return ((Sequence< Reference< XInterface > >*)pData)->getLength();
    }
    else if( Reference<XInterface>( (XInterface*)pData ) == rListener )
    {
        ((XInterface *)pData)->release();
        pData = 0;
    }
    return pData ? 1 : 0;
}

void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
{
    ClearableMutexGuard aGuard( rMutex );
    OInterfaceIteratorHelper aIt( *this );
    // Container freigeben, falls im disposing neue Eintrge kommen
    OSL_ENSHURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
    if( !bIsList && pData )
        ((XInterface *)pData)->release();
    // set the member to null, the iterator delete the values
    pData = NULL;
    bIsList = sal_False;
    bInUse = sal_False;
    aGuard.clear();
    while( aIt.hasMoreElements() )
    {
        Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
        if( xLst.is() )
            xLst->disposing( rEvt );
    }
}

void OInterfaceContainerHelper::clear( )
{
    ClearableMutexGuard aGuard( rMutex );
    OInterfaceIteratorHelper aIt( *this );
    // Container freigeben, falls im disposing neue Eintrge kommen
    OSL_ENSHURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
    if( !bIsList && pData )
        ((XInterface *)pData)->release();
    // set the member to null, the iterator delete the values
    pData = 0;
    bIsList = sal_False;
    bInUse = sal_False;
    // release mutex before aIt destructor call
    aGuard.clear();
}

}

<commit_msg>catching runtimeexception during disposing<commit_after>/*************************************************************************
 *
 *  $RCSfile: interfacecontainer.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: jbu $ $Date: 2000-09-29 08:48:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <cppuhelper/interfacecontainer.hxx>
#include <cppuhelper/queryinterface.hxx>

#include <osl/diagnose.h>
#include <osl/mutex.hxx>

#include <hash_map>

#include <assert.h>

#include <com/sun/star/lang/XEventListener.hpp>

using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;

namespace cppu
{

//===================================================================
//===================================================================
//===================================================================
/**
 * Reallocate the sequence.
 */
static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
{
    Sequence< Reference< XInterface > > aNewSeq( nNewLen );
    Reference< XInterface > * pDest = aNewSeq.getArray();
    // getArray on a const sequence is faster
    const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
    for( sal_Int32 i = (nNewLen < rSeq.getLength() ? nNewLen : rSeq.getLength()) -1; i >= 0; i-- )
        pDest[i] = pSource[i];
    rSeq = aNewSeq;
}

/**
 * Remove an element from an interface sequence.
 */
static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
{
    sal_Int32 nNewLen = rSeq.getLength() - 1;

    Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
    // getArray on a const sequence is faster
    const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
    Reference< XInterface > * pDest = aDestSeq.getArray();
    sal_Int32 i = 0;
    for( ; i < index; i++ )
        pDest[i] = pSource[i];
    for( sal_Int32 j = i ; j < nNewLen; j++ )
        pDest[j] = pSource[j+1];
    rSeq = aDestSeq;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

#ifdef SAL_WNT
#pragma warning( disable: 4786 )
#endif

//===================================================================
//===================================================================
//===================================================================
OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
    : rCont( rCont_ )
{
    MutexGuard aGuard( rCont.rMutex );
    if( rCont.bInUse )
        // worst case, two iterators at the same time
        rCont.copyAndResetInUse();
    bIsList = rCont_.bIsList;
    pData = rCont_.pData;
    if( bIsList )
    {
        rCont.bInUse = sal_True;
        nRemain = ((Sequence< Reference< XInterface > >*)pData)->getLength();
    }
    else if( pData )
    {
        ((XInterface *)pData)->acquire();
        nRemain = 1;
    }
    else
        nRemain = 0;
}

OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
{
    sal_Bool bShared;
    {
    MutexGuard aGuard( rCont.rMutex );
    // bResetInUse protect the iterator against recursion
    bShared = pData == rCont.pData && rCont.bIsList;
    if( bShared )
    {
        OSL_ENSHURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
        rCont.bInUse = sal_False;
    }
    }

    if( !bShared )
    {
        if( bIsList )
            // Sequence owned by the iterator
            delete (Sequence< Reference< XInterface > >*)pData;
        else if( pData )
            // Interface is acquired by the iterator
            ((XInterface*)pData)->release();
    }
}

XInterface * OInterfaceIteratorHelper::next()
{
    if( nRemain )
    {
        nRemain--;
        if( bIsList )
            // typecase to const,so the getArray method is faster
            return ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get();
        else if( pData )
            return (XInterface*)pData;
    }
    // exception
    return 0;
}

//===================================================================
//===================================================================
//===================================================================

OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ )
    : rMutex( rMutex_ )
    , bInUse( sal_False )
    , bIsList( sal_False )
    , pData( 0 )
{
}

OInterfaceContainerHelper::~OInterfaceContainerHelper()
{
    OSL_ENSHURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
    if( bIsList )
        delete (Sequence< Reference< XInterface > >*)pData;
    else if( pData )
        ((XInterface*)pData)->release();
}

sal_Int32   OInterfaceContainerHelper::getLength() const
{
    MutexGuard aGuard( rMutex );
    if( bIsList )
        return ((Sequence< Reference< XInterface > >*)pData)->getLength();
    else if( pData )
        return 1;
    return 0;
}

Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
{
    MutexGuard aGuard( rMutex );
    if( bIsList )
        return *(Sequence< Reference< XInterface > >*)pData;
    else if( pData )
    {
        Reference<XInterface> x( (XInterface *)pData );
        return Sequence< Reference< XInterface > >( &x, 1 );
    }
    return Sequence< Reference< XInterface > >();
}

void OInterfaceContainerHelper::copyAndResetInUse()
{
    OSL_ENSHURE( bInUse, "OInterfaceContainerHelper not in use" );
    if( bInUse )
    {
        // this should be the worst case. If a iterator is active
        // and a new Listener is added.
        if( bIsList )
            pData = new Sequence< Reference< XInterface > >( *(Sequence< Reference< XInterface > >*)pData );
        else if( pData )
            ((XInterface*)pData)->acquire();

        bInUse = sal_False;
    }
}

sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener )
{
    assert( rListener.is() );
    MutexGuard aGuard( rMutex );
    if( bInUse )
        copyAndResetInUse();

    if( bIsList )
    {
        sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength();
        realloc( *(Sequence< Reference< XInterface > >*)pData, nLen +1 );
        ((Sequence< Reference< XInterface > >*)pData)->getArray()[ nLen ] = rListener;
        return nLen +1;
    }
    else if( pData )
    {
        Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
        Reference<XInterface> * pArray = pSeq->getArray();
        pArray[0] = (XInterface *)pData;
        pArray[1] = rListener;
        ((XInterface *)pData)->release();
        pData = pSeq;
        bIsList = sal_True;
        return 2;
    }
    else
    {
        pData = rListener.get();
        if( rListener.is() )
            rListener->acquire();
        return 1;
    }
}

sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener )
{
    assert( rListener.is() );
    MutexGuard aGuard( rMutex );
    if( bInUse )
        copyAndResetInUse();

    if( bIsList )
    {
        const Reference<XInterface> * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray();
        sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength();
        sal_Int32 i;
        for( i = 0; i < nLen; i++ )
        {
            // It is not valid to compare the Pointer direkt, but is is is much
            // more faster.
            if( pL[i].get() == rListener.get() )
            {
                sequenceRemoveElementAt( *(Sequence< Reference< XInterface > >*)pData, i );
                break;
            }
        }

        if( i == nLen )
        {
            // interface not found, use the correct compare method
            for( i = 0; i < nLen; i++ )
            {
                if( pL[i] == rListener )
                {
                    sequenceRemoveElementAt(*(Sequence< Reference< XInterface > >*)pData, i );
                    break;
                }
            }
        }

        if( ((Sequence< Reference< XInterface > >*)pData)->getLength() == 1 )
        {
            XInterface * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[0].get();
            pL->acquire();
            delete (Sequence< Reference< XInterface > >*)pData;
            pData = pL;
            bIsList = sal_False;
            return 1;
        }
        else
            return ((Sequence< Reference< XInterface > >*)pData)->getLength();
    }
    else if( Reference<XInterface>( (XInterface*)pData ) == rListener )
    {
        ((XInterface *)pData)->release();
        pData = 0;
    }
    return pData ? 1 : 0;
}

void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
{
    ClearableMutexGuard aGuard( rMutex );
    OInterfaceIteratorHelper aIt( *this );
    // Container freigeben, falls im disposing neue Eintrge kommen
    OSL_ENSHURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
    if( !bIsList && pData )
        ((XInterface *)pData)->release();
    // set the member to null, the iterator delete the values
    pData = NULL;
    bIsList = sal_False;
    bInUse = sal_False;
    aGuard.clear();
    while( aIt.hasMoreElements() )
    {
        try
        {
            Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
            if( xLst.is() )
                xLst->disposing( rEvt );
        }
        catch ( RuntimeException & )
        {
            // be robust, if e.g. a remote bridge has disposed already.
            // there is no way, to delegate the error to the caller :o(.
        }
    }
}

void OInterfaceContainerHelper::clear( )
{
    ClearableMutexGuard aGuard( rMutex );
    OInterfaceIteratorHelper aIt( *this );
    // Container freigeben, falls im disposing neue Eintrge kommen
    OSL_ENSHURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
    if( !bIsList && pData )
        ((XInterface *)pData)->release();
    // set the member to null, the iterator delete the values
    pData = 0;
    bIsList = sal_False;
    bInUse = sal_False;
    // release mutex before aIt destructor call
    aGuard.clear();
}

}

<|endoftext|>