<commit_before>#ifndef _CH_FRB_IO_RINGBUF_HPP
#define _CH_FRB_IO_RINGBUF_HPP

/**

 "Ring buffer" prototype.

 This class is meant to hold a data stream.  As a way of controlling
 the amount of memory used, it is allowed to have a maximum number of
 objects alive at any time.  When clients retrieve objects from the
 ring buffer, the objects are kept alive (via shared_ptrs), and
 continue to count toward the ring buffer's quota of live objects.
 Only when the last shared_ptr is dropped does the ring buffer get to
 add a new object.

 The use case is that we need to support callbacks (RPCs) that
 retrieve a lot of data and write it to disk, or send it over the
 network, which could take a long time.  While this is happening, we
 don't want to use more and more memory in the ring buffer; we want to
 control the total memory footprint.  We do this by assuming that the
 objects in the ring buffer are all the same size, so then we just
 need to limit the number of objects that are "live".  The RPC client
 will keep objects live via shared pointers.  When the ring buffer is
 asked to accept more data (via push()) and it is already at its
 limit, then it will begin dropping the oldest data from the buffer.
 If no client is holding a pointer to these objects, then they will be
 freed and space will become available for the new data.  If the whole
 buffer is dropped and space still does not become available, then
 space cannot be allocated for the new object and the push() fails.

 This is implemented via shared_ptr Deleter functionality: the Deleter
 is just a function that is called immediately before an object is
 about to be deleted.  The ring buffer decrements its count of the
 number of live objects when this happens; it then knows it is allowed
 to allocate one more new object.

 */

#if (__cplusplus < 201103) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
#error "This source file needs to be compiled with C++11 support (g++ -std=c++11)"
#endif

#include <deque>
#include <memory>
#include <vector>

// forward decl
template<class T>
class RingbufDeleter;

template<class T>
class Ringbuf {
    friend class RingbufDeleter<T>;

public:
    /*
     Creates a new Ringbuf with the given maximum quota size.
     */
    Ringbuf(int maxsize);

    virtual ~Ringbuf();

    /*
     Try to push a new frame onto the ring buffer.  If the quota of
     frames has been reached, frames will be popped off the front
     until the buffer is empty.  If space is still not available, will
     return an empty shared_ptr.

     Returns the enqueued shared_ptr if successful.
     */
    std::shared_ptr<T> push(T* t);

    /*
     Check whether there is room to push a new frame onto the ring
     buffer.  This method will try to free up space by dropping frames
     off the front of the queue.  Returns false if no space can be found.
     */
    bool can_push();

    /*
     Pops the oldest frame from this buffer and returns it.  Returns
     an empty shared_ptr if the buffer is empty.
     */
    std::shared_ptr<T> pop();

    /*
     Retrieves frames from this ring buffer that satisfy the
     (optional) selection function.
     */
    std::vector<std::shared_ptr<T> > snapshot(bool (*testFunc)(const std::shared_ptr<T>));

protected:
    // Small helper class that calls deleted() when one of our frames
    // is deleted.
    RingbufDeleter<T> _deleter;

    // The actual queue of frames.
    std::deque<std::shared_ptr<T> > _q;

    // (and the mutex for it)
    pthread_mutex_t _q_lock;

    // Number of live frames.
    size_t _live;

    // (and the mutex for it)
    pthread_mutex_t _live_lock;

    // Maximum allowable number of live frames.
    size_t _maxsize;

    // We're about to drop this frame.
    virtual void dropping(std::shared_ptr<T> t);

    // Called by the RingbufDeleter when a shared_ptr is deleted
    void deleted(T* t);

};

// Helper class that is the Deleter for our shared_ptr<frames>.  Calls
// Ringbuf.deleted() to track number of live frames.
template<class T>
class RingbufDeleter {
public:
    RingbufDeleter(Ringbuf<T>* rb) {};
    void operator()(T* t) {
        _ringbuf->deleted(t);
    }

protected:
    Ringbuf<T>* _ringbuf;
};

// Implementation... must appear here because Ringbuf is templated!
#include "ringbuf-impl.hpp"

#endif
<commit_msg>oops, lost initialization during refactor!<commit_after>#ifndef _CH_FRB_IO_RINGBUF_HPP
#define _CH_FRB_IO_RINGBUF_HPP

/**

 "Ring buffer" prototype.

 This class is meant to hold a data stream.  As a way of controlling
 the amount of memory used, it is allowed to have a maximum number of
 objects alive at any time.  When clients retrieve objects from the
 ring buffer, the objects are kept alive (via shared_ptrs), and
 continue to count toward the ring buffer's quota of live objects.
 Only when the last shared_ptr is dropped does the ring buffer get to
 add a new object.

 The use case is that we need to support callbacks (RPCs) that
 retrieve a lot of data and write it to disk, or send it over the
 network, which could take a long time.  While this is happening, we
 don't want to use more and more memory in the ring buffer; we want to
 control the total memory footprint.  We do this by assuming that the
 objects in the ring buffer are all the same size, so then we just
 need to limit the number of objects that are "live".  The RPC client
 will keep objects live via shared pointers.  When the ring buffer is
 asked to accept more data (via push()) and it is already at its
 limit, then it will begin dropping the oldest data from the buffer.
 If no client is holding a pointer to these objects, then they will be
 freed and space will become available for the new data.  If the whole
 buffer is dropped and space still does not become available, then
 space cannot be allocated for the new object and the push() fails.

 This is implemented via shared_ptr Deleter functionality: the Deleter
 is just a function that is called immediately before an object is
 about to be deleted.  The ring buffer decrements its count of the
 number of live objects when this happens; it then knows it is allowed
 to allocate one more new object.

 */

#if (__cplusplus < 201103) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
#error "This source file needs to be compiled with C++11 support (g++ -std=c++11)"
#endif

#include <deque>
#include <memory>
#include <vector>

// forward decl
template<class T>
class RingbufDeleter;

template<class T>
class Ringbuf {
    friend class RingbufDeleter<T>;

public:
    /*
     Creates a new Ringbuf with the given maximum quota size.
     */
    Ringbuf(int maxsize);

    virtual ~Ringbuf();

    /*
     Try to push a new frame onto the ring buffer.  If the quota of
     frames has been reached, frames will be popped off the front
     until the buffer is empty.  If space is still not available, will
     return an empty shared_ptr.

     Returns the enqueued shared_ptr if successful.
     */
    std::shared_ptr<T> push(T* t);

    /*
     Check whether there is room to push a new frame onto the ring
     buffer.  This method will try to free up space by dropping frames
     off the front of the queue.  Returns false if no space can be found.
     */
    bool can_push();

    /*
     Pops the oldest frame from this buffer and returns it.  Returns
     an empty shared_ptr if the buffer is empty.
     */
    std::shared_ptr<T> pop();

    /*
     Retrieves frames from this ring buffer that satisfy the
     (optional) selection function.
     */
    std::vector<std::shared_ptr<T> > snapshot(bool (*testFunc)(const std::shared_ptr<T>));

protected:
    // Small helper class that calls deleted() when one of our frames
    // is deleted.
    RingbufDeleter<T> _deleter;

    // The actual queue of frames.
    std::deque<std::shared_ptr<T> > _q;

    // (and the mutex for it)
    pthread_mutex_t _q_lock;

    // Number of live frames.
    size_t _live;

    // (and the mutex for it)
    pthread_mutex_t _live_lock;

    // Maximum allowable number of live frames.
    size_t _maxsize;

    // We're about to drop this frame.
    virtual void dropping(std::shared_ptr<T> t);

    // Called by the RingbufDeleter when a shared_ptr is deleted
    void deleted(T* t);

};

// Helper class that is the Deleter for our shared_ptr<frames>.  Calls
// Ringbuf.deleted() to track number of live frames.
template<class T>
class RingbufDeleter {
public:
    RingbufDeleter(Ringbuf<T>* rb) : _ringbuf(rb) {};
    void operator()(T* t) {
        _ringbuf->deleted(t);
    }

protected:
    Ringbuf<T>* _ringbuf;
};

// Implementation... must appear here because Ringbuf is templated!
#include "ringbuf-impl.hpp"

#endif
<|endoftext|>


<commit_before>/*  -*- c++ -*-
    identitydialog.cpp

    This file is part of KMail, the KDE mail client.
    Copyright (c) 2002 Marc Mutz <mutz@kde.org>

    KMail is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    KMail is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "identitydialog.h"

// other KMail headers:
#include "signatureconfigurator.h"
#include "kmfoldercombobox.h"
#include "kmfoldermgr.h"
#include "transportmanager.h"
#include "kmkernel.h"

// other kdenetwork headers:
#include <kpgpui.h>

// other KDE headers:
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kconfig.h>

// Qt headers:
#include <qtabwidget.h>
#include <qlabel.h>
#include <qwhatsthis.h>

// other headers: (none)

namespace KMail {

  IdentityDialog::IdentityDialog( QWidget * parent, const char * name )
    : KDialogBase( Plain, i18n("Edit Identity"), Ok|Cancel|Help, Ok,
		   parent, name )
  {
    // tmp. vars:
    QWidget * tab;
    QLabel  * label;
    int row;
    QGridLayout * glay;
    QString msg;

    //
    // Tab Widget: General
    //
    row = -1;
    QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
    QTabWidget *tabWidget = new QTabWidget( plainPage(), "config-identity-tab" );
    vlay->addWidget( tabWidget );

    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&General") );
    glay = new QGridLayout( tab, 4, 2, marginHint(), spacingHint() );
    glay->setRowStretch( 3, 1 );
    glay->setColStretch( 1, 1 );

    // "Name" line edit and label:
    ++row;
    mNameEdit = new KLineEdit( tab );
    glay->addWidget( mNameEdit, row, 1 );
    label = new QLabel( mNameEdit, i18n("&Your name:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Your name
"
	       "
This field should have your name, as you'd like "
	       "it to appear in the email header that is sent out.
"
	       "
If you leave this blank, your real name won't "
	       "appear, only the email address.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mNameEdit, msg );

    // "Organization" line edit and label:
    ++row;
    mOrganizationEdit = new KLineEdit( tab );
    glay->addWidget( mOrganizationEdit, row, 1 );
    label =  new QLabel( mOrganizationEdit, i18n("Organi&zation:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Organization
"
	       "
This field should have the name of your organization "
	       "if you'd like it to be shown in the email header that "
	       "is sent out.
"
	       "
It is safe (and normal) to leave this blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mOrganizationEdit, msg );

    // "Email Address" line edit and label:
    // (row 3: spacer)
    ++row;
    mEmailEdit = new KLineEdit( tab );
    glay->addWidget( mEmailEdit, row, 1 );
    label = new QLabel( mEmailEdit, i18n("&Email address:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Email address
"
	       "
This field should have your full email address.
"
	       "
If you leave this blank, or get it wrong, people "
	       "will have trouble replying to you.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mEmailEdit, msg );

    //
    // Tab Widget: Advanced
    //
    row = -1;
    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&Advanced") );
    glay = new QGridLayout( tab, 7, 2, marginHint(), spacingHint() );
    // the last (empty) row takes all the remaining space
    glay->setRowStretch( 7-1, 1 );
    glay->setColStretch( 1, 1 );

    // "Reply-To Address" line edit and label:
    ++row;
    mReplyToEdit = new KLineEdit( tab );
    glay->addWidget( mReplyToEdit, row, 1 );
    label = new QLabel ( mReplyToEdit, i18n("&Reply-To address:"), tab);
    glay->addWidget( label , row, 0 );
    msg = i18n("<qt>
Reply-To addresses
"
	       "
This sets the <tt>Reply-to:</tt> header to contain a "
	       "different email address to the normal <tt>From:</tt> "
	       "address.
"
	       "
This can be useful when you have a group of people "
	       "working together in similar roles. For example, you "
	       "might want any emails sent to have your email in the "
	       "<tt>From:</tt> field, but any responses to go to "
	       "a group address.
"
	       "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mReplyToEdit, msg );

    // "BCC addresses" line edit and label:
    ++row;
    mBccEdit = new KLineEdit( tab );
    glay->addWidget( mBccEdit, row, 1 );
    label = new QLabel( mBccEdit, i18n("&BCC addresses:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
BCC (Blind Carbon Copy) addresses
"
	       "
The addresses that you enter here will be added to each "
	       "outgoing mail that is sent with this identity. They will not "
	       "be visible to other recipients.
"
	       "
This is commonly used to send a copy of each sent message to "
	       "another account of yours.
"
	       "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mBccEdit, msg );

    // "OpenPGP Key" requester and label:
    ++row;
    mPgpKeyRequester = new Kpgp::SecretKeyRequester( tab );
    mPgpKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
    mPgpKeyRequester->setDialogCaption( i18n("Your OpenPGP Key") );
    mPgpKeyRequester->setDialogMessage( i18n("Select the OpenPGP key which "
					     "should be used to sign your "
					     "messages and when encrypting to "
					     "yourself.") );
    msg = i18n("<qt>
The OpenPGP key you choose here will be used "
	       "to sign messages and to encrypt messages to "
	       "yourself. You can also use GnuPG keys.
"
	       "You can leave this blank, but KMail won't be able "
	       "to cryptographically sign emails. Normal mail functions won't "
	       "be affected.
"
	       "You can find out more about keys at http://www.gnupg.org</qt>");

    label = new QLabel( mPgpKeyRequester, i18n("OpenPGP key:"), tab );
    QWhatsThis::add( mPgpKeyRequester, msg );
    QWhatsThis::add( label, msg );

    glay->addWidget( label, row, 0 );
    glay->addWidget( mPgpKeyRequester, row, 1 );

    // "Sent-mail Folder" combo box and label:
    ++row;
    mFccCombo = new KMFolderComboBox( tab );
    mFccCombo->showOutboxFolder( false );
    glay->addWidget( mFccCombo, row, 1 );
    glay->addWidget( new QLabel( mFccCombo, i18n("Sent-mail &folder:"), tab ),
		     row, 0 );

    // "Drafts Folder" combo box and label:
    ++row;
    mDraftsCombo = new KMFolderComboBox( tab );
    mDraftsCombo->showOutboxFolder( false );
    glay->addWidget( mDraftsCombo, row, 1 );
    glay->addWidget( new QLabel( mDraftsCombo, i18n("&Drafts folder:"), tab ),
		     row, 0 );

    // "Special transport" combobox and label:
    ++row;
    mTransportCheck = new QCheckBox( i18n("Special &transport:"), tab );
    glay->addWidget( mTransportCheck, row, 0 );
    mTransportCombo = new QComboBox( true, tab );
    mTransportCombo->setEnabled( false ); // since !mTransportCheck->isChecked()
    mTransportCombo->insertStringList( KMail::TransportManager::transportNames() );
    glay->addWidget( mTransportCombo, row, 1 );
    connect( mTransportCheck, SIGNAL(toggled(bool)),
	     mTransportCombo, SLOT(setEnabled(bool)) );

    // the last row is a spacer

    //
    // Tab Widget: Signature
    //
    mSignatureConfigurator = new SignatureConfigurator( tabWidget );
    mSignatureConfigurator->layout()->setMargin( KDialog::marginHint() );
    tabWidget->addTab( mSignatureConfigurator, i18n("&Signature") );

    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    if ( geometry.hasKey( "Identity Dialog size" ) )
      resize( geometry.readSizeEntry( "Identity Dialog size" ) );
    mNameEdit->setFocus();
  }

  IdentityDialog::~IdentityDialog() {
    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    geometry.writeEntry( "Identity Dialog size", size() );
  }

  bool IdentityDialog::checkFolderExists( const QString & folderID,
					  const QString & msg ) {
    KMFolder * folder = kmkernel->folderMgr()->findIdString( folderID );
    if ( !folder )
      folder = kmkernel->imapFolderMgr()->findIdString( folderID );
    if ( !folder ) {
      KMessageBox::sorry( this, msg );
      return false;
    }
    return true;
  }

  void IdentityDialog::setIdentity( KMIdentity & ident ) {

    setCaption( i18n("Edit Identity \"%1\"").arg( ident.identityName() ) );

    // "General" tab:
    mNameEdit->setText( ident.fullName() );
    mOrganizationEdit->setText( ident.organization() );
    mEmailEdit->setText( ident.emailAddr() );

    // "Advanced" tab:
    mPgpKeyRequester->setKeyIDs( Kpgp::KeyIDList() << ident.pgpIdentity() );
    mReplyToEdit->setText( ident.replyToAddr() );
    mBccEdit->setText( ident.bcc() );
    mTransportCheck->setChecked( !ident.transport().isEmpty() );
    mTransportCombo->setEditText( ident.transport() );
    mTransportCombo->setEnabled( !ident.transport().isEmpty() );

    if ( ident.fcc().isEmpty() ||
	 !checkFolderExists( ident.fcc(),
			     i18n("The custom sent-mail folder for identity "
				  "\"%1\" doesn't exist (anymore). "
				  "Therefore the default sent-mail folder "
				  "will be used.")
			     .arg( ident.identityName() ) ) )
      mFccCombo->setFolder( kmkernel->sentFolder() );
    else
      mFccCombo->setFolder( ident.fcc() );

    if ( ident.drafts().isEmpty() ||
	 !checkFolderExists( ident.drafts(),
			     i18n("The custom drafts folder for identity "
				  "\"%1\" doesn't exist (anymore). "
				  "Therefore the default drafts folder "
				  "will be used.")
			     .arg( ident.identityName() ) ) )
      mDraftsCombo->setFolder( kmkernel->draftsFolder() );
    else
      mDraftsCombo->setFolder( ident.drafts() );

    // "Signature" tab:
    mSignatureConfigurator->setSignature( ident.signature() );
  }

  void IdentityDialog::updateIdentity( KMIdentity & ident ) {
    // "General" tab:
    ident.setFullName( mNameEdit->text() );
    ident.setOrganization( mOrganizationEdit->text() );
	QString email = mEmailEdit->text();
	if ( email.isEmpty() || email.contains('@') == 0)
	  KMessageBox::sorry(this,
						 i18n("You didn't specify a valid email address."
							  "You won't create valid emails without such an address."),
						 i18n("No Email Adress"));
	if (email.contains('@') > 1) {
	  KMessageBox::sorry(this,
						 i18n("Your email address contains two @ characters,"
							  "which most email servers do not accept."
							  "You won't create valid emails without changing your address."),
						 i18n("No Email Adress"));
	}
    ident.setEmailAddr( email );
    // "Advanced" tab:
    ident.setPgpIdentity( mPgpKeyRequester->keyIDs().first() );
    ident.setReplyToAddr( mReplyToEdit->text() );
    ident.setBcc( mBccEdit->text() );
    ident.setTransport( ( mTransportCheck->isChecked() ) ?
			mTransportCombo->currentText() : QString::null );
    ident.setFcc( mFccCombo->getFolder() ?
		  mFccCombo->getFolder()->idString() : QString::null );
    ident.setDrafts( mDraftsCombo->getFolder() ?
		     mDraftsCombo->getFolder()->idString() : QString::null );
    // "Signature" tab:
    ident.setSignature( mSignatureConfigurator->signature() );
  }

  void IdentityDialog::slotUpdateTransportCombo( const QStringList & sl ) {
    // save old setting:
    QString content = mTransportCombo->currentText();
    // update combo box:
    mTransportCombo->clear();
    mTransportCombo->insertStringList( sl );
    // restore saved setting:
    mTransportCombo->setEditText( content );
  }

}

#include "identitydialog.moc"
<commit_msg>for the nit pickers<commit_after>/*  -*- c++ -*-
    identitydialog.cpp

    This file is part of KMail, the KDE mail client.
    Copyright (c) 2002 Marc Mutz <mutz@kde.org>

    KMail is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    KMail is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "identitydialog.h"

// other KMail headers:
#include "signatureconfigurator.h"
#include "kmfoldercombobox.h"
#include "kmfoldermgr.h"
#include "transportmanager.h"
#include "kmkernel.h"

// other kdenetwork headers:
#include <kpgpui.h>

// other KDE headers:
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kconfig.h>

// Qt headers:
#include <qtabwidget.h>
#include <qlabel.h>
#include <qwhatsthis.h>

// other headers: (none)

namespace KMail {

  IdentityDialog::IdentityDialog( QWidget * parent, const char * name )
    : KDialogBase( Plain, i18n("Edit Identity"), Ok|Cancel|Help, Ok,
		   parent, name )
  {
    // tmp. vars:
    QWidget * tab;
    QLabel  * label;
    int row;
    QGridLayout * glay;
    QString msg;

    //
    // Tab Widget: General
    //
    row = -1;
    QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
    QTabWidget *tabWidget = new QTabWidget( plainPage(), "config-identity-tab" );
    vlay->addWidget( tabWidget );

    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&General") );
    glay = new QGridLayout( tab, 4, 2, marginHint(), spacingHint() );
    glay->setRowStretch( 3, 1 );
    glay->setColStretch( 1, 1 );

    // "Name" line edit and label:
    ++row;
    mNameEdit = new KLineEdit( tab );
    glay->addWidget( mNameEdit, row, 1 );
    label = new QLabel( mNameEdit, i18n("&Your name:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Your name
"
	       "
This field should have your name, as you'd like "
	       "it to appear in the email header that is sent out.
"
	       "
If you leave this blank, your real name won't "
	       "appear, only the email address.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mNameEdit, msg );

    // "Organization" line edit and label:
    ++row;
    mOrganizationEdit = new KLineEdit( tab );
    glay->addWidget( mOrganizationEdit, row, 1 );
    label =  new QLabel( mOrganizationEdit, i18n("Organi&zation:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Organization
"
	       "
This field should have the name of your organization "
	       "if you'd like it to be shown in the email header that "
	       "is sent out.
"
	       "
It is safe (and normal) to leave this blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mOrganizationEdit, msg );

    // "Email Address" line edit and label:
    // (row 3: spacer)
    ++row;
    mEmailEdit = new KLineEdit( tab );
    glay->addWidget( mEmailEdit, row, 1 );
    label = new QLabel( mEmailEdit, i18n("&Email address:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Email address
"
	       "
This field should have your full email address.
"
	       "
If you leave this blank, or get it wrong, people "
	       "will have trouble replying to you.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mEmailEdit, msg );

    //
    // Tab Widget: Advanced
    //
    row = -1;
    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&Advanced") );
    glay = new QGridLayout( tab, 7, 2, marginHint(), spacingHint() );
    // the last (empty) row takes all the remaining space
    glay->setRowStretch( 7-1, 1 );
    glay->setColStretch( 1, 1 );

    // "Reply-To Address" line edit and label:
    ++row;
    mReplyToEdit = new KLineEdit( tab );
    glay->addWidget( mReplyToEdit, row, 1 );
    label = new QLabel ( mReplyToEdit, i18n("&Reply-To address:"), tab);
    glay->addWidget( label , row, 0 );
    msg = i18n("<qt>
Reply-To addresses
"
	       "
This sets the <tt>Reply-to:</tt> header to contain a "
	       "different email address to the normal <tt>From:</tt> "
	       "address.
"
	       "
This can be useful when you have a group of people "
	       "working together in similar roles. For example, you "
	       "might want any emails sent to have your email in the "
	       "<tt>From:</tt> field, but any responses to go to "
	       "a group address.
"
	       "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mReplyToEdit, msg );

    // "BCC addresses" line edit and label:
    ++row;
    mBccEdit = new KLineEdit( tab );
    glay->addWidget( mBccEdit, row, 1 );
    label = new QLabel( mBccEdit, i18n("&BCC addresses:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
BCC (Blind Carbon Copy) addresses
"
	       "
The addresses that you enter here will be added to each "
	       "outgoing mail that is sent with this identity. They will not "
	       "be visible to other recipients.
"
	       "
This is commonly used to send a copy of each sent message to "
	       "another account of yours.
"
	       "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mBccEdit, msg );

    // "OpenPGP Key" requester and label:
    ++row;
    mPgpKeyRequester = new Kpgp::SecretKeyRequester( tab );
    mPgpKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
    mPgpKeyRequester->setDialogCaption( i18n("Your OpenPGP Key") );
    mPgpKeyRequester->setDialogMessage( i18n("Select the OpenPGP key which "
					     "should be used to sign your "
					     "messages and when encrypting to "
					     "yourself.") );
    msg = i18n("<qt>
The OpenPGP key you choose here will be used "
	       "to sign messages and to encrypt messages to "
	       "yourself. You can also use GnuPG keys.
"
	       "You can leave this blank, but KMail won't be able "
	       "to cryptographically sign emails. Normal mail functions won't "
	       "be affected.
"
	       "You can find out more about keys at http://www.gnupg.org</qt>");

    label = new QLabel( mPgpKeyRequester, i18n("OpenPGP key:"), tab );
    QWhatsThis::add( mPgpKeyRequester, msg );
    QWhatsThis::add( label, msg );

    glay->addWidget( label, row, 0 );
    glay->addWidget( mPgpKeyRequester, row, 1 );

    // "Sent-mail Folder" combo box and label:
    ++row;
    mFccCombo = new KMFolderComboBox( tab );
    mFccCombo->showOutboxFolder( false );
    glay->addWidget( mFccCombo, row, 1 );
    glay->addWidget( new QLabel( mFccCombo, i18n("Sent-mail &folder:"), tab ),
		     row, 0 );

    // "Drafts Folder" combo box and label:
    ++row;
    mDraftsCombo = new KMFolderComboBox( tab );
    mDraftsCombo->showOutboxFolder( false );
    glay->addWidget( mDraftsCombo, row, 1 );
    glay->addWidget( new QLabel( mDraftsCombo, i18n("&Drafts folder:"), tab ),
		     row, 0 );

    // "Special transport" combobox and label:
    ++row;
    mTransportCheck = new QCheckBox( i18n("Special &transport:"), tab );
    glay->addWidget( mTransportCheck, row, 0 );
    mTransportCombo = new QComboBox( true, tab );
    mTransportCombo->setEnabled( false ); // since !mTransportCheck->isChecked()
    mTransportCombo->insertStringList( KMail::TransportManager::transportNames() );
    glay->addWidget( mTransportCombo, row, 1 );
    connect( mTransportCheck, SIGNAL(toggled(bool)),
	     mTransportCombo, SLOT(setEnabled(bool)) );

    // the last row is a spacer

    //
    // Tab Widget: Signature
    //
    mSignatureConfigurator = new SignatureConfigurator( tabWidget );
    mSignatureConfigurator->layout()->setMargin( KDialog::marginHint() );
    tabWidget->addTab( mSignatureConfigurator, i18n("&Signature") );

    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    if ( geometry.hasKey( "Identity Dialog size" ) )
      resize( geometry.readSizeEntry( "Identity Dialog size" ) );
    mNameEdit->setFocus();
  }

  IdentityDialog::~IdentityDialog() {
    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    geometry.writeEntry( "Identity Dialog size", size() );
  }

  bool IdentityDialog::checkFolderExists( const QString & folderID,
					  const QString & msg ) {
    KMFolder * folder = kmkernel->folderMgr()->findIdString( folderID );
    if ( !folder )
      folder = kmkernel->imapFolderMgr()->findIdString( folderID );
    if ( !folder ) {
      KMessageBox::sorry( this, msg );
      return false;
    }
    return true;
  }

  void IdentityDialog::setIdentity( KMIdentity & ident ) {

    setCaption( i18n("Edit Identity \"%1\"").arg( ident.identityName() ) );

    // "General" tab:
    mNameEdit->setText( ident.fullName() );
    mOrganizationEdit->setText( ident.organization() );
    mEmailEdit->setText( ident.emailAddr() );

    // "Advanced" tab:
    mPgpKeyRequester->setKeyIDs( Kpgp::KeyIDList() << ident.pgpIdentity() );
    mReplyToEdit->setText( ident.replyToAddr() );
    mBccEdit->setText( ident.bcc() );
    mTransportCheck->setChecked( !ident.transport().isEmpty() );
    mTransportCombo->setEditText( ident.transport() );
    mTransportCombo->setEnabled( !ident.transport().isEmpty() );

    if ( ident.fcc().isEmpty() ||
	 !checkFolderExists( ident.fcc(),
			     i18n("The custom sent-mail folder for identity "
				  "\"%1\" doesn't exist (anymore). "
				  "Therefore the default sent-mail folder "
				  "will be used.")
			     .arg( ident.identityName() ) ) )
      mFccCombo->setFolder( kmkernel->sentFolder() );
    else
      mFccCombo->setFolder( ident.fcc() );

    if ( ident.drafts().isEmpty() ||
	 !checkFolderExists( ident.drafts(),
			     i18n("The custom drafts folder for identity "
				  "\"%1\" doesn't exist (anymore). "
				  "Therefore the default drafts folder "
				  "will be used.")
			     .arg( ident.identityName() ) ) )
      mDraftsCombo->setFolder( kmkernel->draftsFolder() );
    else
      mDraftsCombo->setFolder( ident.drafts() );

    // "Signature" tab:
    mSignatureConfigurator->setSignature( ident.signature() );
  }

  void IdentityDialog::updateIdentity( KMIdentity & ident ) {
    // "General" tab:
    ident.setFullName( mNameEdit->text() );
    ident.setOrganization( mOrganizationEdit->text() );
	QString email = mEmailEdit->text();
	if ( email.isEmpty() || email.contains('@') == 0)
	  KMessageBox::sorry(this,
						 i18n("You didn't specify a valid email address."
							  "You won't create valid emails without such an address."),
						 i18n("No Email Adress"));
	if (email.contains('@') > 1) {
	  KMessageBox::sorry(this,
						 i18n("Your email address contains more than one @ character,"
							  "which most email servers do not accept."
							  "You won't create valid emails without changing your address."),
						 i18n("No Email Adress"));
	}
    ident.setEmailAddr( email );
    // "Advanced" tab:
    ident.setPgpIdentity( mPgpKeyRequester->keyIDs().first() );
    ident.setReplyToAddr( mReplyToEdit->text() );
    ident.setBcc( mBccEdit->text() );
    ident.setTransport( ( mTransportCheck->isChecked() ) ?
			mTransportCombo->currentText() : QString::null );
    ident.setFcc( mFccCombo->getFolder() ?
		  mFccCombo->getFolder()->idString() : QString::null );
    ident.setDrafts( mDraftsCombo->getFolder() ?
		     mDraftsCombo->getFolder()->idString() : QString::null );
    // "Signature" tab:
    ident.setSignature( mSignatureConfigurator->signature() );
  }

  void IdentityDialog::slotUpdateTransportCombo( const QStringList & sl ) {
    // save old setting:
    QString content = mTransportCombo->currentText();
    // update combo box:
    mTransportCombo->clear();
    mTransportCombo->insertStringList( sl );
    // restore saved setting:
    mTransportCombo->setEditText( content );
  }

}

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


<commit_before>/** -*- c++ -*-
 * progressdialog.cpp
 *
 *  Copyright (c) 2004 Till Adam <adam@kde.org>,
 *                     David Faure <faure@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; version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of this program with any edition of
 *  the Qt library by Trolltech AS, Norway (or with modified versions
 *  of Qt that use the same license as Qt), and distribute linked
 *  combinations including the two.  You must obey the GNU General
 *  Public License in all respects for all of the code used other than
 *  Qt.  If you modify this file, you may extend this exception to
 *  your version of the file, but you are not obligated to do so.  If
 *  you do not wish to do so, delete this exception statement from
 *  your version.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qlayout.h>
#include <qprogressbar.h>
#include <qtimer.h>
#include <qheader.h>
#include <qobject.h>
#include <qscrollview.h>
#include <qtoolbutton.h>
#include <qpushbutton.h>
#include <qvbox.h>

#include <klocale.h>
#include <kdialog.h>
#include <kstdguiitem.h>
#include <kiconloader.h>
#include <kdebug.h>

#include "progressdialog.h"
#include "progressmanager.h"

using KMail::ProgressItem;
using KMail::ProgressManager;

namespace KMail {

class TransactionItem;

TransactionItemView::TransactionItemView( QWidget * parent,
                                          const char * name,
                                          WFlags f )
    : QScrollView( parent, name, f ) {
    mBigBox = new QVBox( viewport() );
    mBigBox->setSpacing(2);
    addChild( mBigBox );
    setResizePolicy( QScrollView::AutoOneFit ); // Fit so that the box expands horizontally
}

TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
{
   TransactionItem *ti = new TransactionItem( mBigBox, item, first );
   ti->show();
   return ti;
}

void TransactionItemView::resizeContents( int w, int h )
{
  //kdDebug(5006) << k_funcinfo << w << "," << h << endl;
  QScrollView::resizeContents( w, h );
  // Tell the parent (progressdialog) to adapt itself to our new size
  updateGeometry();
  parentWidget()->adjustSize();
}

QSize TransactionItemView::sizeHint() const
{
  return minimumSizeHint();
}

QSize TransactionItemView::minimumSizeHint() const
{
  int f = 2 * frameWidth();
  int minw = topLevelWidget()->width() / 3;
  int maxh = topLevelWidget()->height() / 2;
  QSize sz( mBigBox->minimumSizeHint() );
  sz.setWidth( QMAX( sz.width(), minw ) + f );
  sz.setHeight( QMIN( sz.height(), maxh ) + f );
  return sz;
}

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

TransactionItem::TransactionItem( QWidget* parent,
                                  ProgressItem *item, bool first )
  : QVBox( parent ), mCancelButton( 0 )

{
  setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
  if ( !first ) {
    QFrame *f = new QFrame( this );
    f->setFrameShape( QFrame::HLine );
    f->setFrameShadow( QFrame::Raised );
    f->show();
    setStretchFactor( f, 3 );
  }

  QHBox *h = new QHBox( this );
  h->setSpacing( 5 );
  h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
  mProgress = new QProgressBar( 100, h );
  mProgress->setProgress( item->progress() );
  if ( item->canBeCanceled() ) {
    mCancelButton = new QPushButton( SmallIcon( "cancel" ), QString::null, h );
    connect ( mCancelButton, SIGNAL( clicked() ),
              this, SLOT( slotItemCanceled() ));
  }
  mItemLabel = new QLabel( item->label(), h );

  mItemStatus =  new QLabel( item->status(), this );
}

TransactionItem::~TransactionItem()
{

}

void TransactionItem::setProgress( int progress )
{
  mProgress->setProgress( progress );
}

void TransactionItem::setLabel( const QString& label )
{
  mItemLabel->setText( label );
}

void TransactionItem::setStatus( const QString& status )
{
  mItemStatus->setText( status );
}

void TransactionItem::slotItemCanceled()
{
  item()->setStatus( i18n("cancelling ... ") );
  item()->cancel();
}

void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
{

}

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

ProgressDialog::ProgressDialog( QWidget* alignWidget, QWidget* parent, const char* name )
    : OverlayWidget( alignWidget, parent, name )
{
    setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QFrame
    setSpacing( 0 ); // QHBox
    setMargin( 1 );

    mScrollView = new TransactionItemView( this, "ProgressScrollView" );

    QVBox* rightBox = new QVBox( this );
    QToolButton* pbClose = new QToolButton( rightBox );
    pbClose->setAutoRaise(true);
    pbClose->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
    pbClose->setFixedSize( 16, 16 );
    pbClose->setIconSet( KGlobal::iconLoader()->loadIconSet( "fileclose", KIcon::Small, 14 ) );
    connect(pbClose, SIGNAL(clicked()), this, SLOT(close()));
    QWidget* spacer = new QWidget( rightBox ); // don't let the close button take up all the height
    rightBox->setStretchFactor( spacer, 100 );

    /*
     * Get the singleton ProgressManager item which will inform us of
     * appearing and vanishing items.
     */
    ProgressManager *pm = ProgressManager::instance();
    connect ( pm, SIGNAL( progressItemAdded( ProgressItem* ) ),
              this, SLOT( slotTransactionAdded( ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemCompleted( ProgressItem* ) ),
              this, SLOT( slotTransactionCompleted( ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemProgress( ProgressItem*, unsigned int ) ),
              this, SLOT( slotTransactionProgress( ProgressItem*, unsigned int ) ) );
    connect ( pm, SIGNAL( progressItemStatus( ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionStatus( ProgressItem*, const QString& ) ) );
    connect ( pm, SIGNAL( progressItemLabel( ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionLabel( ProgressItem*, const QString& ) ) );
}

void ProgressDialog::closeEvent( QCloseEvent* e )
{
  e->accept();
  hide();
}

/*
 *  Destructor
 */
ProgressDialog::~ProgressDialog()
{
    // no need to delete child widgets.
}

void ProgressDialog::slotTransactionAdded( ProgressItem *item )
{
   TransactionItem *parent = 0;
   TransactionItem *ti = 0;
   if ( item->parent() ) {
     parent = mTransactionsToListviewItems[ item->parent() ];
     parent->addSubTransaction( item );
   } else {
     ti = mScrollView->addTransactionItem( item, mTransactionsToListviewItems.empty() );
   }
   if ( ti )
     mTransactionsToListviewItems.replace( item, ti );
}

void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setStatus(i18n("Completed"));
     mTransactionsToListviewItems.remove( item );
     QTimer::singleShot( 5000, ti, SLOT( deleteLater() ) );
   }
   // This was the last item, hide.
   if ( mTransactionsToListviewItems.empty() )
     QTimer::singleShot( 5000, this, SLOT( slotHide() ) );
}

void ProgressDialog::slotTransactionCanceled( ProgressItem * )
{
}

void ProgressDialog::slotTransactionProgress( ProgressItem *item,
                                              unsigned int progress )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setProgress( progress );
   }
}

void ProgressDialog::slotTransactionStatus( ProgressItem *item,
                                            const QString& status )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setStatus( status );
   }
}

void ProgressDialog::slotTransactionLabel( ProgressItem *item,
                                           const QString& label )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setLabel( label );
   }
}

void ProgressDialog::slotHide()
{
  // check if a new item showed up since we started the timer. If not, hide
  if ( mTransactionsToListviewItems.isEmpty() )
    hide();
}

}

#include "progressdialog.moc"
<commit_msg>One less frame, a bit more spacing.<commit_after>/** -*- c++ -*-
 * progressdialog.cpp
 *
 *  Copyright (c) 2004 Till Adam <adam@kde.org>,
 *                     David Faure <faure@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; version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of this program with any edition of
 *  the Qt library by Trolltech AS, Norway (or with modified versions
 *  of Qt that use the same license as Qt), and distribute linked
 *  combinations including the two.  You must obey the GNU General
 *  Public License in all respects for all of the code used other than
 *  Qt.  If you modify this file, you may extend this exception to
 *  your version of the file, but you are not obligated to do so.  If
 *  you do not wish to do so, delete this exception statement from
 *  your version.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qlayout.h>
#include <qprogressbar.h>
#include <qtimer.h>
#include <qheader.h>
#include <qobject.h>
#include <qscrollview.h>
#include <qtoolbutton.h>
#include <qpushbutton.h>
#include <qvbox.h>

#include <klocale.h>
#include <kdialog.h>
#include <kstdguiitem.h>
#include <kiconloader.h>
#include <kdebug.h>

#include "progressdialog.h"
#include "progressmanager.h"

using KMail::ProgressItem;
using KMail::ProgressManager;

namespace KMail {

class TransactionItem;

TransactionItemView::TransactionItemView( QWidget * parent,
                                          const char * name,
                                          WFlags f )
    : QScrollView( parent, name, f ) {
  setFrameStyle( NoFrame );
  mBigBox = new QVBox( viewport() );
  mBigBox->setSpacing( 5 );
  addChild( mBigBox );
  setResizePolicy( QScrollView::AutoOneFit ); // Fit so that the box expands horizontally
}

TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
{
   TransactionItem *ti = new TransactionItem( mBigBox, item, first );
   ti->show();
   return ti;
}

void TransactionItemView::resizeContents( int w, int h )
{
  //kdDebug(5006) << k_funcinfo << w << "," << h << endl;
  QScrollView::resizeContents( w, h );
  // Tell the parent (progressdialog) to adapt itself to our new size
  updateGeometry();
  parentWidget()->adjustSize();
}

QSize TransactionItemView::sizeHint() const
{
  return minimumSizeHint();
}

QSize TransactionItemView::minimumSizeHint() const
{
  int f = 2 * frameWidth();
  int minw = topLevelWidget()->width() / 3;
  int maxh = topLevelWidget()->height() / 2;
  QSize sz( mBigBox->minimumSizeHint() );
  sz.setWidth( QMAX( sz.width(), minw ) + f );
  sz.setHeight( QMIN( sz.height(), maxh ) + f );
  return sz;
}

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

TransactionItem::TransactionItem( QWidget* parent,
                                  ProgressItem *item, bool first )
  : QVBox( parent ), mCancelButton( 0 )

{
  setSpacing( 2 );
  setMargin( 2 );
  setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
  if ( !first ) {
    QFrame *f = new QFrame( this );
    f->setFrameShape( QFrame::HLine );
    f->setFrameShadow( QFrame::Raised );
    f->show();
    setStretchFactor( f, 3 );
  }

  QHBox *h = new QHBox( this );
  h->setSpacing( 5 );
  h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
  mProgress = new QProgressBar( 100, h );
  mProgress->setProgress( item->progress() );
  if ( item->canBeCanceled() ) {
    mCancelButton = new QPushButton( SmallIcon( "cancel" ), QString::null, h );
    connect ( mCancelButton, SIGNAL( clicked() ),
              this, SLOT( slotItemCanceled() ));
  }
  mItemLabel = new QLabel( item->label(), h );

  mItemStatus =  new QLabel( item->status(), this );
}

TransactionItem::~TransactionItem()
{

}

void TransactionItem::setProgress( int progress )
{
  mProgress->setProgress( progress );
}

void TransactionItem::setLabel( const QString& label )
{
  mItemLabel->setText( label );
}

void TransactionItem::setStatus( const QString& status )
{
  mItemStatus->setText( status );
}

void TransactionItem::slotItemCanceled()
{
  item()->setStatus( i18n("cancelling ... ") );
  item()->cancel();
}

void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
{

}

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

ProgressDialog::ProgressDialog( QWidget* alignWidget, QWidget* parent, const char* name )
    : OverlayWidget( alignWidget, parent, name )
{
    setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QFrame
    setSpacing( 0 ); // QHBox
    setMargin( 1 );

    mScrollView = new TransactionItemView( this, "ProgressScrollView" );

    QVBox* rightBox = new QVBox( this );
    QToolButton* pbClose = new QToolButton( rightBox );
    pbClose->setAutoRaise(true);
    pbClose->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
    pbClose->setFixedSize( 16, 16 );
    pbClose->setIconSet( KGlobal::iconLoader()->loadIconSet( "fileclose", KIcon::Small, 14 ) );
    connect(pbClose, SIGNAL(clicked()), this, SLOT(close()));
    QWidget* spacer = new QWidget( rightBox ); // don't let the close button take up all the height
    rightBox->setStretchFactor( spacer, 100 );

    /*
     * Get the singleton ProgressManager item which will inform us of
     * appearing and vanishing items.
     */
    ProgressManager *pm = ProgressManager::instance();
    connect ( pm, SIGNAL( progressItemAdded( ProgressItem* ) ),
              this, SLOT( slotTransactionAdded( ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemCompleted( ProgressItem* ) ),
              this, SLOT( slotTransactionCompleted( ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemProgress( ProgressItem*, unsigned int ) ),
              this, SLOT( slotTransactionProgress( ProgressItem*, unsigned int ) ) );
    connect ( pm, SIGNAL( progressItemStatus( ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionStatus( ProgressItem*, const QString& ) ) );
    connect ( pm, SIGNAL( progressItemLabel( ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionLabel( ProgressItem*, const QString& ) ) );
}

void ProgressDialog::closeEvent( QCloseEvent* e )
{
  e->accept();
  hide();
}

/*
 *  Destructor
 */
ProgressDialog::~ProgressDialog()
{
    // no need to delete child widgets.
}

void ProgressDialog::slotTransactionAdded( ProgressItem *item )
{
   TransactionItem *parent = 0;
   TransactionItem *ti = 0;
   if ( item->parent() ) {
     parent = mTransactionsToListviewItems[ item->parent() ];
     parent->addSubTransaction( item );
   } else {
     ti = mScrollView->addTransactionItem( item, mTransactionsToListviewItems.empty() );
   }
   if ( ti )
     mTransactionsToListviewItems.replace( item, ti );
}

void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setStatus(i18n("Completed"));
     mTransactionsToListviewItems.remove( item );
     QTimer::singleShot( 5000, ti, SLOT( deleteLater() ) );
   }
   // This was the last item, hide.
   if ( mTransactionsToListviewItems.empty() )
     QTimer::singleShot( 5000, this, SLOT( slotHide() ) );
}

void ProgressDialog::slotTransactionCanceled( ProgressItem * )
{
}

void ProgressDialog::slotTransactionProgress( ProgressItem *item,
                                              unsigned int progress )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setProgress( progress );
   }
}

void ProgressDialog::slotTransactionStatus( ProgressItem *item,
                                            const QString& status )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setStatus( status );
   }
}

void ProgressDialog::slotTransactionLabel( ProgressItem *item,
                                           const QString& label )
{
   TransactionItem *ti = mTransactionsToListviewItems[ item ];
   if ( ti ) {
     ti->setLabel( label );
   }
}

void ProgressDialog::slotHide()
{
  // check if a new item showed up since we started the timer. If not, hide
  if ( mTransactionsToListviewItems.isEmpty() )
    hide();
}

}

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


<commit_before>// -*- C++ -*-
//
// ----------------------------------------------------------------------
//
// Brad T. Aagaard, U.S. Geological Survey
//
// This code was developed as part of the Computational Infrastructure
// for Geodynamics (http://geodynamics.org).
//
// Copyright (c) 2010-2017 University of California, Davis
//
// See COPYING for license information.
//
// ----------------------------------------------------------------------
//

#include <portinfo>

#include "TestGravityField.hh" // Implementation of class methods

#include "spatialdata/spatialdb/GravityField.hh" // USES GravityField

#include "spatialdata/geocoords/CSCart.hh" // USES CSCart
#include "spatialdata/geocoords/CSGeo.hh" // USES CSGeo
#include "spatialdata/geocoords/CSGeoProj.hh" // USES CSGeoProj
#include "spatialdata/geocoords/CSGeoLocalCart.hh" // USES CSGeoLocalCart

#include <string.h> // USES strcmp()
#include <math.h> // USES sqrt()

// ----------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( spatialdata::spatialdb::TestGravityField );

// ----------------------------------------------------------------------
// Test constructor.
void
spatialdata::spatialdb::TestGravityField::testConstructor(void)
{ // testConstructor
  GravityField db;
} // testConstructor

// ----------------------------------------------------------------------
// Test label().
void
spatialdata::spatialdb::TestGravityField::testLabel(void)
{ // testLabel
  GravityField db;
  const char* label = "database 2";
  db.label(label);
  CPPUNIT_ASSERT(0 == strcmp(label, db.label()));
} // testLabel

// ----------------------------------------------------------------------
// Test gravityDir().
void
spatialdata::spatialdb::TestGravityField::testGravityDir(void)
{ // testGravityDir
  GravityField db;

  const double tolerance = 1.0e-06;

  { // Test default
    const double gravityDir[] = { 0.0, 0.0, -1.0 };
    for (int i=0; i < 3; ++i)
      CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityDir[i], db._gravityDir[i],
				   tolerance);
  } // Test default

  { // Test user-specified
    const double gravityDir[] = { 1.1, 2.2, 3.3 };
    const double mag = 1.1*sqrt(1 + 4 + 9);
    db.gravityDir(gravityDir[0], gravityDir[1], gravityDir[2]);
    for (int i=0; i < 3; ++i)
      CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityDir[i]/mag, db._gravityDir[i],
				   tolerance);
  } // Test user-specified
} // testGravityDir

// ----------------------------------------------------------------------
// Test acceleration().
void
spatialdata::spatialdb::TestGravityField::testAcceleration(void)
{ // testAcceleration
  GravityField db;

  const double tolerance = 1.0e-06;
  const double gSI = 9.80665;
  CPPUNIT_ASSERT_DOUBLES_EQUAL(gSI, db._acceleration, tolerance);

  const double g = 4.5;
  db.gravAcceleration(g);
  CPPUNIT_ASSERT_DOUBLES_EQUAL(g, db._acceleration, tolerance);
} // testAcceleration

// ----------------------------------------------------------------------
// Test queryVals().
void
spatialdata::spatialdb::TestGravityField::testQueryVals(void)
{ // testQueryVals
  GravityField db;

  const int querySize = 2;
  const char* queryNames[] = { "gravity_field_z", "gravity_field_y" };
  const int queryVals[] = { 2, 1 };

  db.queryVals(queryNames, querySize);

  CPPUNIT_ASSERT_EQUAL(querySize, db._querySize);
  for (int i=0; i < querySize; ++i)
    CPPUNIT_ASSERT_EQUAL(queryVals[i], db._queryVals[i]);
} // testQueryVals

// ----------------------------------------------------------------------
// Test query() with 2-D Cartesian coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryCart2(void)
{ // testQueryCart2
  const int spaceDim = 2;
  const double gacc = 2.0;
  const double gravityDir[] = { -0.6, -0.8, 0.0 };
  const double gravityE[] = { -1.2, -1.6 };
  const int querySize = spaceDim;
  const char* queryNames[] = { "gravity_field_x", "gravity_field_y" };

  GravityField db;
  db.gravityDir(gravityDir[0], gravityDir[1], gravityDir[2]);
  db.gravAcceleration(gacc);
  db.open();
  db.queryVals(queryNames, querySize);

  geocoords::CSCart cs;
  cs.setSpaceDim(spaceDim);

  double gravity[querySize];
  const double coords[] = { 2.5, 6.3 };
  const int err = db.query(gravity, querySize, coords, spaceDim, &cs);
  CPPUNIT_ASSERT_EQUAL(0, err);
  db.close();

  const double tolerance = 1.0e-06;
  for (int i=0; i < querySize; ++i)
    CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryCart2

// ----------------------------------------------------------------------
// Test query() with 3-D Cartesian coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryCart3(void)
{ // testQueryCart3
  const int spaceDim = 3;
  const double gacc = 2.0;
  const double gravityDir[] = { 0.3, 0.4, -0.5 };
  const double sqrt2 = sqrt(2.0);
  const double gravityE[] = { 0.6*sqrt2, 0.8*sqrt2, -1.0*sqrt2 };

  GravityField db;
  db.gravityDir(gravityDir[0], gravityDir[1], gravityDir[2]);
  db.gravAcceleration(gacc);
  db.open();

  geocoords::CSCart cs;
  cs.setSpaceDim(spaceDim);

  double gravity[spaceDim];
  const double coords[] = { 2.5, 6.3, -2.4 };
  const int err = db.query(gravity, spaceDim, coords, spaceDim, &cs);
  CPPUNIT_ASSERT_EQUAL(0, err);
  db.close();

  const double tolerance = 1.0e-06;
  for (int i=0; i < spaceDim; ++i)
    CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryCart3

// ----------------------------------------------------------------------
// Test query() with geographic coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryGeographic(void)
{ // testQueryGeographic
  const int spaceDim = 3;
  const double gacc = 2.0;
  const double gravityE[] = { 0.0, 0.0, -gacc };

  GravityField db;
  db.gravAcceleration(gacc);
  db.open();

  geocoords::CSGeo cs;

  double gravity[spaceDim];
  const double coords[] = { 2.5, 6.3, -2.4 };
  const int err = db.query(gravity, spaceDim, coords, spaceDim, &cs);
  CPPUNIT_ASSERT_EQUAL(0, err);
  db.close();

  const double tolerance = 1.0e-06;
  for (int i=0; i < spaceDim; ++i)
    CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryGeographic

// ----------------------------------------------------------------------
// Test query() with projected geographic coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryGeoProj(void)
{ // testQueryGeoProj
  const int spaceDim = 3;
  const double gacc = 2.0;
  const double gravityE[] = { 0.0, 0.0, -gacc };

  GravityField db;
  db.gravAcceleration(gacc);
  db.open();

  geocoords::CSGeoProj cs;

  double gravity[spaceDim];
  const double coords[] = { 2.5, 6.3, -2.4 };
  const int err = db.query(gravity, spaceDim, coords, spaceDim, &cs);
  CPPUNIT_ASSERT_EQUAL(0, err);
  db.close();

  const double tolerance = 1.0e-06;
  for (int i=0; i < spaceDim; ++i)
    CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryGeoProj

// ----------------------------------------------------------------------
// Test query() with geocentric coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryGeocentric(void)
{ // testQueryGeocentric
  const int spaceDim = 3;

  GravityField db;
  db.open();

  geocoords::CSGeo cs;
  cs.isGeocentric(true);
  cs.initialize();

  const double tolerance = 1.0e-06;
  const double gacc = 9.80665;

  const int numLocs = 5;
  const double coords[] = {
    0.0, 0.0, 6356752.31, // (lon=0.0, lat=90.0)
    6378137.00, 0.0, 0.0, // (lon=0.0, lat=0.0)
    0.0, -6378137.00, 0.0, // (lon=-90.0, lat=0.0)
    -2684785.48, -4296554.90, 3861564.10, // (lon=-122.0, lat=37.5)
    -2680581.35, -4289826.89, 3855476.48, // (lon=-122.0, lat=37.5, elev=-10km)
  };
  const double gravityE[] = {
    0.0, 0.0, -gacc,
    -gacc, 0.0, 0.0,
    0.0, gacc, 0.0,
    4.1330772777176055, 6.6143062683936451, -5.9446622298329901,
    4.1330933324795938, 6.6143319681570834, -5.9446224726661976,
  };

  double gravity[spaceDim];
  for (int iLoc=0, index=0; iLoc < numLocs; ++iLoc, index+=spaceDim) {
    const int err = db.query(gravity, spaceDim, &coords[index], spaceDim, &cs);
    CPPUNIT_ASSERT_EQUAL(0, err);

    for (int i=0; i < spaceDim; ++i)
      if (fabs(gravityE[index+i]) > tolerance)
	CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, gravity[i]/gravityE[index+i],
				     tolerance);
      else
	CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[index+i], gravity[i], tolerance);
  } // for

  db.close();
} // testQueryGeocentric

// ----------------------------------------------------------------------
// Test query() with geocentric coordinates and local origin.
void
spatialdata::spatialdb::TestGravityField::testQueryGeoLocal(void)
{ // testQueryGeoLocal
  const int spaceDim = 3;

  GravityField db;
  db.open();

  geocoords::CSGeoLocalCart cs;
  cs.origin(-122.0, 37.75, 0.0);
  cs.initialize();

  const double gacc = 9.80665;

  const int numLocs = 3;
  const double coords[] = {
    0.0, 0.0, 0.0,
    0.0, 0.0, -20e+3,
    10.0e+3, -25e+3, -5e+3,
  };
  const double gravityE[] = {
    0.0, 0.0032487084*gacc, -0.99999472*gacc,
    0.0, 0.0032589402*gacc, -0.99999469*gacc,
    -0.0015710173*gacc, 0.0071787331*gacc, -0.999973*gacc,
  };
  const double tolerance = 1.0e-06;

  double gravity[spaceDim];
  for (int iLoc=0, index=0; iLoc < numLocs; ++iLoc, index+=spaceDim) {
    const int err = db.query(gravity, spaceDim, &coords[index], spaceDim, &cs);
    CPPUNIT_ASSERT_EQUAL(0, err);

    for (int i=0; i < spaceDim; ++i)
      if (fabs(gravityE[index+i]) > tolerance)
	CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, gravity[i]/gravityE[index+i],
				     tolerance);
      else
	CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[index+i], gravity[i], tolerance);
  } // for

  db.close();
} // testQueryGeoLocal

// End of file
<commit_msg>Update for change in method name.<commit_after>// -*- C++ -*-
//
// ----------------------------------------------------------------------
//
// Brad T. Aagaard, U.S. Geological Survey
//
// This code was developed as part of the Computational Infrastructure
// for Geodynamics (http://geodynamics.org).
//
// Copyright (c) 2010-2017 University of California, Davis
//
// See COPYING for license information.
//
// ----------------------------------------------------------------------
//

#include <portinfo>

#include "TestGravityField.hh" // Implementation of class methods

#include "spatialdata/spatialdb/GravityField.hh" // USES GravityField

#include "spatialdata/geocoords/CSCart.hh" // USES CSCart
#include "spatialdata/geocoords/CSGeo.hh" // USES CSGeo
#include "spatialdata/geocoords/CSGeoProj.hh" // USES CSGeoProj
#include "spatialdata/geocoords/CSGeoLocalCart.hh" // USES CSGeoLocalCart

#include <string.h> // USES strcmp()
#include <math.h> // USES sqrt()

// ----------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION(spatialdata::spatialdb::TestGravityField);

// ----------------------------------------------------------------------
// Test constructor.
void
spatialdata::spatialdb::TestGravityField::testConstructor(void)
{ // testConstructor
    GravityField db;
} // testConstructor

// ----------------------------------------------------------------------
// Test label().
void
spatialdata::spatialdb::TestGravityField::testLabel(void)
{ // testLabel
    GravityField db;
    const char* label = "database 2";
    db.label(label);
    CPPUNIT_ASSERT(0 == strcmp(label, db.label()));
} // testLabel

// ----------------------------------------------------------------------
// Test gravityDir().
void
spatialdata::spatialdb::TestGravityField::testGravityDir(void)
{ // testGravityDir
    GravityField db;

    const double tolerance = 1.0e-06;

    { // Test default
        const double gravityDir[] = { 0.0, 0.0, -1.0 };
        for (int i = 0; i < 3; ++i)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityDir[i], db._gravityDir[i],
                                         tolerance);
    } // Test default

    { // Test user-specified
        const double gravityDir[] = { 1.1, 2.2, 3.3 };
        const double mag = 1.1*sqrt(1 + 4 + 9);
        db.gravityDir(gravityDir[0], gravityDir[1], gravityDir[2]);
        for (int i = 0; i < 3; ++i)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityDir[i]/mag, db._gravityDir[i],
                                         tolerance);
    } // Test user-specified
} // testGravityDir

// ----------------------------------------------------------------------
// Test acceleration().
void
spatialdata::spatialdb::TestGravityField::testAcceleration(void)
{ // testAcceleration
    GravityField db;

    const double tolerance = 1.0e-06;
    const double gSI = 9.80665;
    CPPUNIT_ASSERT_DOUBLES_EQUAL(gSI, db._acceleration, tolerance);

    const double g = 4.5;
    db.gravityAcc(g);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(g, db._acceleration, tolerance);
} // testAcceleration

// ----------------------------------------------------------------------
// Test queryVals().
void
spatialdata::spatialdb::TestGravityField::testQueryVals(void)
{ // testQueryVals
    GravityField db;

    const int querySize = 2;
    const char* queryNames[] = { "gravity_field_z", "gravity_field_y" };
    const int queryVals[] = { 2, 1 };

    db.queryVals(queryNames, querySize);

    CPPUNIT_ASSERT_EQUAL(querySize, db._querySize);
    for (int i = 0; i < querySize; ++i)
        CPPUNIT_ASSERT_EQUAL(queryVals[i], db._queryVals[i]);
} // testQueryVals

// ----------------------------------------------------------------------
// Test query() with 2-D Cartesian coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryCart2(void)
{ // testQueryCart2
    const int spaceDim = 2;
    const double gacc = 2.0;
    const double gravityDir[] = { -0.6, -0.8, 0.0 };
    const double gravityE[] = { -1.2, -1.6 };
    const int querySize = spaceDim;
    const char* queryNames[] = { "gravity_field_x", "gravity_field_y" };

    GravityField db;
    db.gravityDir(gravityDir[0], gravityDir[1], gravityDir[2]);
    db.gravityAcc(gacc);
    db.open();
    db.queryVals(queryNames, querySize);

    geocoords::CSCart cs;
    cs.setSpaceDim(spaceDim);

    double gravity[querySize];
    const double coords[] = { 2.5, 6.3 };
    const int err = db.query(gravity, querySize, coords, spaceDim, &cs);
    CPPUNIT_ASSERT_EQUAL(0, err);
    db.close();

    const double tolerance = 1.0e-06;
    for (int i = 0; i < querySize; ++i)
        CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryCart2

// ----------------------------------------------------------------------
// Test query() with 3-D Cartesian coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryCart3(void)
{ // testQueryCart3
    const int spaceDim = 3;
    const double gacc = 2.0;
    const double gravityDir[] = { 0.3, 0.4, -0.5 };
    const double sqrt2 = sqrt(2.0);
    const double gravityE[] = { 0.6*sqrt2, 0.8*sqrt2, -1.0*sqrt2 };

    GravityField db;
    db.gravityDir(gravityDir[0], gravityDir[1], gravityDir[2]);
    db.gravityAcc(gacc);
    db.open();

    geocoords::CSCart cs;
    cs.setSpaceDim(spaceDim);

    double gravity[spaceDim];
    const double coords[] = { 2.5, 6.3, -2.4 };
    const int err = db.query(gravity, spaceDim, coords, spaceDim, &cs);
    CPPUNIT_ASSERT_EQUAL(0, err);
    db.close();

    const double tolerance = 1.0e-06;
    for (int i = 0; i < spaceDim; ++i)
        CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryCart3

// ----------------------------------------------------------------------
// Test query() with geographic coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryGeographic(void)
{ // testQueryGeographic
    const int spaceDim = 3;
    const double gacc = 2.0;
    const double gravityE[] = { 0.0, 0.0, -gacc };

    GravityField db;
    db.gravityAcc(gacc);
    db.open();

    geocoords::CSGeo cs;

    double gravity[spaceDim];
    const double coords[] = { 2.5, 6.3, -2.4 };
    const int err = db.query(gravity, spaceDim, coords, spaceDim, &cs);
    CPPUNIT_ASSERT_EQUAL(0, err);
    db.close();

    const double tolerance = 1.0e-06;
    for (int i = 0; i < spaceDim; ++i)
        CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryGeographic

// ----------------------------------------------------------------------
// Test query() with projected geographic coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryGeoProj(void)
{ // testQueryGeoProj
    const int spaceDim = 3;
    const double gacc = 2.0;
    const double gravityE[] = { 0.0, 0.0, -gacc };

    GravityField db;
    db.gravityAcc(gacc);
    db.open();

    geocoords::CSGeoProj cs;

    double gravity[spaceDim];
    const double coords[] = { 2.5, 6.3, -2.4 };
    const int err = db.query(gravity, spaceDim, coords, spaceDim, &cs);
    CPPUNIT_ASSERT_EQUAL(0, err);
    db.close();

    const double tolerance = 1.0e-06;
    for (int i = 0; i < spaceDim; ++i)
        CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[i], gravity[i], tolerance);
} // testQueryGeoProj

// ----------------------------------------------------------------------
// Test query() with geocentric coordinates.
void
spatialdata::spatialdb::TestGravityField::testQueryGeocentric(void)
{ // testQueryGeocentric
    const int spaceDim = 3;

    GravityField db;
    db.open();

    geocoords::CSGeo cs;
    cs.isGeocentric(true);
    cs.initialize();

    const double tolerance = 1.0e-06;
    const double gacc = 9.80665;

    const int numLocs = 5;
    const double coords[] = {
        0.0, 0.0, 6356752.31, // (lon=0.0, lat=90.0)
        6378137.00, 0.0, 0.0, // (lon=0.0, lat=0.0)
        0.0, -6378137.00, 0.0, // (lon=-90.0, lat=0.0)
        -2684785.48, -4296554.90, 3861564.10, // (lon=-122.0, lat=37.5)
        -2680581.35, -4289826.89, 3855476.48, // (lon=-122.0, lat=37.5, elev=-10km)
    };
    const double gravityE[] = {
        0.0, 0.0, -gacc,
        -gacc, 0.0, 0.0,
        0.0, gacc, 0.0,
        4.1330772777176055, 6.6143062683936451, -5.9446622298329901,
        4.1330933324795938, 6.6143319681570834, -5.9446224726661976,
    };

    double gravity[spaceDim];
    for (int iLoc = 0, index = 0; iLoc < numLocs; ++iLoc, index += spaceDim) {
        const int err = db.query(gravity, spaceDim, &coords[index], spaceDim, &cs);
        CPPUNIT_ASSERT_EQUAL(0, err);

        for (int i = 0; i < spaceDim; ++i)
            if (fabs(gravityE[index+i]) > tolerance) {
                CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, gravity[i]/gravityE[index+i],
                                             tolerance);
            } else {
                CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[index+i], gravity[i], tolerance);
            }
    } // for

    db.close();
} // testQueryGeocentric

// ----------------------------------------------------------------------
// Test query() with geocentric coordinates and local origin.
void
spatialdata::spatialdb::TestGravityField::testQueryGeoLocal(void)
{ // testQueryGeoLocal
    const int spaceDim = 3;

    GravityField db;
    db.open();

    geocoords::CSGeoLocalCart cs;
    cs.origin(-122.0, 37.75, 0.0);
    cs.initialize();

    const double gacc = 9.80665;

    const int numLocs = 3;
    const double coords[] = {
        0.0, 0.0, 0.0,
        0.0, 0.0, -20e+3,
        10.0e+3, -25e+3, -5e+3,
    };
    const double gravityE[] = {
        0.0, 0.0032487084*gacc, -0.99999472*gacc,
        0.0, 0.0032589402*gacc, -0.99999469*gacc,
        -0.0015710173*gacc, 0.0071787331*gacc, -0.999973*gacc,
    };
    const double tolerance = 1.0e-06;

    double gravity[spaceDim];
    for (int iLoc = 0, index = 0; iLoc < numLocs; ++iLoc, index += spaceDim) {
        const int err = db.query(gravity, spaceDim, &coords[index], spaceDim, &cs);
        CPPUNIT_ASSERT_EQUAL(0, err);

        for (int i = 0; i < spaceDim; ++i)
            if (fabs(gravityE[index+i]) > tolerance) {
                CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, gravity[i]/gravityE[index+i],
                                             tolerance);
            } else {
                CPPUNIT_ASSERT_DOUBLES_EQUAL(gravityE[index+i], gravity[i], tolerance);
            }
    } // for

    db.close();
} // testQueryGeoLocal

// End of file
<|endoftext|>


<commit_before>#include <QtTest/QtTest>

#include "tools/qnitetool.h"

class TestQniteTool: public QObject
{
  Q_OBJECT

private slots:

};
QTEST_MAIN(TestQniteTool)
#include "tst_qnitetool.moc"
<commit_msg>added an instance test<commit_after>#include <QtTest/QtTest>

#include "tools/qnitetool.h"

class FooTool: public QniteTool
{
  Q_OBJECT
public:
  FooTool(QQuickItem* parent = 0):
    QniteTool(parent)
  {}
};

class TestQniteTool: public QObject
{
  Q_OBJECT

private slots:

  void testInstance();

};

void TestQniteTool::testInstance()
{
  FooTool f;
}

QTEST_MAIN(TestQniteTool)
#include "tst_qnitetool.moc"
<|endoftext|>


<commit_before>// Implementation of Andrew's monotone chain 2D convex hull algorithm.
// Asymptotic complexity: O(n log n).
// Practical performance: 0.5-1.0 seconds for n=1000000 on a 1GHz machine.
// Adapted (okay, stolen) from http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain

#include <algorithm>
#include <vector>
#include <iostream>
#include <limits>
#include "convexHull.h"
#include "drakeFloatingPointUtil.h"

using namespace std;
using namespace Eigen;

// 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
// Returns a positive value, if OAB makes a counter-clockwise turn,
// negative for clockwise turn, and zero if the points are collinear.
coord2_t cross(const Point &O, const Point &A, const Point &B)
{
  return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}

// Returns a list of points on the convex hull in counter-clockwise order.
// Note: the last point in the returned list is the same as the first one.
vector<Point> convexHull(vector<Point> P)
{

  size_t n = P.size(), k = 0;
  vector<Point> H(2*n);

  if (n == 2) {
    H.resize(3);
    H[0] = P[0];
    H[1] = P[1];
    H[2] = P[0];
    return H;
  }

  // Sort points lexicographically
  sort(P.begin(), P.end());

  // Build lower hull
  for (size_t i = 0; i < n; ++i) {
    while (k >= 2 && cross(H[k-2], H[k-1], P[i]) <= 0) k--;
    H[k++] = P[i];
  }

  // Build upper hull
  for (ptrdiff_t i = n-2, t = k+1; i >= 0; i--) {
    while (k >= t && cross(H[k-2], H[k-1], P[i]) <= 0) k--;
    H[k++] = P[i];
  }

  H.resize(k);

  return H;
}

vector<Point> eigenToPoints(const Ref<const Matrix<double, 2, Dynamic>> &P) {
  vector<Point> points;
  points.reserve(P.cols());
  for (int i=0; i < P.cols(); ++i) {
    Point p;
    p.x = P(0, i);
    p.y = P(1, i);
    points.push_back(p);
  }
  return points;
}

bool inConvexHull(const Ref<const Matrix<double, 2, Dynamic>> &P, const Ref<const Vector2d> &q, double tolerance) {
  return signedDistanceInsideConvexHull(P, q) >= -tolerance;
}

double signedDistanceInsideConvexHull(const Ref<const Matrix<double, 2, Dynamic>> &pts, const Ref<const Vector2d> &q) {
  vector<Point> hull_pts = convexHull(eigenToPoints(pts));
  double d_star = numeric_limits<double>::infinity();

  Matrix2d R;
  R << 0, 1,
       -1, 0;

  for (int i=0; i < hull_pts.size() - 1; ++i) {
    Vector2d ai = R * Vector2d(hull_pts[i+1].x - hull_pts[i].x, hull_pts[i+1].y - hull_pts[i].y);
    double b = ai.transpose() * Vector2d(hull_pts[i].x, hull_pts[i].y);
    double n = ai.norm();
    if (isNormal(n)) {
      ai = ai.array() / n;
      b = b / n;
      double d = b - ai.transpose() * q;
      // std::cout << "pt0: " << hull_pts[i].x << " " << hull_pts[i].y << std::endl;
      // std::cout << "pt1: " << hull_pts[i+1].x << " " << hull_pts[i+1].y << std::endl;
      // std::cout << "ai: " << ai.transpose() << std::endl;
      // std::cout << "b: " << b << std::endl;
      // std::cout << "d: " << d << std::endl;
      if (d < d_star) {
        d_star = d;
      }
    }
  }
  return d_star;
}

<commit_msg>another size_t fix<commit_after>// Implementation of Andrew's monotone chain 2D convex hull algorithm.
// Asymptotic complexity: O(n log n).
// Practical performance: 0.5-1.0 seconds for n=1000000 on a 1GHz machine.
// Adapted (okay, stolen) from http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain

#include <algorithm>
#include <vector>
#include <iostream>
#include <limits>
#include "convexHull.h"
#include "drakeFloatingPointUtil.h"

using namespace std;
using namespace Eigen;

// 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
// Returns a positive value, if OAB makes a counter-clockwise turn,
// negative for clockwise turn, and zero if the points are collinear.
coord2_t cross(const Point &O, const Point &A, const Point &B)
{
  return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}

// Returns a list of points on the convex hull in counter-clockwise order.
// Note: the last point in the returned list is the same as the first one.
vector<Point> convexHull(vector<Point> P)
{

  ptrdiff_t n = P.size();
  ptrdiff_t k = 0;
  vector<Point> H(2*n);

  if (n == 2) {
    H.resize(3);
    H[0] = P[0];
    H[1] = P[1];
    H[2] = P[0];
    return H;
  }

  // Sort points lexicographically
  sort(P.begin(), P.end());

  // Build lower hull
  for (size_t i = 0; i < n; ++i) {
    while (k >= 2 && cross(H[k-2], H[k-1], P[i]) <= 0) k--;
    H[k++] = P[i];
  }

  // Build upper hull
  for (ptrdiff_t i = n-2, t = k+1; i >= 0; i--) {
    while (k >= t && cross(H[k-2], H[k-1], P[i]) <= 0) k--;
    H[k++] = P[i];
  }

  H.resize(k);

  return H;
}

vector<Point> eigenToPoints(const Ref<const Matrix<double, 2, Dynamic>> &P) {
  vector<Point> points;
  points.reserve(P.cols());
  for (int i=0; i < P.cols(); ++i) {
    Point p;
    p.x = P(0, i);
    p.y = P(1, i);
    points.push_back(p);
  }
  return points;
}

bool inConvexHull(const Ref<const Matrix<double, 2, Dynamic>> &P, const Ref<const Vector2d> &q, double tolerance) {
  return signedDistanceInsideConvexHull(P, q) >= -tolerance;
}

double signedDistanceInsideConvexHull(const Ref<const Matrix<double, 2, Dynamic>> &pts, const Ref<const Vector2d> &q) {
  vector<Point> hull_pts = convexHull(eigenToPoints(pts));
  double d_star = numeric_limits<double>::infinity();

  Matrix2d R;
  R << 0, 1,
       -1, 0;

  for (int i=0; i < hull_pts.size() - 1; ++i) {
    Vector2d ai = R * Vector2d(hull_pts[i+1].x - hull_pts[i].x, hull_pts[i+1].y - hull_pts[i].y);
    double b = ai.transpose() * Vector2d(hull_pts[i].x, hull_pts[i].y);
    double n = ai.norm();
    if (isNormal(n)) {
      ai = ai.array() / n;
      b = b / n;
      double d = b - ai.transpose() * q;
      // std::cout << "pt0: " << hull_pts[i].x << " " << hull_pts[i].y << std::endl;
      // std::cout << "pt1: " << hull_pts[i+1].x << " " << hull_pts[i+1].y << std::endl;
      // std::cout << "ai: " << ai.transpose() << std::endl;
      // std::cout << "b: " << b << std::endl;
      // std::cout << "d: " << d << std::endl;
      if (d < d_star) {
        d_star = d;
      }
    }
  }
  return d_star;
}

<|endoftext|>


<commit_before>/*
* Copyright (C) 2012 David Edmundson <kde@davidedmundson.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "contacts-list-model.h"
#include "contact.h"

#include <TelepathyQt/Account>
#include <TelepathyQt/Contact>
#include <TelepathyQt/ContactCapabilities>
#include <TelepathyQt/Connection>
#include <TelepathyQt/ContactManager>

#include <KTp/Models/contacts-model.h>
#include <KTp/presence.h>

class KTp::ContactsListModel::Private
{
public:
    QList<Tp::ContactPtr> contacts;
    KTp::GlobalContactManager *contactManager;
};

KTp::ContactsListModel::ContactsListModel(QObject *parent) :
    QAbstractListModel(parent),
    d(new KTp::ContactsListModel::Private())
{
    d->contactManager = 0;
}

KTp::ContactsListModel::~ContactsListModel()
{
    delete d;
}

void KTp::ContactsListModel::setAccountManager(const Tp::AccountManagerPtr &accountManager)
{
    d->contactManager = new KTp::GlobalContactManager(accountManager, this);
    onContactsChanged(d->contactManager->allKnownContacts(), Tp::Contacts());
    connect(d->contactManager, SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts)), SLOT(onContactsChanged(Tp::Contacts,Tp::Contacts)));
}

int KTp::ContactsListModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED (parent);
    return d->contacts.size();
}

QVariant KTp::ContactsListModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();

    if (row >=0 && row < d->contacts.size()) {
        const KTp::ContactPtr contact = KTp::ContactPtr::qObjectCast(d->contacts[row]);

        switch (role) {
        case ContactsModel::IdRole:
            return contact->id();
        case ContactsModel::TypeRole:
            return ContactsModel::ContactRowType;
        case ContactsModel::ContactRole:
            return QVariant::fromValue(d->contacts[row]); //Tp::ContactPtr and NOT KTp::ContactPtr
        case ContactsModel::AccountRole:
            return QVariant::fromValue(d->contactManager->accountForContact(contact));
        case Qt::DisplayRole:
            return contact->alias();
        case ContactsModel::AliasRole:
            return contact->alias();
        case ContactsModel::PresenceRole:
            return QVariant::fromValue(contact->presence());
        case ContactsModel::PresenceIconRole:
            return QIcon(contact->presence().icon());
        case ContactsModel::PresenceStatusRole:
            return contact->presence().status();
        case ContactsModel::PresenceTypeRole:
            return contact->presence().type();
        case ContactsModel::PresenceMessageRole:
            return contact->presence().statusMessage();
        case ContactsModel::SubscriptionStateRole:
            return contact->subscriptionState();
        case ContactsModel::PublishStateRole:
            return contact->publishState();
        case ContactsModel::BlockedRole:
            return contact->isBlocked();
        case ContactsModel::GroupsRole:
            return contact->groups();
        case ContactsModel::AvatarRole:
            return contact->avatarData().fileName;
        case Qt::DecorationRole:
            return QImage(contact->avatarData().fileName);
        case ContactsModel::TextChatCapabilityRole:
            return contact->capabilities().textChats();
        case ContactsModel::ClientTypesRole:
            return contact->clientTypes();
        default:
            break;
        }

    }
    return QVariant();
}

void KTp::ContactsListModel::onContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
{
    //add contacts.

    Q_FOREACH(const Tp::ContactPtr &contact_uncasted, added) {
        KTp::ContactPtr contact = KTp::ContactPtr::qObjectCast(contact_uncasted);

        connect(contact.data(),
                    SIGNAL(aliasChanged(QString)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(avatarTokenChanged(QString)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(avatarDataChanged(Tp::AvatarData)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(presenceChanged(Tp::Presence)),
                    SLOT(onChanged()));
            connect(contact->manager()->connection()->selfContact().data(),
                    SIGNAL(capabilitiesChanged(Tp::ContactCapabilities)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(capabilitiesChanged(Tp::ContactCapabilities)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(locationUpdated(Tp::LocationInfo)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(infoFieldsChanged(Tp::Contact::InfoFields)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(subscriptionStateChanged(Tp::Contact::PresenceState)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(publishStateChanged(Tp::Contact::PresenceState,QString)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(blockStatusChanged(bool)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(clientTypesChanged(QStringList)),
                    SLOT(onChanged()));

            connect(contact.data(), SIGNAL(invalidated()), SLOT(onConnectionDropped()));
    }

    if (added.size() > 0) {
        beginInsertRows(QModelIndex(), d->contacts.size(), d->contacts.size() + added.size() -1);
        d->contacts.append(added.toList());
        endInsertRows();
    }

    //remove contacts
    Q_FOREACH(const Tp::ContactPtr &contact, removed) {
        int row = d->contacts.indexOf(contact);
        if (row >= 0) { //if contact found in list
            beginRemoveRows(QModelIndex(), row, row);
            d->contacts.removeOne(contact);
            endInsertRows();
        }
    }
}

void KTp::ContactsListModel::onChanged()
{
    KTp::ContactPtr contact(qobject_cast<KTp::Contact*>(sender()));
    int row = d->contacts.indexOf(contact);
    if (row > 0) {
        QModelIndex index = createIndex(row, 0);
        dataChanged(index, index);
    }
}

void KTp::ContactsListModel::onConnectionDropped()
{
    KTp::ContactPtr contact(qobject_cast<KTp::Contact*>(sender()));
    onContactsChanged(Tp::Contacts(), Tp::Contacts() << contact);
}

<commit_msg>Fix contacts-list-model<commit_after>/*
* Copyright (C) 2012 David Edmundson <kde@davidedmundson.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "contacts-list-model.h"
#include "contact.h"

#include <TelepathyQt/Account>
#include <TelepathyQt/Contact>
#include <TelepathyQt/ContactCapabilities>
#include <TelepathyQt/Connection>
#include <TelepathyQt/ContactManager>

#include <KTp/Models/contacts-model.h>
#include <KTp/presence.h>

class KTp::ContactsListModel::Private
{
public:
    QList<Tp::ContactPtr> contacts;
    KTp::GlobalContactManager *contactManager;
};

KTp::ContactsListModel::ContactsListModel(QObject *parent) :
    QAbstractListModel(parent),
    d(new KTp::ContactsListModel::Private())
{
    d->contactManager = 0;
}

KTp::ContactsListModel::~ContactsListModel()
{
    delete d;
}

void KTp::ContactsListModel::setAccountManager(const Tp::AccountManagerPtr &accountManager)
{
    d->contactManager = new KTp::GlobalContactManager(accountManager, this);
    onContactsChanged(d->contactManager->allKnownContacts(), Tp::Contacts());
    connect(d->contactManager, SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts)), SLOT(onContactsChanged(Tp::Contacts,Tp::Contacts)));
}

int KTp::ContactsListModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED (parent);
    return d->contacts.size();
}

QVariant KTp::ContactsListModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();

    if (row >=0 && row < d->contacts.size()) {
        const KTp::ContactPtr contact = KTp::ContactPtr::qObjectCast(d->contacts[row]);

        switch (role) {
        case ContactsModel::IdRole:
            return contact->id();
        case ContactsModel::TypeRole:
            return ContactsModel::ContactRowType;
        case ContactsModel::ContactRole:
            return QVariant::fromValue(d->contacts[row]); //Tp::ContactPtr and NOT KTp::ContactPtr
        case ContactsModel::AccountRole:
            return QVariant::fromValue(d->contactManager->accountForContact(contact));
        case Qt::DisplayRole:
            return contact->alias();
        case ContactsModel::AliasRole:
            return contact->alias();
        case ContactsModel::PresenceRole:
            return QVariant::fromValue(contact->presence());
        case ContactsModel::PresenceIconRole:
            return QIcon(contact->presence().icon());
        case ContactsModel::PresenceStatusRole:
            return contact->presence().status();
        case ContactsModel::PresenceTypeRole:
            return contact->presence().type();
        case ContactsModel::PresenceMessageRole:
            return contact->presence().statusMessage();
        case ContactsModel::SubscriptionStateRole:
            return contact->subscriptionState();
        case ContactsModel::PublishStateRole:
            return contact->publishState();
        case ContactsModel::BlockedRole:
            return contact->isBlocked();
        case ContactsModel::GroupsRole:
            return contact->groups();
        case ContactsModel::AvatarRole:
            return contact->avatarData().fileName;
        case Qt::DecorationRole:
            return QImage(contact->avatarData().fileName);
        case ContactsModel::TextChatCapabilityRole:
            return contact->capabilities().textChats();
        case ContactsModel::ClientTypesRole:
            return contact->clientTypes();
        default:
            break;
        }

    }
    return QVariant();
}

void KTp::ContactsListModel::onContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
{
    //add contacts.

    Q_FOREACH(const Tp::ContactPtr &contact_uncasted, added) {
        KTp::ContactPtr contact = KTp::ContactPtr::qObjectCast(contact_uncasted);

        connect(contact.data(),
                    SIGNAL(aliasChanged(QString)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(avatarTokenChanged(QString)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(avatarDataChanged(Tp::AvatarData)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(presenceChanged(Tp::Presence)),
                    SLOT(onChanged()));
            connect(contact->manager()->connection()->selfContact().data(),
                    SIGNAL(capabilitiesChanged(Tp::ContactCapabilities)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(capabilitiesChanged(Tp::ContactCapabilities)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(locationUpdated(Tp::LocationInfo)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(infoFieldsChanged(Tp::Contact::InfoFields)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(subscriptionStateChanged(Tp::Contact::PresenceState)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(publishStateChanged(Tp::Contact::PresenceState,QString)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(blockStatusChanged(bool)),
                    SLOT(onChanged()));
            connect(contact.data(),
                    SIGNAL(clientTypesChanged(QStringList)),
                    SLOT(onChanged()));

            connect(contact.data(), SIGNAL(invalidated()), SLOT(onConnectionDropped()));
    }

    if (added.size() > 0) {
        beginInsertRows(QModelIndex(), d->contacts.size(), d->contacts.size() + added.size() -1);
        d->contacts.append(added.toList());
        endInsertRows();
    }

    //remove contacts
    Q_FOREACH(const Tp::ContactPtr &contact, removed) {
        int row = d->contacts.indexOf(contact);
        if (row >= 0) { //if contact found in list
            beginRemoveRows(QModelIndex(), row, row);
            d->contacts.removeOne(contact);
            endRemoveRows();
        }
    }
}

void KTp::ContactsListModel::onChanged()
{
    KTp::ContactPtr contact(qobject_cast<KTp::Contact*>(sender()));
    int row = d->contacts.indexOf(contact);
    if (row > 0) {
        QModelIndex index = createIndex(row, 0);
        dataChanged(index, index);
    }
}

void KTp::ContactsListModel::onConnectionDropped()
{
    KTp::ContactPtr contact(qobject_cast<KTp::Contact*>(sender()));
    onContactsChanged(Tp::Contacts(), Tp::Contacts() << contact);
}

<|endoftext|>


<commit_before>#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <math.h>
#include <stdio.h>

using namespace cv;
using namespace std;

int main()
{

	//char dir[100]={"/home/sedrica/Desktop/images.jpg"};

	Mat img;
	img=imread("images.jpg", CV_LOAD_IMAGE_COLOR); // reading the rgb image in Mat data struct

	Mat img_bw;
	cvtColor(img, img_bw,COLOR_RGB2GRAY);  // conversion to greayscale
/*

note: we may have to either pre process the image or not work with the custom bgr to greyscale or both
	  as they might not be able to detect edge very well
*/

	Mat grad_x, grad_y;    // derivative along x and y direction respectively
    Mat square_grad_x, square_grad_y;   // absoute value of derivative

    /// Gradient  along X direction
	Sobel( img_bw, grad_x,CV_16S, 1, 0, 3, 1,0, BORDER_DEFAULT );
	/// Gradient  along y direction
	Sobel( img_bw, grad_y,CV_16S, 0, 1, 3, 1, 0, BORDER_DEFAULT );

	square_grad_y=grad_y.mul(grad_y);
	square_grad_x=grad_x.mul(grad_x);

	Mat img_edge;

    addWeighted( square_grad_x,1, square_grad_y, 0.5, 0,img_edge);    // more weight is provided in the horizontal direction for more importance to lane detection

    Mat img_edge_dilated;
    Point anchor=Point(-1,-1);
    Size str_elem_dim_11;
    str_elem_dim_11=Size(11,11);

    Mat rect_str_elem=getStructuringElement(MORPH_RECT,str_elem_dim_11,anchor);

    dilate(img_edge,img_edge_dilated,rect_str_elem);
/*
    Mat img_eroded;
    Mat circ_str_elem=getStructuringElement(MORPH_ELLIPSE,str_elem_dim_11,anchor);
    erode( img_edge_dilated,img_eroded,circ_str_elem);
*/
    Mat img_flood_fill;
    Point origin=Point(0,0);  // is this have to be origin or (-1,-1) ?

    floodFill(img_flood_fill,origin,Scalar(255),0,Scalar(),Scalar(),4);   /// got an issue with arguments SCALAR

    Mat img_openloops_removed;

    morphologyEx(img_flood_fill,img_openloops_removed,MORPH_OPEN,rect_str_elem);  // <------ confirm it

    Mat img_small_closedloops_removed;
	morphologyEx(img_openloops_removed,img_small_closedloops_removed,MORPH_OPENCLOSED,rect_str_elem);  // comfirm it

	Mat img_erode_post_fill1;img_erode_post_erode;

	erode(img_small_closedloops_removed,img_erode_post_fill1,circ_str_elem);
	erode(img_erode_post_fill1,img_erode_post_erode,circ_str_elem);

	Mat img_final_filled;
	floodFill(img_final_filled,origin,Scalar(255),0,Scalar(),Scalar(),4);   /// got an issue with arguments SCALAR

////////////////////////////////////////////////////////////////////////////

	int connected_components_count;

	Mat img_label;
	connected_components_count=onnectedComponents(img_final_filled,img_label,8,int ltype=cv_32s);

	Mat label;
	label = // add matlab labelmatrix function equivalent of opencv

	Mat final_color_segmented;
	applyColorMap(label,final_color_segmented, COLORMAP_JET);

	return 0;
}
<commit_msg>flood fil<commit_after>#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <math.h>
#include <stdio.h>

using namespace cv;
using namespace std;

int main()
{

	//char dir[100]={"/home/sedrica/Desktop/images.jpg"};

	Mat img;
	img=imread("images.jpg", CV_LOAD_IMAGE_COLOR); // reading the rgb image in Mat data struct

	Mat img_bw;
	cvtColor(img, img_bw,COLOR_RGB2GRAY);  // conversion to greayscale
/*

note: we may have to either pre process the image or not work with the custom bgr to greyscale or both
	  as they might not be able to detect edge very well
*/

	Mat grad_x, grad_y;    // derivative along x and y direction respectively
    Mat square_grad_x, square_grad_y;   // absoute value of derivative

    /// Gradient  along X direction
	Sobel( img_bw, grad_x,CV_16S, 1, 0, 3, 1,0, BORDER_DEFAULT );
	/// Gradient  along y direction
	Sobel( img_bw, grad_y,CV_16S, 0, 1, 3, 1, 0, BORDER_DEFAULT );

	square_grad_y=grad_y.mul(grad_y);
	square_grad_x=grad_x.mul(grad_x);

	Mat img_edge;

    addWeighted( square_grad_x,1, square_grad_y, 0.5, 0,img_edge);    // more weight is provided in the horizontal direction for more importance to lane detection

    Mat img_edge_dilated;
    Point anchor=Point(-1,-1);
    Size str_elem_dim_11;
    str_elem_dim_11=Size(11,11);

    Mat rect_str_elem=getStructuringElement(MORPH_RECT,str_elem_dim_11,anchor);

    dilate(img_edge,img_edge_dilated,rect_str_elem);

    //Mat img_eroded;
    Mat circ_str_elem=getStructuringElement(MORPH_ELLIPSE,str_elem_dim_11,anchor);
    //erode( img_edge_dilated,img_eroded,circ_str_elem);

    Mat img_flood_fill;
    Point origin=Point(0,0);  // is this have to be origin or (-1,-1) ?

    floodFill(img_edge_dilated,img_flood_fill,origin,Scalar(255),0,Scalar(),Scalar(),4);   /// got an issue with arguments SCALAR

    Mat img_openloops_removed;

    morphologyEx(img_flood_fill,img_openloops_removed,MORPH_OPEN,rect_str_elem);  // <------ confirm it

    Mat img_small_closedloops_removed;
	morphologyEx(img_openloops_removed,img_small_closedloops_removed,MORPH_CLOSED,rect_str_elem);  // comfirm it

	Mat img_erode_post_fill1,img_erode_post_erode;

	erode(img_small_closedloops_removed,img_erode_post_fill1,circ_str_elem);
	erode(img_erode_post_fill1,img_erode_post_erode,circ_str_elem);

	Mat img_final_filled;
	floodFill(img_erode_post_fill1,img_final_filled,origin,Scalar(255),0,Scalar(),Scalar(),4);   /// got an issue with arguments SCALAR

////////////////////////////////////////////////////////////////////////////

	int connected_components_count;

	Mat img_label;
	connected_components_count=connectedComponents(img_final_filled,img_label,8,int ltype=cv_32s);

	Mat label;
	label = // add matlab labelmatrix function equivalent of opencv

	Mat final_color_segmented;
	applyColorMap(label,final_color_segmented, COLORMAP_JET);

	return 0;
}
<|endoftext|>