<commit_before>#include "managesievescriptsdialog.h"
#include "managesievescriptsdialog_p.h"

#include "sieveconfig.h"
#include "accountmanager.h"
#include "imapaccountbase.h"
#include "sievejob.h"
#include "kmkernel.h"

#include <klocale.h>
#include <kiconloader.h>
#include <kwin.h>
#include <kapplication.h>
#include <kinputdialog.h>
#include <kglobalsettings.h>
#include <kmessagebox.h>

#include <qlayout.h>
#include <qlistview.h>
#include <qtextedit.h>
#include <qpopupmenu.h>

#include <cassert>

inline QCheckListItem * qcli_cast( QListViewItem * lvi ) {
  return lvi && lvi->rtti() == 1 ? static_cast<QCheckListItem*>( lvi ) : 0 ;
}
inline const QCheckListItem * qcli_cast( const QListViewItem * lvi ) {
  return lvi && lvi->rtti() == 1 ? static_cast<const QCheckListItem*>( lvi ) : 0 ;
}

KMail::ManageSieveScriptsDialog::ManageSieveScriptsDialog( QWidget * parent, const char * name )
  : KDialogBase( Plain, i18n( "Manage Sieve Scripts" ), Ok|Close, Ok, parent, name, false ),
    mSieveEditor( 0 ),
    mContextMenuItem( 0 ),
    mWasActive( false )
{
  setWFlags( WGroupLeader|WDestructiveClose );
  KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );

  QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, 0 );

  mListView = new QListView( plainPage() );
  mListView->addColumn( i18n( "Available Scripts" ) );
  mListView->setResizeMode( QListView::LastColumn );
  mListView->setRootIsDecorated( true );
  mListView->setSelectionMode( QListView::Single );
  connect( mListView, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&,int)),
           this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&)) );
  connect( mListView, SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
           this, SLOT(slotDoubleClicked(QListViewItem*)) );
  connect( mListView, SIGNAL(selectionChanged(QListViewItem*)),
           this, SLOT(slotSelectionChanged(QListViewItem*)) );
  vlay->addWidget( mListView );

  resize( 2 * sizeHint().width(), sizeHint().height() );

  slotRefresh();
}

KMail::ManageSieveScriptsDialog::~ManageSieveScriptsDialog() {
  killAllJobs();
}

void KMail::ManageSieveScriptsDialog::killAllJobs() {
  for ( QMap<SieveJob*,QCheckListItem*>::const_iterator it = mJobs.constBegin(), end = mJobs.constEnd() ; it != end ; ++it )
    it.key()->kill();
  mJobs.clear();
}

static KURL findUrlForAccount( const KMail::ImapAccountBase * a ) {
  assert( a );
  const KMail::SieveConfig sieve = a->sieveConfig();
  if ( !sieve.managesieveSupported() )
    return KURL();
  if ( sieve.reuseConfig() ) {
    // assemble Sieve url from the settings of the account:
    KURL u;
    u.setProtocol( "sieve" );
    u.setHost( a->host() );
    u.setUser( a->login() );
    u.setPass( a->passwd() );
    u.setPort( sieve.port() );
    // Translate IMAP LOGIN to PLAIN:
    u.setQuery( "x-mech=" + ( a->auth() == "*" ? "PLAIN" : a->auth() ) );
    return u;
  } else {
    return sieve.alternateURL();
  }
}

void KMail::ManageSieveScriptsDialog::slotRefresh() {
  killAllJobs();
  mUrls.clear();
  mListView->clear();

  KMail::AccountManager * am = kmkernel->acctMgr();
  assert( am );
  QCheckListItem * last = 0;
  for ( KMAccount * a = am->first() ; a ; a = am->next() ) {
    last = new QCheckListItem( mListView, last, a->name(), QCheckListItem::Controller );
    last->setPixmap( 0, SmallIcon( "server" ) );
    if ( ImapAccountBase * iab = dynamic_cast<ImapAccountBase*>( a ) ) {
      const KURL u = ::findUrlForAccount( iab );
      if ( u.isEmpty() )
        continue;
      SieveJob * job = SieveJob::list( u );
      connect( job, SIGNAL(item(KMail::SieveJob*,const QString&,bool)),
               this, SLOT(slotItem(KMail::SieveJob*,const QString&,bool)) );
      connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
               this, SLOT(slotResult(KMail::SieveJob*,bool,const QString&,bool)) );
      mJobs.insert( job, last );
      mUrls.insert( last, u );
    } else {
      QListViewItem * item = new QListViewItem( last, i18n( "No Sieve URL configured" ) );
      item->setEnabled( false );
      last->setOpen( true );
    }
  }
}

void KMail::ManageSieveScriptsDialog::slotResult( KMail::SieveJob * job, bool success, const QString &, bool ) {
  QCheckListItem * parent = mJobs[job];
  if ( !parent )
    return;

  mJobs.remove( job );

  parent->setOpen( true );

  if ( success )
    return;

  QListViewItem * item = new QListViewItem( parent, i18n( "Failed to fetch the list of scripts" ) );
  item->setEnabled( false );
}

void KMail::ManageSieveScriptsDialog::slotItem( KMail::SieveJob * job, const QString & filename, bool isActive ) {
  QCheckListItem * parent = mJobs[job];
  if ( !parent )
    return;
  QCheckListItem * item = new QCheckListItem( parent, filename, QCheckListItem::RadioButton );
  if ( isActive ) {
    item->setOn( true );
    mSelectedItems[parent] = item;
  }
}

void KMail::ManageSieveScriptsDialog::slotContextMenuRequested( QListViewItem * i, const QPoint & p ) {
  QCheckListItem * item = qcli_cast( i );
  if ( !item )
    return;
  if ( !item->depth() && !mUrls.count( item ) )
    return;
  QPopupMenu menu;
  mContextMenuItem = item;
  if ( item->depth() ) {
    // script items:
    menu.insertItem( i18n( "Delete Script" ), this, SLOT(slotDeleteScript()) );
    menu.insertItem( i18n( "Edit Script..." ), this, SLOT(slotEditScript()) );
  } else {
    // top-levels:
    menu.insertItem( i18n( "New Script..." ), this, SLOT(slotNewScript()) );
  }
  menu.exec( p );
  mContextMenuItem = 0;
}

void KMail::ManageSieveScriptsDialog::slotSelectionChanged( QListViewItem * i ) {
  QCheckListItem * item = qcli_cast( i );
  if ( !item )
    return;
  QCheckListItem * parent = qcli_cast( item->parent() );
  if ( !parent )
    return;
  if ( item->isOn() && mSelectedItems[parent] != item ) {
    mSelectedItems[parent] = item;
    changeActiveScript( parent );
  }
}

void KMail::ManageSieveScriptsDialog::changeActiveScript( QCheckListItem * item ) {
  if ( !item )
    return;
  if ( !mUrls.count( item ) )
    return;
  if ( !mSelectedItems.count( item ) )
    return;
  KURL u = mUrls[item];
  if ( u.isEmpty() )
    return;
  QCheckListItem * selected = mSelectedItems[item];
  if ( !selected )
    return;
  u.setFileName( selected->text( 0 ) );

  SieveJob * job = SieveJob::activate( u );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotRefresh()) );
}

void KMail::ManageSieveScriptsDialog::slotDoubleClicked( QListViewItem * i ) {
  QCheckListItem * item = qcli_cast( i );
  if ( !item )
    return;
  if ( !item->depth() )
    return;
  mContextMenuItem = item;
  slotEditScript();
  mContextMenuItem = 0;
}

void KMail::ManageSieveScriptsDialog::slotDeleteScript() {
  if ( !mContextMenuItem )
    return;
  if ( !mContextMenuItem->depth() )
    return;

  QCheckListItem * parent = qcli_cast( mContextMenuItem->parent() );
  if ( !parent )
    return;

  if ( !mUrls.count( parent ) )
    return;

  KURL u = mUrls[parent];
  if ( u.isEmpty() )
    return;

  u.setFileName( mContextMenuItem->text( 0 ) );

  if ( KMessageBox::questionYesNo( this, i18n( "Really delete script \"%1\" from the server?" ).arg( u.fileName() ),
                                   i18n( "Delete Sieve Script Confirmation" ),
                                   KStdGuiItem::del(), KStdGuiItem::cancel() )
       != KMessageBox::Yes )
    return;

  SieveJob * job = SieveJob::del( u );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotRefresh()) );
}

void KMail::ManageSieveScriptsDialog::slotEditScript() {
  if ( !mContextMenuItem )
    return;
  if ( !mContextMenuItem->depth() )
    return;
  QCheckListItem * parent = qcli_cast( mContextMenuItem->parent() );
  if ( !mUrls.count( parent ) )
    return;
  KURL url = mUrls[parent];
  if ( url.isEmpty() )
    return;
  url.setFileName( mContextMenuItem->text( 0 ) );
  mCurrentURL = url;
  SieveJob * job = SieveJob::get( url );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotGetResult(KMail::SieveJob*,bool,const QString&,bool)) );
}

void KMail::ManageSieveScriptsDialog::slotNewScript() {
  if ( !mContextMenuItem )
    return;
  if ( mContextMenuItem->depth() )
    mContextMenuItem = qcli_cast( mContextMenuItem->parent() );
  if ( !mContextMenuItem )
    return;

  if ( !mUrls.count( mContextMenuItem ) )
    return;

  KURL u = mUrls[mContextMenuItem];
  if ( u.isEmpty() )
    return;

  bool ok = false;
  const QString name = KInputDialog::getText( i18n( "New Sieve Script" ),
                                              i18n( "Please enter a name for the new Sieve script:" ),
                                              i18n( "unnamed" ), &ok, this );
  if ( !ok || name.isEmpty() )
    return;

  u.setFileName( name );

  (void) new QCheckListItem( mContextMenuItem, name, QCheckListItem::RadioButton );

  mCurrentURL = u;
  slotGetResult( 0, true, QString::null, false );
}

KMail::SieveEditor::SieveEditor( QWidget * parent, const char * name )
  : KDialogBase( Plain, i18n( "Edit Sieve Script" ), Ok|Cancel, Ok, parent, name )
{
  QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
  mTextEdit = new QTextEdit( plainPage() );
  vlay->addWidget( mTextEdit );
  mTextEdit->setTextFormat( QTextEdit::PlainText );
  mTextEdit->setWordWrap( QTextEdit::NoWrap );
  mTextEdit->setFont( KGlobalSettings::fixedFont() );

  resize( 3 * sizeHint() );
}

KMail::SieveEditor::~SieveEditor() {}

void KMail::ManageSieveScriptsDialog::slotGetResult( KMail::SieveJob *, bool success, const QString & script, bool isActive ) {
  if ( !success )
    return;

  if ( mSieveEditor )
    return;

  mSieveEditor = new SieveEditor( this );
  mSieveEditor->setScript( script );
  connect( mSieveEditor, SIGNAL(okClicked()), this, SLOT(slotSieveEditorOkClicked()) );
  connect( mSieveEditor, SIGNAL(cancelClicked()), this, SLOT(slotSieveEditorCancelClicked()) );
  mSieveEditor->show();
  mWasActive = isActive;
}

void KMail::ManageSieveScriptsDialog::slotSieveEditorOkClicked() {
  if ( !mSieveEditor )
    return;
  SieveJob * job = SieveJob::put( mCurrentURL,mSieveEditor->script(), mWasActive, mWasActive );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotPutResult(KMail::SieveJob*,bool)) );
}

void KMail::ManageSieveScriptsDialog::slotSieveEditorCancelClicked() {
  mSieveEditor->deleteLater(); mSieveEditor = 0;
  mCurrentURL = KURL();
}

void KMail::ManageSieveScriptsDialog::slotPutResult( KMail::SieveJob *, bool success ) {
  if ( success ) {
    KMessageBox::information( this, i18n( "The Sieve script was successfully uploaded." ),
                              i18n( "Sieve Script Upload" ) );
    mSieveEditor->deleteLater(); mSieveEditor = 0;
    mCurrentURL = KURL();
  } else {
    mSieveEditor->show();
  }
}

#include "managesievescriptsdialog.moc"
#include "managesievescriptsdialog_p.moc"
<commit_msg>The "Ok" button was unnecessary and downright confusing.<commit_after>#include "managesievescriptsdialog.h"
#include "managesievescriptsdialog_p.h"

#include "sieveconfig.h"
#include "accountmanager.h"
#include "imapaccountbase.h"
#include "sievejob.h"
#include "kmkernel.h"

#include <klocale.h>
#include <kiconloader.h>
#include <kwin.h>
#include <kapplication.h>
#include <kinputdialog.h>
#include <kglobalsettings.h>
#include <kmessagebox.h>

#include <qlayout.h>
#include <qlistview.h>
#include <qtextedit.h>
#include <qpopupmenu.h>

#include <cassert>

inline QCheckListItem * qcli_cast( QListViewItem * lvi ) {
  return lvi && lvi->rtti() == 1 ? static_cast<QCheckListItem*>( lvi ) : 0 ;
}
inline const QCheckListItem * qcli_cast( const QListViewItem * lvi ) {
  return lvi && lvi->rtti() == 1 ? static_cast<const QCheckListItem*>( lvi ) : 0 ;
}

KMail::ManageSieveScriptsDialog::ManageSieveScriptsDialog( QWidget * parent, const char * name )
  : KDialogBase( Plain, i18n( "Manage Sieve Scripts" ), Close, Close,
    parent, name, false ),
    mSieveEditor( 0 ),
    mContextMenuItem( 0 ),
    mWasActive( false )
{
  setWFlags( WGroupLeader|WDestructiveClose );
  KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );

  QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, 0 );

  mListView = new QListView( plainPage() );
  mListView->addColumn( i18n( "Available Scripts" ) );
  mListView->setResizeMode( QListView::LastColumn );
  mListView->setRootIsDecorated( true );
  mListView->setSelectionMode( QListView::Single );
  connect( mListView, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&,int)),
           this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&)) );
  connect( mListView, SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
           this, SLOT(slotDoubleClicked(QListViewItem*)) );
  connect( mListView, SIGNAL(selectionChanged(QListViewItem*)),
           this, SLOT(slotSelectionChanged(QListViewItem*)) );
  vlay->addWidget( mListView );

  resize( 2 * sizeHint().width(), sizeHint().height() );

  slotRefresh();
}

KMail::ManageSieveScriptsDialog::~ManageSieveScriptsDialog() {
  killAllJobs();
}

void KMail::ManageSieveScriptsDialog::killAllJobs() {
  for ( QMap<SieveJob*,QCheckListItem*>::const_iterator it = mJobs.constBegin(), end = mJobs.constEnd() ; it != end ; ++it )
    it.key()->kill();
  mJobs.clear();
}

static KURL findUrlForAccount( const KMail::ImapAccountBase * a ) {
  assert( a );
  const KMail::SieveConfig sieve = a->sieveConfig();
  if ( !sieve.managesieveSupported() )
    return KURL();
  if ( sieve.reuseConfig() ) {
    // assemble Sieve url from the settings of the account:
    KURL u;
    u.setProtocol( "sieve" );
    u.setHost( a->host() );
    u.setUser( a->login() );
    u.setPass( a->passwd() );
    u.setPort( sieve.port() );
    // Translate IMAP LOGIN to PLAIN:
    u.setQuery( "x-mech=" + ( a->auth() == "*" ? "PLAIN" : a->auth() ) );
    return u;
  } else {
    return sieve.alternateURL();
  }
}

void KMail::ManageSieveScriptsDialog::slotRefresh() {
  killAllJobs();
  mUrls.clear();
  mListView->clear();

  KMail::AccountManager * am = kmkernel->acctMgr();
  assert( am );
  QCheckListItem * last = 0;
  for ( KMAccount * a = am->first() ; a ; a = am->next() ) {
    last = new QCheckListItem( mListView, last, a->name(), QCheckListItem::Controller );
    last->setPixmap( 0, SmallIcon( "server" ) );
    if ( ImapAccountBase * iab = dynamic_cast<ImapAccountBase*>( a ) ) {
      const KURL u = ::findUrlForAccount( iab );
      if ( u.isEmpty() )
        continue;
      SieveJob * job = SieveJob::list( u );
      connect( job, SIGNAL(item(KMail::SieveJob*,const QString&,bool)),
               this, SLOT(slotItem(KMail::SieveJob*,const QString&,bool)) );
      connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
               this, SLOT(slotResult(KMail::SieveJob*,bool,const QString&,bool)) );
      mJobs.insert( job, last );
      mUrls.insert( last, u );
    } else {
      QListViewItem * item = new QListViewItem( last, i18n( "No Sieve URL configured" ) );
      item->setEnabled( false );
      last->setOpen( true );
    }
  }
}

void KMail::ManageSieveScriptsDialog::slotResult( KMail::SieveJob * job, bool success, const QString &, bool ) {
  QCheckListItem * parent = mJobs[job];
  if ( !parent )
    return;

  mJobs.remove( job );

  parent->setOpen( true );

  if ( success )
    return;

  QListViewItem * item = new QListViewItem( parent, i18n( "Failed to fetch the list of scripts" ) );
  item->setEnabled( false );
}

void KMail::ManageSieveScriptsDialog::slotItem( KMail::SieveJob * job, const QString & filename, bool isActive ) {
  QCheckListItem * parent = mJobs[job];
  if ( !parent )
    return;
  QCheckListItem * item = new QCheckListItem( parent, filename, QCheckListItem::RadioButton );
  if ( isActive ) {
    item->setOn( true );
    mSelectedItems[parent] = item;
  }
}

void KMail::ManageSieveScriptsDialog::slotContextMenuRequested( QListViewItem * i, const QPoint & p ) {
  QCheckListItem * item = qcli_cast( i );
  if ( !item )
    return;
  if ( !item->depth() && !mUrls.count( item ) )
    return;
  QPopupMenu menu;
  mContextMenuItem = item;
  if ( item->depth() ) {
    // script items:
    menu.insertItem( i18n( "Delete Script" ), this, SLOT(slotDeleteScript()) );
    menu.insertItem( i18n( "Edit Script..." ), this, SLOT(slotEditScript()) );
  } else {
    // top-levels:
    menu.insertItem( i18n( "New Script..." ), this, SLOT(slotNewScript()) );
  }
  menu.exec( p );
  mContextMenuItem = 0;
}

void KMail::ManageSieveScriptsDialog::slotSelectionChanged( QListViewItem * i ) {
  QCheckListItem * item = qcli_cast( i );
  if ( !item )
    return;
  QCheckListItem * parent = qcli_cast( item->parent() );
  if ( !parent )
    return;
  if ( item->isOn() && mSelectedItems[parent] != item ) {
    mSelectedItems[parent] = item;
    changeActiveScript( parent );
  }
}

void KMail::ManageSieveScriptsDialog::changeActiveScript( QCheckListItem * item ) {
  if ( !item )
    return;
  if ( !mUrls.count( item ) )
    return;
  if ( !mSelectedItems.count( item ) )
    return;
  KURL u = mUrls[item];
  if ( u.isEmpty() )
    return;
  QCheckListItem * selected = mSelectedItems[item];
  if ( !selected )
    return;
  u.setFileName( selected->text( 0 ) );

  SieveJob * job = SieveJob::activate( u );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotRefresh()) );
}

void KMail::ManageSieveScriptsDialog::slotDoubleClicked( QListViewItem * i ) {
  QCheckListItem * item = qcli_cast( i );
  if ( !item )
    return;
  if ( !item->depth() )
    return;
  mContextMenuItem = item;
  slotEditScript();
  mContextMenuItem = 0;
}

void KMail::ManageSieveScriptsDialog::slotDeleteScript() {
  if ( !mContextMenuItem )
    return;
  if ( !mContextMenuItem->depth() )
    return;

  QCheckListItem * parent = qcli_cast( mContextMenuItem->parent() );
  if ( !parent )
    return;

  if ( !mUrls.count( parent ) )
    return;

  KURL u = mUrls[parent];
  if ( u.isEmpty() )
    return;

  u.setFileName( mContextMenuItem->text( 0 ) );

  if ( KMessageBox::questionYesNo( this, i18n( "Really delete script \"%1\" from the server?" ).arg( u.fileName() ),
                                   i18n( "Delete Sieve Script Confirmation" ),
                                   KStdGuiItem::del(), KStdGuiItem::cancel() )
       != KMessageBox::Yes )
    return;

  SieveJob * job = SieveJob::del( u );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotRefresh()) );
}

void KMail::ManageSieveScriptsDialog::slotEditScript() {
  if ( !mContextMenuItem )
    return;
  if ( !mContextMenuItem->depth() )
    return;
  QCheckListItem * parent = qcli_cast( mContextMenuItem->parent() );
  if ( !mUrls.count( parent ) )
    return;
  KURL url = mUrls[parent];
  if ( url.isEmpty() )
    return;
  url.setFileName( mContextMenuItem->text( 0 ) );
  mCurrentURL = url;
  SieveJob * job = SieveJob::get( url );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotGetResult(KMail::SieveJob*,bool,const QString&,bool)) );
}

void KMail::ManageSieveScriptsDialog::slotNewScript() {
  if ( !mContextMenuItem )
    return;
  if ( mContextMenuItem->depth() )
    mContextMenuItem = qcli_cast( mContextMenuItem->parent() );
  if ( !mContextMenuItem )
    return;

  if ( !mUrls.count( mContextMenuItem ) )
    return;

  KURL u = mUrls[mContextMenuItem];
  if ( u.isEmpty() )
    return;

  bool ok = false;
  const QString name = KInputDialog::getText( i18n( "New Sieve Script" ),
                                              i18n( "Please enter a name for the new Sieve script:" ),
                                              i18n( "unnamed" ), &ok, this );
  if ( !ok || name.isEmpty() )
    return;

  u.setFileName( name );

  (void) new QCheckListItem( mContextMenuItem, name, QCheckListItem::RadioButton );

  mCurrentURL = u;
  slotGetResult( 0, true, QString::null, false );
}

KMail::SieveEditor::SieveEditor( QWidget * parent, const char * name )
  : KDialogBase( Plain, i18n( "Edit Sieve Script" ), Ok|Cancel, Ok, parent, name )
{
  QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
  mTextEdit = new QTextEdit( plainPage() );
  vlay->addWidget( mTextEdit );
  mTextEdit->setTextFormat( QTextEdit::PlainText );
  mTextEdit->setWordWrap( QTextEdit::NoWrap );
  mTextEdit->setFont( KGlobalSettings::fixedFont() );

  resize( 3 * sizeHint() );
}

KMail::SieveEditor::~SieveEditor() {}

void KMail::ManageSieveScriptsDialog::slotGetResult( KMail::SieveJob *, bool success, const QString & script, bool isActive ) {
  if ( !success )
    return;

  if ( mSieveEditor )
    return;

  mSieveEditor = new SieveEditor( this );
  mSieveEditor->setScript( script );
  connect( mSieveEditor, SIGNAL(okClicked()), this, SLOT(slotSieveEditorOkClicked()) );
  connect( mSieveEditor, SIGNAL(cancelClicked()), this, SLOT(slotSieveEditorCancelClicked()) );
  mSieveEditor->show();
  mWasActive = isActive;
}

void KMail::ManageSieveScriptsDialog::slotSieveEditorOkClicked() {
  if ( !mSieveEditor )
    return;
  SieveJob * job = SieveJob::put( mCurrentURL,mSieveEditor->script(), mWasActive, mWasActive );
  connect( job, SIGNAL(result(KMail::SieveJob*,bool,const QString&,bool)),
           this, SLOT(slotPutResult(KMail::SieveJob*,bool)) );
}

void KMail::ManageSieveScriptsDialog::slotSieveEditorCancelClicked() {
  mSieveEditor->deleteLater(); mSieveEditor = 0;
  mCurrentURL = KURL();
}

void KMail::ManageSieveScriptsDialog::slotPutResult( KMail::SieveJob *, bool success ) {
  if ( success ) {
    KMessageBox::information( this, i18n( "The Sieve script was successfully uploaded." ),
                              i18n( "Sieve Script Upload" ) );
    mSieveEditor->deleteLater(); mSieveEditor = 0;
    mCurrentURL = KURL();
  } else {
    mSieveEditor->show();
  }
}

#include "managesievescriptsdialog.moc"
#include "managesievescriptsdialog_p.moc"
<|endoftext|>


<commit_before>int main(int argc, char const *argv[]) {
  printf("%s\n", "hellooooooo world by YzolaPhilo!!!");
  return 0;
}
<commit_msg>测试SourceTree提交<commit_after>int main(int argc, char const *argv[]) {
  printf("%s\n", "hellooooooo world by YzolaPhilo!!!");
  printf("this is a changed, test github!!!\n", );
  return 0;
}
<|endoftext|>


<commit_before>// The local APIC manages internal (non-I/O) interrupts.
// See Chapter 8 & Appendix C of Intel processor manual volume 3.

#include "types.h"
#include "amd64.h"
#include "kernel.hh"
#include "traps.h"
#include "bits.hh"
#include "cpu.hh"
#include "apic.hh"

// Local APIC registers, divided by 4 for use as uint[] indices.
#define ID      (0x0020/4)   // ID
#define VER     (0x0030/4)   // Version
#define TPR     (0x0080/4)   // Task Priority
#define EOI     (0x00B0/4)   // EOI
#define SVR     (0x00F0/4)   // Spurious Interrupt Vector
  #define ENABLE     0x00000100   // Unit Enable
#define ESR     (0x0280/4)   // Error Status
#define ICRLO   (0x0300/4)   // Interrupt Command
  #define INIT       0x00000500   // INIT/RESET
  #define STARTUP    0x00000600   // Startup IPI
  #define DELIVS     0x00001000   // Delivery status
  #define ASSERT     0x00004000   // Assert interrupt (vs deassert)
  #define DEASSERT   0x00000000
  #define LEVEL      0x00008000   // Level triggered
  #define BCAST      0x00080000   // Send to all APICs, including self.
  #define BUSY       0x00001000
  #define FIXED      0x00000000
#define ICRHI   (0x0310/4)   // Interrupt Command [63:32]
#define TIMER   (0x0320/4)   // Local Vector Table 0 (TIMER)
  #define X1         0x0000000B   // divide counts by 1
  #define PERIODIC   0x00020000   // Periodic
#define PCINT   (0x0340/4)   // Performance Counter LVT
#define LINT0   (0x0350/4)   // Local Vector Table 1 (LINT0)
#define LINT1   (0x0360/4)   // Local Vector Table 2 (LINT1)
#define ERROR   (0x0370/4)   // Local Vector Table 3 (ERROR)
  #define MASKED     0x00010000   // Interrupt masked
  #define MT_NMI     0x00000400   // NMI message type
  #define MT_FIX     0x00000000   // Fixed message type
#define TICR    (0x0380/4)   // Timer Initial Count
#define TCCR    (0x0390/4)   // Timer Current Count
#define TDCR    (0x03E0/4)   // Timer Divide Configuration

#define IO_RTC  0x70

static volatile u32 *xapic = (u32 *)(KBASE + 0xfee00000);
static u64 xapichz;

static void
xapicw(int index, int value)
{
  xapic[index] = value;
  xapic[ID];  // wait for write to finish, by reading
}

static u32
xapicr(u32 off)
{
  return xapic[off];
}

static int
xapicwait()
{
  int i = 100000;
  while ((xapicr(ICRLO) & BUSY) != 0) {
    nop_pause();
    i--;
    if (i == 0) {
      cprintf("xapicwait: wedged?\n");
      return -1;
    }
  }
  return 0;
}

void
initxapic(void)
{
  u64 count;
  u64 apicbar;

  // See Intel Arch. Manual Vol 3a, the APIC section
  // Check if x2APIC is enabled, disable it if so..
  apicbar = readmsr(MSR_APIC_BAR);
  if (apicbar & APIC_BAR_X2APIC_EN) {
    // Disable x2APIC and the xAPIC
    apicbar &= ~(APIC_BAR_XAPIC_EN | APIC_BAR_X2APIC_EN);
    writemsr(MSR_APIC_BAR, apicbar);
    // Re-enable the xAPIC
    apicbar |= APIC_BAR_XAPIC_EN;
    writemsr(MSR_APIC_BAR, apicbar);
    // Sanity-check..
    u32 ebx;
    cpuid(CPUID_FEATURES, 0, &ebx, 0, 0);
    assert(xapic[ID]>>24 == FEATURE_EBX_APIC(ebx));
  }

  // Enable local APIC; set spurious interrupt vector.
  xapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS));

  if (xapichz == 0) {
    // Measure the TICR frequency
    xapicw(TDCR, X1);
    xapicw(TICR, 0xffffffff);
    u64 ccr0 = xapicr(TCCR);
    microdelay(10 * 1000);    // 1/100th of a second
    u64 ccr1 = xapicr(TCCR);
    xapichz = 100 * (ccr0 - ccr1);
  }

  count = (QUANTUM*xapichz) / 1000;
  if (count > 0xffffffff)
    panic("initxapic: QUANTUM too large");

  // The timer repeatedly counts down at bus frequency
  // from xapic[TICR] and then issues an interrupt.
  xapicw(TDCR, X1);
  xapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
  xapicw(TICR, count);

  // Disable logical interrupt lines.
  xapicw(LINT0, MASKED);
  xapicw(LINT1, MASKED);

  // Disable performance counter overflow interrupts
  // on machines that provide that interrupt entry.
  if(((xapic[VER]>>16) & 0xFF) >= 4)
    xapicpc(0);

  // Map error interrupt to IRQ_ERROR.
  xapicw(ERROR, T_IRQ0 + IRQ_ERROR);

  // Clear error status register (requires back-to-back writes).
  xapicw(ESR, 0);
  xapicw(ESR, 0);

  // Ack any outstanding interrupts.
  xapicw(EOI, 0);

  // Send an Init Level De-Assert to synchronise arbitration ID's.
  xapicw(ICRHI, 0);
  xapicw(ICRLO, BCAST | INIT | LEVEL);
  while(xapic[ICRLO] & DELIVS)
    ;

  // Enable interrupts on the APIC (but not on the processor).
  xapicw(TPR, 0);
}

void
xapicpc(char mask)
{
  xapicw(PCINT, mask ? MASKED : MT_NMI);
}

hwid_t
xapicid(void)
{
  if (readrflags() & FL_IF) {
    cli();
    panic("cpunum() called from %p with interrupts enabled\n",
      __builtin_return_address(0));
  }

  // To be safe, read the APIC ID from the CPUID register
  u32 ebx;
  cpuid(CPUID_FEATURES, 0, &ebx, 0, 0);
  return HWID(FEATURE_EBX_APIC(ebx));

#if 0
  // It should be safe to read from the APIC's MMIO anytime,
  // but it's not.  The BIOS might have enabled the x2APIC,
  // in which case the value of xapic[ID]>>24 is undefined.
  if (xapic == nullptr)
    panic("xapicid");
  return HWID(xapic[ID]>>24);
#endif
}

// Acknowledge interrupt.
void
xapiceoi(void)
{
  if(xapic)
    xapicw(EOI, 0);
}

// Send IPI
void
xapic_ipi(hwid_t hwid, int ino)
{
  xapicw(ICRHI, hwid.num << 24);
  xapicw(ICRLO, FIXED | DEASSERT | ino);
  if (xapicwait() < 0)
    panic("xapic_ipi: xapicwait failure");
}

void
xapic_tlbflush(hwid_t hwid)
{
  xapic_ipi(hwid, T_TLBFLUSH);
}

void
xapic_sampconf(hwid_t hwid)
{
  xapic_ipi(hwid, T_SAMPCONF);
}

// Start additional processor running bootstrap code at addr.
// See Appendix B of MultiProcessor Specification.
void
xapicstartap(hwid hwid, u32 addr)
{
  int i;
  volatile u16 *wrv;

  // "The BSP must initialize CMOS shutdown code to 0AH
  // and the warm reset vector (DWORD based at 40:67) to point at
  // the AP startup code prior to the [universal startup algorithm]."
  outb(IO_RTC, 0xF);  // offset 0xF is shutdown code
  outb(IO_RTC+1, 0x0A);
  wrv = (u16*)(0x40<<4 | 0x67);  // Warm reset vector
  wrv[0] = 0;
  wrv[1] = addr >> 4;

  // "Universal startup algorithm."
  // Send INIT (level-triggered) interrupt to reset other CPU.
  xapicw(ICRHI, hwid.num<<24);
  xapicw(ICRLO, hwid.num | INIT | LEVEL | ASSERT);
  xapicwait();
  microdelay(10000);
  xapicw(ICRLO, hwid.num |INIT | LEVEL);
  xapicwait();
  microdelay(10000);    // should be 10ms, but too slow in Bochs!

  // Send startup IPI (twice!) to enter bootstrap code.
  // Regular hardware is supposed to only accept a STARTUP
  // when it is in the halted state due to an INIT.  So the second
  // should be ignored, but it is part of the official Intel algorithm.
  // Bochs complains about the second one.  Too bad for Bochs.
  for(i = 0; i < 2; i++){
    xapicw(ICRHI, hwid.num<<24);
    xapicw(ICRLO, STARTUP | (addr>>12));
    microdelay(200);
  }
}
<commit_msg>Some XXX on the old xapic code<commit_after>// The local APIC manages internal (non-I/O) interrupts.
// See Chapter 8 & Appendix C of Intel processor manual volume 3.

#include "types.h"
#include "amd64.h"
#include "kernel.hh"
#include "traps.h"
#include "bits.hh"
#include "cpu.hh"
#include "apic.hh"

// Local APIC registers, divided by 4 for use as uint[] indices.
#define ID      (0x0020/4)   // ID
#define VER     (0x0030/4)   // Version
#define TPR     (0x0080/4)   // Task Priority
#define EOI     (0x00B0/4)   // EOI
#define SVR     (0x00F0/4)   // Spurious Interrupt Vector
  #define ENABLE     0x00000100   // Unit Enable
#define ESR     (0x0280/4)   // Error Status
#define ICRLO   (0x0300/4)   // Interrupt Command
  #define INIT       0x00000500   // INIT/RESET
  #define STARTUP    0x00000600   // Startup IPI
  #define DELIVS     0x00001000   // Delivery status
  #define ASSERT     0x00004000   // Assert interrupt (vs deassert)
  #define DEASSERT   0x00000000
  #define LEVEL      0x00008000   // Level triggered
  #define BCAST      0x00080000   // Send to all APICs, including self.
// XXX(sbw) BUSY and DELIVS?
  #define BUSY       0x00001000
  #define FIXED      0x00000000
#define ICRHI   (0x0310/4)   // Interrupt Command [63:32]
#define TIMER   (0x0320/4)   // Local Vector Table 0 (TIMER)
  #define X1         0x0000000B   // divide counts by 1
  #define PERIODIC   0x00020000   // Periodic
#define PCINT   (0x0340/4)   // Performance Counter LVT
#define LINT0   (0x0350/4)   // Local Vector Table 1 (LINT0)
#define LINT1   (0x0360/4)   // Local Vector Table 2 (LINT1)
#define ERROR   (0x0370/4)   // Local Vector Table 3 (ERROR)
  #define MASKED     0x00010000   // Interrupt masked
  #define MT_NMI     0x00000400   // NMI message type
  #define MT_FIX     0x00000000   // Fixed message type
#define TICR    (0x0380/4)   // Timer Initial Count
#define TCCR    (0x0390/4)   // Timer Current Count
#define TDCR    (0x03E0/4)   // Timer Divide Configuration

#define IO_RTC  0x70

static volatile u32 *xapic = (u32 *)(KBASE + 0xfee00000);
static u64 xapichz;

static void
xapicw(int index, int value)
{
  xapic[index] = value;
  xapic[ID];  // wait for write to finish, by reading
}

static u32
xapicr(u32 off)
{
  return xapic[off];
}

static int
xapicwait()
{
  int i = 100000;
  while ((xapicr(ICRLO) & BUSY) != 0) {
    nop_pause();
    i--;
    if (i == 0) {
      cprintf("xapicwait: wedged?\n");
      return -1;
    }
  }
  return 0;
}

void
initxapic(void)
{
  u64 count;
  u64 apicbar;

  // See Intel Arch. Manual Vol 3a, the APIC section
  // Check if x2APIC is enabled, disable it if so..
  apicbar = readmsr(MSR_APIC_BAR);
  if (apicbar & APIC_BAR_X2APIC_EN) {
    // Disable x2APIC and the xAPIC
    apicbar &= ~(APIC_BAR_XAPIC_EN | APIC_BAR_X2APIC_EN);
    writemsr(MSR_APIC_BAR, apicbar);
    // Re-enable the xAPIC
    apicbar |= APIC_BAR_XAPIC_EN;
    writemsr(MSR_APIC_BAR, apicbar);
    // Sanity-check..
    u32 ebx;
    cpuid(CPUID_FEATURES, 0, &ebx, 0, 0);
    assert(xapic[ID]>>24 == FEATURE_EBX_APIC(ebx));
  }

  // Enable local APIC; set spurious interrupt vector.
  xapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS));

  if (xapichz == 0) {
    // Measure the TICR frequency
    xapicw(TDCR, X1);
    xapicw(TICR, 0xffffffff);
    u64 ccr0 = xapicr(TCCR);
    microdelay(10 * 1000);    // 1/100th of a second
    u64 ccr1 = xapicr(TCCR);
    xapichz = 100 * (ccr0 - ccr1);
  }

  count = (QUANTUM*xapichz) / 1000;
  if (count > 0xffffffff)
    panic("initxapic: QUANTUM too large");

  // The timer repeatedly counts down at bus frequency
  // from xapic[TICR] and then issues an interrupt.
  xapicw(TDCR, X1);
  xapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
  xapicw(TICR, count);

  // Disable logical interrupt lines.
  xapicw(LINT0, MASKED);
  xapicw(LINT1, MASKED);

  // Disable performance counter overflow interrupts
  // on machines that provide that interrupt entry.
  if(((xapic[VER]>>16) & 0xFF) >= 4)
    xapicpc(0);

  // Map error interrupt to IRQ_ERROR.
  xapicw(ERROR, T_IRQ0 + IRQ_ERROR);

  // Clear error status register (requires back-to-back writes).
  xapicw(ESR, 0);
  xapicw(ESR, 0);

  // Ack any outstanding interrupts.
  xapicw(EOI, 0);

  // Send an Init Level De-Assert to synchronise arbitration ID's.
  xapicw(ICRHI, 0);
  xapicw(ICRLO, BCAST | INIT | LEVEL);
  while(xapic[ICRLO] & DELIVS)
    ;

  // Enable interrupts on the APIC (but not on the processor).
  xapicw(TPR, 0);
}

void
xapicpc(char mask)
{
  xapicw(PCINT, mask ? MASKED : MT_NMI);
}

hwid_t
xapicid(void)
{
  if (readrflags() & FL_IF) {
    cli();
    panic("cpunum() called from %p with interrupts enabled\n",
      __builtin_return_address(0));
  }

  // To be safe, read the APIC ID from the CPUID register
  u32 ebx;
  cpuid(CPUID_FEATURES, 0, &ebx, 0, 0);
  return HWID(FEATURE_EBX_APIC(ebx));

#if 0
  // It should be safe to read from the APIC's MMIO anytime,
  // but it's not.  The BIOS might have enabled the x2APIC,
  // in which case the value of xapic[ID]>>24 is undefined.
  if (xapic == nullptr)
    panic("xapicid");
  return HWID(xapic[ID]>>24);
#endif
}

// Acknowledge interrupt.
void
xapiceoi(void)
{
  if(xapic)
    xapicw(EOI, 0);
}

// Send IPI
void
xapic_ipi(hwid_t hwid, int ino)
{
  xapicw(ICRHI, hwid.num << 24);
  xapicw(ICRLO, FIXED | DEASSERT | ino);
  if (xapicwait() < 0)
    panic("xapic_ipi: xapicwait failure");
}

void
xapic_tlbflush(hwid_t hwid)
{
  xapic_ipi(hwid, T_TLBFLUSH);
}

void
xapic_sampconf(hwid_t hwid)
{
  xapic_ipi(hwid, T_SAMPCONF);
}

// Start additional processor running bootstrap code at addr.
// See Appendix B of MultiProcessor Specification.
void
xapicstartap(hwid hwid, u32 addr)
{
  int i;
  volatile u16 *wrv;

  // "The BSP must initialize CMOS shutdown code to 0AH
  // and the warm reset vector (DWORD based at 40:67) to point at
  // the AP startup code prior to the [universal startup algorithm]."
  outb(IO_RTC, 0xF);  // offset 0xF is shutdown code
  outb(IO_RTC+1, 0x0A);
  wrv = (u16*)(0x40<<4 | 0x67);  // Warm reset vector
  wrv[0] = 0;
  wrv[1] = addr >> 4;

  // "Universal startup algorithm."
  // Send INIT (level-triggered) interrupt to reset other CPU.

  xapicw(ICRHI, hwid.num<<24);
  // XXX(sbw) why hwid.num in ICRLO?
  xapicw(ICRLO, hwid.num | INIT | LEVEL | ASSERT);
  xapicwait();
  microdelay(10000);
  // XXX(sbw) why hwid.num in ICRLO?
  xapicw(ICRLO, hwid.num |INIT | LEVEL);
  xapicwait();
  microdelay(10000);    // should be 10ms, but too slow in Bochs!

  // Send startup IPI (twice!) to enter bootstrap code.
  // Regular hardware is supposed to only accept a STARTUP
  // when it is in the halted state due to an INIT.  So the second
  // should be ignored, but it is part of the official Intel algorithm.
  // Bochs complains about the second one.  Too bad for Bochs.
  for(i = 0; i < 2; i++){
    xapicw(ICRHI, hwid.num<<24);
    xapicw(ICRLO, STARTUP | (addr>>12));
    microdelay(200);
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "net/base/cert_database.h"

#include <openssl/x509.h>

#include "base/logging.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/base/openssl_private_key_store.h"
#include "net/base/x509_certificate.h"

namespace net {

CertDatabase::CertDatabase() {
}

int CertDatabase::CheckUserCert(X509Certificate* cert) {
  if (!cert)
    return ERR_CERT_INVALID;
  if (cert->HasExpired())
    return ERR_CERT_DATE_INVALID;

  if (!OpenSSLPrivateKeyStore::GetInstance()->FetchPrivateKey(
      X509_PUBKEY_get(X509_get_X509_PUBKEY(cert->os_cert_handle()))))
    return ERR_NO_PRIVATE_KEY_FOR_CERT;

  return OK;
}

int CertDatabase::AddUserCert(X509Certificate* cert) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

void CertDatabase::ListCerts(CertificateList* certs) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
}

CryptoModule* CertDatabase::GetPublicModule() const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return NULL;
}

CryptoModule* CertDatabase::GetPrivateModule() const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return NULL;
}

void CertDatabase::ListModules(CryptoModuleList* modules, bool need_rw) const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  modules->clear();
}

int CertDatabase::ImportFromPKCS12(CryptoModule* module,
                                   const std::string& data,
                                   const string16& password,
                                   bool is_extractable) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

int CertDatabase::ExportToPKCS12(const CertificateList& certs,
                                 const string16& password,
                                 std::string* output) const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return 0;
}

bool CertDatabase::DeleteCertAndKey(const X509Certificate* cert) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return false;
}

CertDatabase::TrustBits CertDatabase::GetCertTrust(const X509Certificate* cert,
                                                   CertType type) const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return 0;
}

bool CertDatabase::SetCertTrust(const X509Certificate* cert,
                                CertType type,
                                TrustBits trust_bits) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return false;
}

}  // namespace net
<commit_msg>net: build fix for OpenSSL from r113998<commit_after>// Copyright (c) 2011 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 "net/base/cert_database.h"

#include <openssl/x509.h>

#include "base/logging.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/base/openssl_private_key_store.h"
#include "net/base/x509_certificate.h"

namespace net {

CertDatabase::CertDatabase() {
}

int CertDatabase::CheckUserCert(X509Certificate* cert) {
  if (!cert)
    return ERR_CERT_INVALID;
  if (cert->HasExpired())
    return ERR_CERT_DATE_INVALID;

  if (!OpenSSLPrivateKeyStore::GetInstance()->FetchPrivateKey(
      X509_PUBKEY_get(X509_get_X509_PUBKEY(cert->os_cert_handle()))))
    return ERR_NO_PRIVATE_KEY_FOR_CERT;

  return OK;
}

int CertDatabase::AddUserCert(X509Certificate* cert) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

void CertDatabase::ListCerts(CertificateList* certs) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
}

CryptoModule* CertDatabase::GetPublicModule() const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return NULL;
}

CryptoModule* CertDatabase::GetPrivateModule() const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return NULL;
}

void CertDatabase::ListModules(CryptoModuleList* modules, bool need_rw) const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  modules->clear();
}

int CertDatabase::ImportFromPKCS12(CryptoModule* module,
                                   const std::string& data,
                                   const string16& password,
                                   bool is_extractable,
                                   CertificateList* imported_certs) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

int CertDatabase::ExportToPKCS12(const CertificateList& certs,
                                 const string16& password,
                                 std::string* output) const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return 0;
}

bool CertDatabase::DeleteCertAndKey(const X509Certificate* cert) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return false;
}

CertDatabase::TrustBits CertDatabase::GetCertTrust(const X509Certificate* cert,
                                                   CertType type) const {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return 0;
}

bool CertDatabase::SetCertTrust(const X509Certificate* cert,
                                CertType type,
                                TrustBits trust_bits) {
  // TODO(bulach): implement me.
  NOTIMPLEMENTED();
  return false;
}

}  // namespace net
<|endoftext|>


<commit_before>/**
 Copyright 2017 Daniel Garcia Vaglio <degv364@gmail.com> Esteban Zamora Alvarado <estebanzacr.20@gmail.com>

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 associated documentation files (the "Software"), to deal in the Software without restriction,
 including without limitation the rights to use, copy, modify, merge, publish, distribute,
 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
 OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 **/

/* Standard Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "msp.h"

/* Project Includes*/
#include "common_def.hh"
#include "hd/periph.hh"
#include "hi/hi_def.hh"

/*Variables defined in other files*/
extern volatile uint64_t g_SystemTicks;

//FIXME: Remove after testing ADC config
extern volatile int16_t resultsBuffer[3];

/*Interrupt Service Routines (ISR) Definition*/
extern "C"
{

/* ISR activated by Timer32-1 for time measurement through the
 * software timer update
*/
void T32_INT1_IRQHandler(void)
{
    __disable_irq();

    periph::Timer::cleanIRQ(TIMER32_0_BASE);
    g_SystemTicks++;

    __enable_irq();
}

/* ISR activated by Timer32-2 for ADC sampling frequency
*/
void T32_INT2_IRQHandler(void)
{
    __disable_irq();

    periph::Timer::cleanIRQ(TIMER32_1_BASE);
    //FIXME: Implement ADC Timer ISR
    MAP_ADC14_toggleConversionTrigger();

    __enable_irq();
}

/* ISR that manages the ADC Accelerometer reading
 * sampling frequency
*/
void ADC14_IRQHandler(void)
{
    __disable_irq();
    //FIXME: Implement ADC ISR

    if (periph::AccelADC::CheckAndCleanIRQ(ADC_INT2))
    {
        resultsBuffer[0] = ADC14_getResult(ADC_MEM0);
        resultsBuffer[1] = ADC14_getResult(ADC_MEM1);
        resultsBuffer[2] = ADC14_getResult(ADC_MEM2);
    }

    __enable_irq();
}

}

<commit_msg>Updated Lab2 ISR Fixmes<commit_after>/**
 Copyright 2017 Daniel Garcia Vaglio <degv364@gmail.com> Esteban Zamora Alvarado <estebanzacr.20@gmail.com>

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 associated documentation files (the "Software"), to deal in the Software without restriction,
 including without limitation the rights to use, copy, modify, merge, publish, distribute,
 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
 OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 **/

/* Standard Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "msp.h"

/* Project Includes*/
#include "common_def.hh"
#include "hd/periph.hh"
#include "hi/hi_def.hh"

/*Variables defined in other files*/
extern volatile uint64_t g_SystemTicks;

//FIXME: Remove after testing ADC config
extern volatile int16_t resultsBuffer[3];

/*Interrupt Service Routines (ISR) Definition*/
extern "C"
{

/* ISR activated by Timer32-1 for time measurement through the
 * software timer update
*/
void T32_INT1_IRQHandler(void)
{
    __disable_irq();

    periph::Timer::cleanIRQ(TIMER32_0_BASE);
    //FIXME: Check if frame is finished
    g_SystemTicks++;

    __enable_irq();
}

/* ISR activated by Timer32-2 for ADC sampling frequency
*/
void T32_INT2_IRQHandler(void)
{
    __disable_irq();

    periph::Timer::cleanIRQ(TIMER32_1_BASE);
    MAP_ADC14_toggleConversionTrigger();

    __enable_irq();
}

/* ISR that manages the ADC Accelerometer reading
 * sampling frequency
*/
void ADC14_IRQHandler(void)
{
    __disable_irq();
    //FIXME: Implement ADC ISR

    if (periph::AccelADC::CheckAndCleanIRQ(ADC_INT2))
    {
        resultsBuffer[0] = ADC14_getResult(ADC_MEM0);
        resultsBuffer[1] = ADC14_getResult(ADC_MEM1);
        resultsBuffer[2] = ADC14_getResult(ADC_MEM2);
    }

    __enable_irq();
}

}

<|endoftext|>


<commit_before>// Author: Enrico Guiraud, Danilo Piparo CERN  09/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TDATASOURCE
#define ROOT_TDATASOURCE

#include "RStringView.h"
#include "RtypesCore.h" // ULong64_t
#include <algorithm> // std::transform
#include <vector>
#include <typeinfo>

namespace ROOT {
namespace Experimental {
namespace TDF {

/**
\class ROOT::Experimental::TDF::TDataSource
\ingroup dataframe
\brief The TDataSource interface dictates how a TDataFrame interface to an arbitrary data format should look like.

A TDataSource allows to seamlessly provide an adaptor for any kind of data set or data format to the TDataFrame. Another way to imagine it is a veritable "cursor".
*/
class TDataSource {
public:
   virtual ~TDataSource() = default;

   /// \brief Returns a reference to the collection of the dataset's column names
   virtual const std::vector<std::string> &GetColumnNames() const = 0;

   /// \brief Checks if the dataset has a certain column
   /// \param[in] columnName The name of the column
   virtual bool HasColumn(std::string_view) const = 0;

   /// \brief Type of a column as a string, e.g. `GetTypeName("x") == "double"`. Required for jitting e.g. `df.Filter("x>0")`.
   /// \param[in] columnName The name of the column
   virtual std::string GetTypeName(std::string_view) const = 0;

   /// Called at most once per column by TDF. Return vector of pointers to pointers to column values - one per slot.
   /// \tparam T The type of the data stored in the column
   /// \param[in] columnName The name of the column
   ///
   /// These pointers are veritable cursors: it's a responsibility of the TDataSource implementation that they point to the
   /// "right" memory region.
   template <typename T>
   std::vector<T **> GetColumnReaders(std::string_view columnName)
   {
      auto typeErasedVec = GetColumnReadersImpl(columnName, typeid(T));
      std::vector<T **> typedVec(typeErasedVec.size());
      std::transform(typeErasedVec.begin(), typeErasedVec.end(), typedVec.begin(),
                     [](void *p) { return static_cast<T **>(p); });
      return typedVec;
   }

   /// \brief Return ranges of entries to distribute to tasks.
   /// They are required to be contiguous intervals with no entries skipped. Supposing a dataset with nEntries, the intervals
   /// must start at 0 and end at nEntries, e.g. [0-5],[5-10] for 10 entries.
   virtual const std::vector<std::pair<ULong64_t, ULong64_t>> &GetEntryRanges() const = 0;

   /// \brief Advance the "cursors" returned by GetColumnReaders to the selected entry for a particular slot.
   /// \param[in] slot The data processing slot that needs to be considered
   /// \param[in] entry The entry which needs to be pointed to by the reader pointers
   /// Slots are adopted to accommodate parallel data processing. Different workers will loop over different ranges and will
   /// be labelled by different "slot" values.
   virtual void SetEntry(unsigned int slot, ULong64_t entry) = 0;

   /// \brief Convenience method to set the number of slots
   /// For some implementation it's necessary to know the number of slots in advance for optimisation purposes.
   virtual void SetNSlots(unsigned int nSlots) = 0;

   /// \brief Convenience method called at the start of the data processing.
   /// \param[in] slot The data processing slot wihch needs to be initialised
   /// \param[in] firstEntry The first entry of the range that the task will process.
   virtual void InitSlot(unsigned int /*slot*/, ULong64_t /*firstEntry*/) {}

protected:
   /// type-erased vector of pointers to pointers to column values - one per slot
   virtual std::vector<void *>
   GetColumnReadersImpl(std::string_view name, const std::type_info &) = 0;
};

} // ns TDF
} // ns Experimental
} // ns ROOT

#endif // ROOT_TDATASOURCE
<commit_msg>[TDF] Add to the TDataSource the FinaliseSlot method<commit_after>// Author: Enrico Guiraud, Danilo Piparo CERN  09/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TDATASOURCE
#define ROOT_TDATASOURCE

#include "RStringView.h"
#include "RtypesCore.h" // ULong64_t
#include <algorithm> // std::transform
#include <vector>
#include <typeinfo>

namespace ROOT {
namespace Experimental {
namespace TDF {

/**
\class ROOT::Experimental::TDF::TDataSource
\ingroup dataframe
\brief The TDataSource interface dictates how a TDataFrame interface to an arbitrary data format should look like.

A TDataSource allows to seamlessly provide an adaptor for any kind of data set or data format to the TDataFrame. Another way to imagine it is a veritable "cursor".
*/
class TDataSource {
public:
   virtual ~TDataSource() = default;

   /// \brief Returns a reference to the collection of the dataset's column names
   virtual const std::vector<std::string> &GetColumnNames() const = 0;

   /// \brief Checks if the dataset has a certain column
   /// \param[in] columnName The name of the column
   virtual bool HasColumn(std::string_view) const = 0;

   /// \brief Type of a column as a string, e.g. `GetTypeName("x") == "double"`. Required for jitting e.g. `df.Filter("x>0")`.
   /// \param[in] columnName The name of the column
   virtual std::string GetTypeName(std::string_view) const = 0;

   /// Called at most once per column by TDF. Return vector of pointers to pointers to column values - one per slot.
   /// \tparam T The type of the data stored in the column
   /// \param[in] columnName The name of the column
   ///
   /// These pointers are veritable cursors: it's a responsibility of the TDataSource implementation that they point to the
   /// "right" memory region.
   template <typename T>
   std::vector<T **> GetColumnReaders(std::string_view columnName)
   {
      auto typeErasedVec = GetColumnReadersImpl(columnName, typeid(T));
      std::vector<T **> typedVec(typeErasedVec.size());
      std::transform(typeErasedVec.begin(), typeErasedVec.end(), typedVec.begin(),
                     [](void *p) { return static_cast<T **>(p); });
      return typedVec;
   }

   /// \brief Return ranges of entries to distribute to tasks.
   /// They are required to be contiguous intervals with no entries skipped. Supposing a dataset with nEntries, the intervals
   /// must start at 0 and end at nEntries, e.g. [0-5],[5-10] for 10 entries.
   virtual const std::vector<std::pair<ULong64_t, ULong64_t>> &GetEntryRanges() const = 0;

   /// \brief Advance the "cursors" returned by GetColumnReaders to the selected entry for a particular slot.
   /// \param[in] slot The data processing slot that needs to be considered
   /// \param[in] entry The entry which needs to be pointed to by the reader pointers
   /// Slots are adopted to accommodate parallel data processing. Different workers will loop over different ranges and will
   /// be labelled by different "slot" values.
   virtual void SetEntry(unsigned int slot, ULong64_t entry) = 0;

   /// \brief Convenience method to set the number of slots
   /// For some implementation it's necessary to know the number of slots in advance for optimisation purposes.
   virtual void SetNSlots(unsigned int nSlots) = 0;

   /// \brief Convenience method called at the start of the data processing associated to a slot.
   /// \param[in] slot The data processing slot wihch needs to be initialised
   /// \param[in] firstEntry The first entry of the range that the task will process.
   virtual void InitSlot(unsigned int /*slot*/, ULong64_t /*firstEntry*/) {}

   /// \brief Convenience method called at the end of the data processing associated to a slot.
   /// \param[in] slot The data processing slot wihch needs to be finalised
   virtual void FinaliseSlot(unsigned int /*slot*/) {}

protected:
   /// type-erased vector of pointers to pointers to column values - one per slot
   virtual std::vector<void *>
   GetColumnReadersImpl(std::string_view name, const std::type_info &) = 0;
};

} // ns TDF
} // ns Experimental
} // ns ROOT

#endif // ROOT_TDATASOURCE
<|endoftext|>


<commit_before>void MUONtestabso (Int_t evNumber1=0,Int_t evNumber2=0)
{
/////////////////////////////////////////////////////////////////////////
//   This macro is a small example of a ROOT macro
//   illustrating how to read the output of GALICE
//   and do some analysis.
//
/////////////////////////////////////////////////////////////////////////

// Dynamically link some shared libs
    static Float_t xmuon, ymuon;

   if (gClassTable->GetID("AliRun") < 0) {
      gROOT->LoadMacro("loadlibs.C");
      loadlibs();
   }

// Connect the Root Galice file containing Geometry, Kine and Hits

    TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root");

    if (!file) {
	printf("\n Creating galice.root \n");
	file = new TFile("galice.root");
    } else {
	printf("\n galice.root found in file list");
    }
    file->ls();

// Get AliRun object from file or create it if not on file
    if (!gAlice) {
	gAlice = (AliRun*)(file->Get("gAlice"));
	if (gAlice) printf("AliRun object found on file\n");
	if (!gAlice) {
	    printf("\n Create new gAlice object");
	    gAlice = new AliRun("gAlice","Alice test program");
	}
    }

//  Create some histograms

   TH1F *zv = new TH1F("zv","z vertex" ,140,470.,505.);
   TH1F *xv = new TH1F("xv","x vertex" ,140,-70.,70.);
   TH1F *yv = new TH1F("yv","y vertex", 140,-70.,70.);

   TH1F *ip  = new TH1F("ip","geant part",50,0.,10.);
   TH2F *rzv  = new TH2F("rzv","R-z vert",100,502,504.,100,0.,100.);

   TH1F *ptUps  = new TH1F("ptUps","pT Upsilon",50,0.,25.);
   TH1F *hde  = new TH1F("hde","dE",200,0.,50);
   TH1F *hde2  = new TH1F("hde2","dE",100,1.5,5.5);
   TH2F *hdevsn  = new TH2F("hdevsn","dE vs N electron",100,0.,15., 20, 0.,20.);

   TH1F *ekine  = new TH1F("ekine","E_kin electrons",70,-5,2);
   TH1F *etheta = new TH1F("etheta","Theta electrons",90,0,90);
   TH1F *edr = new TH1F("edr","Distance to muon",100,0,10);

   TH1F *de  = new TH1F("de","correction",100,-1,1);

   TH1F *dtheta = new TH1F("dtheta","Delta Theta" ,200,-5.,5.);
   AliMUONChamber*  iChamber;
//
//   Loop over events
//
   Int_t Nh=0;
   Int_t Nh1=0;
       Int_t Nel1=0;
       Int_t Nel2=0;
       Int_t Nel3=0;
       Int_t Nel4=0;

   for (Int_t nev=0; nev<= evNumber2; nev++) {
       //cout << "nev         " << nev <<endl;
       Int_t nparticles = gAlice->GetEvent(nev);
       //cout << "nparticles  " << nparticles <<endl;
       if (nev < evNumber1) continue;
       if (nparticles <= 0) return;

       AliMUON *MUON  = (AliMUON*) gAlice->GetModule("MUON");

       TTree *TH = gAlice->TreeH();
       Int_t ntracks = TH->GetEntries();
//
//   Loop over tracks
//

       Float_t dE;

       for (Int_t track=0; track<ntracks;track++) {
	   Int_t Nelt=0;
	   printf("\n nev %d %d %d %d %d\n ", nev, Nel1, Nel2, Nel3, Nel4);
	   gAlice->ResetHits();
	   Int_t nbytes += TH->GetEvent(track);
	   if (MUON)  {
	       for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1);
		   mHit;
		   mHit=(AliMUONHit*)MUON->NextHit())
	       {
		   Int_t   nch   = mHit->fChamber;  // chamber number
		   Float_t x     = mHit->fX;        // x-pos of hit
		   Float_t y     = mHit->fY;        // y-pos
		   Float_t z     = mHit->fZ;        // y-pos

		   if (nch != 1) continue;

		   Int_t ipart = mHit->fParticle;
		   TClonesArray *fPartArray = gAlice->Particles();
		   TParticle *Part;
		   Int_t ftrack = mHit->fTrack;
		   Part = (TParticle*) fPartArray->UncheckedAt(ftrack);
		   Int_t ipart = Part->GetPdgCode();
		   ip->Fill((float)ipart);
		   TParticle *Mother;

		   Float_t px0=Part->Px();
		   Float_t py0=Part->Py();
		   Float_t pz0=Part->Pz();
		   Float_t thetax0=TMath::ATan2(px0,pz0);
		   Float_t thetay0=TMath::ATan2(py0,pz0);

		   if (ipart == kMuonPlus || ipart == kMuonMinus) {
//		       Int_t imo = Part->GetFirstMother();
//		       Mother = (TParticle*) fPartArray->UncheckedAt(imo);
//		       Float_t pt = Mother->Pt();
//		       ptUps->Fill(pt, (float) 1);
		       Float_t E=Part->Energy();
		       Float_t Eloc=mHit->fPTot;
		       Float_t corr=Eloc+CorrectP(Eloc,mHit->fTheta);
		       printf("\n %f %f %f", E, Eloc, corr);
		       de->Fill(E-corr,1.);
		       dE = E-Eloc;
		       if (dE<50)  hde->Fill(dE, (float) 1);
		       if (dE<5.5) hde2->Fill(dE, (float) 1);
		       xmuon=mHit->fX;
		       ymuon=mHit->fY;
		       Float_t thetax=TMath::ATan2(mHit->Px(), mHit->Momentum());
		       Float_t thetay=TMath::ATan2(mHit->Py(), mHit->Momentum());
		       dtheta->Fill((thetax-thetax0)*1000., 1.);
		       dtheta->Fill((thetay-thetay0)*1000., 1.);
		   }

		   if (ipart == kElectron || ipart == kPositron) {

		       Float_t xvert = Part->Vx();       //  vertex
		       Float_t yvert = Part->Vy();       //  vertex
		       Float_t zvert = Part->Vz();       // z vertex
		       if (zvert < 503 && mHit->fTheta<90) {
			   Nelt++;
			   Float_t px = Part->Px();
			   Float_t py = Part->Py();
			   Float_t pz = Part->Pz();
			   Float_t Ek = Part->Energy()-Part->GetMass();

			   Int_t imo = Part->GetFirstMother();
			   Mother = (TParticle*) fPartArray->UncheckedAt(imo);
			   Int_t imot = Mother->GetPdgCode();
			   xv->Fill(xvert);
			   yv->Fill(yvert);
			   zv->Fill(zvert);
			   Float_t rvert=TMath::Sqrt(xvert*xvert+yvert*yvert);
			   rzv->Fill(zvert,rvert);
			   ekine->Fill(TMath::Log10(Ek),1.);
			   etheta->Fill(mHit->fTheta,1.);
			   Float_t ex=mHit->fX;
			   Float_t ey=mHit->fY;
			   dr=TMath::Sqrt((ex-xmuon)*(ex-xmuon)+(ey-ymuon)*(ey-ymuon));
			   edr->Fill(dr,1.);

		       }
		   }

	       } // hits
	   } // if MUON
	   if (Nelt == 1) Nel1++;
	   if (Nelt == 2) Nel2++;
	   if (Nelt == 3) Nel3++;
	   if (Nelt  > 3) Nel4++;
	   hdevsn->Fill(dE, (float) Nelt, (float) 1);

       } // tracks

    } // event

//Create a canvas, set the view range, show histograms
   TCanvas *c1 = new TCanvas("c1","Vetices from electrons and positrons",400,10,600,700);
   c1->Divide(2,2);

   c1->cd(1);
   ip->SetFillColor(42);
   ip->SetXTitle("ipart");
   ip->Draw();

   c1->cd(2);
   xv->SetFillColor(42);
   xv->SetXTitle("xvert");
   xv->Draw();

   c1->cd(3);
   yv->SetFillColor(42);
   yv->SetXTitle("yvert");
   yv->Draw();

   c1->cd(4);
   zv->SetFillColor(42);
   zv->SetXTitle("zvert");
   zv->Draw();

   TCanvas *c2 = new TCanvas("c2"," ",400,10,600,700);
   c2->Divide(2,2);
   c2->cd(1);
   rzv->SetXTitle("zvert");
   rzv->SetYTitle("rvert");
   rzv->Draw();

   c2->cd(2);
   ptUps->SetXTitle("pt");
   ptUps->Draw();

   c2->cd(3);
   hde->SetXTitle("dE");
   hde->Draw();

   c2->cd(4);
   hde2->SetXTitle("dE");
   hde2->Draw();
   TCanvas *c3 = new TCanvas("c3"," ",400,10,600,700);
   c3->Divide(2,2);
   c3->cd(1);
   ekine->SetXTitle("E_kin");
   ekine->Draw();

   c3->cd(2);
   etheta->SetXTitle("Theta");
   etheta->Draw();

   c3->cd(3);
   edr->SetXTitle("Distance to muon");
   edr->Draw();

   c3->cd(4);
   dtheta->SetXTitle(" ");
   dtheta->Draw();

}

Float_t CorrectP(Float_t p, Float_t theta)
{
    printf("\n %f%", theta);

    if (theta<3.) {
//W
	if (p<15) {
	    return 2.737+0.0494*p-0.001123*p*p;
	} else {
	    return 3.0643+0.01346*p;
	}
    } else {
//Pb
	if (p<15) {
	    return 2.1380+0.0351*p-0.000853*p*p;
	} else {
	    return 2.407+0.00702*p;
	}
    }
}

<commit_msg>remove obsolete macro<commit_after><|endoftext|>


<commit_before>#include <stdlib.h>
#include <winsock.h>
#include "../lib/as3.hpp"
#include <string>
using std::string; using std::to_string;
#include <iostream>
using std::cout; using std::endl; using std::cin;

namespace as3
{
    auto inline make_address() -> sockaddr_in
    {
        auto addr = sockaddr_in{};
        memset(&addr, 0, sizeof(addr));
        return addr;
    }

    auto inline bind(as3::Socket const& sock, sockaddr_in const& addr) -> bool
    {
        if ( 0 != ::bind(sock.get(), (struct sockaddr *)(&addr), sizeof(addr)) )
        {
            as3::println("Bind failed!");
            return false;
        }
        return true;
    }
}

int main(int argc, char *argv[])
{
    as3::setup_win_sock_api(as3::WSVERS);
    as3::Socket sock{ AF_INET, SOCK_STREAM, 0 };
    if (sock.is_failed()) as3::println( "socket failed" );

    auto local_addr = as3::make_address();
    {
        local_addr.sin_family = AF_INET;
        if (argc == 2) local_addr.sin_port = htons((u_short)atoi(argv[1]));
        else local_addr.sin_port = htons(1234);//default listening port
        local_addr.sin_addr.s_addr = INADDR_ANY;//server IP address should be local
    }

    if (as3::bind(sock, local_addr) == false) return 1;
    //if (bind(sock.get(), (struct sockaddr *)(&local_addr), sizeof(local_addr)) != 0)
    //{
    //    as3::println("Bind failed!");
    //    exit(0);
    //}

    auto remote_addr = as3::make_address();
    for (listen(sock.get(), 5); true; as3::println("disconnected from " + string(inet_ntoa(remote_addr.sin_addr))))
    {
        int addrlen = sizeof(remote_addr);
        as3::Socket new_sock{ ::accept(sock.get(), (sockaddr*)(&remote_addr), &addrlen) };
        if (new_sock.is_failed()) break;
        as3::println("accepted connection from IP " + string(inet_ntoa(remote_addr.sin_addr)) + " port " + to_string(ntohs(remote_addr.sin_port)));

        for (auto receive = as3::Receive{}; receive.is_normal(); )
        {
            auto message_reveived = receive(new_sock);
            if (!receive.is_normal()) break;
            as3::println("The client is sending:\n" + message_reveived);

            auto feed_back = "<<< SERVER SAYS:The client typed '" + message_reveived + "' -- " + to_string(message_reveived.size()) + " bytes in total\r\n";
            as3::send(new_sock.get(), feed_back);
        }
    }
    return 0;
}<commit_msg>	modified:   src/2015a3/rsa/server/server.cpp<commit_after>#include <stdlib.h>
#include <winsock.h>
#include "../lib/as3.hpp"
#include <string>
using std::string; using std::to_string;
#include <iostream>
using std::cout; using std::endl; using std::cin;

namespace as3
{
    auto inline make_address() -> sockaddr_in
    {
        auto addr = sockaddr_in{};
        memset(&addr, 0, sizeof(addr));
        return addr;
    }

    auto inline bind(as3::Socket const& sock, sockaddr_in const& addr) -> bool
    {
        if ( 0 != ::bind(sock.get(), (struct sockaddr *)(&addr), sizeof(addr)) )
        {
            as3::println("Bind failed!");
            return false;
        }
        return true;
    }
}

int main(int argc, char *argv[])
{
    as3::setup_win_sock_api(as3::WSVERS);
    as3::Socket sock{ AF_INET, SOCK_STREAM, 0 };
    if (sock.is_failed()) as3::println( "socket failed" );

    auto local_addr = as3::make_address();
    {
        local_addr.sin_family = AF_INET;
        if (argc == 2) local_addr.sin_port = htons((u_short)atoi(argv[1]));
        else local_addr.sin_port = htons(1234);//default listening port
        local_addr.sin_addr.s_addr = INADDR_ANY;//server IP address should be local
    }

    if (as3::bind(sock, local_addr) == false) return 1;
    auto remote_addr = as3::make_address();
    for (listen(sock.get(), 5); true; as3::println("disconnected from " + string(inet_ntoa(remote_addr.sin_addr))))
    {
        int addrlen = sizeof(remote_addr);
        as3::Socket new_sock{ ::accept(sock.get(), (sockaddr*)(&remote_addr), &addrlen) };
        if (new_sock.is_failed()) break;
        as3::println("accepted connection from IP " + string(inet_ntoa(remote_addr.sin_addr)) + " port " + to_string(ntohs(remote_addr.sin_port)));

        for (auto receive = as3::Receive{}; receive.is_normal(); )
        {
            auto message_reveived = receive(new_sock);
            if (!receive.is_normal()) break;
            as3::println("The client is sending:\n" + message_reveived);

            auto feed_back = "<<< SERVER SAYS:The client typed '" + message_reveived + "' -- " + to_string(message_reveived.size()) + " bytes in total\r\n";
            as3::send(new_sock.get(), feed_back);
        }
    }
    return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "chrome/common/child_thread.h"

#include "base/command_line.h"
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/ipc_logging.h"
#include "webkit/glue/webkit_glue.h"

ChildThread::ChildThread(Thread::Options options)
    : Thread("Chrome_ChildThread"),
      owner_loop_(MessageLoop::current()),
      in_send_(0),
      options_(options) {
  DCHECK(owner_loop_);
  channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kProcessChannelID);

  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserAgent)) {
#if defined(OS_WIN)
    // TODO(port): calling this connects an, otherwise disconnected, subgraph
    // of symbols, causing huge numbers of linker errors.
    webkit_glue::SetUserAgent(WideToUTF8(
        CommandLine::ForCurrentProcess()->GetSwitchValue(switches::kUserAgent)));
#endif
  }
}

ChildThread::~ChildThread() {
}

bool ChildThread::Run() {
  return StartWithOptions(options_);
}

void ChildThread::OnChannelError() {
  owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}

bool ChildThread::Send(IPC::Message* msg) {
  if (!channel_.get()) {
    delete msg;
    return false;
  }

  in_send_++;
  bool rv = channel_->Send(msg);
  in_send_--;
  return rv;
}

void ChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
  DCHECK(MessageLoop::current() == message_loop());

  router_.AddRoute(routing_id, listener);
}

void ChildThread::RemoveRoute(int32 routing_id) {
  DCHECK(MessageLoop::current() == message_loop());

  router_.RemoveRoute(routing_id);
}

void ChildThread::OnMessageReceived(const IPC::Message& msg) {
  if (msg.routing_id() == MSG_ROUTING_CONTROL) {
    OnControlMessageReceived(msg);
  } else {
    router_.OnMessageReceived(msg);
  }
}

ChildThread* ChildThread::current() {
  return ChildProcess::current()->child_thread();
}

void ChildThread::Init() {
  channel_.reset(new IPC::SyncChannel(channel_name_,
      IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
      ChildProcess::current()->GetShutDownEvent()));
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::current()->SetIPCSender(this);
#endif
}

void ChildThread::CleanUp() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::current()->SetIPCSender(NULL);
#endif
  // Need to destruct the SyncChannel to the browser before we go away because
  // it caches a pointer to this thread.
  channel_.reset();
}
<commit_msg>Fix release build break<commit_after>// Copyright (c) 2009 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 "chrome/common/child_thread.h"

#include "base/command_line.h"
#include "base/string_util.h"
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/ipc_logging.h"
#include "webkit/glue/webkit_glue.h"

ChildThread::ChildThread(Thread::Options options)
    : Thread("Chrome_ChildThread"),
      owner_loop_(MessageLoop::current()),
      in_send_(0),
      options_(options) {
  DCHECK(owner_loop_);
  channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kProcessChannelID);

  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserAgent)) {
#if defined(OS_WIN)
    // TODO(port): calling this connects an, otherwise disconnected, subgraph
    // of symbols, causing huge numbers of linker errors.
    webkit_glue::SetUserAgent(WideToUTF8(
        CommandLine::ForCurrentProcess()->GetSwitchValue(switches::kUserAgent)));
#endif
  }
}

ChildThread::~ChildThread() {
}

bool ChildThread::Run() {
  return StartWithOptions(options_);
}

void ChildThread::OnChannelError() {
  owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}

bool ChildThread::Send(IPC::Message* msg) {
  if (!channel_.get()) {
    delete msg;
    return false;
  }

  in_send_++;
  bool rv = channel_->Send(msg);
  in_send_--;
  return rv;
}

void ChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
  DCHECK(MessageLoop::current() == message_loop());

  router_.AddRoute(routing_id, listener);
}

void ChildThread::RemoveRoute(int32 routing_id) {
  DCHECK(MessageLoop::current() == message_loop());

  router_.RemoveRoute(routing_id);
}

void ChildThread::OnMessageReceived(const IPC::Message& msg) {
  if (msg.routing_id() == MSG_ROUTING_CONTROL) {
    OnControlMessageReceived(msg);
  } else {
    router_.OnMessageReceived(msg);
  }
}

ChildThread* ChildThread::current() {
  return ChildProcess::current()->child_thread();
}

void ChildThread::Init() {
  channel_.reset(new IPC::SyncChannel(channel_name_,
      IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
      ChildProcess::current()->GetShutDownEvent()));
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::current()->SetIPCSender(this);
#endif
}

void ChildThread::CleanUp() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::current()->SetIPCSender(NULL);
#endif
  // Need to destruct the SyncChannel to the browser before we go away because
  // it caches a pointer to this thread.
  channel_.reset();
}
<|endoftext|>


<commit_before><commit_msg>Crash on serious error in sqlite (release build)<commit_after><|endoftext|>


<commit_before>/*
    Copyright (C) 2013  David Edmundson <davidedmundson@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 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "kpeople-actions-plugin.h"

#include <QAction>

#include <QIcon>
#include <KLocalizedString>
#include <KPluginFactory>
#include <QFileDialog>

#include "KTp/contact.h"
#include "KTp/actions.h"
#include "KTp/core.h"
#include "KTp/global-contact-manager.h"

#include <TelepathyQt/Account>
#include <TelepathyQt/ContactManager>

#include <KPeople/PersonData>

enum IMActionType {
    TextChannel,
    AudioChannel,
    VideoChannel,
    FileTransfer,
    LogViewer,
    CollabEditing
};

class IMAction : public QAction {
    Q_OBJECT
public:
    IMAction(const QString &text, const QIcon &icon, const KTp::ContactPtr &contact,
             const Tp::AccountPtr &account, IMActionType type, QObject *parent);
    IMAction(const QString &text, const QIcon &icon, const QUrl &uri,
             IMActionType type, QObject *parent);
    KTp::ContactPtr contact() const;
    Tp::AccountPtr account() const;
    IMActionType type() const;
    QUrl uri() const;
private:
    KTp::ContactPtr m_contact;
    Tp::AccountPtr m_account;
    QUrl m_uri;
    IMActionType m_type;
};

IMAction::IMAction(const QString &text, const QIcon &icon, const KTp::ContactPtr &contact,
                   const Tp::AccountPtr &account, IMActionType type, QObject *parent):
    QAction(icon, text, parent),
    m_contact(contact),
    m_account(account),
    m_type(type)
{
}

IMAction::IMAction(const QString &text, const QIcon &icon, const QUrl &uri,
                   IMActionType type, QObject *parent):
    QAction(icon, text, parent),
    m_uri(uri),
    m_type(type)
{
}

KTp::ContactPtr IMAction::contact() const
{
    return m_contact;
}

Tp::AccountPtr IMAction::account() const
{
    return m_account;
}

IMActionType IMAction::type() const
{
    return m_type;
}

QUrl IMAction::uri() const
{
    return m_uri;
}

KPeopleActionsPlugin::KPeopleActionsPlugin(QObject *parent, const QVariantList &args)
    : AbstractPersonAction(parent)
{
    Q_UNUSED(args);
}

QList<QAction*> KPeopleActionsPlugin::actionsForPerson(const KPeople::PersonData &person,
                                                       QObject *parent) const
{
    QList<QAction*> actions;

    // === TODO ===
    // This creates actions just for the "most online contact", what we want is to query all
    // the subcontacts for all capabilities and fill them in on the Person, so if eg. one of
    // the subcontacts can do audio calls and the other can do video calls, the Person
    // should have both actions present.
    QString accountPath = person.contactCustomProperty(QLatin1String("telepathy-accountPath")).toString();
    QString contactId = person.contactCustomProperty(QLatin1String("telepathy-contactId")).toString();

    const Tp::AccountPtr account = KTp::contactManager()->accountForAccountPath(accountPath);
    if (!account) {
        return actions;
    }

    const KTp::ContactPtr contact = KTp::contactManager()->contactForContactId(accountPath, contactId);
    if (!contact || !contact->manager()) {
        return actions;
    }

    if (contact->textChatCapability()) {
        QAction *action = new IMAction(i18n("Start Chat Using %1...", account->displayName()),
                            QIcon::fromTheme(QStringLiteral("text-x-generic")),
                            contact,
                            account,
                            TextChannel,
                            parent);
        connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
        actions << action;
    }
    if (contact->audioCallCapability()) {
        QAction *action = new IMAction(i18n("Start Audio Call Using %1...", account->displayName()),
                            QIcon::fromTheme(QStringLiteral("audio-headset")),
                            contact,
                            account,
                            AudioChannel,
                            parent);
        connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
        actions << action;
    }
    if (contact->videoCallCapability()) {
        QAction *action = new IMAction(i18n("Start Video Call Using %1...", account->displayName()),
                            QIcon::fromTheme(QStringLiteral("camera-web")),
                            contact,
                            account,
                            VideoChannel,
                            parent);
        connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
        actions << action;
    }

    if (contact->fileTransferCapability()) {
        QAction *action = new IMAction(i18n("Send Files Using %1...", account->displayName()),
                                    QIcon::fromTheme(QStringLiteral("mail-attachment")),
                                    contact,
                                    account,
                                    FileTransfer,
                                    parent);
        connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
        actions << action;
    }
    if (contact->collaborativeEditingCapability()) {
        QAction *action = new IMAction(i18n("Collaboratively edit a document Using %1...", account->displayName()),
                                    QIcon::fromTheme(QStringLiteral("document-edit")),
                                    contact,
                                    account,
                                    CollabEditing,
                                    parent);
        connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
        actions << action;
    }

    //FIXME-KPEOPLE
//     QAction *action = new IMAction(i18n("Open Log Viewer..."),
//                                    QIcon::fromTheme(QStringLiteral("documentation")),
//                                    personData->uri(),
//                                    LogViewer,
//                                    parent);
//     connect(action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
//     actions << action;
    return actions;
}

void KPeopleActionsPlugin::onActionTriggered()
{
    IMAction *action = qobject_cast<IMAction*>(sender());
    KTp::ContactPtr contact = action->contact();
    Tp::AccountPtr account = action->account();
    IMActionType type = action->type();

    switch (type) {
        case TextChannel:
            KTp::Actions::startChat(account, contact);
            break;
        case AudioChannel:
            KTp::Actions::startAudioCall(account, contact);
            break;
        case VideoChannel:
            KTp::Actions::startAudioVideoCall(account, contact);
            break;
        case FileTransfer: {
            const QStringList fileNames = QFileDialog::getOpenFileNames(Q_NULLPTR, i18n("Choose files to send to %1", contact->alias()),
                                                                        QStringLiteral("kfiledialog:///FileTransferLastDirectory"));
            Q_FOREACH(const QString& file, fileNames) {
                KTp::Actions::startFileTransfer(account, contact, file);
            }
            break;
        }
        case LogViewer:
            KTp::Actions::openLogViewer(action->uri());
            break;
        case CollabEditing: {
            const QUrl file = QFileDialog::getOpenFileName(Q_NULLPTR, i18n("Choose a file to edit with %1", contact->alias()),
                                                           QStringLiteral("kfiledialog:///CollabEditingLastDirectory"));
            KTp::Actions::startCollaborativeEditing(account, contact, QList<QUrl>() << file, true);
            break;
        }
    }
}

K_PLUGIN_FACTORY( KPeopleActionsPluginFactory, registerPlugin<KPeopleActionsPlugin>(); )
K_EXPORT_PLUGIN( KPeopleActionsPluginFactory("ktp_kpeople_plugin", "ktp-common-internals") )

#include "kpeople-actions-plugin.moc"
<commit_msg>Make actions plugin return actions also for all subcontacts<commit_after>/*
    Copyright (C) 2013  David Edmundson <davidedmundson@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 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "kpeople-actions-plugin.h"

#include <QAction>

#include <QIcon>
#include <KLocalizedString>
#include <KPluginFactory>
#include <QFileDialog>

#include "KTp/contact.h"
#include "KTp/actions.h"
#include "KTp/core.h"
#include "KTp/global-contact-manager.h"

#include <TelepathyQt/Account>
#include <TelepathyQt/ContactManager>
#include <TelepathyQt/Constants>

#include <KPeople/PersonData>

enum IMActionType {
    TextChannel,
    AudioChannel,
    VideoChannel,
    FileTransfer,
    LogViewer,
    CollabEditing
};

class IMAction : public QAction {
    Q_OBJECT
public:
    IMAction(const QString &text, const QIcon &icon, const KTp::ContactPtr &contact,
             const Tp::AccountPtr &account, IMActionType type, QObject *parent);
    IMAction(const QString &text, const QIcon &icon, const QUrl &uri,
             IMActionType type, QObject *parent);
    KTp::ContactPtr contact() const;
    Tp::AccountPtr account() const;
    IMActionType type() const;
    QUrl uri() const;
private:
    KTp::ContactPtr m_contact;
    Tp::AccountPtr m_account;
    QUrl m_uri;
    IMActionType m_type;
};

IMAction::IMAction(const QString &text, const QIcon &icon, const KTp::ContactPtr &contact,
                   const Tp::AccountPtr &account, IMActionType type, QObject *parent):
    QAction(icon, text, parent),
    m_contact(contact),
    m_account(account),
    m_type(type)
{
}

IMAction::IMAction(const QString &text, const QIcon &icon, const QUrl &uri,
                   IMActionType type, QObject *parent):
    QAction(icon, text, parent),
    m_uri(uri),
    m_type(type)
{
}

KTp::ContactPtr IMAction::contact() const
{
    return m_contact;
}

Tp::AccountPtr IMAction::account() const
{
    return m_account;
}

IMActionType IMAction::type() const
{
    return m_type;
}

QUrl IMAction::uri() const
{
    return m_uri;
}

KPeopleActionsPlugin::KPeopleActionsPlugin(QObject *parent, const QVariantList &args)
    : AbstractPersonAction(parent)
{
    Q_UNUSED(args);
}

QList<QAction*> KPeopleActionsPlugin::actionsForPerson(const KPeople::PersonData &person,
                                                       QObject *parent) const
{
    QList<QAction*> actions;

    // Get the most online account path and contact id
    QString personAccountPath = person.contactCustomProperty(QLatin1String("telepathy-accountPath")).toString();

    // The property for "telepathy-accountPath" is in form "/org/freedesktop/Telepathy/Account/gabble/jabber/myjabberaccount"
    // which is needed for retrieving the account from Tp::AccountManager. However we can only retrieve the other
    // contact uri list, not any objects which would give us the "telepathy-accountPath" for the subcontact.
    // So the code below constructs the account path from the contact uri which is known to be for ktp contacts
    // in form of "ktp:// + short account path + ? + contact id". But in order to not have the same actions
    // twice in the menu (one for most online and one from the contactUris()), this turns these properties into regular
    // uri format and puts it into the first position in the list, making sure that they will appear at the beggining.
    // It's also easier to simply remove it here and not having to check each uri separately in the foreach below.
    // And it cannot take the person.personUri() because for metacontacts that is in form of "kpeople://num_id".
    personAccountPath = personAccountPath.right(personAccountPath.length() - TP_QT_ACCOUNT_OBJECT_PATH_BASE.size() - 1);
    QString personContactId = person.contactCustomProperty(QLatin1String("telepathy-contactId")).toString();
    QString mostOnlineUri = QStringLiteral("ktp://") + personAccountPath + QLatin1Char('?') + personContactId;

    QStringList uris{mostOnlineUri};
    QStringList contactUris = person.contactUris();

    // Only append the child contacts if there is more than 1, otherwise
    // it means this contact has only itself as a subcontact.
    if (contactUris.size() > 1) {
        uris.append(contactUris);
        // Make sure we don't have duplicate uris in the list
        uris.removeDuplicates();
    }

    Q_FOREACH (const QString &uri, uris) {
        if (!uri.startsWith(QStringLiteral("ktp://"))) {
            continue;
        }

        int delimiterIndex = uri.indexOf(QLatin1Char('?'));
        QString contactId = uri.right(uri.length() - delimiterIndex - 1);
        QString accountPath = uri.mid(6, delimiterIndex - 6);
        // Prepend the "/org/freedesktop/Telepathy" part so that Tp::AccountManager
        // returns valid account
        accountPath.prepend(TP_QT_ACCOUNT_OBJECT_PATH_BASE + QLatin1Char('/'));

        const Tp::AccountPtr account = KTp::contactManager()->accountForAccountPath(accountPath);
        if (!account) {
            continue;
        }

        const KTp::ContactPtr contact = KTp::contactManager()->contactForContactId(accountPath, contactId);
        if (!contact || !contact->manager()) {
            continue;
        }

        if (contact->textChatCapability()) {
            QAction *action = new IMAction(i18n("Start Chat Using %1...", account->displayName()),
                                QIcon::fromTheme(QStringLiteral("text-x-generic")),
                                contact,
                                account,
                                TextChannel,
                                parent);
            connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
            actions << action;
        }
        if (contact->audioCallCapability()) {
            QAction *action = new IMAction(i18n("Start Audio Call Using %1...", account->displayName()),
                                QIcon::fromTheme(QStringLiteral("audio-headset")),
                                contact,
                                account,
                                AudioChannel,
                                parent);
            connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
            actions << action;
        }
        if (contact->videoCallCapability()) {
            QAction *action = new IMAction(i18n("Start Video Call Using %1...", account->displayName()),
                                QIcon::fromTheme(QStringLiteral("camera-web")),
                                contact,
                                account,
                                VideoChannel,
                                parent);
            connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
            actions << action;
        }

        if (contact->fileTransferCapability()) {
            QAction *action = new IMAction(i18n("Send Files Using %1...", account->displayName()),
                                        QIcon::fromTheme(QStringLiteral("mail-attachment")),
                                        contact,
                                        account,
                                        FileTransfer,
                                        parent);
            connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
            actions << action;
        }
        if (contact->collaborativeEditingCapability()) {
            QAction *action = new IMAction(i18n("Collaboratively edit a document Using %1...", account->displayName()),
                                        QIcon::fromTheme(QStringLiteral("document-edit")),
                                        contact,
                                        account,
                                        CollabEditing,
                                        parent);
            connect (action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
            actions << action;
        }
    }

    QAction *action = new IMAction(i18n("Previous Conversations..."),
                                   QIcon::fromTheme(QStringLiteral("documentation")),
                                   person.personUri(),
                                   LogViewer,
                                   parent);
    connect(action, SIGNAL(triggered(bool)), SLOT(onActionTriggered()));
    actions << action;

    return actions;
}

void KPeopleActionsPlugin::onActionTriggered()
{
    IMAction *action = qobject_cast<IMAction*>(sender());
    KTp::ContactPtr contact = action->contact();
    Tp::AccountPtr account = action->account();
    IMActionType type = action->type();

    switch (type) {
        case TextChannel:
            KTp::Actions::startChat(account, contact);
            break;
        case AudioChannel:
            KTp::Actions::startAudioCall(account, contact);
            break;
        case VideoChannel:
            KTp::Actions::startAudioVideoCall(account, contact);
            break;
        case FileTransfer: {
            const QStringList fileNames = QFileDialog::getOpenFileNames(Q_NULLPTR, i18n("Choose files to send to %1", contact->alias()),
                                                                        QStringLiteral("kfiledialog:///FileTransferLastDirectory"));
            Q_FOREACH(const QString& file, fileNames) {
                KTp::Actions::startFileTransfer(account, contact, file);
            }
            break;
        }
        case LogViewer:
            KTp::Actions::openLogViewer(action->uri());
            break;
        case CollabEditing: {
            const QUrl file = QFileDialog::getOpenFileName(Q_NULLPTR, i18n("Choose a file to edit with %1", contact->alias()),
                                                           QStringLiteral("kfiledialog:///CollabEditingLastDirectory"));
            KTp::Actions::startCollaborativeEditing(account, contact, QList<QUrl>() << file, true);
            break;
        }
    }
}

K_PLUGIN_FACTORY( KPeopleActionsPluginFactory, registerPlugin<KPeopleActionsPlugin>(); )
K_EXPORT_PLUGIN( KPeopleActionsPluginFactory("ktp_kpeople_plugin", "ktp-common-internals") )

#include "kpeople-actions-plugin.moc"
<|endoftext|>