<commit_before>/*
    Copyright (c) 2009 Kevin Ottens <ervin@kde.org>

    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.
*/

#include "ak_storagemodel.h"

#include <akonadi/attributefactory.h>
#include <akonadi/collection.h>
#include <akonadi/collectionstatistics.h>
#include <akonadi/entityfilterproxymodel.h>
#include <akonadi/entitytreemodel.h>
#include <akonadi/selectionproxymodel.h>
#include <akonadi/item.h>
#include <akonadi/itemmodifyjob.h>
#include <akonadi/kmime/messagefolderattribute.h>

#include <KDE/KCodecs>
#include <KDE/KLocale>

#include "messagelistview/akonadi/ak_storagemodel.h"
#include "messagelistview/core/messageitem.h"

#include <QtCore/QAbstractItemModel>
#include <QtGui/QItemSelectionModel>

using namespace Akonadi::MessageListView;
using namespace KMail::MessageListView;

StorageModel::StorageModel( QAbstractItemModel *model, QItemSelectionModel *selectionModel, QObject *parent )
  : Core::StorageModel( parent ), mModel( 0 ), mSelectionModel( selectionModel )
{
  AttributeFactory::registerAttribute<MessageFolderAttribute>();

  SelectionProxyModel *childrenFilter = new SelectionProxyModel( mSelectionModel, this );
  childrenFilter->setSourceModel( model );
  childrenFilter->setFilterBehavior( SelectionProxyModel::OnlySelectedChildren );

  EntityFilterProxyModel *itemFilter = new EntityFilterProxyModel( this );
  itemFilter->setSourceModel( childrenFilter );
  itemFilter->addMimeTypeExclusionFilter( Collection::mimeType() );
  itemFilter->addMimeTypeInclusionFilter( "message/rfc822" );
  itemFilter->setHeaderSet( EntityTreeModel::ItemListHeaders );

  mModel = itemFilter;

  // Custom/System colors
  KConfigGroup config( KSharedConfig::openConfig( "kmailrc" ), "Reader" );

  mColorNewMessage = QColor( "red" );
  mColorUnreadMessage = QColor( "blue" );
  mColorImportantMessage = QColor( 0x00, 0x7f, 0x00 );
  mColorToDoMessage = QColor( 0x00, 0x98, 0x00 );

  if ( !config.readEntry( "defaultColors", true ) ) {
    mColorNewMessage = config.readEntry( "NewMessage", mColorNewMessage );
    mColorUnreadMessage = config.readEntry( "UnreadMessage", mColorUnreadMessage );
    mColorImportantMessage = config.readEntry( "FlagMessage", mColorImportantMessage );
    mColorToDoMessage = config.readEntry( "TodoMessage", mColorToDoMessage );
  }

  connect( mModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
           this, SLOT(onSourceDataChanged(QModelIndex, QModelIndex)) );

  connect( mModel, SIGNAL(layoutAboutToBeChanged()),
           this, SIGNAL(layoutAboutToBeChanged()) );
  connect( mModel, SIGNAL(layoutChanged()),
           this, SIGNAL(layoutChanged()) );
  connect( mModel, SIGNAL(modelAboutToBeReset()),
           this, SIGNAL(modelAboutToBeReset()) );
  connect( mModel, SIGNAL(modelReset()),
           this, SIGNAL(modelReset()) );

  //Here we assume we'll always get QModelIndex() in the parameters
  connect( mModel, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)),
           this, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)) );
  connect( mModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
           this, SIGNAL(rowsInserted(QModelIndex, int, int)) );
  connect( mModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
           this, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)) );
  connect( mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
           this, SIGNAL(rowsRemoved(QModelIndex, int, int)) );

  connect( mSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
           this, SLOT(onSelectionChanged()) );
}

StorageModel::~StorageModel()
{
}

QString StorageModel::id() const
{
  // Just use the pointer value
  return "0x"+QString::number(reinterpret_cast<qint64>(this), 16);
}

bool StorageModel::containsOutboundMessages() const
{
  QModelIndexList indexes = mSelectionModel->selectedRows();

  foreach ( const QModelIndex &index, indexes ) {
    Collection c = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
    if ( c.isValid()
      && c.hasAttribute<MessageFolderAttribute>()
      && c.attribute<MessageFolderAttribute>()->isOutboundFolder() ) {
      return true;
    }
  }

  return false;
}

int StorageModel::initialUnreadRowCountGuess() const
{
  QModelIndexList indexes = mSelectionModel->selectedRows();

  int unreadCount = 0;

  foreach ( const QModelIndex &index, indexes ) {
    Collection c = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
    if ( c.isValid() ) {
      unreadCount+= c.statistics().unreadCount();
    }
  }

  return unreadCount;
}

bool StorageModel::initializeMessageItem( KMail::MessageListView::Core::MessageItem *mi,
                                          int row, bool bUseReceiver ) const
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();
  const MessagePtr mail = messageForRow( row );
  if ( !mail ) return false;

  QString sender = mail->from()->asUnicodeString();
  QString receiver = mail->to()->asUnicodeString();

  // Static for speed reasons
  static const QString noSubject = i18nc( "displayed as subject when the subject of a mail is empty", "No Subject" );
  static const QString unknown( i18nc( "displayed when a mail has unknown sender, receiver or date", "Unknown" ) );

  if ( sender.isEmpty() ) {
    sender = unknown;
  }
  if ( receiver.isEmpty() ) {
    receiver = unknown;
  }

  mi->initialSetup( mail->date()->dateTime().toTime_t(),
                    item.size(),
                    sender, receiver,
                    bUseReceiver ? receiver : sender );

  mi->setUniqueId( item.id() );

  QString subject = mail->subject()->asUnicodeString();
  if ( subject.isEmpty() ) {
    subject = '(' + noSubject + ')';
  }

  mi->setSubject( subject );

  updateMessageItemData( mi, row );

  return true;
}

static QString md5Encode( const QString &str )
{
  if ( str.trimmed().isEmpty() ) return QString();

  KMD5 md5( str.trimmed().toUtf8() );
  static const int Base64EncodedMD5Len = 22;
  return md5.base64Digest().left( Base64EncodedMD5Len );
}

void StorageModel::fillMessageItemThreadingData( KMail::MessageListView::Core::MessageItem *mi,
                                                 int row, ThreadingDataSubset subset ) const
{
  const MessagePtr mail = messageForRow( row );
  Q_ASSERT( mail ); // We ASSUME that initializeMessageItem has been called successfully...

  switch ( subset ) {
  case PerfectThreadingReferencesAndSubject:
    mi->setStrippedSubjectMD5( md5Encode( mail->subject()->stripOffPrefixes() ) );
    mi->setSubjectIsPrefixed( mail->subject()->asUnicodeString()!=mail->subject()->stripOffPrefixes() );
    // fall through
  case PerfectThreadingPlusReferences:
    if ( !mail->references()->identifiers().isEmpty() ) {
      mi->setReferencesIdMD5( md5Encode( mail->references()->identifiers().first() ) );
    }
    // fall through
  case PerfectThreadingOnly:
    mi->setMessageIdMD5( md5Encode( mail->messageID()->asUnicodeString() ) );
    if ( !mail->inReplyTo()->identifiers().isEmpty() ) {
      mi->setInReplyToIdMD5( md5Encode( mail->inReplyTo()->identifiers().first() ) );
    }
    break;
  default:
    Q_ASSERT( false ); // should never happen
    break;
  }
}

void StorageModel::updateMessageItemData( KMail::MessageListView::Core::MessageItem *mi,
                                          int row ) const
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();
  const MessagePtr mail = messageForRow( row );
  Q_ASSERT( mail );

  KPIM::MessageStatus stat;
  stat.setStatusFromFlags( item.flags() );

  mi->setStatus( stat );

  mi->setEncryptionState( Core::MessageItem::EncryptionStateUnknown );
  if ( mail->contentType()->isSubtype( "encrypted" )
    || mail->contentType()->isSubtype( "pgp-encrypted" )
    || mail->contentType()->isSubtype( "pkcs7-mime" ) ) {
      mi->setEncryptionState( Core::MessageItem::FullyEncrypted );
  } else if ( mail->mainBodyPart( "multipart/encrypted" )
           || mail->mainBodyPart( "application/pgp-encrypted" )
           || mail->mainBodyPart( "application/pkcs7-mime" ) ) {
    mi->setEncryptionState( Core::MessageItem::PartiallyEncrypted );
  }

  mi->setSignatureState( Core::MessageItem::SignatureStateUnknown );
  if ( mail->contentType()->isSubtype( "signed" )
    || mail->contentType()->isSubtype( "pgp-signature" )
    || mail->contentType()->isSubtype( "pkcs7-signature" )
    || mail->contentType()->isSubtype( "x-pkcs7-signature" ) ) {
      mi->setSignatureState( Core::MessageItem::FullySigned );
  } else if ( mail->mainBodyPart( "multipart/signed" )
           || mail->mainBodyPart( "application/pgp-signature" )
           || mail->mainBodyPart( "application/pkcs7-signature" )
           || mail->mainBodyPart( "application/x-pkcs7-signature" ) ) {
    mi->setSignatureState( Core::MessageItem::PartiallySigned );
  }

  QColor clr;
  QColor backClr;
#if 0
  //FIXME: Missing tag handling, nepomuk based?
  QList< Core::MessageItem::Tag * > * tagList;
  tagList = fillTagList( msg, clr, backClr );
  mi->setTagList( tagList );
#endif

  if ( !clr.isValid() ) {
    if ( stat.isNew() ) {
      clr = mColorNewMessage;
    } else if ( stat.isUnread() ) {
      clr = mColorUnreadMessage;
    } else if ( stat.isImportant() ) {
      clr = mColorImportantMessage;
    } else if ( stat.isToAct() ) {
      clr = mColorToDoMessage;
    }
  }

  if ( clr.isValid() ) {
    mi->setTextColor( clr );
  }
  if ( backClr.isValid() ) {
    mi->setBackgroundColor( backClr );
  }
}

void StorageModel::setMessageItemStatus( KMail::MessageListView::Core::MessageItem *mi,
                                         int row, const KPIM::MessageStatus &status )
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();
  item.setFlags( status.getStatusFlags() );
  new Akonadi::ItemModifyJob( item, this );
}

QVariant StorageModel::data( const QModelIndex &index, int role ) const
{
  // We don't provide an implementation for data() in No-Akonadi-KMail.
  // This is because StorageModel must be a wrapper anyway (because columns
  // must be re-mapped and functions not available in a QAbstractItemModel
  // are strictly needed. So when porting to Akonadi this class will
  // either wrap or subclass the MessageModel and implement initializeMessageItem()
  // with appropriate calls to data(). And for No-Akonadi-KMail we still have
  // a somewhat efficient implementation.

  Q_UNUSED( index );
  Q_UNUSED( role );

  return QVariant();
}

int StorageModel::columnCount( const QModelIndex &parent ) const
{
  if ( !parent.isValid() )
    return 1;
  return 0; // this model is flat.
}

QModelIndex StorageModel::index( int row, int column, const QModelIndex &parent ) const
{
  if ( !parent.isValid() )
    return createIndex( row, column, 0 );

  return QModelIndex(); // this model is flat.
}

QModelIndex StorageModel::parent( const QModelIndex &index ) const
{
  Q_UNUSED( index );
  return QModelIndex(); // this model is flat.
}

int StorageModel::rowCount( const QModelIndex &parent ) const
{
  if ( !parent.isValid() )
    return mModel->rowCount();
  return 0; // this model is flat.
}

void StorageModel::prepareForScan()
{

}

void StorageModel::onSourceDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight )
{
  emit dataChanged( index( topLeft.row(), 0 ),
                    index( bottomRight.row(), 0 ) );
}

void StorageModel::onSelectionChanged()
{
  emit headerDataChanged( Qt::Horizontal, 0, columnCount()-1 );
}

MessagePtr StorageModel::messageForRow( int row ) const
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();

  if ( !item.hasPayload<MessagePtr>() ) {
    kWarning() << "Not a message" << item.id() << item.remoteId() << item.mimeType();
    return MessagePtr();
  }

  return item.payload<MessagePtr>();
}
<commit_msg>As advised by Thomas change the id depending on the selection.<commit_after>/*
    Copyright (c) 2009 Kevin Ottens <ervin@kde.org>

    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.
*/

#include "ak_storagemodel.h"

#include <akonadi/attributefactory.h>
#include <akonadi/collection.h>
#include <akonadi/collectionstatistics.h>
#include <akonadi/entityfilterproxymodel.h>
#include <akonadi/entitytreemodel.h>
#include <akonadi/selectionproxymodel.h>
#include <akonadi/item.h>
#include <akonadi/itemmodifyjob.h>
#include <akonadi/kmime/messagefolderattribute.h>

#include <KDE/KCodecs>
#include <KDE/KLocale>

#include "messagelistview/akonadi/ak_storagemodel.h"
#include "messagelistview/core/messageitem.h"

#include <QtCore/QAbstractItemModel>
#include <QtGui/QItemSelectionModel>

using namespace Akonadi::MessageListView;
using namespace KMail::MessageListView;

StorageModel::StorageModel( QAbstractItemModel *model, QItemSelectionModel *selectionModel, QObject *parent )
  : Core::StorageModel( parent ), mModel( 0 ), mSelectionModel( selectionModel )
{
  AttributeFactory::registerAttribute<MessageFolderAttribute>();

  SelectionProxyModel *childrenFilter = new SelectionProxyModel( mSelectionModel, this );
  childrenFilter->setSourceModel( model );
  childrenFilter->setFilterBehavior( SelectionProxyModel::OnlySelectedChildren );

  EntityFilterProxyModel *itemFilter = new EntityFilterProxyModel( this );
  itemFilter->setSourceModel( childrenFilter );
  itemFilter->addMimeTypeExclusionFilter( Collection::mimeType() );
  itemFilter->addMimeTypeInclusionFilter( "message/rfc822" );
  itemFilter->setHeaderSet( EntityTreeModel::ItemListHeaders );

  mModel = itemFilter;

  // Custom/System colors
  KConfigGroup config( KSharedConfig::openConfig( "kmailrc" ), "Reader" );

  mColorNewMessage = QColor( "red" );
  mColorUnreadMessage = QColor( "blue" );
  mColorImportantMessage = QColor( 0x00, 0x7f, 0x00 );
  mColorToDoMessage = QColor( 0x00, 0x98, 0x00 );

  if ( !config.readEntry( "defaultColors", true ) ) {
    mColorNewMessage = config.readEntry( "NewMessage", mColorNewMessage );
    mColorUnreadMessage = config.readEntry( "UnreadMessage", mColorUnreadMessage );
    mColorImportantMessage = config.readEntry( "FlagMessage", mColorImportantMessage );
    mColorToDoMessage = config.readEntry( "TodoMessage", mColorToDoMessage );
  }

  connect( mModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
           this, SLOT(onSourceDataChanged(QModelIndex, QModelIndex)) );

  connect( mModel, SIGNAL(layoutAboutToBeChanged()),
           this, SIGNAL(layoutAboutToBeChanged()) );
  connect( mModel, SIGNAL(layoutChanged()),
           this, SIGNAL(layoutChanged()) );
  connect( mModel, SIGNAL(modelAboutToBeReset()),
           this, SIGNAL(modelAboutToBeReset()) );
  connect( mModel, SIGNAL(modelReset()),
           this, SIGNAL(modelReset()) );

  //Here we assume we'll always get QModelIndex() in the parameters
  connect( mModel, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)),
           this, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)) );
  connect( mModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
           this, SIGNAL(rowsInserted(QModelIndex, int, int)) );
  connect( mModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
           this, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)) );
  connect( mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
           this, SIGNAL(rowsRemoved(QModelIndex, int, int)) );

  connect( mSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
           this, SLOT(onSelectionChanged()) );
}

StorageModel::~StorageModel()
{
}

QString StorageModel::id() const
{
  QStringList ids;
  QModelIndexList indexes = mSelectionModel->selectedRows();

  foreach ( const QModelIndex &index, indexes ) {
    Collection c = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
    if ( c.isValid() ) {
      ids << QString::number( c.id() );
    }
  }

  ids.sort();
  return ids.join(":");
}

bool StorageModel::containsOutboundMessages() const
{
  QModelIndexList indexes = mSelectionModel->selectedRows();

  foreach ( const QModelIndex &index, indexes ) {
    Collection c = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
    if ( c.isValid()
      && c.hasAttribute<MessageFolderAttribute>()
      && c.attribute<MessageFolderAttribute>()->isOutboundFolder() ) {
      return true;
    }
  }

  return false;
}

int StorageModel::initialUnreadRowCountGuess() const
{
  QModelIndexList indexes = mSelectionModel->selectedRows();

  int unreadCount = 0;

  foreach ( const QModelIndex &index, indexes ) {
    Collection c = index.data( EntityTreeModel::CollectionRole ).value<Collection>();
    if ( c.isValid() ) {
      unreadCount+= c.statistics().unreadCount();
    }
  }

  return unreadCount;
}

bool StorageModel::initializeMessageItem( KMail::MessageListView::Core::MessageItem *mi,
                                          int row, bool bUseReceiver ) const
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();
  const MessagePtr mail = messageForRow( row );
  if ( !mail ) return false;

  QString sender = mail->from()->asUnicodeString();
  QString receiver = mail->to()->asUnicodeString();

  // Static for speed reasons
  static const QString noSubject = i18nc( "displayed as subject when the subject of a mail is empty", "No Subject" );
  static const QString unknown( i18nc( "displayed when a mail has unknown sender, receiver or date", "Unknown" ) );

  if ( sender.isEmpty() ) {
    sender = unknown;
  }
  if ( receiver.isEmpty() ) {
    receiver = unknown;
  }

  mi->initialSetup( mail->date()->dateTime().toTime_t(),
                    item.size(),
                    sender, receiver,
                    bUseReceiver ? receiver : sender );

  mi->setUniqueId( item.id() );

  QString subject = mail->subject()->asUnicodeString();
  if ( subject.isEmpty() ) {
    subject = '(' + noSubject + ')';
  }

  mi->setSubject( subject );

  updateMessageItemData( mi, row );

  return true;
}

static QString md5Encode( const QString &str )
{
  if ( str.trimmed().isEmpty() ) return QString();

  KMD5 md5( str.trimmed().toUtf8() );
  static const int Base64EncodedMD5Len = 22;
  return md5.base64Digest().left( Base64EncodedMD5Len );
}

void StorageModel::fillMessageItemThreadingData( KMail::MessageListView::Core::MessageItem *mi,
                                                 int row, ThreadingDataSubset subset ) const
{
  const MessagePtr mail = messageForRow( row );
  Q_ASSERT( mail ); // We ASSUME that initializeMessageItem has been called successfully...

  switch ( subset ) {
  case PerfectThreadingReferencesAndSubject:
    mi->setStrippedSubjectMD5( md5Encode( mail->subject()->stripOffPrefixes() ) );
    mi->setSubjectIsPrefixed( mail->subject()->asUnicodeString()!=mail->subject()->stripOffPrefixes() );
    // fall through
  case PerfectThreadingPlusReferences:
    if ( !mail->references()->identifiers().isEmpty() ) {
      mi->setReferencesIdMD5( md5Encode( mail->references()->identifiers().first() ) );
    }
    // fall through
  case PerfectThreadingOnly:
    mi->setMessageIdMD5( md5Encode( mail->messageID()->asUnicodeString() ) );
    if ( !mail->inReplyTo()->identifiers().isEmpty() ) {
      mi->setInReplyToIdMD5( md5Encode( mail->inReplyTo()->identifiers().first() ) );
    }
    break;
  default:
    Q_ASSERT( false ); // should never happen
    break;
  }
}

void StorageModel::updateMessageItemData( KMail::MessageListView::Core::MessageItem *mi,
                                          int row ) const
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();
  const MessagePtr mail = messageForRow( row );
  Q_ASSERT( mail );

  KPIM::MessageStatus stat;
  stat.setStatusFromFlags( item.flags() );

  mi->setStatus( stat );

  mi->setEncryptionState( Core::MessageItem::EncryptionStateUnknown );
  if ( mail->contentType()->isSubtype( "encrypted" )
    || mail->contentType()->isSubtype( "pgp-encrypted" )
    || mail->contentType()->isSubtype( "pkcs7-mime" ) ) {
      mi->setEncryptionState( Core::MessageItem::FullyEncrypted );
  } else if ( mail->mainBodyPart( "multipart/encrypted" )
           || mail->mainBodyPart( "application/pgp-encrypted" )
           || mail->mainBodyPart( "application/pkcs7-mime" ) ) {
    mi->setEncryptionState( Core::MessageItem::PartiallyEncrypted );
  }

  mi->setSignatureState( Core::MessageItem::SignatureStateUnknown );
  if ( mail->contentType()->isSubtype( "signed" )
    || mail->contentType()->isSubtype( "pgp-signature" )
    || mail->contentType()->isSubtype( "pkcs7-signature" )
    || mail->contentType()->isSubtype( "x-pkcs7-signature" ) ) {
      mi->setSignatureState( Core::MessageItem::FullySigned );
  } else if ( mail->mainBodyPart( "multipart/signed" )
           || mail->mainBodyPart( "application/pgp-signature" )
           || mail->mainBodyPart( "application/pkcs7-signature" )
           || mail->mainBodyPart( "application/x-pkcs7-signature" ) ) {
    mi->setSignatureState( Core::MessageItem::PartiallySigned );
  }

  QColor clr;
  QColor backClr;
#if 0
  //FIXME: Missing tag handling, nepomuk based?
  QList< Core::MessageItem::Tag * > * tagList;
  tagList = fillTagList( msg, clr, backClr );
  mi->setTagList( tagList );
#endif

  if ( !clr.isValid() ) {
    if ( stat.isNew() ) {
      clr = mColorNewMessage;
    } else if ( stat.isUnread() ) {
      clr = mColorUnreadMessage;
    } else if ( stat.isImportant() ) {
      clr = mColorImportantMessage;
    } else if ( stat.isToAct() ) {
      clr = mColorToDoMessage;
    }
  }

  if ( clr.isValid() ) {
    mi->setTextColor( clr );
  }
  if ( backClr.isValid() ) {
    mi->setBackgroundColor( backClr );
  }
}

void StorageModel::setMessageItemStatus( KMail::MessageListView::Core::MessageItem *mi,
                                         int row, const KPIM::MessageStatus &status )
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();
  item.setFlags( status.getStatusFlags() );
  new Akonadi::ItemModifyJob( item, this );
}

QVariant StorageModel::data( const QModelIndex &index, int role ) const
{
  // We don't provide an implementation for data() in No-Akonadi-KMail.
  // This is because StorageModel must be a wrapper anyway (because columns
  // must be re-mapped and functions not available in a QAbstractItemModel
  // are strictly needed. So when porting to Akonadi this class will
  // either wrap or subclass the MessageModel and implement initializeMessageItem()
  // with appropriate calls to data(). And for No-Akonadi-KMail we still have
  // a somewhat efficient implementation.

  Q_UNUSED( index );
  Q_UNUSED( role );

  return QVariant();
}

int StorageModel::columnCount( const QModelIndex &parent ) const
{
  if ( !parent.isValid() )
    return 1;
  return 0; // this model is flat.
}

QModelIndex StorageModel::index( int row, int column, const QModelIndex &parent ) const
{
  if ( !parent.isValid() )
    return createIndex( row, column, 0 );

  return QModelIndex(); // this model is flat.
}

QModelIndex StorageModel::parent( const QModelIndex &index ) const
{
  Q_UNUSED( index );
  return QModelIndex(); // this model is flat.
}

int StorageModel::rowCount( const QModelIndex &parent ) const
{
  if ( !parent.isValid() )
    return mModel->rowCount();
  return 0; // this model is flat.
}

void StorageModel::prepareForScan()
{

}

void StorageModel::onSourceDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight )
{
  emit dataChanged( index( topLeft.row(), 0 ),
                    index( bottomRight.row(), 0 ) );
}

void StorageModel::onSelectionChanged()
{
  emit headerDataChanged( Qt::Horizontal, 0, columnCount()-1 );
}

MessagePtr StorageModel::messageForRow( int row ) const
{
  Item item = mModel->data( mModel->index( row, 0 ), EntityTreeModel::ItemRole ).value<Item>();

  if ( !item.hasPayload<MessagePtr>() ) {
    kWarning() << "Not a message" << item.id() << item.remoteId() << item.mimeType();
    return MessagePtr();
  }

  return item.payload<MessagePtr>();
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <Common/Colorful.hh>
#include <Lex/Lexer.hh>
#include <Object/StringObject.hh>
#include <Core/TadpoleVM.hh>
#include <Compiler/Parser.hh>

namespace Tadpole::Compiler {

GlobalParser::GlobalParser(Core::TadpoleVM& vm, Lex::Lexer& lex) noexcept
  : vm_(vm), lex_(lex) {
}

void GlobalParser::iter_objects(Object::ObjectVisitor&& visitor) {
  // TODO:
}

Object::FunctionObject* GlobalParser::compile() {
  // TODO:
  return nullptr;
}

const ParseRule& GlobalParser::get_rule(Lex::TokenKind kind) const noexcept {
  static const ParseRule _rules[] = {
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(LPAREN, "(")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(RPAREN, ")")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(LBRACE, "{")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(RBRACE, "}")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(COMMA, ",")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(MINUS, "-")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(PLUS, "+")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(SEMI, ";")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(SLASH, "/")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(STAR, "*")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(EQ, "=")

    {nullptr, nullptr, Precedence::NONE}, // TOKEN(IDENTIFIER, "Identifier")
    {nullptr, nullptr, Precedence::NONE}, // TOKEN(NUMERIC, "Numeric")
    {nullptr, nullptr, Precedence::NONE}, // TOKEN(STRING, "String")

    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(FALSE, "false")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(FN, "fn")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(NIL, "nil")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(TRUE, "true")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(VAR, "var")

    {nullptr, nullptr, Precedence::NONE}, // TOKEN(EOF, "Eof")
    {nullptr, nullptr, Precedence::NONE}, // TOKEN(ERR, "Error")
  };

  return _rules[Common::as_type<int>(kind)];
}

void GlobalParser::error_at(const Lex::Token& tok, const str_t& msg) noexcept {
  if (panic_mode_)
    return;
  panic_mode_ = true;

  std::cerr
    << Common::Colorful::fg::red
    << "SyntaxError:" << std::endl
    << "  [LINE: " << tok.lineno() << "] ERROR ";
  if (tok.kind() == Lex::TokenKind::TK_EOF)
    std::cerr << "at end ";
  else if (tok.kind() == Lex::TokenKind::TK_ERR)
    TADPOLE_UNUSED(0);
  else
    std::cerr << "at `" << tok.literal() << "` ";
  std::cerr << ": " << msg << Common::Colorful::reset << std::endl;
}

void GlobalParser::advance() {
  prev_ = curr_;

  for (;;) {
    curr_ = lex_.next_token();
    if (!check(Lex::TokenKind::TK_ERR))
      break;

    error_at_current(curr_.as_string());
  }
}

void GlobalParser::consume(Lex::TokenKind kind, const str_t& msg) {
  if (check(kind))
    advance();
  else
    error_at_current(msg);
}

bool GlobalParser::match(Lex::TokenKind kind) {
  if (check(kind)) {
    advance();
    return true;
  }
  return false;
}

void GlobalParser::init_compiler(FunctionCompiler* compiler, int scope_depth, FunctionType fn_type) {
  Object::StringObject* fn_name{};
  if (fn_type == FunctionType::FUNCTION)
    fn_name = Object::StringObject::create(prev_.as_string());

  compiler->set_compiler(
      curr_compiler_,
      Object::FunctionObject::create(fn_name),
      fn_type,
      scope_depth);
  curr_compiler_ = compiler;

  curr_compiler_->append_local({Lex::Token::make(""), curr_compiler_->scope_depth(), false});
}

Object::FunctionObject* GlobalParser::finish_compiler() {
  emit_return();

  Object::FunctionObject* fn = curr_compiler_->fn();
#if defined(_TADPOLE_DEBUG_VM)
  if (!had_error_)
    curr_chunk()->dis(fn->name_asstr());
#endif

  curr_compiler_ = curr_compiler_->enclosing();
  return fn;
}

void GlobalParser::enter_scope() {
  curr_compiler_->enter_scope();
}

void GlobalParser::leave_scope() {
  curr_compiler_->leave_scope([this](const LocalVar& var) {
        emit_byte(var.is_upvalue ? Core::Code::CLOSE_UPVALUE : Core::Code::POP);
      });
}

u8_t GlobalParser::identifier_constant(const Lex::Token& name) noexcept {
  return curr_chunk()->add_constant(Object::StringObject::create(name.as_string()));
}

u8_t GlobalParser::parse_variable(const str_t& msg) {
  consume(Lex::TokenKind::TK_IDENTIFIER, msg);

  curr_compiler_->declare_localvar(prev_, [this](const str_t& m) { error(m); });
  if (curr_compiler_->scope_depth() > 0)
    return 0;
  return identifier_constant(prev_);
}

void GlobalParser::mark_initialized() {
  if (curr_compiler_->scope_depth() == 0)
    return;
  curr_compiler_->peek_local().depth = curr_compiler_->scope_depth();
}

void GlobalParser::define_global(u8_t global) {
  if (curr_compiler_->scope_depth() > 0) {
    mark_initialized();
    return;
  }
  emit_bytes(Core::Code::DEF_GLOBAL, global);
}

u8_t GlobalParser::arguments() {
  u8_t nargs = 0;
  if (!check(Lex::TokenKind::TK_RPAREN)) {
    do {
      expression();
      ++nargs;

      if (nargs > kMaxArgs)
        error(Common::from_fmt("cannot have more than `%d` arguments", kMaxArgs));
    } while (match(Lex::TokenKind::TK_COMMA));
  }
  consume(Lex::TokenKind::TK_RPAREN, "expect `)` after function arguments");

  return nargs;
}

void GlobalParser::named_variable(const Lex::Token& name, bool can_assign) {
  // TODO:
}

void GlobalParser::parse_precedence(Precedence precedence) {
  // TODO:
}

void GlobalParser::binary(bool can_assign) {}
void GlobalParser::call(bool can_assign) {}
void GlobalParser::grouping(bool can_assign) {}
void GlobalParser::literal(bool can_assign) {}
void GlobalParser::variable(bool can_assign) {}
void GlobalParser::numeric(bool can_assign) {}
void GlobalParser::string(bool can_assign) {}

void GlobalParser::block() {}
void GlobalParser::function(FunctionType fn_type) {}
void GlobalParser::synchronize() {}
void GlobalParser::expression() {}
void GlobalParser::declaration() {}
void GlobalParser::statement() {}
void GlobalParser::fn_decl() {}
void GlobalParser::var_decl() {}
void GlobalParser::expr_stmt() {}

}
<commit_msg>:construction: chore(parser): add named variable of parser for tadpole<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <Common/Colorful.hh>
#include <Lex/Lexer.hh>
#include <Object/StringObject.hh>
#include <Core/TadpoleVM.hh>
#include <Compiler/Parser.hh>

namespace Tadpole::Compiler {

GlobalParser::GlobalParser(Core::TadpoleVM& vm, Lex::Lexer& lex) noexcept
  : vm_(vm), lex_(lex) {
}

void GlobalParser::iter_objects(Object::ObjectVisitor&& visitor) {
  // TODO:
}

Object::FunctionObject* GlobalParser::compile() {
  // TODO:
  return nullptr;
}

const ParseRule& GlobalParser::get_rule(Lex::TokenKind kind) const noexcept {
  static const ParseRule _rules[] = {
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(LPAREN, "(")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(RPAREN, ")")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(LBRACE, "{")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(RBRACE, "}")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(COMMA, ",")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(MINUS, "-")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(PLUS, "+")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(SEMI, ";")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(SLASH, "/")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(STAR, "*")
    {nullptr, nullptr, Precedence::NONE}, // PUNCTUATOR(EQ, "=")

    {nullptr, nullptr, Precedence::NONE}, // TOKEN(IDENTIFIER, "Identifier")
    {nullptr, nullptr, Precedence::NONE}, // TOKEN(NUMERIC, "Numeric")
    {nullptr, nullptr, Precedence::NONE}, // TOKEN(STRING, "String")

    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(FALSE, "false")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(FN, "fn")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(NIL, "nil")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(TRUE, "true")
    {nullptr, nullptr, Precedence::NONE}, // KEYWORD(VAR, "var")

    {nullptr, nullptr, Precedence::NONE}, // TOKEN(EOF, "Eof")
    {nullptr, nullptr, Precedence::NONE}, // TOKEN(ERR, "Error")
  };

  return _rules[Common::as_type<int>(kind)];
}

void GlobalParser::error_at(const Lex::Token& tok, const str_t& msg) noexcept {
  if (panic_mode_)
    return;
  panic_mode_ = true;

  std::cerr
    << Common::Colorful::fg::red
    << "SyntaxError:" << std::endl
    << "  [LINE: " << tok.lineno() << "] ERROR ";
  if (tok.kind() == Lex::TokenKind::TK_EOF)
    std::cerr << "at end ";
  else if (tok.kind() == Lex::TokenKind::TK_ERR)
    TADPOLE_UNUSED(0);
  else
    std::cerr << "at `" << tok.literal() << "` ";
  std::cerr << ": " << msg << Common::Colorful::reset << std::endl;
}

void GlobalParser::advance() {
  prev_ = curr_;

  for (;;) {
    curr_ = lex_.next_token();
    if (!check(Lex::TokenKind::TK_ERR))
      break;

    error_at_current(curr_.as_string());
  }
}

void GlobalParser::consume(Lex::TokenKind kind, const str_t& msg) {
  if (check(kind))
    advance();
  else
    error_at_current(msg);
}

bool GlobalParser::match(Lex::TokenKind kind) {
  if (check(kind)) {
    advance();
    return true;
  }
  return false;
}

void GlobalParser::init_compiler(FunctionCompiler* compiler, int scope_depth, FunctionType fn_type) {
  Object::StringObject* fn_name{};
  if (fn_type == FunctionType::FUNCTION)
    fn_name = Object::StringObject::create(prev_.as_string());

  compiler->set_compiler(
      curr_compiler_,
      Object::FunctionObject::create(fn_name),
      fn_type,
      scope_depth);
  curr_compiler_ = compiler;

  curr_compiler_->append_local({Lex::Token::make(""), curr_compiler_->scope_depth(), false});
}

Object::FunctionObject* GlobalParser::finish_compiler() {
  emit_return();

  Object::FunctionObject* fn = curr_compiler_->fn();
#if defined(_TADPOLE_DEBUG_VM)
  if (!had_error_)
    curr_chunk()->dis(fn->name_asstr());
#endif

  curr_compiler_ = curr_compiler_->enclosing();
  return fn;
}

void GlobalParser::enter_scope() {
  curr_compiler_->enter_scope();
}

void GlobalParser::leave_scope() {
  curr_compiler_->leave_scope([this](const LocalVar& var) {
        emit_byte(var.is_upvalue ? Core::Code::CLOSE_UPVALUE : Core::Code::POP);
      });
}

u8_t GlobalParser::identifier_constant(const Lex::Token& name) noexcept {
  return curr_chunk()->add_constant(Object::StringObject::create(name.as_string()));
}

u8_t GlobalParser::parse_variable(const str_t& msg) {
  consume(Lex::TokenKind::TK_IDENTIFIER, msg);

  curr_compiler_->declare_localvar(prev_, [this](const str_t& m) { error(m); });
  if (curr_compiler_->scope_depth() > 0)
    return 0;
  return identifier_constant(prev_);
}

void GlobalParser::mark_initialized() {
  if (curr_compiler_->scope_depth() == 0)
    return;
  curr_compiler_->peek_local().depth = curr_compiler_->scope_depth();
}

void GlobalParser::define_global(u8_t global) {
  if (curr_compiler_->scope_depth() > 0) {
    mark_initialized();
    return;
  }
  emit_bytes(Core::Code::DEF_GLOBAL, global);
}

u8_t GlobalParser::arguments() {
  u8_t nargs = 0;
  if (!check(Lex::TokenKind::TK_RPAREN)) {
    do {
      expression();
      ++nargs;

      if (nargs > kMaxArgs)
        error(Common::from_fmt("cannot have more than `%d` arguments", kMaxArgs));
    } while (match(Lex::TokenKind::TK_COMMA));
  }
  consume(Lex::TokenKind::TK_RPAREN, "expect `)` after function arguments");

  return nargs;
}

void GlobalParser::named_variable(const Lex::Token& name, bool can_assign) {
  auto errfn = [this](const str_t& msg) { error(msg); };

  Core::Code getop, setop;
  int arg = curr_compiler_->resolve_local(name, errfn);
  if (arg != -1) {
    getop = Core::Code::GET_LOCAL;
    setop = Core::Code::SET_LOCAL;
  }
  else if (arg = curr_compiler_->resolve_upvalue(name, errfn); arg != -1) {
    getop = Core::Code::GET_UPVALUE;
    setop = Core::Code::SET_UPVALUE;
  }
  else {
    arg = identifier_constant(name);
    getop = Core::Code::GET_GLOBAL;
    setop = Core::Code::SET_GLOBAL;
  }

  if (can_assign && match(Lex::TokenKind::TK_EQ)) {
    expression();
    emit_bytes(setop, arg);
  }
  else {
    emit_bytes(getop, arg);
  }
}

void GlobalParser::parse_precedence(Precedence precedence) {
  // TODO:
}

void GlobalParser::binary(bool can_assign) {}
void GlobalParser::call(bool can_assign) {}
void GlobalParser::grouping(bool can_assign) {}
void GlobalParser::literal(bool can_assign) {}
void GlobalParser::variable(bool can_assign) {}
void GlobalParser::numeric(bool can_assign) {}
void GlobalParser::string(bool can_assign) {}

void GlobalParser::block() {}
void GlobalParser::function(FunctionType fn_type) {}
void GlobalParser::synchronize() {}
void GlobalParser::expression() {}
void GlobalParser::declaration() {}
void GlobalParser::statement() {}
void GlobalParser::fn_decl() {}
void GlobalParser::var_decl() {}
void GlobalParser::expr_stmt() {}

}
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/test_shell_delegate.h"
#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/views/app_list_view.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/events/test/event_generator.h"

namespace ash {

namespace {

const int kMinimalCenteredAppListMargin = 10;

}

// The parameter is true to test the centered app list, false for normal.
// (The test name ends in "/0" for normal, "/1" for centered.)
class AppListControllerTest : public test::AshTestBase,
                              public ::testing::WithParamInterface<bool> {
 public:
  AppListControllerTest();
  virtual ~AppListControllerTest();
  void SetUp() override;

  bool IsCentered() const;
};

AppListControllerTest::AppListControllerTest() {
}

AppListControllerTest::~AppListControllerTest() {
}

void AppListControllerTest::SetUp() {
  AshTestBase::SetUp();
  if (IsCentered()) {
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    command_line->AppendSwitch(app_list::switches::kEnableCenteredAppList);
  }
}

bool AppListControllerTest::IsCentered() const {
  return GetParam();
}

// Tests that app launcher hides when focus moves to a normal window.
TEST_P(AppListControllerTest, HideOnFocusOut) {
  Shell::GetInstance()->ShowAppList(NULL);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  wm::ActivateWindow(window.get());

  EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
}

// Tests that app launcher remains visible when focus is moved to a different
// window in kShellWindowId_AppListContainer.
TEST_P(AppListControllerTest, RemainVisibleWhenFocusingToApplistContainer) {
  Shell::GetInstance()->ShowAppList(NULL);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  aura::Window* applist_container = Shell::GetContainer(
      Shell::GetPrimaryRootWindow(), kShellWindowId_AppListContainer);
  scoped_ptr<aura::Window> window(
      aura::test::CreateTestWindowWithId(0, applist_container));
  wm::ActivateWindow(window.get());

  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
}

// Tests that clicking outside the app-list bubble closes it.
TEST_P(AppListControllerTest, ClickOutsideBubbleClosesBubble) {
  Shell* shell = Shell::GetInstance();
  shell->ShowAppList(NULL);

  aura::Window* app_window = shell->GetAppListWindow();
  ASSERT_TRUE(app_window);
  ui::test::EventGenerator generator(shell->GetPrimaryRootWindow(), app_window);
  // Click on the bubble itself. The bubble should remain visible.
  generator.ClickLeftButton();
  EXPECT_TRUE(shell->GetAppListTargetVisibility());

  // Click outside the bubble. This should close it.
  gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow();
  gfx::Point point_outside =
      gfx::Point(app_window_bounds.right(), app_window_bounds.y()) +
      gfx::Vector2d(10, 0);
  EXPECT_TRUE(shell->GetPrimaryRootWindow()->bounds().Contains(point_outside));
  generator.MoveMouseToInHost(point_outside);
  generator.ClickLeftButton();
  EXPECT_FALSE(shell->GetAppListTargetVisibility());
}

// Tests that clicking outside the app-list bubble closes it.
TEST_P(AppListControllerTest, TapOutsideBubbleClosesBubble) {
  Shell* shell = Shell::GetInstance();
  shell->ShowAppList(NULL);

  aura::Window* app_window = shell->GetAppListWindow();
  ASSERT_TRUE(app_window);
  gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow();

  ui::test::EventGenerator generator(shell->GetPrimaryRootWindow());
  // Click on the bubble itself. The bubble should remain visible.
  generator.GestureTapAt(app_window_bounds.CenterPoint());
  EXPECT_TRUE(shell->GetAppListTargetVisibility());

  // Click outside the bubble. This should close it.
  gfx::Point point_outside =
      gfx::Point(app_window_bounds.right(), app_window_bounds.y()) +
      gfx::Vector2d(10, 0);
  EXPECT_TRUE(shell->GetPrimaryRootWindow()->bounds().Contains(point_outside));
  generator.GestureTapAt(point_outside);
  EXPECT_FALSE(shell->GetAppListTargetVisibility());
}

// Tests opening the app launcher on a non-primary display, then deleting the
// display.
TEST_P(AppListControllerTest, NonPrimaryDisplay) {
  if (!SupportsMultipleDisplays())
    return;

  // Set up a screen with two displays (horizontally adjacent).
  UpdateDisplay("800x600,800x600");

  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2u, root_windows.size());
  aura::Window* secondary_window = root_windows[1];
  EXPECT_EQ("800,0 800x600", secondary_window->GetBoundsInScreen().ToString());

  Shell::GetInstance()->ShowAppList(secondary_window);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  // Remove the secondary display. Shouldn't crash (http://crbug.com/368990).
  UpdateDisplay("800x600");

  // Updating the displays should close the app list.
  EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
}

// Tests opening the app launcher on a tiny display that is too small to contain
// it.
TEST_P(AppListControllerTest, TinyDisplay) {
  // Don't test this for the non-centered app list case; it isn't designed for
  // small displays. The most common case of a small display --- when the
  // virtual keyboard is open --- switches into the centered app list mode, so
  // we just want to run this test in that case.
  if (!IsCentered())
    return;

  // UpdateDisplay is not supported in this case, so just skip the test.
  if (!SupportsHostWindowResize())
    return;

  // Set up a screen with a tiny display (height smaller than the app list).
  UpdateDisplay("400x300");

  Shell::GetInstance()->ShowAppList(NULL);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  // The top of the app list should be on-screen (even if the bottom is not).
  // We need to manually calculate the Y coordinate of the top of the app list
  // from the anchor (center) and height. There isn't a bounds rect that gives
  // the actual app list position (the widget bounds include the bubble border
  // which is much bigger than the actual app list size).
  app_list::AppListView* app_list = Shell::GetInstance()->GetAppListView();
  int app_list_view_top =
      app_list->anchor_rect().y() - app_list->bounds().height() / 2;
  EXPECT_GE(app_list_view_top, kMinimalCenteredAppListMargin);
}

INSTANTIATE_TEST_CASE_P(AppListControllerTestInstance,
                        AppListControllerTest,
                        ::testing::Bool());

}  // namespace ash
<commit_msg>AppListControllerTest: Increase the display size to 1024x768.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/test_shell_delegate.h"
#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/views/app_list_view.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/events/test/event_generator.h"

namespace ash {

namespace {

const int kMinimalCenteredAppListMargin = 10;

}

// The parameter is true to test the centered app list, false for normal.
// (The test name ends in "/0" for normal, "/1" for centered.)
class AppListControllerTest : public test::AshTestBase,
                              public ::testing::WithParamInterface<bool> {
 public:
  AppListControllerTest();
  virtual ~AppListControllerTest();
  void SetUp() override;

  bool IsCentered() const;
};

AppListControllerTest::AppListControllerTest() {
}

AppListControllerTest::~AppListControllerTest() {
}

void AppListControllerTest::SetUp() {
  AshTestBase::SetUp();
  if (IsCentered()) {
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    command_line->AppendSwitch(app_list::switches::kEnableCenteredAppList);
  }

  // Make the display big enough to hold the experimental app list.
  UpdateDisplay("1024x768");
}

bool AppListControllerTest::IsCentered() const {
  return GetParam();
}

// Tests that app launcher hides when focus moves to a normal window.
TEST_P(AppListControllerTest, HideOnFocusOut) {
  Shell::GetInstance()->ShowAppList(NULL);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  wm::ActivateWindow(window.get());

  EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
}

// Tests that app launcher remains visible when focus is moved to a different
// window in kShellWindowId_AppListContainer.
TEST_P(AppListControllerTest, RemainVisibleWhenFocusingToApplistContainer) {
  Shell::GetInstance()->ShowAppList(NULL);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  aura::Window* applist_container = Shell::GetContainer(
      Shell::GetPrimaryRootWindow(), kShellWindowId_AppListContainer);
  scoped_ptr<aura::Window> window(
      aura::test::CreateTestWindowWithId(0, applist_container));
  wm::ActivateWindow(window.get());

  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
}

// Tests that clicking outside the app-list bubble closes it.
TEST_P(AppListControllerTest, ClickOutsideBubbleClosesBubble) {
  Shell* shell = Shell::GetInstance();
  shell->ShowAppList(NULL);

  aura::Window* app_window = shell->GetAppListWindow();
  ASSERT_TRUE(app_window);
  ui::test::EventGenerator generator(shell->GetPrimaryRootWindow(), app_window);
  // Click on the bubble itself. The bubble should remain visible.
  generator.ClickLeftButton();
  EXPECT_TRUE(shell->GetAppListTargetVisibility());

  // Click outside the bubble. This should close it.
  gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow();
  gfx::Point point_outside =
      gfx::Point(app_window_bounds.right(), app_window_bounds.y()) +
      gfx::Vector2d(10, 0);
  EXPECT_TRUE(shell->GetPrimaryRootWindow()->bounds().Contains(point_outside));
  generator.MoveMouseToInHost(point_outside);
  generator.ClickLeftButton();
  EXPECT_FALSE(shell->GetAppListTargetVisibility());
}

// Tests that clicking outside the app-list bubble closes it.
TEST_P(AppListControllerTest, TapOutsideBubbleClosesBubble) {
  Shell* shell = Shell::GetInstance();
  shell->ShowAppList(NULL);

  aura::Window* app_window = shell->GetAppListWindow();
  ASSERT_TRUE(app_window);
  gfx::Rect app_window_bounds = app_window->GetBoundsInRootWindow();

  ui::test::EventGenerator generator(shell->GetPrimaryRootWindow());
  // Click on the bubble itself. The bubble should remain visible.
  generator.GestureTapAt(app_window_bounds.CenterPoint());
  EXPECT_TRUE(shell->GetAppListTargetVisibility());

  // Click outside the bubble. This should close it.
  gfx::Point point_outside =
      gfx::Point(app_window_bounds.right(), app_window_bounds.y()) +
      gfx::Vector2d(10, 0);
  EXPECT_TRUE(shell->GetPrimaryRootWindow()->bounds().Contains(point_outside));
  generator.GestureTapAt(point_outside);
  EXPECT_FALSE(shell->GetAppListTargetVisibility());
}

// Tests opening the app launcher on a non-primary display, then deleting the
// display.
TEST_P(AppListControllerTest, NonPrimaryDisplay) {
  if (!SupportsMultipleDisplays())
    return;

  // Set up a screen with two displays (horizontally adjacent).
  UpdateDisplay("1024x768,1024x768");

  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2u, root_windows.size());
  aura::Window* secondary_window = root_windows[1];
  EXPECT_EQ("1024,0 1024x768",
            secondary_window->GetBoundsInScreen().ToString());

  Shell::GetInstance()->ShowAppList(secondary_window);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  // Remove the secondary display. Shouldn't crash (http://crbug.com/368990).
  UpdateDisplay("1024x768");

  // Updating the displays should close the app list.
  EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
}

// Tests opening the app launcher on a tiny display that is too small to contain
// it.
TEST_P(AppListControllerTest, TinyDisplay) {
  // Don't test this for the non-centered app list case; it isn't designed for
  // small displays. The most common case of a small display --- when the
  // virtual keyboard is open --- switches into the centered app list mode, so
  // we just want to run this test in that case.
  if (!IsCentered())
    return;

  // UpdateDisplay is not supported in this case, so just skip the test.
  if (!SupportsHostWindowResize())
    return;

  // Set up a screen with a tiny display (height smaller than the app list).
  UpdateDisplay("400x300");

  Shell::GetInstance()->ShowAppList(NULL);
  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());

  // The top of the app list should be on-screen (even if the bottom is not).
  // We need to manually calculate the Y coordinate of the top of the app list
  // from the anchor (center) and height. There isn't a bounds rect that gives
  // the actual app list position (the widget bounds include the bubble border
  // which is much bigger than the actual app list size).
  app_list::AppListView* app_list = Shell::GetInstance()->GetAppListView();
  int app_list_view_top =
      app_list->anchor_rect().y() - app_list->bounds().height() / 2;
  EXPECT_GE(app_list_view_top, kMinimalCenteredAppListMargin);
}

INSTANTIATE_TEST_CASE_P(AppListControllerTestInstance,
                        AppListControllerTest,
                        ::testing::Bool());

}  // namespace ash
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: hfi_tag.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2003-06-10 11:34:03 $
 *
 *  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 <precomp.h>
#include "hfi_tag.hxx"

// NOT FULLY DEFINED SERVICES
#include <ary_i/d_token.hxx>
#include <ary/idl/i_ce.hxx>
#include <ary/idl/i_module.hxx>
#include <toolkit/out_tree.hxx>
#include "hfi_typetext.hxx"
#include "hi_ary.hxx"
#include "hi_env.hxx"
#include "hi_linkhelper.hxx"

inline void
HF_IdlTag::Enter_TextOut( Xml::Element & o_rText ) const
{
    aTextOut.Out().Enter(o_rText);
}

inline void
HF_IdlTag::Leave_TextOut() const
{
    aTextOut.Out().Leave();
}

inline void
HF_IdlTag::PutText_Out( const ary::info::DocuTex2 & i_rText ) const
{
    i_rText.DisplayAt( const_cast< HF_IdlDocuTextDisplay& >(aTextOut) );
}

HF_IdlTag::HF_IdlTag( Environment &                 io_rEnv,
                      const ary::idl::CodeEntity &  i_rScopeGivingCe )
    :   HtmlFactory_Idl( io_rEnv, 0 ),
        pTitleOut(0),
        aTextOut(io_rEnv, 0, i_rScopeGivingCe)
{
}

HF_IdlTag::~HF_IdlTag()
{
}

void
HF_IdlTag::Produce_byData( Xml::Element &              o_rTitle,
                           Xml::Element &              o_rText,
                           const ary::info::AtTag2 &   i_rTag ) const
{
    pTitleOut = &o_rTitle;
    Enter_TextOut(o_rText);
    i_rTag.DisplayAt( const_cast< HF_IdlTag& >(*this) );
    Leave_TextOut();
}

void
HF_IdlTag::Display_StdAtTag( const csi::dsapi::DT_StdAtTag & i_rTag )
{
    if ( i_rTag.Text().IsEmpty() )
        return;

    csv_assert( pTitleOut != 0 );
    *pTitleOut << i_rTag.Title();
    PutText_Out( i_rTag.Text() );
}

void
HF_IdlTag::Display_SeeAlsoAtTag( const csi::dsapi::DT_SeeAlsoAtTag & i_rTag )
{
    if ( i_rTag.Text().IsEmpty() )
        return;

    csv_assert( pTitleOut != 0 );
    *pTitleOut << "See also";

    HF_IdlTypeText aLinkText(Env(),aTextOut.CurOut(),true, &aTextOut.ScopeGivingCe());
    aLinkText.Produce_byData( i_rTag.LinkText() );

    aTextOut.CurOut() << new Html::LineBreak;
    PutText_Out( i_rTag.Text() );
}

void
HF_IdlTag::Display_ParameterAtTag( const csi::dsapi::DT_ParameterAtTag & i_rTag )
{
    csv_assert( pTitleOut != 0 );
    *pTitleOut
        << ( StreamLock(100)() << "Parameter " << i_rTag.Title() << c_str );
    PutText_Out( i_rTag.Text() );
}

void
HF_IdlTag::Display_SinceAtTag( const csi::dsapi::DT_SinceAtTag & i_rTag )
{
    if ( i_rTag.Text().IsEmpty() )
        return;

    csv_assert( pTitleOut != 0 );
    *pTitleOut << "Since version";
    PutText_Out( i_rTag.Text() );
}

//********************      HF_IdlShortDocu     *********************/

HF_IdlShortDocu::HF_IdlShortDocu( Environment &         io_rEnv,
                                  Xml::Element &        o_rOut )
    :   HtmlFactory_Idl( io_rEnv, &o_rOut )
{
}

HF_IdlShortDocu::~HF_IdlShortDocu()
{
}

void
HF_IdlShortDocu::Produce_byData( const ary::idl::CodeEntity & i_rCe )
{
    if (i_rCe.Docu() == 0)
        return;

    const ce_info &
        rDocu = *i_rCe.Docu();
    if ( rDocu.IsDeprecated() )
    {
        CurOut()
            >> *new Html::Bold
                << "[ DEPRECATED ]" << new Html::LineBreak;
    }
    if ( rDocu.IsOptional() )
    {
        CurOut()
            >> *new Html::Bold
                << "[ OPTIONAL ]" << new Html::LineBreak;
    }

    HF_IdlDocuTextDisplay
        aText( Env(), &CurOut(), i_rCe);
    rDocu.Short().DisplayAt(aText);
}

//********************      HF_IdlDocuTextDisplay       *********************/

HF_IdlDocuTextDisplay::HF_IdlDocuTextDisplay( Environment &                 io_rEnv,
                                              Xml::Element *                o_pOut,
                                              const ary::idl::CodeEntity &  i_rScopeGivingCe )
    :   HtmlFactory_Idl(io_rEnv, o_pOut),
        sScope(),
        sLinkToken(),
        bGatherLink(false),
        pScopeGivingCe(&i_rScopeGivingCe)
{
}

HF_IdlDocuTextDisplay::~HF_IdlDocuTextDisplay()
{
}

void
HF_IdlDocuTextDisplay::Display_TextToken( const csi::dsapi::DT_TextToken & i_rToken )
{
    if (bGatherLink)
    {
        if (sLinkToken.length() == 0)
        {
            sLinkToken = i_rToken.GetText();
            return;
        }
        else
        {
            Cerr() << "Error in documentation: Too many or too few tokens for a link in <member> or <type>." << Endl();
            Cerr() << "  Link won't be created, but all tokens shown plain." << Endl();
            Cerr() << "  \"" << sLinkToken << "\"";
            if ( pScopeGivingCe != 0 )
                Cerr() << " in " << pScopeGivingCe->LocalName();
            Cerr() << Endl();
            StopLinkGathering();
        }
    }   // endif (bGatherLink)

    CurOut() << " " << new Xml::XmlCode( i_rToken.GetText() );
}

void
HF_IdlDocuTextDisplay::Display_MupType( const csi::dsapi::DT_MupType & i_rToken )
{
    if (i_rToken.IsBegin())
    {
        StartLinkGathering(i_rToken.Scope());
    }
    else
    {
        if (bGatherLink)
        {
            CurOut()
                << " ";
            CreateTypeLink();
            StopLinkGathering();
        }
    }
}

void
HF_IdlDocuTextDisplay::Display_MupMember( const csi::dsapi::DT_MupMember & i_rToken )
{
    if (i_rToken.IsBegin())
    {
        StartLinkGathering(i_rToken.Scope());
    }
    else
    {
        if (bGatherLink)
        {
            CurOut()
                << " ";
            CreateMemberLink();
            StopLinkGathering();
        }
    }
}

void
HF_IdlDocuTextDisplay::Display_MupConst( const csi::dsapi::DT_MupConst & i_rToken )
{
    CurOut()
        << " "
        >> *new Html::Bold
           << i_rToken.GetText();
}

void
HF_IdlDocuTextDisplay::Display_Style( const csi::dsapi::DT_Style & i_rToken )
{
    CurOut() << new Xml::XmlCode( i_rToken.GetText() );
}

void
HF_IdlDocuTextDisplay::Display_EOL()
{
    CurOut() << "\n";
}

void
HF_IdlDocuTextDisplay::CreateTypeLink()
{
    if (strchr(sLinkToken,':') != 0)
    {
         Cerr() << "Warning: Qualified name (probably member) \""
                << sLinkToken
                << "\" found in <type> tag in "
               << Env().CurPageCe_AsText()
               << Endl();
        CurOut() << sLinkToken;
        return;
    }
    HF_IdlTypeText aLink(Env(), CurOut(), true, &ScopeGivingCe());
    aLink.Produce_LinkInDocu(sScope, sLinkToken, String::Null_());
}

void
HF_IdlDocuTextDisplay::CreateMemberLink()
{

    HF_IdlTypeText aLink(Env(), CurOut(), true, &ScopeGivingCe());

    const char *
        sSplit = strchr(sLinkToken,':');

    if (sSplit != 0)
    {
        String sCe(sLinkToken.c_str(), sSplit - sLinkToken.c_str());
        String sMember(sSplit+2);

        if (NOT sScope.empty() OR ScopeGivingCe().LocalName() != sCe )
            aLink.Produce_LinkInDocu(sScope, sCe, sMember);
        else
            aLink.Produce_LocalLinkInDocu(sMember);
    }
    else
    {
        aLink.Produce_LocalLinkInDocu(sLinkToken);
    }
}
<commit_msg>INTEGRATION: CWS adc8 (1.3.54); FILE MERGED 2004/07/02 14:44:34 np 1.3.54.1: #i30967#<commit_after>/*************************************************************************
 *
 *  $RCSfile: hfi_tag.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-12 15:29:59 $
 *
 *  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 <precomp.h>
#include "hfi_tag.hxx"

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_ce.hxx>
#include <ary/idl/i_module.hxx>
#include <ary_i/ci_text2.hxx>
#include <ary_i/d_token.hxx>
#include <toolkit/out_tree.hxx>
#include <adc_cl.hxx>
#include "hfi_typetext.hxx"
#include "hi_ary.hxx"
#include "hi_env.hxx"
#include "hi_linkhelper.hxx"

using ary::info::DocuTex2;

inline void
HF_IdlTag::Enter_TextOut( Xml::Element & o_rText ) const
{
    aTextOut.Out().Enter(o_rText);
}

inline void
HF_IdlTag::Leave_TextOut() const
{
    aTextOut.Out().Leave();
}

inline void
HF_IdlTag::PutText_Out( const ary::info::DocuTex2 & i_rText ) const
{
    i_rText.DisplayAt( const_cast< HF_IdlDocuTextDisplay& >(aTextOut) );
}

HF_IdlTag::HF_IdlTag( Environment &                 io_rEnv,
                      const ary::idl::CodeEntity &  i_rScopeGivingCe )
    :   HtmlFactory_Idl( io_rEnv, 0 ),
        pTitleOut(0),
        aTextOut(io_rEnv, 0, i_rScopeGivingCe)
{
}

HF_IdlTag::~HF_IdlTag()
{
}

void
HF_IdlTag::Produce_byData( Xml::Element &              o_rTitle,
                           Xml::Element &              o_rText,
                           const ary::info::AtTag2 &   i_rTag ) const
{
    pTitleOut = &o_rTitle;
    Enter_TextOut(o_rText);
    i_rTag.DisplayAt( const_cast< HF_IdlTag& >(*this) );
    Leave_TextOut();
}

void
HF_IdlTag::Display_StdAtTag( const csi::dsapi::DT_StdAtTag & i_rTag )
{
    if ( i_rTag.Text().IsEmpty() )
        return;

    csv_assert( pTitleOut != 0 );
    *pTitleOut << i_rTag.Title();
    PutText_Out( i_rTag.Text() );
}

void
HF_IdlTag::Display_SeeAlsoAtTag( const csi::dsapi::DT_SeeAlsoAtTag & i_rTag )
{
    if ( i_rTag.Text().IsEmpty() )
        return;

    csv_assert( pTitleOut != 0 );
    *pTitleOut << "See also";

    HF_IdlTypeText aLinkText(Env(),aTextOut.CurOut(),true, &aTextOut.ScopeGivingCe());
    aLinkText.Produce_byData( i_rTag.LinkText() );

    aTextOut.CurOut() << new Html::LineBreak;
    PutText_Out( i_rTag.Text() );
}

void
HF_IdlTag::Display_ParameterAtTag( const csi::dsapi::DT_ParameterAtTag & i_rTag )
{
    csv_assert( pTitleOut != 0 );
    *pTitleOut
        << ( StreamLock(100)() << "Parameter " << i_rTag.Title() << c_str );
    PutText_Out( i_rTag.Text() );
}

void
HF_IdlTag::Display_SinceAtTag( const csi::dsapi::DT_SinceAtTag & i_rTag )
{
    csv_assert(pTitleOut != 0);

    if ( i_rTag.Text().IsEmpty()
         OR
         NOT autodoc::CommandLine::Get_().Display_SinceTag() )
    {
         return;
    }

    // Transform the value of the @since tag into the text to be displayed.
    String sDisplay =
        autodoc::CommandLine::Get_().DisplayOf_SinceTagValue(
                                        i_rTag.Text().TextOfFirstToken() );
    if (sDisplay.empty())
        return;

    *pTitleOut << "Since ";
    DocuTex2 aHelp;
    aHelp.AddToken(* new csi::dsapi::DT_TextToken(sDisplay));
    PutText_Out(aHelp);
}

//********************      HF_IdlShortDocu     *********************/

HF_IdlShortDocu::HF_IdlShortDocu( Environment &         io_rEnv,
                                  Xml::Element &        o_rOut )
    :   HtmlFactory_Idl( io_rEnv, &o_rOut )
{
}

HF_IdlShortDocu::~HF_IdlShortDocu()
{
}

void
HF_IdlShortDocu::Produce_byData( const ary::idl::CodeEntity & i_rCe )
{
    if (i_rCe.Docu() == 0)
        return;

    const ce_info &
        rDocu = *i_rCe.Docu();
    if ( rDocu.IsDeprecated() )
    {
        CurOut()
            >> *new Html::Bold
                << "[ DEPRECATED ]" << new Html::LineBreak;
    }
    if ( rDocu.IsOptional() )
    {
        CurOut()
            >> *new Html::Bold
                << "[ OPTIONAL ]" << new Html::LineBreak;
    }

    HF_IdlDocuTextDisplay
        aText( Env(), &CurOut(), i_rCe);
    rDocu.Short().DisplayAt(aText);
}

//********************      HF_IdlDocuTextDisplay       *********************/

HF_IdlDocuTextDisplay::HF_IdlDocuTextDisplay( Environment &                 io_rEnv,
                                              Xml::Element *                o_pOut,
                                              const ary::idl::CodeEntity &  i_rScopeGivingCe )
    :   HtmlFactory_Idl(io_rEnv, o_pOut),
        sScope(),
        sLinkToken(),
        bGatherLink(false),
        pScopeGivingCe(&i_rScopeGivingCe)
{
}

HF_IdlDocuTextDisplay::~HF_IdlDocuTextDisplay()
{
}

void
HF_IdlDocuTextDisplay::Display_TextToken( const csi::dsapi::DT_TextToken & i_rToken )
{
    if (bGatherLink)
    {
        if (sLinkToken.length() == 0)
        {
            sLinkToken = i_rToken.GetText();
            return;
        }
        else
        {
            Cerr() << "Error in documentation: Too many or too few tokens for a link in <member> or <type>." << Endl();
            Cerr() << "  Link won't be created, but all tokens shown plain." << Endl();
            Cerr() << "  \"" << sLinkToken << "\"";
            if ( pScopeGivingCe != 0 )
                Cerr() << " in " << pScopeGivingCe->LocalName();
            Cerr() << Endl();
            StopLinkGathering();
        }
    }   // endif (bGatherLink)

    CurOut() << " " << new Xml::XmlCode( i_rToken.GetText() );
}

void
HF_IdlDocuTextDisplay::Display_MupType( const csi::dsapi::DT_MupType & i_rToken )
{
    if (i_rToken.IsBegin())
    {
        StartLinkGathering(i_rToken.Scope());
    }
    else
    {
        if (bGatherLink)
        {
            CurOut()
                << " ";
            CreateTypeLink();
            StopLinkGathering();
        }
    }
}

void
HF_IdlDocuTextDisplay::Display_MupMember( const csi::dsapi::DT_MupMember & i_rToken )
{
    if (i_rToken.IsBegin())
    {
        StartLinkGathering(i_rToken.Scope());
    }
    else
    {
        if (bGatherLink)
        {
            CurOut()
                << " ";
            CreateMemberLink();
            StopLinkGathering();
        }
    }
}

void
HF_IdlDocuTextDisplay::Display_MupConst( const csi::dsapi::DT_MupConst & i_rToken )
{
    CurOut()
        << " "
        >> *new Html::Bold
           << i_rToken.GetText();
}

void
HF_IdlDocuTextDisplay::Display_Style( const csi::dsapi::DT_Style & i_rToken )
{
    CurOut() << new Xml::XmlCode( i_rToken.GetText() );
}

void
HF_IdlDocuTextDisplay::Display_EOL()
{
    CurOut() << "\n";
}

void
HF_IdlDocuTextDisplay::CreateTypeLink()
{
    if (strchr(sLinkToken,':') != 0)
    {
         Cerr() << "Warning: Qualified name (probably member) \""
                << sLinkToken
                << "\" found in <type> tag in "
               << Env().CurPageCe_AsText()
               << Endl();
        CurOut() << sLinkToken;
        return;
    }
    HF_IdlTypeText aLink(Env(), CurOut(), true, &ScopeGivingCe());
    aLink.Produce_LinkInDocu(sScope, sLinkToken, String::Null_());
}

void
HF_IdlDocuTextDisplay::CreateMemberLink()
{

    HF_IdlTypeText aLink(Env(), CurOut(), true, &ScopeGivingCe());

    const char *
        sSplit = strchr(sLinkToken,':');

    if (sSplit != 0)
    {
        String sCe(sLinkToken.c_str(), sSplit - sLinkToken.c_str());
        String sMember(sSplit+2);

        if (NOT sScope.empty() OR ScopeGivingCe().LocalName() != sCe )
            aLink.Produce_LinkInDocu(sScope, sCe, sMember);
        else
            aLink.Produce_LocalLinkInDocu(sMember);
    }
    else
    {
        aLink.Produce_LocalLinkInDocu(sLinkToken);
    }
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <precomp.h>
#include <parser/unoidl.hxx>

// NOT FULLY DECLARED SERVICES
#include <stdlib.h>
#include <cosv/file.hxx>
#include <ary/ary.hxx>
#include <ary/idl/i_gate.hxx>
#include <ary/doc/d_oldidldocu.hxx>
#include <../parser/inc/x_docu.hxx>
#include <parser/parserinfo.hxx>
#include <tools/filecoll.hxx>
#include <tools/tkpchars.hxx>
#include <s2_luidl/tkp_uidl.hxx>
#include <s2_luidl/distrib.hxx>
#include <s2_luidl/pe_file2.hxx>
#include <s2_dsapi/cx_dsapi.hxx>
#include <adc_msg.hxx>
#include <x_parse2.hxx>

namespace autodoc
{

class FileParsePerformers
{
  public:
                        FileParsePerformers(
                            ary::Repository &
                                                io_rRepository,
                            ParserInfo &        io_rParserInfo );

    void                ParseFile(
                            const char *        i_sFullPath );

    void                ConnectLinks();

  private:
    CharacterSource     aFileLoader;
    Dyn<csi::uidl::TokenParser_Uidl>
                        pTokens;
    csi::uidl::TokenDistributor
                        aDistributor;
    Dyn<csi::uidl::PE_File>
                        pFileParseEnvironment;
    ary::Repository &
                        rRepository;
    ParserInfo &        rParserInfo;
};

IdlParser::IdlParser( ary::Repository & io_rRepository )
    :   pRepository(&io_rRepository)
{
}

void
IdlParser::Run( const autodoc::FileCollector_Ifc & i_rFiles )
{
    Dyn<FileParsePerformers>
        pFileParsePerformers(
            new FileParsePerformers(*pRepository,
                                    static_cast< ParserInfo& >(*this)) );

    FileCollector::const_iterator iEnd = i_rFiles.End();
    for ( FileCollector::const_iterator iter = i_rFiles.Begin();
          iter != iEnd;
          ++iter )
    {
        Cout() << (*iter) << " ..."<< Endl();

        try
        {
            pFileParsePerformers->ParseFile(*iter);
        }
        catch (X_AutodocParser &)
        {
            /// Ignore and goon
            TheMessages().Out_ParseError(CurFile(), CurLine());
            pFileParsePerformers
                = new FileParsePerformers(*pRepository,
                                          static_cast< ParserInfo& >(*this));
        }
        catch (X_Docu & xd)
        {
            // Currently thic catches only wrong since tags, while since tags are
            // transformed. In this case the program shall be terminated.
            Cerr() << xd << Endl();
            exit(1);
        }
        catch (...)
        {
            Cout() << "Unknown error." << Endl();
            exit(0);
//          pFileParsePerformers = new FileParsePerformers( *pRepository );
        }
    }

    pFileParsePerformers->ConnectLinks();
}

FileParsePerformers::FileParsePerformers( ary::Repository & io_rRepository,
                                          ParserInfo &           io_rParserInfo )
    :   pTokens(0),
        aDistributor(io_rRepository, io_rParserInfo),
        rRepository( io_rRepository ),
        rParserInfo(io_rParserInfo)
{
    DYN csi::dsapi::Context_Docu *
        dpDocuContext
            = new csi::dsapi::Context_Docu( aDistributor.DocuTokens_Receiver() );
    pTokens = new csi::uidl::TokenParser_Uidl( aDistributor.CodeTokens_Receiver(), *dpDocuContext );
    pFileParseEnvironment
            = new csi::uidl::PE_File(aDistributor,rParserInfo);

    aDistributor.SetTokenProvider(*pTokens);
    aDistributor.SetTopParseEnvironment(*pFileParseEnvironment);
}

void
FileParsePerformers::ParseFile( const char * i_sFullPath )
{
    csv::File aFile(i_sFullPath);

    aFile.open( csv::CFM_READ );
    csv_assert( aFile.is_open() );
    aFileLoader.LoadText(aFile);
    aFile.close();

    rParserInfo.Set_CurFile(i_sFullPath, true); // true = count lines
    pTokens->Start(aFileLoader);
    aDistributor.Reset();

    do {
        aDistributor.TradeToken();
    } while ( NOT aFileLoader.IsFinished() );
}

void
FileParsePerformers::ConnectLinks()
{
    // KORR_FUTURE ?
//  rRepository.RwGate_Idl().ConnectAdditionalLinks();
}

}   // namespace autodoc

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>remove empty method<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <precomp.h>
#include <parser/unoidl.hxx>

// NOT FULLY DECLARED SERVICES
#include <stdlib.h>
#include <cosv/file.hxx>
#include <ary/ary.hxx>
#include <ary/idl/i_gate.hxx>
#include <ary/doc/d_oldidldocu.hxx>
#include <../parser/inc/x_docu.hxx>
#include <parser/parserinfo.hxx>
#include <tools/filecoll.hxx>
#include <tools/tkpchars.hxx>
#include <s2_luidl/tkp_uidl.hxx>
#include <s2_luidl/distrib.hxx>
#include <s2_luidl/pe_file2.hxx>
#include <s2_dsapi/cx_dsapi.hxx>
#include <adc_msg.hxx>
#include <x_parse2.hxx>

namespace autodoc
{

class FileParsePerformers
{
  public:
                        FileParsePerformers(
                            ary::Repository &
                                                io_rRepository,
                            ParserInfo &        io_rParserInfo );

    void                ParseFile(
                            const char *        i_sFullPath );

  private:
    CharacterSource     aFileLoader;
    Dyn<csi::uidl::TokenParser_Uidl>
                        pTokens;
    csi::uidl::TokenDistributor
                        aDistributor;
    Dyn<csi::uidl::PE_File>
                        pFileParseEnvironment;
    ary::Repository &
                        rRepository;
    ParserInfo &        rParserInfo;
};

IdlParser::IdlParser( ary::Repository & io_rRepository )
    :   pRepository(&io_rRepository)
{
}

void
IdlParser::Run( const autodoc::FileCollector_Ifc & i_rFiles )
{
    Dyn<FileParsePerformers>
        pFileParsePerformers(
            new FileParsePerformers(*pRepository,
                                    static_cast< ParserInfo& >(*this)) );

    FileCollector::const_iterator iEnd = i_rFiles.End();
    for ( FileCollector::const_iterator iter = i_rFiles.Begin();
          iter != iEnd;
          ++iter )
    {
        Cout() << (*iter) << " ..."<< Endl();

        try
        {
            pFileParsePerformers->ParseFile(*iter);
        }
        catch (X_AutodocParser &)
        {
            /// Ignore and goon
            TheMessages().Out_ParseError(CurFile(), CurLine());
            pFileParsePerformers
                = new FileParsePerformers(*pRepository,
                                          static_cast< ParserInfo& >(*this));
        }
        catch (X_Docu & xd)
        {
            // Currently thic catches only wrong since tags, while since tags are
            // transformed. In this case the program shall be terminated.
            Cerr() << xd << Endl();
            exit(1);
        }
        catch (...)
        {
            Cout() << "Unknown error." << Endl();
            exit(0);
//          pFileParsePerformers = new FileParsePerformers( *pRepository );
        }
    }
}

FileParsePerformers::FileParsePerformers( ary::Repository & io_rRepository,
                                          ParserInfo &           io_rParserInfo )
    :   pTokens(0),
        aDistributor(io_rRepository, io_rParserInfo),
        rRepository( io_rRepository ),
        rParserInfo(io_rParserInfo)
{
    DYN csi::dsapi::Context_Docu *
        dpDocuContext
            = new csi::dsapi::Context_Docu( aDistributor.DocuTokens_Receiver() );
    pTokens = new csi::uidl::TokenParser_Uidl( aDistributor.CodeTokens_Receiver(), *dpDocuContext );
    pFileParseEnvironment
            = new csi::uidl::PE_File(aDistributor,rParserInfo);

    aDistributor.SetTokenProvider(*pTokens);
    aDistributor.SetTopParseEnvironment(*pFileParseEnvironment);
}

void
FileParsePerformers::ParseFile( const char * i_sFullPath )
{
    csv::File aFile(i_sFullPath);

    aFile.open( csv::CFM_READ );
    csv_assert( aFile.is_open() );
    aFileLoader.LoadText(aFile);
    aFile.close();

    rParserInfo.Set_CurFile(i_sFullPath, true); // true = count lines
    pTokens->Start(aFileLoader);
    aDistributor.Reset();

    do {
        aDistributor.TradeToken();
    } while ( NOT aFileLoader.IsFinished() );
}

}   // namespace autodoc

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Author: Filimon Roukoutakis 02/08/2006

/******************************************************************************
  MOOD - Monitor Of On-line Data and Detector Debugger for ALICE Experiment
******************************************************************************/

#include <RConfig.h>
#include <TError.h>
#include <TSystem.h>
#include <TSysEvtHandler.h>
#include <TGrid.h>
#include "deroot.h"

int deroot(const char *rootFileName, const char *dateFileName, const char *ddlFilesFolder);

int deroot(const char *rootFileName, const char *dateFileName, const char *ddlFilesFolder) {

 TString str = rootFileName;
 if (str.BeginsWith("alien://"))
   TGrid::Connect("alien://");

 TFile *rootFile = TFile::Open(rootFileName,"READ");
 if (!rootFile) {
   cerr << "Raw data file can not be opened" << endl;
   return(1);
 }

 TTree *t=(TTree *)rootFile->Get("RAW");
 if(!t) {
  cerr << "Error getting RAW tree" << endl;
  return(1);
 }
 AliRawVEvent *rootEvent=NULL;

 t->SetBranchAddress("rawevent", &rootEvent);

 FILE *dateFile;
#if defined(R__SEEK64)
 if(!(dateFile=fopen64(dateFileName, "wb"))) {
#else
 if(!(dateFile=fopen(dateFileName, "wb"))) {
#endif
  cerr << "Error opening DATE file" << endl;
  return(1);
 }

 UInt_t eventSize = 10000000; // 10MB by default
 unsigned char *dateEvent = new unsigned char[eventSize];
 for(Long_t gdcCounter=0; gdcCounter<t->GetEntries(); gdcCounter++) {
  rootEvent=NULL;
  t->GetEntry(gdcCounter);
  if (rootEvent->GetHeader()->GetEventSize() > eventSize) {
    delete [] dateEvent;
    eventSize = (UInt_t)(1.05*rootEvent->GetHeader()->GetEventSize());
    dateEvent = new unsigned char[eventSize];
  }

  size_t gdcSize;
  if (ddlFilesFolder) {
    char command[256];
    snprintf(command, sizeof(command), "rm -rf %s/raw%ld", ddlFilesFolder, gdcCounter);
    gSystem->Exec(command);
    snprintf(command, sizeof(command), "%s/raw%ld", ddlFilesFolder, gdcCounter);
    if (gSystem->MakeDirectory(command) < 0) {
      cerr << "Can not create directory " << command << endl;
      return(1);
    }
    gdcSize=Root2Date(rootEvent, dateEvent, command);
  }
  else
    gdcSize=Root2Date(rootEvent, dateEvent, NULL);

  delete rootEvent;
  cerr << "\r     \r" << setprecision(3) << 100*(float)(gdcCounter+1)/t->GetEntries() << "% ";
  fwrite(dateEvent, gdcSize, 1, dateFile);
 }

 // Cleanup resources

 cerr << "\r     \r";
 cerr.flush();
 delete t;
 rootFile->Close();
 fclose(dateFile);
 delete [] dateEvent;

 return(0);

}

int main(int argc, char **argv) {

  if (argc != 3 && argc != 4) {
    cerr << "Usage: deroot <input_root_file> <output_date_file> [<optional_folder_for_ddl_files>]" << endl;
    return 1;
  }

  if (argc ==3)
    deroot(argv[1], argv[2], NULL);
  else
    deroot(argv[1], argv[2], argv[3]);

 return(0);

}

<commit_msg>Coverity fixes.<commit_after>// Author: Filimon Roukoutakis 02/08/2006

/******************************************************************************
  MOOD - Monitor Of On-line Data and Detector Debugger for ALICE Experiment
******************************************************************************/

#include <RConfig.h>
#include <TError.h>
#include <TSystem.h>
#include <TSysEvtHandler.h>
#include <TGrid.h>
#include "deroot.h"

int deroot(const char *rootFileName, const char *dateFileName, const char *ddlFilesFolder);

int deroot(const char *rootFileName, const char *dateFileName, const char *ddlFilesFolder) {

 TString str = rootFileName;
 if (str.BeginsWith("alien://"))
   TGrid::Connect("alien://");

 TFile *rootFile = TFile::Open(rootFileName,"READ");
 if (!rootFile) {
   cerr << "Raw data file can not be opened" << endl;
   return(1);
 }

 TTree *t=(TTree *)rootFile->Get("RAW");
 if(!t) {
  cerr << "Error getting RAW tree" << endl;
  return(1);
 }
 AliRawVEvent *rootEvent=NULL;

 t->SetBranchAddress("rawevent", &rootEvent);

 FILE *dateFile;
#if defined(R__SEEK64)
 if(!(dateFile=fopen64(dateFileName, "wb"))) {
#else
 if(!(dateFile=fopen(dateFileName, "wb"))) {
#endif
  cerr << "Error opening DATE file" << endl;
  return(1);
 }

 UInt_t eventSize = 10000000; // 10MB by default
 unsigned char *dateEvent = new unsigned char[eventSize];
 for(Long_t gdcCounter=0; gdcCounter<t->GetEntries(); gdcCounter++) {
  rootEvent=NULL;
  t->GetEntry(gdcCounter);
  if (rootEvent->GetHeader()->GetEventSize() > eventSize) {
    delete [] dateEvent;
    eventSize = (UInt_t)(1.05*rootEvent->GetHeader()->GetEventSize());
    dateEvent = new unsigned char[eventSize];
  }

  size_t gdcSize;
  if (ddlFilesFolder) {
    char command[256];
    snprintf(command, sizeof(command), "rm -rf %s/raw%ld", ddlFilesFolder, gdcCounter);
    gSystem->Exec(command);
    snprintf(command, sizeof(command), "%s/raw%ld", ddlFilesFolder, gdcCounter);
    if (gSystem->MakeDirectory(command) < 0) {
      cerr << "Can not create directory " << command << endl;
      fclose(dateFile);
      delete [] dateEvent;
      return(1);
    }
    gdcSize=Root2Date(rootEvent, dateEvent, command);
  }
  else
    gdcSize=Root2Date(rootEvent, dateEvent, NULL);

  delete rootEvent;
  cerr << "\r     \r" << setprecision(3) << 100*(float)(gdcCounter+1)/t->GetEntries() << "% ";
  fwrite(dateEvent, gdcSize, 1, dateFile);
 }

 // Cleanup resources

 cerr << "\r     \r";
 cerr.flush();
 delete t;
 rootFile->Close();
 fclose(dateFile);
 delete [] dateEvent;

 return(0);

}

int main(int argc, char **argv) {

  if (argc != 3 && argc != 4) {
    cerr << "Usage: deroot <input_root_file> <output_date_file> [<optional_folder_for_ddl_files>]" << endl;
    return 1;
  }

  if (argc ==3)
    deroot(argv[1], argv[2], NULL);
  else
    deroot(argv[1], argv[2], argv[3]);

 return(0);

}

<|endoftext|>