<commit_before>/*
 * Author: Brendan Le Foll <brendan.le.foll@intel.com>
 * Copyright (c) 2014 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#pragma once

#include "i2c.h"
#include <stdexcept>

namespace mraa {

/**
 * @brief API to Inter-Integrated Circuit
 *
 * An I2c object represents an i2c master and can talk multiple i2c slaves by
 * selecting the correct address
 * @htmlinclude i2c.txt
 *
 * @snippet I2c-compass.cpp Interesting
 */
class I2c {
    public:
        /**
         * Instantiates an i2c bus. Multiple instances of the same bus can
         * exist and the bus is not guarranteed to be on the correct address
         * before read/write.
         *
         * @param bus The i2c bus to use
         * @param raw Whether to disable pinmapper for your board
         */
        I2c(int bus, bool raw=false) {
            if (raw) {
                m_i2c = mraa_i2c_init_raw(bus);
            }
            else {
                m_i2c = mraa_i2c_init(bus);
            }
            if (m_i2c == NULL) {
                throw std::invalid_argument("Invalid i2c bus");
            }
        }

        /**
         * Closes the I2c Bus used. This does not guarrantee the bus will not
         * be usable by anyone else or communicates this disconnect to any
         * slaves.
         */
        ~I2c() {
            mraa_i2c_stop(m_i2c);
        }

        /**
         * Sets the i2c Frequency for communication. Your board may not support
         * the set frequency. Anyone can change this at any time and this will
         * affect every slave on the bus
         *
         * @param mode Frequency to set the bus to
         * @return Result of operation
         */
        mraa_result_t frequency(mraa_i2c_mode_t mode) {
            return mraa_i2c_frequency(m_i2c, mode);
        }

        /**
         * Set the slave to talk to, typically called before every read/write
         * operation
         *
         * @param address Communicate to the i2c slave on this address
         * @return Result of operation
         */
        mraa_result_t address(uint8_t address) {
            return mraa_i2c_address(m_i2c, address);
        }

        /**
         * Read exactly one byte from the bus
         *
         * @return char read from the bus
         */
        uint8_t readByte() {
            return (uint8_t) mraa_i2c_read_byte(m_i2c);
        }

        /**
	 * Read length bytes from the bus into *data pointer
         *
         * @param data Data to read into
         * @param length Size of read in bytes to make
         * @return length of read, should match length
         */
        int read(uint8_t *data, int length) {
            return mraa_i2c_read(m_i2c, data, length);
        }

        /**
         * Read byte from an i2c register
         *
         * @param reg Register to read from
         * @return char read from register
         */
        uint8_t readReg(uint8_t reg) {
            return mraa_i2c_read_byte_data(m_i2c, reg);
        }

        /**
         * Read word from an i2c register
         *
         * @param reg Register to read from
         * @return char read from register
         */
        uint16_t readWordReg(uint8_t reg) {
            return mraa_i2c_read_word_data(m_i2c, reg);
        }

        /**
         * Read length bytes from the bus into *data pointer starting from
         * an i2c register
         *
         * @param reg Register to read from
         * @param data pointer to the byte array to read data in to
         * @param length max number of bytes to read
         * @return length passed to the function or 0
         */
        int readBytesReg(uint8_t reg, uint8_t* data, int length) {
            return mraa_i2c_read_bytes_data(m_i2c, reg, data, length);
        }

        /**
         * Write a byte on the bus
         *
         * @param data The byte to send on the bus
         * @return Result of operation
         */
        mraa_result_t writeByte(uint8_t data) {
            return mraa_i2c_write_byte(m_i2c, data);
        }

        /**
         * Write length bytes to the bus, the first byte in the array is the
         * command/register to write
         *
         * @param data Buffer to send on the bus, first byte is i2c command
         * @param length Size of buffer to send
         * @return Result of operation
         */
        mraa_result_t write(const uint8_t* data, int length) {
            return mraa_i2c_write(m_i2c, data, length);
        }

        /**
         * Write a byte to an i2c register
         *
         * @param reg Register to write to
         * @param data Value to write to register
         * @return Result of operation
         */
        mraa_result_t writeReg(uint8_t reg, uint8_t data) {
            return mraa_i2c_write_byte_data(m_i2c, data, reg);
        }

        /**
         * Write a word to an i2c register
         *
         * @param reg Register to write to
         * @param data Value to write to register
         * @return Result of operation
         */
        mraa_result_t writeWordReg(uint8_t reg, uint16_t data) {
            return mraa_i2c_write_word_data(m_i2c, data, reg);
        }
    private:
        mraa_i2c_context m_i2c;
};

}
<commit_msg>i2c.hpp: Remove tab<commit_after>/*
 * Author: Brendan Le Foll <brendan.le.foll@intel.com>
 * Copyright (c) 2014 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#pragma once

#include "i2c.h"
#include <stdexcept>

namespace mraa {

/**
 * @brief API to Inter-Integrated Circuit
 *
 * An I2c object represents an i2c master and can talk multiple i2c slaves by
 * selecting the correct address
 * @htmlinclude i2c.txt
 *
 * @snippet I2c-compass.cpp Interesting
 */
class I2c {
    public:
        /**
         * Instantiates an i2c bus. Multiple instances of the same bus can
         * exist and the bus is not guarranteed to be on the correct address
         * before read/write.
         *
         * @param bus The i2c bus to use
         * @param raw Whether to disable pinmapper for your board
         */
        I2c(int bus, bool raw=false) {
            if (raw) {
                m_i2c = mraa_i2c_init_raw(bus);
            }
            else {
                m_i2c = mraa_i2c_init(bus);
            }
            if (m_i2c == NULL) {
                throw std::invalid_argument("Invalid i2c bus");
            }
        }

        /**
         * Closes the I2c Bus used. This does not guarrantee the bus will not
         * be usable by anyone else or communicates this disconnect to any
         * slaves.
         */
        ~I2c() {
            mraa_i2c_stop(m_i2c);
        }

        /**
         * Sets the i2c Frequency for communication. Your board may not support
         * the set frequency. Anyone can change this at any time and this will
         * affect every slave on the bus
         *
         * @param mode Frequency to set the bus to
         * @return Result of operation
         */
        mraa_result_t frequency(mraa_i2c_mode_t mode) {
            return mraa_i2c_frequency(m_i2c, mode);
        }

        /**
         * Set the slave to talk to, typically called before every read/write
         * operation
         *
         * @param address Communicate to the i2c slave on this address
         * @return Result of operation
         */
        mraa_result_t address(uint8_t address) {
            return mraa_i2c_address(m_i2c, address);
        }

        /**
         * Read exactly one byte from the bus
         *
         * @return char read from the bus
         */
        uint8_t readByte() {
            return (uint8_t) mraa_i2c_read_byte(m_i2c);
        }

        /**
         * Read length bytes from the bus into *data pointer
         *
         * @param data Data to read into
         * @param length Size of read in bytes to make
         * @return length of read, should match length
         */
        int read(uint8_t *data, int length) {
            return mraa_i2c_read(m_i2c, data, length);
        }

        /**
         * Read byte from an i2c register
         *
         * @param reg Register to read from
         * @return char read from register
         */
        uint8_t readReg(uint8_t reg) {
            return mraa_i2c_read_byte_data(m_i2c, reg);
        }

        /**
         * Read word from an i2c register
         *
         * @param reg Register to read from
         * @return char read from register
         */
        uint16_t readWordReg(uint8_t reg) {
            return mraa_i2c_read_word_data(m_i2c, reg);
        }

        /**
         * Read length bytes from the bus into *data pointer starting from
         * an i2c register
         *
         * @param reg Register to read from
         * @param data pointer to the byte array to read data in to
         * @param length max number of bytes to read
         * @return length passed to the function or 0
         */
        int readBytesReg(uint8_t reg, uint8_t* data, int length) {
            return mraa_i2c_read_bytes_data(m_i2c, reg, data, length);
        }

        /**
         * Write a byte on the bus
         *
         * @param data The byte to send on the bus
         * @return Result of operation
         */
        mraa_result_t writeByte(uint8_t data) {
            return mraa_i2c_write_byte(m_i2c, data);
        }

        /**
         * Write length bytes to the bus, the first byte in the array is the
         * command/register to write
         *
         * @param data Buffer to send on the bus, first byte is i2c command
         * @param length Size of buffer to send
         * @return Result of operation
         */
        mraa_result_t write(const uint8_t* data, int length) {
            return mraa_i2c_write(m_i2c, data, length);
        }

        /**
         * Write a byte to an i2c register
         *
         * @param reg Register to write to
         * @param data Value to write to register
         * @return Result of operation
         */
        mraa_result_t writeReg(uint8_t reg, uint8_t data) {
            return mraa_i2c_write_byte_data(m_i2c, data, reg);
        }

        /**
         * Write a word to an i2c register
         *
         * @param reg Register to write to
         * @param data Value to write to register
         * @return Result of operation
         */
        mraa_result_t writeWordReg(uint8_t reg, uint16_t data) {
            return mraa_i2c_write_word_data(m_i2c, data, reg);
        }
    private:
        mraa_i2c_context m_i2c;
};

}
<|endoftext|>


<commit_before>#include "OneDHeatForcingFunctionRZ.h"

registerMooseObject("RELAP7App", OneDHeatForcingFunctionRZ);

template <>
InputParameters
validParams<OneDHeatForcingFunctionRZ>()
{
  InputParameters params = validParams<OneDHeatForcingFunction>();
  return params;
}

OneDHeatForcingFunctionRZ::OneDHeatForcingFunctionRZ(const InputParameters & parameters)
  : OneDHeatForcingFunction(parameters), RZSymmetry(parameters)
{
}

Real
OneDHeatForcingFunctionRZ::computeQpResidual()
{
  Real r = computeRadius(_q_point[_qp]);
  return 2. * libMesh::pi * r * OneDHeatForcingFunction::computeQpResidual();
}

Real
OneDHeatForcingFunctionRZ::computeQpJacobian()
{
  Real r = computeRadius(_q_point[_qp]);
  return 2. * libMesh::pi * r * OneDHeatForcingFunction::computeQpJacobian();
}
<commit_msg>Added missing RZSymmetry parameters in OneDHeatForcingFunctionRZ<commit_after>#include "OneDHeatForcingFunctionRZ.h"

registerMooseObject("RELAP7App", OneDHeatForcingFunctionRZ);

template <>
InputParameters
validParams<OneDHeatForcingFunctionRZ>()
{
  InputParameters params = validParams<OneDHeatForcingFunction>();
  params += validParams<RZSymmetry>();
  return params;
}

OneDHeatForcingFunctionRZ::OneDHeatForcingFunctionRZ(const InputParameters & parameters)
  : OneDHeatForcingFunction(parameters), RZSymmetry(parameters)
{
}

Real
OneDHeatForcingFunctionRZ::computeQpResidual()
{
  Real r = computeRadius(_q_point[_qp]);
  return 2. * libMesh::pi * r * OneDHeatForcingFunction::computeQpResidual();
}

Real
OneDHeatForcingFunctionRZ::computeQpJacobian()
{
  Real r = computeRadius(_q_point[_qp]);
  return 2. * libMesh::pi * r * OneDHeatForcingFunction::computeQpJacobian();
}
<|endoftext|>


<commit_before>// -*- mode: C++; c-file-style: "gnu" -*-
// kmcomposewin.cpp
// Author: Markus Wuebben <markus.wuebben@kde.org>
// This code is published under the GPL.

#include "kmlineeditspell.h"

#include "recentaddresses.h"
#include "kmkernel.h"
#include "globalsettings.h"

#include <libkdepim/kvcarddrag.h>
#include <libemailfunctions/email.h>

#include <kabc/vcardconverter.h>
#include <kio/netaccess.h>

#include <kpopupmenu.h>
#include <kurl.h>
#include <kurldrag.h>
#include <kmessagebox.h>
#include <kcompletionbox.h>
#include <klocale.h>

#include <qevent.h>
#include <qfile.h>
#include <qcstring.h>
#include <qcursor.h>

KMLineEdit::KMLineEdit(bool useCompletion,
                       QWidget *parent, const char *name)
    : KPIM::AddresseeLineEdit(parent,useCompletion,name)
{
   allowSemiColonAsSeparator( GlobalSettings::allowSemicolonAsAddressSeparator() );
}

//-----------------------------------------------------------------------------
void KMLineEdit::keyPressEvent(QKeyEvent *e)
{
  if ((e->key() == Key_Enter || e->key() == Key_Return) &&
      !completionBox()->isVisible())
  {
    emit focusDown();
    AddresseeLineEdit::keyPressEvent(e);
    return;
  }
  if (e->key() == Key_Up)
  {
    emit focusUp();
    return;
  }
  if (e->key() == Key_Down)
  {
    emit focusDown();
    return;
  }
  AddresseeLineEdit::keyPressEvent(e);
}

void KMLineEdit::insertEmails( const QStringList & emails )
{
  if ( emails.empty() )
    return;

  QString contents = text();
  if ( !contents.isEmpty() )
    contents += ',';
  // only one address, don't need kpopup to choose
  if ( emails.size() == 1 ) {
    setText( contents + emails.front() );
    return;
  }
  //multiple emails, let the user choose one
  KPopupMenu menu( this, "Addresschooser" );
  for ( QStringList::const_iterator it = emails.begin(), end = emails.end() ; it != end; ++it )
    menu.insertItem( *it );
  const int result = menu.exec( QCursor::pos() );
  if ( result < 0 )
    return;
  setText( contents + menu.text( result ) );
}

void KMLineEdit::dropEvent(QDropEvent *event)
{
  QString vcards;
  KVCardDrag::decode( event, vcards );
  if ( !vcards.isEmpty() ) {
    KABC::VCardConverter converter;
    KABC::Addressee::List list = converter.parseVCards( vcards );
    KABC::Addressee::List::Iterator ait;
    for ( ait = list.begin(); ait != list.end(); ++ait ){
      insertEmails( (*ait).emails() );
    }
  } else {
    KURL::List urls;
    if ( KURLDrag::decode( event, urls) ) {
      //kdDebug(5006) << "urlList" << endl;
      KURL::List::Iterator it = urls.begin();
      KABC::VCardConverter converter;
      KABC::Addressee::List list;
      QString fileName;
      QString caption( i18n( "vCard Import Failed" ) );
      for ( it = urls.begin(); it != urls.end(); ++it ) {
        if ( KIO::NetAccess::download( *it, fileName, parentWidget() ) ) {
          QFile file( fileName );
          file.open( IO_ReadOnly );
          QByteArray rawData = file.readAll();
          file.close();
          QString data = QString::fromUtf8( rawData.data(), rawData.size() + 1 );
          list += converter.parseVCards( data );
          KIO::NetAccess::removeTempFile( fileName );
        } else {
          QString text = i18n( "<qt>Unable to access %1.</qt>" );
          KMessageBox::error( parentWidget(), text.arg( (*it).url() ), caption );
        }
        KABC::Addressee::List::Iterator ait;
        for ( ait = list.begin(); ait != list.end(); ++ait )
          insertEmails((*ait).emails());
      }
    } else {
      KPIM::AddresseeLineEdit::dropEvent( event );
    }
  }
}

QPopupMenu *KMLineEdit::createPopupMenu()
{
    QPopupMenu *menu = KPIM::AddresseeLineEdit::createPopupMenu();
    if ( !menu )
        return 0;

    menu->insertSeparator();
    menu->insertItem( i18n( "Edit Recent Addresses..." ),
                      this, SLOT( editRecentAddresses() ) );

    return menu;
}

void KMLineEdit::editRecentAddresses()
{
  KRecentAddress::RecentAddressDialog dlg( this );
  dlg.setAddresses( KRecentAddress::RecentAddresses::self( KMKernel::config() )->addresses() );
  if ( !dlg.exec() )
    return;
  KRecentAddress::RecentAddresses::self( KMKernel::config() )->clear();
  const QStringList addrList = dlg.addresses();
  for ( QStringList::const_iterator it = addrList.begin(), end = addrList.end() ; it != end ; ++it )
    KRecentAddress::RecentAddresses::self( KMKernel::config() )->add( *it );
  loadContacts();
}

//-----------------------------------------------------------------------------
void KMLineEdit::loadContacts()
{
  AddresseeLineEdit::loadContacts();

  if ( GlobalSettings::self()->showRecentAddressesInComposer() ){
    if ( KMKernel::self() ) {
      QStringList recent =
        KRecentAddress::RecentAddresses::self( KMKernel::config() )->addresses();
      QStringList::Iterator it = recent.begin();
      QString name, email;
      // FIXME: Make the 120 configureable. This is also hardcoded somewhere else!
      int idx = addCompletionSource( i18n( "Recent Addresses" ), 120 );
      for ( ; it != recent.end(); ++it ) {
        KABC::Addressee addr;
        KPIM::getNameAndMail(*it, name, email);
        addr.setNameFromString( KPIM::quoteNameIfNecessary( name ));
        addr.insertEmail( email, true );
        addContact( addr, 120, idx ); // more weight than kabc entries and more than ldap results
      }
    }
  }
}

KMLineEditSpell::KMLineEditSpell(bool useCompletion,
                       QWidget *parent, const char *name)
    : KMLineEdit(useCompletion,parent,name)
{
}

void KMLineEditSpell::highLightWord( unsigned int length, unsigned int pos )
{
    setSelection ( pos, length );
}

void KMLineEditSpell::spellCheckDone( const QString &s )
{
    if( s != text() )
        setText( s );
}

void KMLineEditSpell::spellCheckerMisspelling( const QString &_text, const QStringList&, unsigned int pos)
{
     highLightWord( _text.length(),pos );
}

void KMLineEditSpell::spellCheckerCorrected( const QString &old, const QString &corr, unsigned int pos)
{
    if( old!= corr )
    {
        setSelection ( pos, old.length() );
        insert( corr );
        setSelection ( pos, corr.length() );
        emit subjectTextSpellChecked();
    }
}

#include "kmlineeditspell.moc"
<commit_msg>display the Recent Addresses sublist last, by default. kolab/issue3804<commit_after>// -*- mode: C++; c-file-style: "gnu" -*-
// kmcomposewin.cpp
// Author: Markus Wuebben <markus.wuebben@kde.org>
// This code is published under the GPL.

#include "kmlineeditspell.h"

#include "recentaddresses.h"
#include "kmkernel.h"
#include "globalsettings.h"

#include <libkdepim/kvcarddrag.h>
#include <libemailfunctions/email.h>

#include <kabc/vcardconverter.h>
#include <kio/netaccess.h>

#include <kpopupmenu.h>
#include <kurl.h>
#include <kurldrag.h>
#include <kmessagebox.h>
#include <kcompletionbox.h>
#include <klocale.h>

#include <qevent.h>
#include <qfile.h>
#include <qcstring.h>
#include <qcursor.h>

KMLineEdit::KMLineEdit(bool useCompletion,
                       QWidget *parent, const char *name)
    : KPIM::AddresseeLineEdit(parent,useCompletion,name)
{
   allowSemiColonAsSeparator( GlobalSettings::allowSemicolonAsAddressSeparator() );
}

//-----------------------------------------------------------------------------
void KMLineEdit::keyPressEvent(QKeyEvent *e)
{
  if ((e->key() == Key_Enter || e->key() == Key_Return) &&
      !completionBox()->isVisible())
  {
    emit focusDown();
    AddresseeLineEdit::keyPressEvent(e);
    return;
  }
  if (e->key() == Key_Up)
  {
    emit focusUp();
    return;
  }
  if (e->key() == Key_Down)
  {
    emit focusDown();
    return;
  }
  AddresseeLineEdit::keyPressEvent(e);
}

void KMLineEdit::insertEmails( const QStringList & emails )
{
  if ( emails.empty() )
    return;

  QString contents = text();
  if ( !contents.isEmpty() )
    contents += ',';
  // only one address, don't need kpopup to choose
  if ( emails.size() == 1 ) {
    setText( contents + emails.front() );
    return;
  }
  //multiple emails, let the user choose one
  KPopupMenu menu( this, "Addresschooser" );
  for ( QStringList::const_iterator it = emails.begin(), end = emails.end() ; it != end; ++it )
    menu.insertItem( *it );
  const int result = menu.exec( QCursor::pos() );
  if ( result < 0 )
    return;
  setText( contents + menu.text( result ) );
}

void KMLineEdit::dropEvent(QDropEvent *event)
{
  QString vcards;
  KVCardDrag::decode( event, vcards );
  if ( !vcards.isEmpty() ) {
    KABC::VCardConverter converter;
    KABC::Addressee::List list = converter.parseVCards( vcards );
    KABC::Addressee::List::Iterator ait;
    for ( ait = list.begin(); ait != list.end(); ++ait ){
      insertEmails( (*ait).emails() );
    }
  } else {
    KURL::List urls;
    if ( KURLDrag::decode( event, urls) ) {
      //kdDebug(5006) << "urlList" << endl;
      KURL::List::Iterator it = urls.begin();
      KABC::VCardConverter converter;
      KABC::Addressee::List list;
      QString fileName;
      QString caption( i18n( "vCard Import Failed" ) );
      for ( it = urls.begin(); it != urls.end(); ++it ) {
        if ( KIO::NetAccess::download( *it, fileName, parentWidget() ) ) {
          QFile file( fileName );
          file.open( IO_ReadOnly );
          QByteArray rawData = file.readAll();
          file.close();
          QString data = QString::fromUtf8( rawData.data(), rawData.size() + 1 );
          list += converter.parseVCards( data );
          KIO::NetAccess::removeTempFile( fileName );
        } else {
          QString text = i18n( "<qt>Unable to access %1.</qt>" );
          KMessageBox::error( parentWidget(), text.arg( (*it).url() ), caption );
        }
        KABC::Addressee::List::Iterator ait;
        for ( ait = list.begin(); ait != list.end(); ++ait )
          insertEmails((*ait).emails());
      }
    } else {
      KPIM::AddresseeLineEdit::dropEvent( event );
    }
  }
}

QPopupMenu *KMLineEdit::createPopupMenu()
{
    QPopupMenu *menu = KPIM::AddresseeLineEdit::createPopupMenu();
    if ( !menu )
        return 0;

    menu->insertSeparator();
    menu->insertItem( i18n( "Edit Recent Addresses..." ),
                      this, SLOT( editRecentAddresses() ) );

    return menu;
}

void KMLineEdit::editRecentAddresses()
{
  KRecentAddress::RecentAddressDialog dlg( this );
  dlg.setAddresses( KRecentAddress::RecentAddresses::self( KMKernel::config() )->addresses() );
  if ( !dlg.exec() )
    return;
  KRecentAddress::RecentAddresses::self( KMKernel::config() )->clear();
  const QStringList addrList = dlg.addresses();
  for ( QStringList::const_iterator it = addrList.begin(), end = addrList.end() ; it != end ; ++it )
    KRecentAddress::RecentAddresses::self( KMKernel::config() )->add( *it );
  loadContacts();
}

//-----------------------------------------------------------------------------
void KMLineEdit::loadContacts()
{
  AddresseeLineEdit::loadContacts();

  if ( GlobalSettings::self()->showRecentAddressesInComposer() ){
    if ( KMKernel::self() ) {
      QStringList recent =
        KRecentAddress::RecentAddresses::self( KMKernel::config() )->addresses();
      QStringList::Iterator it = recent.begin();
      QString name, email;
      // FIXME: Make the 10 configureable. This is also hardcoded somewhere else!
      int idx = addCompletionSource( i18n( "Recent Addresses" ), 10 );
      for ( ; it != recent.end(); ++it ) {
        KABC::Addressee addr;
        KPIM::getNameAndMail(*it, name, email);
        addr.setNameFromString( KPIM::quoteNameIfNecessary( name ));
        addr.insertEmail( email, true );
        addContact( addr, 10, idx ); // more weight than kabc entries and more than ldap results
      }
    }
  }
}

KMLineEditSpell::KMLineEditSpell(bool useCompletion,
                       QWidget *parent, const char *name)
    : KMLineEdit(useCompletion,parent,name)
{
}

void KMLineEditSpell::highLightWord( unsigned int length, unsigned int pos )
{
    setSelection ( pos, length );
}

void KMLineEditSpell::spellCheckDone( const QString &s )
{
    if( s != text() )
        setText( s );
}

void KMLineEditSpell::spellCheckerMisspelling( const QString &_text, const QStringList&, unsigned int pos)
{
     highLightWord( _text.length(),pos );
}

void KMLineEditSpell::spellCheckerCorrected( const QString &old, const QString &corr, unsigned int pos)
{
    if( old!= corr )
    {
        setSelection ( pos, old.length() );
        insert( corr );
        setSelection ( pos, corr.length() );
        emit subjectTextSpellChecked();
    }
}

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


<commit_before><commit_msg>Import new fix from libcxxrt.  This fixes the case where you attempt to rethrow an exception when you haven't caught one.  This is largely a cosmetic fix, as (unless you have a very unusual terminate handler installed) it will print a nice error and then abort, rather than just aborting.<commit_after><|endoftext|>


<commit_before>// kmreadermainwin
// (c) 2002 Don Sanders <sanders@kde.org>
// License: GPL
//
// A toplevel KMainWindow derived class for displaying
// single messages or single message parts.
//
// Could be extended to include support for normal main window
// widgets like a toolbar.

#include <qaccel.h>
#include <kapplication.h>
#include <klocale.h>
#include <kstdaccel.h>
#include <kwin.h>
#include <kaction.h>

#include "kmcommands.h"
#include "kmenubar.h"
#include "kpopupmenu.h"
#include "kmreaderwin.h"
#include "kmfolderindex.h"

#include "kmreadermainwin.h"
#include "kmreadermainwin.moc"

KMReaderMainWin::KMReaderMainWin( bool htmlOverride, char *name )
  : KMTopLevelWidget( name ), mMsg( 0 )
{
  KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon());
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  //mReaderWin->setShowCompleteMessage( true );
  mReaderWin->setAutoDelete( true );
  mReaderWin->setHtmlOverride( htmlOverride );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin( char *name )
  : KMTopLevelWidget( name ), mMsg( 0 )
{
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  mReaderWin->setAutoDelete( true );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin(KMMessagePart* aMsgPart,
    bool aHTML, const QString& aFileName, const QString& pname,
    const QTextCodec *codec, char *name )
  : KMTopLevelWidget( name ), mMsg( 0 )
{
  resize( 550, 600 );
  mReaderWin = new KMReaderWin( this, this, actionCollection() ); //new reader
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsgPart( aMsgPart, aHTML, aFileName, pname );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::~KMReaderMainWin()
{
  saveMainWindowSettings(KMKernel::config(), "Separate Reader Window");
}

void KMReaderMainWin::showMsg( const QTextCodec *codec, KMMessage *msg )
{
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsg( msg, true );
  setCaption( msg->subject() );
  mMsg = msg;
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotPrintMsg()
{
  KMCommand *command = new KMPrintCommand( this, mReaderWin->message(),
      mReaderWin->htmlOverride() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyToMsg()
{
  KMCommand *command = new KMReplyToCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAuthorToMsg()
{
  KMCommand *command = new KMReplyAuthorCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAllToMsg()
{
  KMCommand *command = new KMReplyToAllCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyListToMsg()
{
  KMCommand *command = new KMReplyListCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardMsg()
{
  KMCommand *command = new KMForwardCommand( this, mReaderWin->message(),
      mReaderWin->message()->parent()->identity() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardAttachedMsg()
{
  KMCommand *command =
    new KMForwardAttachedCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotRedirectMsg()
{
  KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotBounceMsg()
{
  KMCommand *command = new KMBounceCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotConfigChanged()
{
  readConfig();
}

void KMReaderMainWin::setupAccel()
{
  if (kmkernel->xmlGuiInstance())
    setInstance( kmkernel->xmlGuiInstance() );
  KStdAction::close( this, SLOT( close() ), actionCollection() );
  applyMainWindowSettings(KMKernel::config(), "Separate Reader Window");
  QAccel *accel = new QAccel(mReaderWin, "showMsg()");
  accel->connectItem(accel->insertItem(Key_Up),
                     mReaderWin, SLOT(slotScrollUp()));
  accel->connectItem(accel->insertItem(Key_Down),
                     mReaderWin, SLOT(slotScrollDown()));
  accel->connectItem(accel->insertItem(Key_Prior),
                     mReaderWin, SLOT(slotScrollPrior()));
  accel->connectItem(accel->insertItem(Key_Next),
                     mReaderWin, SLOT(slotScrollNext()));
  accel->connectItem(accel->insertItem(KStdAccel::shortcut(KStdAccel::Copy)),
                     mReaderWin, SLOT(slotCopySelectedText()));
  connect( mReaderWin, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
	  this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
  connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
	  mReaderWin, SLOT(slotUrlClicked()));

  mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
					"mail_forward", actionCollection(),
					"message_forward" );

  mForwardAction = new KAction( i18n("&Inline..."), "mail_forward",
				SHIFT+Key_F, this, SLOT(slotForwardMsg()),
				actionCollection(), "message_forward" );
  mForwardActionMenu->insert( mForwardAction );

  mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
				       "mail_forward", Key_F, this,
					SLOT(slotForwardAttachedMsg()), actionCollection(),
					"message_forward_as_attachment" );
  mForwardActionMenu->insert( mForwardAttachedAction );

  mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
				 Key_E, this, SLOT(slotRedirectMsg()),
				 actionCollection(), "message_forward_redirect" );
  mForwardActionMenu->insert( mRedirectAction );

  mBounceAction = new KAction( i18n("&Bounce..."), 0, this,
			      SLOT(slotBounceMsg()), actionCollection(), "bounce" );

  mReplyActionMenu = new KActionMenu( i18n("Message->","&Reply"),
                                      "mail_reply", actionCollection(),
                                      "message_reply_menu" );
  connect( mReplyActionMenu, SIGNAL(activated()), this,
	   SLOT(slotReplyToMsg()) );

  mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", Key_R, this,
			      SLOT(slotReplyToMsg()), actionCollection(), "reply" );
  mReplyActionMenu->insert( mReplyAction );

  mReplyAuthorAction = new KAction( i18n("Reply to A&uthor..."), "mail_reply",
                                    SHIFT+Key_A, this,
                                    SLOT(slotReplyAuthorToMsg()),
                                    actionCollection(), "reply_author" );
  mReplyActionMenu->insert( mReplyAuthorAction );

  mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall",
				 Key_A, this, SLOT(slotReplyAllToMsg()),
				 actionCollection(), "reply_all" );
  mReplyActionMenu->insert( mReplyAllAction );

  mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."),
				  "mail_replylist", Key_L, this,
				  SLOT(slotReplyListToMsg()), actionCollection(),
				  "reply_list" );
  mReplyActionMenu->insert( mReplyListAction );

  mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
  createGUI( "kmreadermainwin.rc" );
  menuBar()->hide();

}

void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoint& aPoint)
{
  KPopupMenu * menu = new KPopupMenu;
  mUrl = aUrl;
  mMsg = &aMsg;

  if (!aUrl.isEmpty()) {
    if (aUrl.protocol() == "mailto") {
      // popup on a mailto URL
      mReaderWin->mailToComposeAction()->plug( menu );
      if ( mMsg ) {
	mReaderWin->mailToReplyAction()->plug( menu );
	mReaderWin->mailToForwardAction()->plug( menu );
        menu->insertSeparator();
      }
      mReaderWin->addAddrBookAction()->plug( menu );
      mReaderWin->openAddrBookAction()->plug( menu );
      mReaderWin->copyAction()->plug( menu );
    } else {
      // popup on a not-mailto URL
      mReaderWin->urlOpenAction()->plug( menu );
      mReaderWin->urlSaveAsAction()->plug( menu );
      mReaderWin->copyURLAction()->plug( menu );
      mReaderWin->addBookmarksAction()->plug( menu );
    }
  } else {
    // popup somewhere else (i.e., not a URL) on the message

    if (!mMsg) // no message
    {
      delete menu;
      return;
    }

    mReplyAction->plug( menu );
    mReplyAllAction->plug( menu );
    mReplyAuthorAction->plug( menu );
    mReplyListAction->plug( menu );
    mForwardActionMenu->plug( menu );
    mBounceAction->plug( menu );

    menu->insertSeparator();

    QPopupMenu* copyMenu = new QPopupMenu(menu);
    KMMenuCommand::folderToPopupMenu( false, this, &mMenuToFolder, copyMenu );
    menu->insertItem( i18n("&Copy To" ), copyMenu );
    menu->insertSeparator();
    mReaderWin->toggleFixFontAction()->plug( menu );
    mReaderWin->viewSourceAction()->plug( menu );

    mPrintAction->plug( menu );

    menu->insertItem( i18n("Save &As..."), mReaderWin, SLOT(slotSaveMsg()) );
    menu->insertItem( i18n("Save Attachments..."), mReaderWin, SLOT(slotSaveAttachments()) );
  }
  menu->exec(aPoint, 0);
  delete menu;
}

void KMReaderMainWin::copySelectedToFolder( int menuId )
{
  if (!mMenuToFolder[menuId])
    return;

  KMCommand *command = new KMCopyCommand( mMenuToFolder[menuId], mMsg );
  command->start();
}
<commit_msg>Don't crash when forwarding messages that are not in any folder, such as attachments.<commit_after>// kmreadermainwin
// (c) 2002 Don Sanders <sanders@kde.org>
// License: GPL
//
// A toplevel KMainWindow derived class for displaying
// single messages or single message parts.
//
// Could be extended to include support for normal main window
// widgets like a toolbar.

#include <qaccel.h>
#include <kapplication.h>
#include <klocale.h>
#include <kstdaccel.h>
#include <kwin.h>
#include <kaction.h>

#include "kmcommands.h"
#include "kmenubar.h"
#include "kpopupmenu.h"
#include "kmreaderwin.h"
#include "kmfolderindex.h"

#include "kmreadermainwin.h"
#include "kmreadermainwin.moc"

KMReaderMainWin::KMReaderMainWin( bool htmlOverride, char *name )
  : KMTopLevelWidget( name ), mMsg( 0 )
{
  KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon());
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  //mReaderWin->setShowCompleteMessage( true );
  mReaderWin->setAutoDelete( true );
  mReaderWin->setHtmlOverride( htmlOverride );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin( char *name )
  : KMTopLevelWidget( name ), mMsg( 0 )
{
  mReaderWin = new KMReaderWin( this, this, actionCollection() );
  mReaderWin->setAutoDelete( true );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::KMReaderMainWin(KMMessagePart* aMsgPart,
    bool aHTML, const QString& aFileName, const QString& pname,
    const QTextCodec *codec, char *name )
  : KMTopLevelWidget( name ), mMsg( 0 )
{
  resize( 550, 600 );
  mReaderWin = new KMReaderWin( this, this, actionCollection() ); //new reader
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsgPart( aMsgPart, aHTML, aFileName, pname );
  setCentralWidget( mReaderWin );
  setupAccel();

  connect( kmkernel, SIGNAL( configChanged() ),
           this, SLOT( slotConfigChanged() ) );
}

KMReaderMainWin::~KMReaderMainWin()
{
  saveMainWindowSettings(KMKernel::config(), "Separate Reader Window");
}

void KMReaderMainWin::showMsg( const QTextCodec *codec, KMMessage *msg )
{
  mReaderWin->setOverrideCodec( codec );
  mReaderWin->setMsg( msg, true );
  setCaption( msg->subject() );
  mMsg = msg;
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotPrintMsg()
{
  KMCommand *command = new KMPrintCommand( this, mReaderWin->message(),
      mReaderWin->htmlOverride() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyToMsg()
{
  KMCommand *command = new KMReplyToCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAuthorToMsg()
{
  KMCommand *command = new KMReplyAuthorCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyAllToMsg()
{
  KMCommand *command = new KMReplyToAllCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotReplyListToMsg()
{
  KMCommand *command = new KMReplyListCommand( this, mReaderWin->message(),
      mReaderWin->copyText() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardMsg()
{
   KMCommand *command = NULL;
   if ( mReaderWin->message()->parent() ) {
    command = new KMForwardCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
   } else {
    command = new KMForwardCommand( this, mReaderWin->message() );
   }
   if ( command )
     command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotForwardAttachedMsg()
{
   KMCommand *command = NULL;
   if ( mReaderWin->message()->parent() ) {
     command = new KMForwardAttachedCommand( this, mReaderWin->message(),
        mReaderWin->message()->parent()->identity() );
   } else {
     command = new KMForwardAttachedCommand( this, mReaderWin->message() );
   }
   if ( command )
     command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotRedirectMsg()
{
  KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotBounceMsg()
{
  KMCommand *command = new KMBounceCommand( this, mReaderWin->message() );
  command->start();
}

//-----------------------------------------------------------------------------
void KMReaderMainWin::slotConfigChanged()
{
  readConfig();
}

void KMReaderMainWin::setupAccel()
{
  if (kmkernel->xmlGuiInstance())
    setInstance( kmkernel->xmlGuiInstance() );
  KStdAction::close( this, SLOT( close() ), actionCollection() );
  applyMainWindowSettings(KMKernel::config(), "Separate Reader Window");
  QAccel *accel = new QAccel(mReaderWin, "showMsg()");
  accel->connectItem(accel->insertItem(Key_Up),
                     mReaderWin, SLOT(slotScrollUp()));
  accel->connectItem(accel->insertItem(Key_Down),
                     mReaderWin, SLOT(slotScrollDown()));
  accel->connectItem(accel->insertItem(Key_Prior),
                     mReaderWin, SLOT(slotScrollPrior()));
  accel->connectItem(accel->insertItem(Key_Next),
                     mReaderWin, SLOT(slotScrollNext()));
  accel->connectItem(accel->insertItem(KStdAccel::shortcut(KStdAccel::Copy)),
                     mReaderWin, SLOT(slotCopySelectedText()));
  connect( mReaderWin, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
	  this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
  connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
	  mReaderWin, SLOT(slotUrlClicked()));

  mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
					"mail_forward", actionCollection(),
					"message_forward" );

  mForwardAction = new KAction( i18n("&Inline..."), "mail_forward",
				SHIFT+Key_F, this, SLOT(slotForwardMsg()),
				actionCollection(), "message_forward" );
  mForwardActionMenu->insert( mForwardAction );

  mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
				       "mail_forward", Key_F, this,
					SLOT(slotForwardAttachedMsg()), actionCollection(),
					"message_forward_as_attachment" );
  mForwardActionMenu->insert( mForwardAttachedAction );

  mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
				 Key_E, this, SLOT(slotRedirectMsg()),
				 actionCollection(), "message_forward_redirect" );
  mForwardActionMenu->insert( mRedirectAction );

  mBounceAction = new KAction( i18n("&Bounce..."), 0, this,
			      SLOT(slotBounceMsg()), actionCollection(), "bounce" );

  mReplyActionMenu = new KActionMenu( i18n("Message->","&Reply"),
                                      "mail_reply", actionCollection(),
                                      "message_reply_menu" );
  connect( mReplyActionMenu, SIGNAL(activated()), this,
	   SLOT(slotReplyToMsg()) );

  mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", Key_R, this,
			      SLOT(slotReplyToMsg()), actionCollection(), "reply" );
  mReplyActionMenu->insert( mReplyAction );

  mReplyAuthorAction = new KAction( i18n("Reply to A&uthor..."), "mail_reply",
                                    SHIFT+Key_A, this,
                                    SLOT(slotReplyAuthorToMsg()),
                                    actionCollection(), "reply_author" );
  mReplyActionMenu->insert( mReplyAuthorAction );

  mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall",
				 Key_A, this, SLOT(slotReplyAllToMsg()),
				 actionCollection(), "reply_all" );
  mReplyActionMenu->insert( mReplyAllAction );

  mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."),
				  "mail_replylist", Key_L, this,
				  SLOT(slotReplyListToMsg()), actionCollection(),
				  "reply_list" );
  mReplyActionMenu->insert( mReplyListAction );

  mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
  createGUI( "kmreadermainwin.rc" );
  menuBar()->hide();

}

void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoint& aPoint)
{
  KPopupMenu * menu = new KPopupMenu;
  mUrl = aUrl;
  mMsg = &aMsg;

  if (!aUrl.isEmpty()) {
    if (aUrl.protocol() == "mailto") {
      // popup on a mailto URL
      mReaderWin->mailToComposeAction()->plug( menu );
      if ( mMsg ) {
	mReaderWin->mailToReplyAction()->plug( menu );
	mReaderWin->mailToForwardAction()->plug( menu );
        menu->insertSeparator();
      }
      mReaderWin->addAddrBookAction()->plug( menu );
      mReaderWin->openAddrBookAction()->plug( menu );
      mReaderWin->copyAction()->plug( menu );
    } else {
      // popup on a not-mailto URL
      mReaderWin->urlOpenAction()->plug( menu );
      mReaderWin->urlSaveAsAction()->plug( menu );
      mReaderWin->copyURLAction()->plug( menu );
      mReaderWin->addBookmarksAction()->plug( menu );
    }
  } else {
    // popup somewhere else (i.e., not a URL) on the message

    if (!mMsg) // no message
    {
      delete menu;
      return;
    }

    mReplyAction->plug( menu );
    mReplyAllAction->plug( menu );
    mReplyAuthorAction->plug( menu );
    mReplyListAction->plug( menu );
    mForwardActionMenu->plug( menu );
    mBounceAction->plug( menu );

    menu->insertSeparator();

    QPopupMenu* copyMenu = new QPopupMenu(menu);
    KMMenuCommand::folderToPopupMenu( false, this, &mMenuToFolder, copyMenu );
    menu->insertItem( i18n("&Copy To" ), copyMenu );
    menu->insertSeparator();
    mReaderWin->toggleFixFontAction()->plug( menu );
    mReaderWin->viewSourceAction()->plug( menu );

    mPrintAction->plug( menu );

    menu->insertItem( i18n("Save &As..."), mReaderWin, SLOT(slotSaveMsg()) );
    menu->insertItem( i18n("Save Attachments..."), mReaderWin, SLOT(slotSaveAttachments()) );
  }
  menu->exec(aPoint, 0);
  delete menu;
}

void KMReaderMainWin::copySelectedToFolder( int menuId )
{
  if (!mMenuToFolder[menuId])
    return;

  KMCommand *command = new KMCopyCommand( mMenuToFolder[menuId], mMsg );
  command->start();
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkUnstructuredGridPreIntegration.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

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

/*
 * Copyright 2004 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

#include "vtkUnstructuredGridPreIntegration.h"

#include "vtkObjectFactory.h"
#include "vtkVolumeProperty.h"
#include "vtkVolume.h"
#include "vtkAbstractVolumeMapper.h"
#include "vtkUnstructuredGrid.h"
#include "vtkDoubleArray.h"
#include "vtkUnstructuredGridPartialPreIntegration.h"

#include <vtkstd/algorithm>
#include <math.h>

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

vtkCxxRevisionMacro(vtkUnstructuredGridPreIntegration, "1.3");
vtkStandardNewMacro(vtkUnstructuredGridPreIntegration);

vtkCxxSetObjectMacro(vtkUnstructuredGridPreIntegration, Integrator,
                     vtkUnstructuredGridVolumeRayIntegrator);

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

vtkUnstructuredGridPreIntegration::vtkUnstructuredGridPreIntegration()
{
  this->Integrator = vtkUnstructuredGridPartialPreIntegration::New();
  this->Property = NULL;

  this->NumComponents = 0;
  this->IntegrationTable = NULL;
  this->IntegrationTableScalarShift = NULL;
  this->IntegrationTableScalarScale = NULL;

  this->IntegrationTableScalarResolution = 128;
  this->IntegrationTableLengthResolution = 256;

  this->IncrementalPreIntegration = 1;
}

vtkUnstructuredGridPreIntegration::~vtkUnstructuredGridPreIntegration()
{
  this->SetIntegrator(NULL);

  if (this->IntegrationTable)
    {
    for (int i = 0; i < this->NumComponents; i++)
      {
      delete[] this->IntegrationTable[i];
      }
    delete[] this->IntegrationTable;
    }
  if (this->IntegrationTableScalarShift)
    {
    delete[] this->IntegrationTableScalarShift;
    }
  if (this->IntegrationTableScalarScale)
    {
    delete[] this->IntegrationTableScalarScale;
    }
}

void vtkUnstructuredGridPreIntegration::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Integrator: " << this->Integrator << endl;

  os << indent << "IntegrationTableScalarResolution: "
     << this->IntegrationTableScalarResolution << endl;
  os << indent << "IntegrationTableLengthResolution: "
     << this->IntegrationTableLengthResolution << endl;

  os << indent << "IncrementalPreIntegration: "
     << this->IncrementalPreIntegration << endl;
}

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

double vtkUnstructuredGridPreIntegration::GetIntegrationTableScalarShift(int component)
{
  return this->IntegrationTableScalarShift[component];
}

double vtkUnstructuredGridPreIntegration::GetIntegrationTableScalarScale(int component)
{
  return this->IntegrationTableScalarScale[component];
}

double vtkUnstructuredGridPreIntegration::GetIntegrationTableLengthScale()
{
  return this->IntegrationTableLengthScale;
}

float *vtkUnstructuredGridPreIntegration::GetPreIntegrationTable(int component)
{
  return this->IntegrationTable[component];
}

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

void vtkUnstructuredGridPreIntegration::BuildPreIntegrationTables(vtkDataArray *scalars)
{
  // Establish temporary inputs to integrator.
  vtkVolume         *tmpVolume = vtkVolume::New();
  vtkVolumeProperty *tmpProperty = vtkVolumeProperty::New();
  vtkDataArray      *tmpScalars
    = vtkDataArray::CreateDataArray(scalars->GetDataType());

  tmpVolume->SetMapper(this->Volume->GetMapper());
  tmpVolume->SetProperty(tmpProperty);

  tmpProperty->IndependentComponentsOn();
  tmpProperty->SetInterpolationType(this->Property->GetInterpolationType());

  tmpScalars->SetNumberOfComponents(1);
  tmpScalars->SetNumberOfTuples(2);

  vtkDoubleArray *tmpIntersectionLengths = vtkDoubleArray::New();
  vtkDataArray   *tmpNearIntersections
    = vtkDataArray::CreateDataArray(scalars->GetDataType());
  vtkDataArray   *tmpFarIntersections
    = vtkDataArray::CreateDataArray(scalars->GetDataType());

  tmpIntersectionLengths->SetNumberOfComponents(1);
  tmpIntersectionLengths->SetNumberOfTuples(1);
  tmpNearIntersections->SetNumberOfComponents(1);
  tmpNearIntersections->SetNumberOfTuples(1);
  tmpFarIntersections->SetNumberOfComponents(1);
  tmpFarIntersections->SetNumberOfTuples(1);

  this->IntegrationTable = new float*[this->NumComponents];
  this->IntegrationTableScalarShift = new double[this->NumComponents];
  this->IntegrationTableScalarScale = new double[this->NumComponents];
  // Note that the scale set up such that a length of (this->MaxLength +
  // epsilon + 0.5) will scale to this->IntegrationTableLengthResolution-1.
  // Similar scaling is performed for the other dimensions of the
  // pre-integration table.
  this->IntegrationTableLengthScale
    = (this->IntegrationTableLengthResolution-2)/this->MaxLength;

  // We only do computations at one length.
  float d_length = (float)(1/this->IntegrationTableLengthScale);

  for (int component = 0; component < this->NumComponents; component++)
    {
    int d_idx, sb_idx, sf_idx;
    float *c;

    // Allocate table.
    this->IntegrationTable[component]
      = new float[4*this->IntegrationTableScalarResolution
                 *this->IntegrationTableScalarResolution
                 *this->IntegrationTableLengthResolution];
    // Determine scale and shift.
    double *range = scalars->GetRange(component);
    if (range[0] == range[1])
      {
      // Unusual case where the scalars are all the same.
      this->IntegrationTableScalarScale[component] = 1.0;
      }
    else
      {
      this->IntegrationTableScalarScale[component]
        = (this->IntegrationTableScalarResolution-2)/(range[1]-range[0]);
      }
    this->IntegrationTableScalarShift[component]
      = -range[0]*this->IntegrationTableScalarScale[component];

    // Set values for d=0 (they are all zero).
    c = this->IntegrationTable[component];
    for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution; sb_idx++)
      {
      for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
           sf_idx++)
        {
        c[0] = c[1] = c[2] = c[3] = 0.0f;
        c += 4;
        }
      }

    // Initialize integrator.
    if (this->Property->GetColorChannels(component) == 3)
      {
      tmpProperty->SetColor(this->Property->GetRGBTransferFunction(component));
      }
    else
      {
      tmpProperty->SetColor(this->Property->GetGrayTransferFunction(component));
      }
    tmpProperty->SetScalarOpacity(this->Property->GetScalarOpacity(component));
    tmpProperty->SetScalarOpacityUnitDistance
      (this->Property->GetScalarOpacityUnitDistance(component));
    tmpProperty->SetShade(this->Property->GetShade(component));
    tmpProperty->SetAmbient(this->Property->GetAmbient(component));
    tmpProperty->SetDiffuse(this->Property->GetDiffuse(component));
    tmpProperty->SetSpecular(this->Property->GetSpecular(component));
    tmpProperty->SetSpecularPower(this->Property->GetSpecularPower(component));
    tmpScalars->SetTuple1(0, range[0]);
    tmpScalars->SetTuple1(1, range[1]);
    this->Integrator->Initialize(tmpVolume, tmpScalars);

    // Set values for next smallest d (the base values).
    tmpIntersectionLengths->SetTuple1(0, d_length);
    for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution; sb_idx++)
      {
      tmpFarIntersections
        ->SetTuple1(0,
                    (  (sb_idx - this->IntegrationTableScalarShift[component])
                     / (this->IntegrationTableScalarScale[component]) ));
      for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
           sf_idx++)
        {
        tmpNearIntersections
          ->SetTuple1(0,
                      (  (sf_idx - this->IntegrationTableScalarShift[component])
                       / (this->IntegrationTableScalarScale[component]) ));
        c[0] = c[1] = c[2] = c[3] = 0;
        this->Integrator->Integrate(tmpIntersectionLengths,
                                    tmpNearIntersections, tmpFarIntersections,
                                    c);
        c += 4;
        }
      }

    // Set rest of values using other values in table.
    if (this->IncrementalPreIntegration)
      {
      for (d_idx = 2; d_idx < this->IntegrationTableLengthResolution; d_idx++)
        {
        for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution;
             sb_idx++)
          {
          for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
               sf_idx++)
            {
            // We are going to perform incremental pre-integration.  To do
            // this, we compute the integration of a ray from sf to sb of
            // length d by combining two entries in the table.  The first
            // entry will be from sf to sm of length delta d (the smallest
            // non-zero length stored in the table).  The second entry will
            // be from sm to sb of length d - delta d.  See Weiler, et
            // al. "Hardware-Based Ray Casting for Tetrahedral Meshes" for
            // more details.
            int sm_idx = ((d_idx-1)*sf_idx + sb_idx + d_idx/2)/d_idx;

            float *colorf = this->GetIndexedTableEntry(sf_idx, sm_idx, 1,
                                                       component);
            float *colorb = this->GetIndexedTableEntry(sm_idx, sb_idx, d_idx-1,
                                                       component);

            c[0] = colorf[0] + colorb[0]*(1-colorf[3]);
            c[1] = colorf[1] + colorb[1]*(1-colorf[3]);
            c[2] = colorf[2] + colorb[2]*(1-colorf[3]);
            c[3] = colorf[3] + colorb[3]*(1-colorf[3]);
            c += 4;
            }
          }
        }
      }
    else
      {
      for (d_idx = 2; d_idx < this->IntegrationTableLengthResolution; d_idx++)
        {
        for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution;
             sb_idx++)
          {
          for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
               sf_idx++)
            {
            // Compute the integration table the old-fashioned slow way.
            float length = d_idx*d_length;
            float sb = (float)
              (  (sb_idx - this->IntegrationTableScalarShift[component])
               / (this->IntegrationTableScalarScale[component]) );
            float sf = (float)
              (  (sf_idx - this->IntegrationTableScalarShift[component])
               / (this->IntegrationTableScalarScale[component]) );
            tmpIntersectionLengths->SetTuple1(0, length);
            tmpFarIntersections->SetTuple1(0, sb);
            tmpNearIntersections->SetTuple1(0, sf);
            c[0] = c[1] = c[2] = c[3] = 0;
            this->Integrator->Integrate(tmpIntersectionLengths,
                                        tmpNearIntersections,
                                        tmpFarIntersections,
                                        c);
            c += 4;
            }
          }
        }
      }
    }

  // Get rid of temporary data.
  tmpVolume->Delete();
  tmpProperty->Delete();
  tmpScalars->Delete();

  tmpIntersectionLengths->Delete();
  tmpNearIntersections->Delete();
  tmpFarIntersections->Delete();
}

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

void vtkUnstructuredGridPreIntegration::Initialize(vtkVolume *volume,
                                                   vtkDataArray *scalars)
{
  vtkIdType i;
  vtkVolumeProperty *property = volume->GetProperty();

  if (   (property == this->Property)
      && (this->IntegrationTableBuilt > property->GetMTime())
      && (this->IntegrationTableBuilt > this->MTime) )
    {
    // Nothing changed from the last time Initialize was run.
    return;
    }

  // Delete old tables.
  for (i = 0; i < this->NumComponents; i++)
    {
    delete[] this->IntegrationTable[i];
    }
  delete[] this->IntegrationTable;
  delete[] this->IntegrationTableScalarShift;
  delete[] this->IntegrationTableScalarScale;

  this->NumComponents = scalars->GetNumberOfComponents();
  this->Property = property;
  this->Volume = volume;
  this->IntegrationTableBuilt.Modified();

  if (!property->GetIndependentComponents())
    {
    vtkErrorMacro("Cannot store dependent components in pre-integration table.");
    return;
    }

  // Determine the maximum possible length of a ray segment.
  vtkDataSet *input = volume->GetMapper()->GetDataSetInput();
  vtkIdType numcells = input->GetNumberOfCells();
  this->MaxLength = 0;
  for (i = 0; i < numcells; i++)
    {
    double cellbounds[6];
    input->GetCellBounds(i, cellbounds);
#define SQR(x)  ((x)*(x))
    double diagonal_length = sqrt(  SQR(cellbounds[1]-cellbounds[0])
                                  + SQR(cellbounds[3]-cellbounds[2])
                                  + SQR(cellbounds[5]-cellbounds[4]) );
#undef SQR
    if (diagonal_length > this->MaxLength)
      {
      this->MaxLength = diagonal_length;
      }
    }

  this->BuildPreIntegrationTables(scalars);
}

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

void vtkUnstructuredGridPreIntegration::Integrate(
                                            vtkDoubleArray *intersectionLengths,
                                            vtkDataArray *nearIntersections,
                                            vtkDataArray *farIntersections,
                                            float color[4])
{
  vtkIdType numIntersections = intersectionLengths->GetNumberOfTuples();

  for (vtkIdType i = 0; i < numIntersections; i++)
    {
    float newcolor[4];
    float *c;
    c = this->GetTableEntry(nearIntersections->GetComponent(i, 0),
                            farIntersections->GetComponent(i, 0),
                            intersectionLengths->GetComponent(i, 0), 0);
    newcolor[0] = c[0];  newcolor[1] = c[1];
    newcolor[2] = c[2];  newcolor[3] = c[3];
    for (int component = 1; component < this->NumComponents; component++)
      {
      c = this->GetTableEntry(nearIntersections->GetComponent(i, component),
                              farIntersections->GetComponent(i, component),
                              intersectionLengths->GetComponent(i, 0),
                              component);
      // The blending I'm using is a combination of porter and duff xors
      // and ins.
      float coef1=1-0.5f*c[3];
      float coef2=1-0.5f*newcolor[3];
      newcolor[0] = newcolor[0]*coef1 + c[0]*coef2;
      newcolor[1] = newcolor[1]*coef1 + c[1]*coef2;
      newcolor[2] = newcolor[2]*coef1 + c[2]*coef2;
      newcolor[3] = newcolor[3]*coef1 + c[3]*coef2;
      }

    float coef=1-color[3];
    color[0] += newcolor[0]*coef;
    color[1] += newcolor[1]*coef;
    color[2] += newcolor[2]*coef;
    color[3] += newcolor[3]*coef;
    }
}

<commit_msg>BUG: Handle the failure to allocate an integration table.  Hopefully this will fix the crashes that happen on destiny.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkUnstructuredGridPreIntegration.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

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

/*
 * Copyright 2004 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

#include "vtkUnstructuredGridPreIntegration.h"

#include "vtkObjectFactory.h"
#include "vtkVolumeProperty.h"
#include "vtkVolume.h"
#include "vtkAbstractVolumeMapper.h"
#include "vtkUnstructuredGrid.h"
#include "vtkDoubleArray.h"
#include "vtkUnstructuredGridPartialPreIntegration.h"

#include <vtkstd/algorithm>
#include <math.h>

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

vtkCxxRevisionMacro(vtkUnstructuredGridPreIntegration, "1.4");
vtkStandardNewMacro(vtkUnstructuredGridPreIntegration);

vtkCxxSetObjectMacro(vtkUnstructuredGridPreIntegration, Integrator,
                     vtkUnstructuredGridVolumeRayIntegrator);

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

vtkUnstructuredGridPreIntegration::vtkUnstructuredGridPreIntegration()
{
  this->Integrator = vtkUnstructuredGridPartialPreIntegration::New();
  this->Property = NULL;

  this->NumComponents = 0;
  this->IntegrationTable = NULL;
  this->IntegrationTableScalarShift = NULL;
  this->IntegrationTableScalarScale = NULL;

  this->IntegrationTableScalarResolution = 128;
  this->IntegrationTableLengthResolution = 256;

  this->IncrementalPreIntegration = 1;
}

vtkUnstructuredGridPreIntegration::~vtkUnstructuredGridPreIntegration()
{
  this->SetIntegrator(NULL);

  if (this->IntegrationTable)
    {
    for (int i = 0; i < this->NumComponents; i++)
      {
      delete[] this->IntegrationTable[i];
      }
    delete[] this->IntegrationTable;
    }
  if (this->IntegrationTableScalarShift)
    {
    delete[] this->IntegrationTableScalarShift;
    }
  if (this->IntegrationTableScalarScale)
    {
    delete[] this->IntegrationTableScalarScale;
    }
}

void vtkUnstructuredGridPreIntegration::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Integrator: " << this->Integrator << endl;

  os << indent << "IntegrationTableScalarResolution: "
     << this->IntegrationTableScalarResolution << endl;
  os << indent << "IntegrationTableLengthResolution: "
     << this->IntegrationTableLengthResolution << endl;

  os << indent << "IncrementalPreIntegration: "
     << this->IncrementalPreIntegration << endl;
}

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

double vtkUnstructuredGridPreIntegration::GetIntegrationTableScalarShift(int component)
{
  return this->IntegrationTableScalarShift[component];
}

double vtkUnstructuredGridPreIntegration::GetIntegrationTableScalarScale(int component)
{
  return this->IntegrationTableScalarScale[component];
}

double vtkUnstructuredGridPreIntegration::GetIntegrationTableLengthScale()
{
  return this->IntegrationTableLengthScale;
}

float *vtkUnstructuredGridPreIntegration::GetPreIntegrationTable(int component)
{
  return this->IntegrationTable[component];
}

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

void vtkUnstructuredGridPreIntegration::BuildPreIntegrationTables(vtkDataArray *scalars)
{
  // Delete old tables.
  if (this->IntegrationTable)
    {
    for (int i = 0; i < this->NumComponents; i++)
      {
      delete[] this->IntegrationTable[i];
      }
    delete[] this->IntegrationTable;
    }
  if (this->IntegrationTableScalarShift)
    {
    delete[] this->IntegrationTableScalarShift;
    }
  if (this->IntegrationTableScalarScale)
    {
    delete[] this->IntegrationTableScalarScale;
    }

  // Establish temporary inputs to integrator.
  vtkVolume         *tmpVolume = vtkVolume::New();
  vtkVolumeProperty *tmpProperty = vtkVolumeProperty::New();
  vtkDataArray      *tmpScalars
    = vtkDataArray::CreateDataArray(scalars->GetDataType());

  tmpVolume->SetMapper(this->Volume->GetMapper());
  tmpVolume->SetProperty(tmpProperty);

  tmpProperty->IndependentComponentsOn();
  tmpProperty->SetInterpolationType(this->Property->GetInterpolationType());

  tmpScalars->SetNumberOfComponents(1);
  tmpScalars->SetNumberOfTuples(2);

  vtkDoubleArray *tmpIntersectionLengths = vtkDoubleArray::New();
  vtkDataArray   *tmpNearIntersections
    = vtkDataArray::CreateDataArray(scalars->GetDataType());
  vtkDataArray   *tmpFarIntersections
    = vtkDataArray::CreateDataArray(scalars->GetDataType());

  tmpIntersectionLengths->SetNumberOfComponents(1);
  tmpIntersectionLengths->SetNumberOfTuples(1);
  tmpNearIntersections->SetNumberOfComponents(1);
  tmpNearIntersections->SetNumberOfTuples(1);
  tmpFarIntersections->SetNumberOfComponents(1);
  tmpFarIntersections->SetNumberOfTuples(1);

  this->IntegrationTable = new float*[this->NumComponents];
  this->IntegrationTableScalarShift = new double[this->NumComponents];
  this->IntegrationTableScalarScale = new double[this->NumComponents];
  // Note that the scale set up such that a length of (this->MaxLength +
  // epsilon + 0.5) will scale to this->IntegrationTableLengthResolution-1.
  // Similar scaling is performed for the other dimensions of the
  // pre-integration table.
  this->IntegrationTableLengthScale
    = (this->IntegrationTableLengthResolution-2)/this->MaxLength;

  // We only do computations at one length.
  float d_length = (float)(1/this->IntegrationTableLengthScale);

  for (int component = 0; component < this->NumComponents; component++)
    {
    int d_idx, sb_idx, sf_idx;
    float *c;

    // Allocate table.
    try
      {
      this->IntegrationTable[component]
        = new float[4*this->IntegrationTableScalarResolution
                   *this->IntegrationTableScalarResolution
                   *this->IntegrationTableLengthResolution];
      }
    catch (...)
      {
      this->IntegrationTable[component] = NULL;
      }

    if (this->IntegrationTable[component] == NULL)
      {
      // Could not allocate memory for table.
      if (   (this->IntegrationTableScalarResolution > 32)
          || (this->IntegrationTableLengthResolution > 64) )
        {
        vtkWarningMacro("Could not allocate integration table.\n"
                        "Reducing the table size and trying again.");
        for (int i = 0; i < component; i++)
          {
          delete[] this->IntegrationTable[i];
          }
        delete[] this->IntegrationTable;
        this->IntegrationTable = NULL;

        this->IntegrationTableScalarResolution = 32;
        this->IntegrationTableLengthResolution = 64;
        this->BuildPreIntegrationTables(scalars);
        }
      else
        {
        vtkErrorMacro("Could not allocate integration table.");
        }
      break;
      }

    // Determine scale and shift.
    double *range = scalars->GetRange(component);
    if (range[0] == range[1])
      {
      // Unusual case where the scalars are all the same.
      this->IntegrationTableScalarScale[component] = 1.0;
      }
    else
      {
      this->IntegrationTableScalarScale[component]
        = (this->IntegrationTableScalarResolution-2)/(range[1]-range[0]);
      }
    this->IntegrationTableScalarShift[component]
      = -range[0]*this->IntegrationTableScalarScale[component];

    // Set values for d=0 (they are all zero).
    c = this->IntegrationTable[component];
    for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution; sb_idx++)
      {
      for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
           sf_idx++)
        {
        c[0] = c[1] = c[2] = c[3] = 0.0f;
        c += 4;
        }
      }

    // Initialize integrator.
    if (this->Property->GetColorChannels(component) == 3)
      {
      tmpProperty->SetColor(this->Property->GetRGBTransferFunction(component));
      }
    else
      {
      tmpProperty->SetColor(this->Property->GetGrayTransferFunction(component));
      }
    tmpProperty->SetScalarOpacity(this->Property->GetScalarOpacity(component));
    tmpProperty->SetScalarOpacityUnitDistance
      (this->Property->GetScalarOpacityUnitDistance(component));
    tmpProperty->SetShade(this->Property->GetShade(component));
    tmpProperty->SetAmbient(this->Property->GetAmbient(component));
    tmpProperty->SetDiffuse(this->Property->GetDiffuse(component));
    tmpProperty->SetSpecular(this->Property->GetSpecular(component));
    tmpProperty->SetSpecularPower(this->Property->GetSpecularPower(component));
    tmpScalars->SetTuple1(0, range[0]);
    tmpScalars->SetTuple1(1, range[1]);
    this->Integrator->Initialize(tmpVolume, tmpScalars);

    // Set values for next smallest d (the base values).
    tmpIntersectionLengths->SetTuple1(0, d_length);
    for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution; sb_idx++)
      {
      tmpFarIntersections
        ->SetTuple1(0,
                    (  (sb_idx - this->IntegrationTableScalarShift[component])
                     / (this->IntegrationTableScalarScale[component]) ));
      for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
           sf_idx++)
        {
        tmpNearIntersections
          ->SetTuple1(0,
                      (  (sf_idx - this->IntegrationTableScalarShift[component])
                       / (this->IntegrationTableScalarScale[component]) ));
        c[0] = c[1] = c[2] = c[3] = 0;
        this->Integrator->Integrate(tmpIntersectionLengths,
                                    tmpNearIntersections, tmpFarIntersections,
                                    c);
        c += 4;
        }
      }

    // Set rest of values using other values in table.
    if (this->IncrementalPreIntegration)
      {
      for (d_idx = 2; d_idx < this->IntegrationTableLengthResolution; d_idx++)
        {
        for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution;
             sb_idx++)
          {
          for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
               sf_idx++)
            {
            // We are going to perform incremental pre-integration.  To do
            // this, we compute the integration of a ray from sf to sb of
            // length d by combining two entries in the table.  The first
            // entry will be from sf to sm of length delta d (the smallest
            // non-zero length stored in the table).  The second entry will
            // be from sm to sb of length d - delta d.  See Weiler, et
            // al. "Hardware-Based Ray Casting for Tetrahedral Meshes" for
            // more details.
            int sm_idx = ((d_idx-1)*sf_idx + sb_idx + d_idx/2)/d_idx;

            float *colorf = this->GetIndexedTableEntry(sf_idx, sm_idx, 1,
                                                       component);
            float *colorb = this->GetIndexedTableEntry(sm_idx, sb_idx, d_idx-1,
                                                       component);

            c[0] = colorf[0] + colorb[0]*(1-colorf[3]);
            c[1] = colorf[1] + colorb[1]*(1-colorf[3]);
            c[2] = colorf[2] + colorb[2]*(1-colorf[3]);
            c[3] = colorf[3] + colorb[3]*(1-colorf[3]);
            c += 4;
            }
          }
        }
      }
    else
      {
      for (d_idx = 2; d_idx < this->IntegrationTableLengthResolution; d_idx++)
        {
        for (sb_idx = 0; sb_idx < this->IntegrationTableScalarResolution;
             sb_idx++)
          {
          for (sf_idx = 0; sf_idx < this->IntegrationTableScalarResolution;
               sf_idx++)
            {
            // Compute the integration table the old-fashioned slow way.
            float length = d_idx*d_length;
            float sb = (float)
              (  (sb_idx - this->IntegrationTableScalarShift[component])
               / (this->IntegrationTableScalarScale[component]) );
            float sf = (float)
              (  (sf_idx - this->IntegrationTableScalarShift[component])
               / (this->IntegrationTableScalarScale[component]) );
            tmpIntersectionLengths->SetTuple1(0, length);
            tmpFarIntersections->SetTuple1(0, sb);
            tmpNearIntersections->SetTuple1(0, sf);
            c[0] = c[1] = c[2] = c[3] = 0;
            this->Integrator->Integrate(tmpIntersectionLengths,
                                        tmpNearIntersections,
                                        tmpFarIntersections,
                                        c);
            c += 4;
            }
          }
        }
      }
    }

  // Get rid of temporary data.
  tmpVolume->Delete();
  tmpProperty->Delete();
  tmpScalars->Delete();

  tmpIntersectionLengths->Delete();
  tmpNearIntersections->Delete();
  tmpFarIntersections->Delete();
}

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

void vtkUnstructuredGridPreIntegration::Initialize(vtkVolume *volume,
                                                   vtkDataArray *scalars)
{
  vtkIdType i;
  vtkVolumeProperty *property = volume->GetProperty();

  if (   (property == this->Property)
      && (this->IntegrationTableBuilt > property->GetMTime())
      && (this->IntegrationTableBuilt > this->MTime) )
    {
    // Nothing changed from the last time Initialize was run.
    return;
    }

  this->NumComponents = scalars->GetNumberOfComponents();
  this->Property = property;
  this->Volume = volume;
  this->IntegrationTableBuilt.Modified();

  if (!property->GetIndependentComponents())
    {
    vtkErrorMacro("Cannot store dependent components in pre-integration table.");
    return;
    }

  // Determine the maximum possible length of a ray segment.
  vtkDataSet *input = volume->GetMapper()->GetDataSetInput();
  vtkIdType numcells = input->GetNumberOfCells();
  this->MaxLength = 0;
  for (i = 0; i < numcells; i++)
    {
    double cellbounds[6];
    input->GetCellBounds(i, cellbounds);
#define SQR(x)  ((x)*(x))
    double diagonal_length = sqrt(  SQR(cellbounds[1]-cellbounds[0])
                                  + SQR(cellbounds[3]-cellbounds[2])
                                  + SQR(cellbounds[5]-cellbounds[4]) );
#undef SQR
    if (diagonal_length > this->MaxLength)
      {
      this->MaxLength = diagonal_length;
      }
    }

  this->BuildPreIntegrationTables(scalars);
}

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

void vtkUnstructuredGridPreIntegration::Integrate(
                                            vtkDoubleArray *intersectionLengths,
                                            vtkDataArray *nearIntersections,
                                            vtkDataArray *farIntersections,
                                            float color[4])
{
  vtkIdType numIntersections = intersectionLengths->GetNumberOfTuples();

  for (vtkIdType i = 0; i < numIntersections; i++)
    {
    float newcolor[4];
    float *c;
    c = this->GetTableEntry(nearIntersections->GetComponent(i, 0),
                            farIntersections->GetComponent(i, 0),
                            intersectionLengths->GetComponent(i, 0), 0);
    newcolor[0] = c[0];  newcolor[1] = c[1];
    newcolor[2] = c[2];  newcolor[3] = c[3];
    for (int component = 1; component < this->NumComponents; component++)
      {
      c = this->GetTableEntry(nearIntersections->GetComponent(i, component),
                              farIntersections->GetComponent(i, component),
                              intersectionLengths->GetComponent(i, 0),
                              component);
      // The blending I'm using is a combination of porter and duff xors
      // and ins.
      float coef1=1-0.5f*c[3];
      float coef2=1-0.5f*newcolor[3];
      newcolor[0] = newcolor[0]*coef1 + c[0]*coef2;
      newcolor[1] = newcolor[1]*coef1 + c[1]*coef2;
      newcolor[2] = newcolor[2]*coef1 + c[2]*coef2;
      newcolor[3] = newcolor[3]*coef1 + c[3]*coef2;
      }

    float coef=1-color[3];
    color[0] += newcolor[0]*coef;
    color[1] += newcolor[1]*coef;
    color[2] += newcolor[2]*coef;
    color[3] += newcolor[3]*coef;
    }
}

<|endoftext|>


<commit_before>/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
**
** This is a wrapper for pilot-link's general
** Pilot database structures. These records are
*** just collections of bits. See PilotAppCategory
** for interpreting the bits in a meaningful way.
**
** As a crufty hack, the non-inline parts of
** PilotAppCategory live in this file as well.
*/

/*
** This program 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 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "options.h"

#include <string.h>

#include <qtextcodec.h>
#include <qregexp.h>

#include <kglobal.h>
#include <kcharsets.h>

// PilotAppCategory includes pilotRecord and we
// provide its implementation here as well.
//
#include "pilotAppCategory.h"

static const char *pilotRecord_id =
	"$Id$";

/* static */ int PilotRecord::fAllocated = 0;
/* static */ int PilotRecord::fDeleted = 0;

/* static */ void PilotRecord::allocationInfo()
{
#ifdef DEBUG
	FUNCTIONSETUP;
	DEBUGKPILOT << fname
		<< ": Allocated " << fAllocated
		<< "  Deleted " << fDeleted;
#endif
}

PilotRecord::PilotRecord(void *data, int len, int attrib, int cat,
	pi_uid_t uid) :
	fData(0L),
	fLen(len),
	fAttrib(attrib),
	fCat(cat),
	fID(uid),
	fBuffer(0L)
{
	FUNCTIONSETUP;
	fData = new char[len];

	memcpy(fData, data, len);

	fAllocated++;
	(void) pilotRecord_id;
}

PilotRecord::PilotRecord(PilotRecord * orig) :
	fBuffer(0L)
{
	FUNCTIONSETUP;
	fData = new char[orig->getLen()];

	memcpy(fData, orig->getData(), orig->getLen());
	fLen = orig->getLen();
	fAttrib = orig->getAttrib();
	fCat = orig->category();
	fID = orig->id();

	fAllocated++;
}

PilotRecord & PilotRecord::operator = (PilotRecord & orig)
{
	FUNCTIONSETUP;
	if (fBuffer)
	{
#if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
		kdWarning() << kde_funcinfo << ": Uninitialized pi_buffer" << endl;
#else
		pi_buffer_free(fBuffer);
		fBuffer=0L;
		fData=0L;
#endif
	}

	if (fData)
		delete[]fData;
	fData = new char[orig.getLen()];

	memcpy(fData, orig.getData(), orig.getLen());
	fLen = orig.getLen();
	fAttrib = orig.getAttrib();
	fCat = orig.category();
	fID = orig.id();
	return *this;
}

recordid_t PilotRecord::getID() const
{
	return id();
}

void PilotRecord::makeDeleted()
{
	setDeleted(true);
}

void PilotRecord::makeSecret()
{
	setSecret(true);
}

int PilotRecord::getCat() const
{
	return category();
}

void PilotRecord::setCat(int i)
{
	return setCategory(i);
}

void PilotRecord::setData(const char *data, int len)
{
	FUNCTIONSETUP;
	if (fData)
		delete[]fData;
	fData = new char[len];

	memcpy(fData, data, len);
	fLen = len;
}

/* static */ QTextCodec *PilotAppCategory::pilotCodec = 0L;

/* static */ QTextCodec *PilotAppCategory::setupPilotCodec(const QString &s)
{
	FUNCTIONSETUP;
	QString encoding(KGlobal::charsets()->encodingForName(s));

#ifdef DEBUG
	DEBUGKPILOT << fname << ": Creating codec " << encoding << endl;
#endif

	// if the desired codec can't be found, latin1 will be returned anyway, no need to do this manually
	pilotCodec = KGlobal::charsets()->codecForName(encoding);

#ifdef DEBUG
	DEBUGKPILOT << fname
		<< ": Got codec " << codecName() << " for setting "
		<< s << endl;
#endif
	return codec();
}

/* static */ QString PilotAppCategory::codecName()
{
	return codec()->name();
}
<commit_msg>Work for pre-0.12 too<commit_after>/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
**
** This is a wrapper for pilot-link's general
** Pilot database structures. These records are
*** just collections of bits. See PilotAppCategory
** for interpreting the bits in a meaningful way.
**
** As a crufty hack, the non-inline parts of
** PilotAppCategory live in this file as well.
*/

/*
** This program 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 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "options.h"

#include <string.h>

#include <qtextcodec.h>
#include <qregexp.h>

#include <kglobal.h>
#include <kcharsets.h>

// PilotAppCategory includes pilotRecord and we
// provide its implementation here as well.
//
#include "pilotAppCategory.h"

static const char *pilotRecord_id =
	"$Id$";

/* static */ int PilotRecord::fAllocated = 0;
/* static */ int PilotRecord::fDeleted = 0;

/* static */ void PilotRecord::allocationInfo()
{
#ifdef DEBUG
	FUNCTIONSETUP;
	DEBUGKPILOT << fname
		<< ": Allocated " << fAllocated
		<< "  Deleted " << fDeleted;
#endif
}

PilotRecord::PilotRecord(void *data, int len, int attrib, int cat,
	pi_uid_t uid) :
	fData(0L),
	fLen(len),
	fAttrib(attrib),
	fCat(cat),
	fID(uid)
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	,
	fBuffer(0L)
#endif
{
	FUNCTIONSETUP;
	fData = new char[len];

	memcpy(fData, data, len);

	fAllocated++;
	(void) pilotRecord_id;
}

PilotRecord::PilotRecord(PilotRecord * orig) :
	fID(orig->id())
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	,
	fBuffer(0L)
#endif
{
	FUNCTIONSETUP;
	fData = new char[orig->getLen()];

	memcpy(fData, orig->getData(), orig->getLen());
	fLen = orig->getLen();
	fAttrib = orig->getAttrib();
	fCat = orig->category();
	fID = orig->id();

	fAllocated++;
}

PilotRecord & PilotRecord::operator = (PilotRecord & orig)
{
	FUNCTIONSETUP;
#if PILOT_LINK_NUMBER >= PILOT_LINK_0_12_0
	if (fBuffer)
	{
		pi_buffer_free(fBuffer);
		fBuffer=0L;
		fData=0L;
	}
#endif

	if (fData)
		delete[]fData;
	fData = new char[orig.getLen()];

	memcpy(fData, orig.getData(), orig.getLen());
	fLen = orig.getLen();
	fAttrib = orig.getAttrib();
	fCat = orig.category();
	fID = orig.id();
	return *this;
}

recordid_t PilotRecord::getID() const
{
	return id();
}

void PilotRecord::makeDeleted()
{
	setDeleted(true);
}

void PilotRecord::makeSecret()
{
	setSecret(true);
}

int PilotRecord::getCat() const
{
	return category();
}

void PilotRecord::setCat(int i)
{
	return setCategory(i);
}

void PilotRecord::setData(const char *data, int len)
{
	FUNCTIONSETUP;
	if (fData)
		delete[]fData;
	fData = new char[len];

	memcpy(fData, data, len);
	fLen = len;
}

/* static */ QTextCodec *PilotAppCategory::pilotCodec = 0L;

/* static */ QTextCodec *PilotAppCategory::setupPilotCodec(const QString &s)
{
	FUNCTIONSETUP;
	QString encoding(KGlobal::charsets()->encodingForName(s));

#ifdef DEBUG
	DEBUGKPILOT << fname << ": Creating codec " << encoding << endl;
#endif

	// if the desired codec can't be found, latin1 will be returned anyway, no need to do this manually
	pilotCodec = KGlobal::charsets()->codecForName(encoding);

#ifdef DEBUG
	DEBUGKPILOT << fname
		<< ": Got codec " << codecName() << " for setting "
		<< s << endl;
#endif
	return codec();
}

/* static */ QString PilotAppCategory::codecName()
{
	return codec()->name();
}
<|endoftext|>