<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TestSmplMail.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2007-01-02 16:13:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"

//-----------------------------------------------------------
//  interface includes
//-----------------------------------------------------------

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#ifndef _COM_SUN_STAR_REGISTRY_XSIMPLEREGISTRY_HPP_
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#endif

#ifndef _COM_SUN_STAR_SYSTEM_XSIMPLEMAILCLIENTSUPPLIER_HPP_
#include <com/sun/star/system/XSimpleMailClientSupplier.hpp>
#endif

#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
#include <cppuhelper/servicefactory.hxx>
#endif

#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
#include <cppuhelper/servicefactory.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#include <stdio.h>
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif

#include <osl/file.hxx>

//--------------------------------------------------------------
//  namesapces
//--------------------------------------------------------------

using namespace ::rtl                   ;
using namespace ::cppu                  ;
using namespace ::com::sun::star::uno   ;
using namespace ::com::sun::star::lang  ;
using namespace std                     ;
using namespace com::sun::star::system;

//--------------------------------------------------------------
//  defines
//--------------------------------------------------------------

#define RDB_SYSPATH "D:\\Projects\\gsl\\shell\\wntmsci7\\bin\\applicat.rdb"

//--------------------------------------------------------------
//  global variables
//--------------------------------------------------------------

Reference< XMultiServiceFactory >   g_xFactory;

//--------------------------------------------------------------
//  main
//--------------------------------------------------------------

// int SAL_CALL main(int nArgc, char* Argv[], char* pEnv[]  )
// make Warning free, leave out typename
int SAL_CALL main(int , char*, char* )
{
    //-------------------------------------------------
    // get the global service-manager
    //-------------------------------------------------

    // Get global factory for uno services.
    OUString rdbName = OUString( RTL_CONSTASCII_USTRINGPARAM( RDB_SYSPATH ) );
    Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( rdbName ) );

    // Print a message if an error occured.
    if ( g_xFactory.is() == sal_False )
    {
        OSL_ENSURE(sal_False, "Can't create RegistryServiceFactory");
        return(-1);
    }

    printf("Creating RegistryServiceFactory successful\n");

    //-------------------------------------------------
    // try to get an Interface to a XFilePicker Service
    //-------------------------------------------------

    try
    {
        Reference< XSimpleMailClientSupplier > xSmplMailClientSuppl(
            g_xFactory->createInstance( OUString::createFromAscii( "com.sun.star.system.SimpleSystemMail" ) ), UNO_QUERY );

        if ( !xSmplMailClientSuppl.is() )
        {
            OSL_ENSURE( sal_False, "Error creating SimpleSystemMail Service" );
            return(-1);
        }

        Reference< XSimpleMailClient > xSmplMailClient(
            xSmplMailClientSuppl->querySimpleMailClient( ) );

        if ( xSmplMailClient.is( ) )
        {
            Reference< XSimpleMailMessage > xSmplMailMsg(
                xSmplMailClient->createSimpleMailMessage( ) );

            if ( xSmplMailMsg.is( ) )
            {
                xSmplMailMsg->setRecipient( OUString::createFromAscii("tino.rachui@germany.sun.com") );
                xSmplMailMsg->setOriginator( OUString::createFromAscii( "tino.rachui@germany.sun.com" ) );

                Sequence< OUString > ccRecips( 1 );
                ccRecips[0] = OUString::createFromAscii( "tino.rachui@germany.sun.com" );

                xSmplMailMsg->setCcRecipient( ccRecips );

                Sequence< OUString > bccRecips( 1 );
                bccRecips[0] = OUString::createFromAscii( "tino.rachui@germany.sun.com" );

                xSmplMailMsg->setBccRecipient( bccRecips );

                xSmplMailMsg->setSubject( OUString::createFromAscii( "Mapi Test" ) );

                Sequence< OUString > attachements( 2 );

                OUString aFile = OUString::createFromAscii( "D:\\Projects\\gsl\\shell\\wntmsci7\\bin\\testprx.exe" );
                OUString aFileURL;

                osl::FileBase::getFileURLFromSystemPath( aFile, aFileURL );
                attachements[0] = aFileURL;

                aFile = OUString::createFromAscii( "D:\\Projects\\gsl\\shell\\wntmsci7\\bin\\testsyssh.exe" );
                osl::FileBase::getFileURLFromSystemPath( aFile, aFileURL );

                attachements[1] = aFile;

                xSmplMailMsg->setAttachement( attachements );

                xSmplMailClient->sendSimpleMailMessage( xSmplMailMsg, 0 );
            }
        }
    }
    catch( Exception& )
    {
    }

    //--------------------------------------------------
    // shutdown
    //--------------------------------------------------

    // Cast factory to XComponent
    Reference< XComponent > xComponent( g_xFactory, UNO_QUERY );

    // Print a message if an error occured.
    if ( xComponent.is() == sal_False )
    {
        OSL_ENSURE(sal_False, "Error shuting down");
    }

    // Dispose and clear factory
    xComponent->dispose();
    g_xFactory.clear();
    g_xFactory = Reference< XMultiServiceFactory >();

    printf("Test successful\n");

    return 0;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.6.100); FILE MERGED 2008/04/01 15:40:30 thb 1.6.100.3: #i85898# Stripping all external header guards 2008/04/01 12:41:18 thb 1.6.100.2: #i85898# Stripping all external header guards 2008/03/31 13:17:15 rt 1.6.100.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: TestSmplMail.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"

//-----------------------------------------------------------
//  interface includes
//-----------------------------------------------------------
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/system/XSimpleMailClientSupplier.hpp>
#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <osl/diagnose.h>

#include <stdio.h>
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif

#include <osl/file.hxx>

//--------------------------------------------------------------
//  namesapces
//--------------------------------------------------------------

using namespace ::rtl                   ;
using namespace ::cppu                  ;
using namespace ::com::sun::star::uno   ;
using namespace ::com::sun::star::lang  ;
using namespace std                     ;
using namespace com::sun::star::system;

//--------------------------------------------------------------
//  defines
//--------------------------------------------------------------

#define RDB_SYSPATH "D:\\Projects\\gsl\\shell\\wntmsci7\\bin\\applicat.rdb"

//--------------------------------------------------------------
//  global variables
//--------------------------------------------------------------

Reference< XMultiServiceFactory >   g_xFactory;

//--------------------------------------------------------------
//  main
//--------------------------------------------------------------

// int SAL_CALL main(int nArgc, char* Argv[], char* pEnv[]  )
// make Warning free, leave out typename
int SAL_CALL main(int , char*, char* )
{
    //-------------------------------------------------
    // get the global service-manager
    //-------------------------------------------------

    // Get global factory for uno services.
    OUString rdbName = OUString( RTL_CONSTASCII_USTRINGPARAM( RDB_SYSPATH ) );
    Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( rdbName ) );

    // Print a message if an error occured.
    if ( g_xFactory.is() == sal_False )
    {
        OSL_ENSURE(sal_False, "Can't create RegistryServiceFactory");
        return(-1);
    }

    printf("Creating RegistryServiceFactory successful\n");

    //-------------------------------------------------
    // try to get an Interface to a XFilePicker Service
    //-------------------------------------------------

    try
    {
        Reference< XSimpleMailClientSupplier > xSmplMailClientSuppl(
            g_xFactory->createInstance( OUString::createFromAscii( "com.sun.star.system.SimpleSystemMail" ) ), UNO_QUERY );

        if ( !xSmplMailClientSuppl.is() )
        {
            OSL_ENSURE( sal_False, "Error creating SimpleSystemMail Service" );
            return(-1);
        }

        Reference< XSimpleMailClient > xSmplMailClient(
            xSmplMailClientSuppl->querySimpleMailClient( ) );

        if ( xSmplMailClient.is( ) )
        {
            Reference< XSimpleMailMessage > xSmplMailMsg(
                xSmplMailClient->createSimpleMailMessage( ) );

            if ( xSmplMailMsg.is( ) )
            {
                xSmplMailMsg->setRecipient( OUString::createFromAscii("tino.rachui@germany.sun.com") );
                xSmplMailMsg->setOriginator( OUString::createFromAscii( "tino.rachui@germany.sun.com" ) );

                Sequence< OUString > ccRecips( 1 );
                ccRecips[0] = OUString::createFromAscii( "tino.rachui@germany.sun.com" );

                xSmplMailMsg->setCcRecipient( ccRecips );

                Sequence< OUString > bccRecips( 1 );
                bccRecips[0] = OUString::createFromAscii( "tino.rachui@germany.sun.com" );

                xSmplMailMsg->setBccRecipient( bccRecips );

                xSmplMailMsg->setSubject( OUString::createFromAscii( "Mapi Test" ) );

                Sequence< OUString > attachements( 2 );

                OUString aFile = OUString::createFromAscii( "D:\\Projects\\gsl\\shell\\wntmsci7\\bin\\testprx.exe" );
                OUString aFileURL;

                osl::FileBase::getFileURLFromSystemPath( aFile, aFileURL );
                attachements[0] = aFileURL;

                aFile = OUString::createFromAscii( "D:\\Projects\\gsl\\shell\\wntmsci7\\bin\\testsyssh.exe" );
                osl::FileBase::getFileURLFromSystemPath( aFile, aFileURL );

                attachements[1] = aFile;

                xSmplMailMsg->setAttachement( attachements );

                xSmplMailClient->sendSimpleMailMessage( xSmplMailMsg, 0 );
            }
        }
    }
    catch( Exception& )
    {
    }

    //--------------------------------------------------
    // shutdown
    //--------------------------------------------------

    // Cast factory to XComponent
    Reference< XComponent > xComponent( g_xFactory, UNO_QUERY );

    // Print a message if an error occured.
    if ( xComponent.is() == sal_False )
    {
        OSL_ENSURE(sal_False, "Error shuting down");
    }

    // Dispose and clear factory
    xComponent->dispose();
    g_xFactory.clear();
    g_xFactory = Reference< XMultiServiceFactory >();

    printf("Test successful\n");

    return 0;
}
<|endoftext|>


<commit_before>/*  -*- mode: C++; c-file-style: "gnu" -*-

    This file is part of kdepim.
    Copyright (c) 2004 KDEPIM developers

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "email.h"
#include <kdebug.h>
#include <klocale.h>
#include <qregexp.h>

//-----------------------------------------------------------------------------
QStringList KPIM::splitEmailAddrList(const QString& aStr)
{
  // Features:
  // - always ignores quoted characters
  // - ignores everything (including parentheses and commas)
  //   inside quoted strings
  // - supports nested comments
  // - ignores everything (including double quotes and commas)
  //   inside comments

  QStringList list;

  if (aStr.isEmpty())
    return list;

  QString addr;
  uint addrstart = 0;
  int commentlevel = 0;
  bool insidequote = false;

  for (uint index=0; index<aStr.length(); index++) {
    // the following conversion to latin1 is o.k. because
    // we can safely ignore all non-latin1 characters
    switch (aStr[index].latin1()) {
    case '"' : // start or end of quoted string
      if (commentlevel == 0)
        insidequote = !insidequote;
      break;
    case '(' : // start of comment
      if (!insidequote)
        commentlevel++;
      break;
    case ')' : // end of comment
      if (!insidequote) {
        if (commentlevel > 0)
          commentlevel--;
        else {
          kdDebug(5300) << "Error in address splitting: Unmatched ')'"
                        << endl;
          return list;
        }
      }
      break;
    case '\\' : // quoted character
      index++; // ignore the quoted character
      break;
    case ',' :
      if (!insidequote && (commentlevel == 0)) {
        addr = aStr.mid(addrstart, index-addrstart);
        if (!addr.isEmpty())
          list += addr.simplifyWhiteSpace();
        addrstart = index+1;
      }
      break;
    }
  }
  // append the last address to the list
  if (!insidequote && (commentlevel == 0)) {
    addr = aStr.mid(addrstart, aStr.length()-addrstart);
    if (!addr.isEmpty())
      list += addr.simplifyWhiteSpace();
  }
  else
    kdDebug(5300) << "Error in address splitting: "
                  << "Unexpected end of address list"
                  << endl;

  return list;
}

//-----------------------------------------------------------------------------
KPIM::EmailParseResult KPIM::isValidEmailAddress( const QString& aStr )
{
  // If we are passed an empty string bail right away no need to process further
  // and waste resources
  if ( aStr.isEmpty() ) {
    return AddressEmpty;
  }

  // count how many @'s are in the string that is passed to us
  // if 0 or > 1 take action
  // at this point to many @'s cannot bail out right away since
  // @ is allowed in qoutes, so we use a bool to keep track
  // and then make a judgement further down in the parser
  // FIXME count only @ not in double quotes

  bool tooManyAtsFlag = false;

  int atCount = aStr.contains('@');
  if ( atCount > 1 ) {
    tooManyAtsFlag = true;;
  } else if ( atCount == 0 ) {
	  return TooFewAts;
  }

  // The main parser, try and catch all weird and wonderful
  // mistakes users and/or machines can create

  enum { TopLevel, InComment, InAngleAddress } context = TopLevel;
  bool inQuotedString = false;
  int commentLevel = 0;

  unsigned int strlen = aStr.length();

  for ( unsigned int index=0; index < strlen; index++ ) {
    switch ( context ) {
    case TopLevel : {
      switch ( aStr[index].latin1() ) {
        case '"' : inQuotedString = !inQuotedString;
          break;
        case '(' :
          if ( !inQuotedString ) {
            context = InComment;
            commentLevel = 1;
          }
          break;
        case '<' :
          if ( !inQuotedString ) {
            context = InAngleAddress;
          }
          break;
        case '\\' : // quoted character
          ++index; // skip the '\'
          if ( ++index > strlen )
            return UnexpectedEnd;
          break;
        case ',' :
          if ( !inQuotedString )
            return UnexpectedComma;
          break;
        case ')' :
          if ( !inQuotedString )
            return UnbalancedParens;
          break;
        case '>' :
          if ( !inQuotedString )
            return UnopenedAngleAddr;
          break;
        case '@' :
          if ( !inQuotedString ) {
            if ( index == 0 ) {  // Missing local part
              return MissingLocalPart;
            } else if( index == strlen-1 ) {
              return MissingDomainPart;
              break;
              }
            } else if ( inQuotedString ) {
              --atCount;
              if ( atCount == 1 ) {
                tooManyAtsFlag = false;
              }
            }
            break;
      }
      break;
    }
    case InComment : {
      switch ( aStr[index] ) {
        case '(' : ++commentLevel;
          break;
        case ')' : --commentLevel;
          if ( commentLevel == 0 ) {
            context = TopLevel;
          }
          break;
        case '\\' : // quoted character
          ++index; // skip the '\'
          if ( ++index > strlen )
            return UnexpectedEnd;
            break;
        }
        break;
    }

    case InAngleAddress : {
      switch ( aStr[index] ) {
        case '"' : inQuotedString = !inQuotedString;
            break;
        case '@' :
          if ( inQuotedString ) {
            --atCount;
            if ( atCount == 1 ) {
              tooManyAtsFlag = false;
            }
          }
          break;
        case '>' :
          if ( !inQuotedString ) {
            context = TopLevel;
            break;
          }
          break;
        case '\\' : // quoted character
          ++index; // skip the '\'
          if ( ++index > strlen )
            return UnexpectedEnd;
          break;
          }
        break;
      }
    }
  }
  if ( context == InComment )
    return UnbalancedParens;

  if ( context == TopLevel && !tooManyAtsFlag ) {
    return AddressOk;
  }

  if ( context == InAngleAddress )
    return UnclosedAngleAddr;

  if ( tooManyAtsFlag ) {
    return TooManyAts;
  }
}

//-----------------------------------------------------------------------------
QString KPIM::emailParseResultToString( EmailParseResult errorCode )
{
  switch ( errorCode ) {
    case TooManyAts :
      return i18n("The email address you entered is not valid because it "
                "contains more than one @ "
                "you will not create valid messages if you do not "
                "change your address.");
    case TooFewAts :
      return i18n("The email address you entered is not valid because it "
                "does not contain a @ "
                "you will not create valid messages if you do not "
                "change your address.");
    case AddressEmpty :
      return i18n("You have to enter something in the email address field.");
    case MissingLocalPart :
      return i18n("The email address you entered is not valid because it "
                "does not contain a local part.");
    case MissingDomainPart :
      return i18n("The email address you entered is not valid because it "
                "does not contain a domain part.");
    case UnbalancedParens :
      return i18n("The email address you entered is not valid because it "
                "contains unclosed comments/brackets.");
    case AddressOk :
      return i18n("The email address you entered is valid.");
    case UnclosedAngleAddr :
      return i18n("The email address you entered is not valid because it "
                "contains an unclosed anglebracket.");
    case UnopenedAngleAddr :
      return i18n("The email address you entered is not valid because it "
                "contains an unopened anglebracket.");
    case UnexpectedComma :
      return i18n("The email address you have entered is not valid because it "
                "contains an unexpected comma.");
    case UnexpectedEnd :
      return i18n("The email address you entered is not valid because it ended "
                "unexpectadly, this probably means you have used an escaping type "
                "character like an \\  as the last character in your email "
                "address.");
  }
  return i18n("Unknown problem with email address");
}

//-----------------------------------------------------------------------------
bool KPIM::isValidSimpleEmailAddress( const QString& aStr )
{
  // If we are passed an empty string bail right away no need to process further
  // and waste resources
  if ( aStr.isEmpty() ) {
    return false;
  }

  int atChar = aStr.findRev( '@' );
  QString domainPart = aStr.mid( atChar + 1);
  QString localPart = aStr.left( atChar );
  bool tooManyAtsFlag = false;
  bool inQuotedString = false;
  int atCount = localPart.contains( '@' );

  unsigned int strlen = localPart.length();
  for ( unsigned int index=0; index < strlen; index++ ) {
    switch( localPart[ index ].latin1() ) {
      case '"' : inQuotedString = !inQuotedString;
        break;
      case '@' :
        if ( inQuotedString ) {
          --atCount;
          if ( atCount == 0 ) {
            tooManyAtsFlag = false;
          }
        }
        break;
      }
  }

  QString addrRx = "[a-zA-Z]*[\\w.-]*[a-zA-Z0-9]@";
  if ( localPart[ 0 ] == '\"' || localPart[ localPart.length()-1 ] == '\"' ) {
    addrRx = "\"[a-zA-Z@]*[\\w.@-]*[a-zA-Z0-9@]\"@";
  }
  if ( domainPart[ 0 ] == '[' || domainPart[ domainPart.length()-1 ] == ']' ) {
    addrRx += "\\[[0-9]{,3}(\\.[0-9]{,3}){3}\\]";
  } else {
    addrRx += "[\\w-]+(\\.[\\w-]+)";
  }
  QRegExp rx( addrRx );
  return  rx.exactMatch( aStr ) && !tooManyAtsFlag;
}

//-----------------------------------------------------------------------------
QCString KPIM::getEmailAddr(const QString& aStr)
{
  int a, i, j, len, found = 0;
  QChar c;
  // Find the '@' in the email address:
  a = aStr.find('@');
  if (a<0) return aStr.latin1();
  // Loop backwards until we find '<', '(', ' ', or beginning of string.
  for (i = a - 1; i >= 0; i--) {
    c = aStr[i];
    if (c == '<' || c == '(' || c == ' ') found = 1;
    if (found) break;
  }
  // Reset found for next loop.
  found = 0;
  // Loop forwards until we find '>', ')', ' ', or end of string.
  for (j = a + 1; j < (int)aStr.length(); j++) {
    c = aStr[j];
    if (c == '>' || c == ')' || c == ' ') found = 1;
    if (found) break;
  }
  // Calculate the length and return the result.
  len = j - (i + 1);
  return aStr.mid(i+1,len).latin1();
}

bool KPIM::getNameAndMail(const QString& aStr, QString& name, QString& mail)
{
  name = QString::null;
  mail = QString::null;

  const int len=aStr.length();
  const char cQuotes = '"';

  bool bInComment, bInQuotesOutsideOfEmail;
  int i=0, iAd=0, iMailStart=0, iMailEnd=0;
  QChar c;

  // Find the '@' of the email address
  // skipping all '@' inside "(...)" comments:
  bInComment = false;
  while( i < len ){
    c = aStr[i];
    if( !bInComment ){
      if( '(' == c ){
        bInComment = true;
      }else{
        if( '@' == c ){
          iAd = i;
          break; // found it
        }
      }
    }else{
      if( ')' == c ){
        bInComment = false;
      }
    }
    ++i;
  }

  if( !iAd ){
    // We suppose the user is typing the string manually and just
    // has not finished typing the mail address part.
    // So we take everything that's left of the '<' as name and the rest as mail
    for( i = 0; len > i; ++i ) {
      c = aStr[i];
      if( '<' != c )
        name.append( c );
      else
        break;
    }
    mail = aStr.mid( i+1 );
    if ( mail.endsWith( ">" ) )
      mail.truncate( mail.length() - 1 );

  }else{

    // Loop backwards until we find the start of the string
    // or a ',' that is outside of a comment
    //          and outside of quoted text before the leading '<'.
    bInComment = false;
    bInQuotesOutsideOfEmail = false;
    for( i = iAd-1; 0 <= i; --i ) {
      c = aStr[i];
      if( bInComment ){
        if( '(' == c ){
          if( !name.isEmpty() )
            name.prepend( ' ' );
          bInComment = false;
        }else{
          name.prepend( c ); // all comment stuff is part of the name
        }
      }else if( bInQuotesOutsideOfEmail ){
        if( cQuotes == c )
          bInQuotesOutsideOfEmail = false;
        else
          name.prepend( c );
      }else{
        // found the start of this addressee ?
        if( ',' == c )
          break;
        // stuff is before the leading '<' ?
        if( iMailStart ){
          if( cQuotes == c )
            bInQuotesOutsideOfEmail = true; // end of quoted text found
          else
            name.prepend( c );
        }else{
          switch( c ){
            case '<':
              iMailStart = i;
              break;
            case ')':
              if( !name.isEmpty() )
                name.prepend( ' ' );
              bInComment = true;
              break;
            default:
              if( ' ' != c )
                mail.prepend( c );
          }
        }
      }
    }

    name = name.simplifyWhiteSpace();
    mail = mail.simplifyWhiteSpace();

    if( mail.isEmpty() )
      return false;

    mail.append('@');

    // Loop forward until we find the end of the string
    // or a ',' that is outside of a comment
    //          and outside of quoted text behind the trailing '>'.
    bInComment = false;
    bInQuotesOutsideOfEmail = false;
    for( i = iAd+1; len > i; ++i ) {
      c = aStr[i];
      if( bInComment ){
        if( ')' == c ){
          if( !name.isEmpty() )
            name.append( ' ' );
          bInComment = false;
        }else{
          name.append( c ); // all comment stuff is part of the name
        }
      }else if( bInQuotesOutsideOfEmail ){
        if( cQuotes == c )
          bInQuotesOutsideOfEmail = false;
        else
          name.append( c );
      }else{
        // found the end of this addressee ?
        if( ',' == c )
          break;
        // stuff is behind the trailing '>' ?
        if( iMailEnd ){
          if( cQuotes == c )
            bInQuotesOutsideOfEmail = true; // start of quoted text found
          else
            name.append( c );
        }else{
          switch( c ){
            case '>':
              iMailEnd = i;
              break;
            case '(':
              if( !name.isEmpty() )
                name.append( ' ' );
              bInComment = true;
              break;
            default:
              if( ' ' != c )
                mail.append( c );
          }
        }
      }
    }
  }

  name = name.simplifyWhiteSpace();
  mail = mail.simplifyWhiteSpace();

  return ! (name.isEmpty() || mail.isEmpty());
}

bool KPIM::compareEmail( const QString& email1, const QString& email2,
                         bool matchName )
{
  QString e1Name, e1Email, e2Name, e2Email;

  getNameAndMail( email1, e1Name, e1Email );
  getNameAndMail( email2, e2Name, e2Email );

  return e1Email == e2Email &&
    ( !matchName || ( e1Name == e2Name ) );
}
<commit_msg>Fix compiler warning<commit_after>/*  -*- mode: C++; c-file-style: "gnu" -*-

    This file is part of kdepim.
    Copyright (c) 2004 KDEPIM developers

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "email.h"
#include <kdebug.h>
#include <klocale.h>
#include <qregexp.h>

//-----------------------------------------------------------------------------
QStringList KPIM::splitEmailAddrList(const QString& aStr)
{
  // Features:
  // - always ignores quoted characters
  // - ignores everything (including parentheses and commas)
  //   inside quoted strings
  // - supports nested comments
  // - ignores everything (including double quotes and commas)
  //   inside comments

  QStringList list;

  if (aStr.isEmpty())
    return list;

  QString addr;
  uint addrstart = 0;
  int commentlevel = 0;
  bool insidequote = false;

  for (uint index=0; index<aStr.length(); index++) {
    // the following conversion to latin1 is o.k. because
    // we can safely ignore all non-latin1 characters
    switch (aStr[index].latin1()) {
    case '"' : // start or end of quoted string
      if (commentlevel == 0)
        insidequote = !insidequote;
      break;
    case '(' : // start of comment
      if (!insidequote)
        commentlevel++;
      break;
    case ')' : // end of comment
      if (!insidequote) {
        if (commentlevel > 0)
          commentlevel--;
        else {
          kdDebug(5300) << "Error in address splitting: Unmatched ')'"
                        << endl;
          return list;
        }
      }
      break;
    case '\\' : // quoted character
      index++; // ignore the quoted character
      break;
    case ',' :
      if (!insidequote && (commentlevel == 0)) {
        addr = aStr.mid(addrstart, index-addrstart);
        if (!addr.isEmpty())
          list += addr.simplifyWhiteSpace();
        addrstart = index+1;
      }
      break;
    }
  }
  // append the last address to the list
  if (!insidequote && (commentlevel == 0)) {
    addr = aStr.mid(addrstart, aStr.length()-addrstart);
    if (!addr.isEmpty())
      list += addr.simplifyWhiteSpace();
  }
  else
    kdDebug(5300) << "Error in address splitting: "
                  << "Unexpected end of address list"
                  << endl;

  return list;
}

//-----------------------------------------------------------------------------
KPIM::EmailParseResult KPIM::isValidEmailAddress( const QString& aStr )
{
  // If we are passed an empty string bail right away no need to process further
  // and waste resources
  if ( aStr.isEmpty() ) {
    return AddressEmpty;
  }

  // count how many @'s are in the string that is passed to us
  // if 0 or > 1 take action
  // at this point to many @'s cannot bail out right away since
  // @ is allowed in qoutes, so we use a bool to keep track
  // and then make a judgement further down in the parser
  // FIXME count only @ not in double quotes

  bool tooManyAtsFlag = false;

  int atCount = aStr.contains('@');
  if ( atCount > 1 ) {
    tooManyAtsFlag = true;;
  } else if ( atCount == 0 ) {
	  return TooFewAts;
  }

  // The main parser, try and catch all weird and wonderful
  // mistakes users and/or machines can create

  enum { TopLevel, InComment, InAngleAddress } context = TopLevel;
  bool inQuotedString = false;
  int commentLevel = 0;

  unsigned int strlen = aStr.length();

  for ( unsigned int index=0; index < strlen; index++ ) {
    switch ( context ) {
    case TopLevel : {
      switch ( aStr[index].latin1() ) {
        case '"' : inQuotedString = !inQuotedString;
          break;
        case '(' :
          if ( !inQuotedString ) {
            context = InComment;
            commentLevel = 1;
          }
          break;
        case '<' :
          if ( !inQuotedString ) {
            context = InAngleAddress;
          }
          break;
        case '\\' : // quoted character
          ++index; // skip the '\'
          if ( ++index > strlen )
            return UnexpectedEnd;
          break;
        case ',' :
          if ( !inQuotedString )
            return UnexpectedComma;
          break;
        case ')' :
          if ( !inQuotedString )
            return UnbalancedParens;
          break;
        case '>' :
          if ( !inQuotedString )
            return UnopenedAngleAddr;
          break;
        case '@' :
          if ( !inQuotedString ) {
            if ( index == 0 ) {  // Missing local part
              return MissingLocalPart;
            } else if( index == strlen-1 ) {
              return MissingDomainPart;
              break;
              }
            } else if ( inQuotedString ) {
              --atCount;
              if ( atCount == 1 ) {
                tooManyAtsFlag = false;
              }
            }
            break;
      }
      break;
    }
    case InComment : {
      switch ( aStr[index] ) {
        case '(' : ++commentLevel;
          break;
        case ')' : --commentLevel;
          if ( commentLevel == 0 ) {
            context = TopLevel;
          }
          break;
        case '\\' : // quoted character
          ++index; // skip the '\'
          if ( ++index > strlen )
            return UnexpectedEnd;
            break;
        }
        break;
    }

    case InAngleAddress : {
      switch ( aStr[index] ) {
        case '"' : inQuotedString = !inQuotedString;
            break;
        case '@' :
          if ( inQuotedString ) {
            --atCount;
            if ( atCount == 1 ) {
              tooManyAtsFlag = false;
            }
          }
          break;
        case '>' :
          if ( !inQuotedString ) {
            context = TopLevel;
            break;
          }
          break;
        case '\\' : // quoted character
          ++index; // skip the '\'
          if ( ++index > strlen )
            return UnexpectedEnd;
          break;
          }
        break;
      }
    }
  }
  if ( context == InComment )
    return UnbalancedParens;

  if ( context == TopLevel && !tooManyAtsFlag ) {
    return AddressOk;
  }

  if ( context == InAngleAddress )
    return UnclosedAngleAddr;

  if ( tooManyAtsFlag ) {
    return TooManyAts;
  }
  return AddressEmpty;
}

//-----------------------------------------------------------------------------
QString KPIM::emailParseResultToString( EmailParseResult errorCode )
{
  switch ( errorCode ) {
    case TooManyAts :
      return i18n("The email address you entered is not valid because it "
                "contains more than one @ "
                "you will not create valid messages if you do not "
                "change your address.");
    case TooFewAts :
      return i18n("The email address you entered is not valid because it "
                "does not contain a @ "
                "you will not create valid messages if you do not "
                "change your address.");
    case AddressEmpty :
      return i18n("You have to enter something in the email address field.");
    case MissingLocalPart :
      return i18n("The email address you entered is not valid because it "
                "does not contain a local part.");
    case MissingDomainPart :
      return i18n("The email address you entered is not valid because it "
                "does not contain a domain part.");
    case UnbalancedParens :
      return i18n("The email address you entered is not valid because it "
                "contains unclosed comments/brackets.");
    case AddressOk :
      return i18n("The email address you entered is valid.");
    case UnclosedAngleAddr :
      return i18n("The email address you entered is not valid because it "
                "contains an unclosed anglebracket.");
    case UnopenedAngleAddr :
      return i18n("The email address you entered is not valid because it "
                "contains an unopened anglebracket.");
    case UnexpectedComma :
      return i18n("The email address you have entered is not valid because it "
                "contains an unexpected comma.");
    case UnexpectedEnd :
      return i18n("The email address you entered is not valid because it ended "
                "unexpectadly, this probably means you have used an escaping type "
                "character like an \\  as the last character in your email "
                "address.");
  }
  return i18n("Unknown problem with email address");
}

//-----------------------------------------------------------------------------
bool KPIM::isValidSimpleEmailAddress( const QString& aStr )
{
  // If we are passed an empty string bail right away no need to process further
  // and waste resources
  if ( aStr.isEmpty() ) {
    return false;
  }

  int atChar = aStr.findRev( '@' );
  QString domainPart = aStr.mid( atChar + 1);
  QString localPart = aStr.left( atChar );
  bool tooManyAtsFlag = false;
  bool inQuotedString = false;
  int atCount = localPart.contains( '@' );

  unsigned int strlen = localPart.length();
  for ( unsigned int index=0; index < strlen; index++ ) {
    switch( localPart[ index ].latin1() ) {
      case '"' : inQuotedString = !inQuotedString;
        break;
      case '@' :
        if ( inQuotedString ) {
          --atCount;
          if ( atCount == 0 ) {
            tooManyAtsFlag = false;
          }
        }
        break;
      }
  }

  QString addrRx = "[a-zA-Z]*[\\w.-]*[a-zA-Z0-9]@";
  if ( localPart[ 0 ] == '\"' || localPart[ localPart.length()-1 ] == '\"' ) {
    addrRx = "\"[a-zA-Z@]*[\\w.@-]*[a-zA-Z0-9@]\"@";
  }
  if ( domainPart[ 0 ] == '[' || domainPart[ domainPart.length()-1 ] == ']' ) {
    addrRx += "\\[[0-9]{,3}(\\.[0-9]{,3}){3}\\]";
  } else {
    addrRx += "[\\w-]+(\\.[\\w-]+)";
  }
  QRegExp rx( addrRx );
  return  rx.exactMatch( aStr ) && !tooManyAtsFlag;
}

//-----------------------------------------------------------------------------
QCString KPIM::getEmailAddr(const QString& aStr)
{
  int a, i, j, len, found = 0;
  QChar c;
  // Find the '@' in the email address:
  a = aStr.find('@');
  if (a<0) return aStr.latin1();
  // Loop backwards until we find '<', '(', ' ', or beginning of string.
  for (i = a - 1; i >= 0; i--) {
    c = aStr[i];
    if (c == '<' || c == '(' || c == ' ') found = 1;
    if (found) break;
  }
  // Reset found for next loop.
  found = 0;
  // Loop forwards until we find '>', ')', ' ', or end of string.
  for (j = a + 1; j < (int)aStr.length(); j++) {
    c = aStr[j];
    if (c == '>' || c == ')' || c == ' ') found = 1;
    if (found) break;
  }
  // Calculate the length and return the result.
  len = j - (i + 1);
  return aStr.mid(i+1,len).latin1();
}

bool KPIM::getNameAndMail(const QString& aStr, QString& name, QString& mail)
{
  name = QString::null;
  mail = QString::null;

  const int len=aStr.length();
  const char cQuotes = '"';

  bool bInComment, bInQuotesOutsideOfEmail;
  int i=0, iAd=0, iMailStart=0, iMailEnd=0;
  QChar c;

  // Find the '@' of the email address
  // skipping all '@' inside "(...)" comments:
  bInComment = false;
  while( i < len ){
    c = aStr[i];
    if( !bInComment ){
      if( '(' == c ){
        bInComment = true;
      }else{
        if( '@' == c ){
          iAd = i;
          break; // found it
        }
      }
    }else{
      if( ')' == c ){
        bInComment = false;
      }
    }
    ++i;
  }

  if( !iAd ){
    // We suppose the user is typing the string manually and just
    // has not finished typing the mail address part.
    // So we take everything that's left of the '<' as name and the rest as mail
    for( i = 0; len > i; ++i ) {
      c = aStr[i];
      if( '<' != c )
        name.append( c );
      else
        break;
    }
    mail = aStr.mid( i+1 );
    if ( mail.endsWith( ">" ) )
      mail.truncate( mail.length() - 1 );

  }else{

    // Loop backwards until we find the start of the string
    // or a ',' that is outside of a comment
    //          and outside of quoted text before the leading '<'.
    bInComment = false;
    bInQuotesOutsideOfEmail = false;
    for( i = iAd-1; 0 <= i; --i ) {
      c = aStr[i];
      if( bInComment ){
        if( '(' == c ){
          if( !name.isEmpty() )
            name.prepend( ' ' );
          bInComment = false;
        }else{
          name.prepend( c ); // all comment stuff is part of the name
        }
      }else if( bInQuotesOutsideOfEmail ){
        if( cQuotes == c )
          bInQuotesOutsideOfEmail = false;
        else
          name.prepend( c );
      }else{
        // found the start of this addressee ?
        if( ',' == c )
          break;
        // stuff is before the leading '<' ?
        if( iMailStart ){
          if( cQuotes == c )
            bInQuotesOutsideOfEmail = true; // end of quoted text found
          else
            name.prepend( c );
        }else{
          switch( c ){
            case '<':
              iMailStart = i;
              break;
            case ')':
              if( !name.isEmpty() )
                name.prepend( ' ' );
              bInComment = true;
              break;
            default:
              if( ' ' != c )
                mail.prepend( c );
          }
        }
      }
    }

    name = name.simplifyWhiteSpace();
    mail = mail.simplifyWhiteSpace();

    if( mail.isEmpty() )
      return false;

    mail.append('@');

    // Loop forward until we find the end of the string
    // or a ',' that is outside of a comment
    //          and outside of quoted text behind the trailing '>'.
    bInComment = false;
    bInQuotesOutsideOfEmail = false;
    for( i = iAd+1; len > i; ++i ) {
      c = aStr[i];
      if( bInComment ){
        if( ')' == c ){
          if( !name.isEmpty() )
            name.append( ' ' );
          bInComment = false;
        }else{
          name.append( c ); // all comment stuff is part of the name
        }
      }else if( bInQuotesOutsideOfEmail ){
        if( cQuotes == c )
          bInQuotesOutsideOfEmail = false;
        else
          name.append( c );
      }else{
        // found the end of this addressee ?
        if( ',' == c )
          break;
        // stuff is behind the trailing '>' ?
        if( iMailEnd ){
          if( cQuotes == c )
            bInQuotesOutsideOfEmail = true; // start of quoted text found
          else
            name.append( c );
        }else{
          switch( c ){
            case '>':
              iMailEnd = i;
              break;
            case '(':
              if( !name.isEmpty() )
                name.append( ' ' );
              bInComment = true;
              break;
            default:
              if( ' ' != c )
                mail.append( c );
          }
        }
      }
    }
  }

  name = name.simplifyWhiteSpace();
  mail = mail.simplifyWhiteSpace();

  return ! (name.isEmpty() || mail.isEmpty());
}

bool KPIM::compareEmail( const QString& email1, const QString& email2,
                         bool matchName )
{
  QString e1Name, e1Email, e2Name, e2Email;

  getNameAndMail( email1, e1Name, e1Email );
  getNameAndMail( email2, e2Name, e2Email );

  return e1Email == e2Email &&
    ( !matchName || ( e1Name == e2Name ) );
}
<|endoftext|>


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

  Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "kconfigwizard.h"
#include "kconfigpropagator.h"

#include <KAboutData>
#include <KComponentData>
#include <KConfigSkeleton>
#include <KDebug>
#include <KLocale>
#include <KMessageBox>
#include <KPageDialog>

#include <QApplication>
#include <QLayout>
#include <QTimer>
#include <QVBoxLayout>
#include <Q3ListView>

using namespace KPIM;

KConfigWizard::KConfigWizard( QWidget *parent, bool modal )
  : KPageDialog( parent ), mPropagator( 0 ), mChangesPage( 0 )
{
  setModal( modal );
  init();
}

KConfigWizard::KConfigWizard( KConfigPropagator *propagator, QWidget *parent,
                              bool modal )
  : KPageDialog( parent ), mPropagator( propagator ), mChangesPage( 0 )
{
  setModal( modal );
  init();
}

KConfigWizard::~KConfigWizard()
{
  delete mPropagator;
}

void KConfigWizard::init()
{
  setFaceType( KPageDialog::Tree );
  setWindowTitle(
    KGlobal::mainComponent().aboutData()->programName().isEmpty()
    ? i18nc( "@title:window", "Configuration Wizard" )
    : KGlobal::mainComponent().aboutData()->programName() );
  setWindowIcon( KIcon("tools-wizard") );
  setButtons( Ok|Cancel );
  setDefaultButton( Ok );

  connect( this, SIGNAL( currentPageChanged(KPageWidgetItem *, KPageWidgetItem * )),
           SLOT( slotAboutToShowPage(KPageWidgetItem *, KPageWidgetItem *) ) );
  connect( this, SIGNAL(okClicked()),
           SLOT( slotOk()));
  QTimer::singleShot( 0, this, SLOT( readConfig() ) );
}

void KConfigWizard::setPropagator( KConfigPropagator *p )
{
  mPropagator = p;
}

void KConfigWizard::slotAboutToShowPage( KPageWidgetItem *page, KPageWidgetItem * )
{
  if ( page == mChangesPage ) {
    updateChanges();
  }
}

QWidget *KConfigWizard::createWizardPage( const QString &title )
{
  QFrame *page = new QFrame(this);
  addPage( page, title );
  return page;
}

void KConfigWizard::setupRulesPage()
{
  QFrame *page = new QFrame(this);
  KPageWidgetItem *item = addPage( page, i18nc( "@title:tab", "Rules" ) );
  item->setHeader( i18nc( "@title:window", "Setup Rules" ) );
  //TODO: set item icon
  //rame *topFrame = new QFrame( this );
  QVBoxLayout *topLayout = new QVBoxLayout;
  page->setLayout(topLayout);
  mRuleView = new Q3ListView;
  topLayout->addWidget( mRuleView );

  mRuleView->addColumn( i18nc( "@title:column source file,group,entry", "Source" ) );
  mRuleView->addColumn( i18nc( "@title:column target file,group,entry", "Target" ) );
  mRuleView->addColumn( i18nc( "@title:column file,group,key,value", "Condition" ) );

  updateRules();
}

void KConfigWizard::updateRules()
{
  if ( !mPropagator ) {
    kError() << "KConfigWizard: No KConfigPropagator set.";
    return;
  }

  mRuleView->clear();

  const KConfigPropagator::Rule::List rules = mPropagator->rules();
  KConfigPropagator::Rule::List::ConstIterator it;
  for ( it = rules.constBegin(); it != rules.constEnd(); ++it ) {
    KConfigPropagator::Rule r = *it;
    QString source = r.sourceFile + '/' + r.sourceGroup + '/' +
                     r.sourceEntry;
    QString target = r.targetFile + '/' + r.targetGroup + '/' +
                     r.targetEntry;
    QString condition;
    KConfigPropagator::Condition c = r.condition;
    if ( c.isValid ) {
      condition = c.file + '/' + c.group + '/' + c.key + " = " + c.value;
    }
    new Q3ListViewItem( mRuleView, source, target, condition );
  }
}

void KConfigWizard::setupChangesPage()
{
  QFrame *page = new QFrame( this );
  KPageWidgetItem *item = addPage( page, i18nc( "@title:tab", "Changes" ) );
  item->setHeader( i18nc( "@title:window", "Setup Changes" ) );
  //TODO: set item icon
  QVBoxLayout *topLayout = new QVBoxLayout;
  page->setLayout(topLayout);
  mChangeView = new Q3ListView;
  topLayout->addWidget( mChangeView );

  mChangeView->addColumn( i18nc( "@title:column change action", "Action" ) );
  mChangeView->addColumn( i18nc( "@title:column option to change", "Option" ) );
  mChangeView->addColumn( i18nc( "@title:column value for option", "Value" ) );
  mChangeView->setSorting( -1 );

  mChangesPage = item;
}

void KConfigWizard::updateChanges()
{
  kDebug() << "KConfigWizard::updateChanges()";

  if ( !mPropagator ) {
    kError() << "KConfigWizard: No KConfigPropagator set.";
    return;
  }

  usrWriteConfig();

  mPropagator->updateChanges();

  mChangeView->clear();

  KConfigPropagator::Change::List changes = mPropagator->changes();
  KConfigPropagator::Change *c;
  for ( c = changes.first(); c; c = changes.next() ) {
    new Q3ListViewItem( mChangeView, mChangeView->lastItem(), c->title(), c->arg1(), c->arg2() );
  }
}

void KConfigWizard::readConfig()
{
  kDebug() << "KConfigWizard::readConfig()";

  setEnabled( false );
  int result = KMessageBox::warningContinueCancel(
    0,
    i18nc( "@info", "Please make sure that the programs which are "
          "configured by the wizard do not run in parallel to the wizard; "
          "otherwise, changes done by the wizard could be lost." ),
    i18nc( "@title:window warn about running instances", "Warning" ),
    KGuiItem( i18nc( "@action:button", "Run Wizard Now" ) ),
    KStandardGuiItem::cancel(), "warning_running_instances" );
  if ( result != KMessageBox::Continue ) {
    qApp->quit();
  }
  setEnabled( true );

  usrReadConfig();
}

void KConfigWizard::slotOk()
{
  QString error = validate();
  if ( error.isNull() ) {
    usrWriteConfig();

    if ( !mPropagator ) {
      kError() << "KConfigWizard: No KConfigPropagator set.";
      return;
    } else {
      if ( mPropagator->skeleton() ) {
        mPropagator->skeleton()->writeConfig();
      }
      mPropagator->commit();
    }

    accept();
  } else {
    KMessageBox::sorry( this, error );
  }
}

#include "kconfigwizard.moc"
<commit_msg>Grammar<commit_after>/*
  This file is part of libkdepim.

  Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "kconfigwizard.h"
#include "kconfigpropagator.h"

#include <KAboutData>
#include <KComponentData>
#include <KConfigSkeleton>
#include <KDebug>
#include <KLocale>
#include <KMessageBox>
#include <KPageDialog>

#include <QApplication>
#include <QLayout>
#include <QTimer>
#include <QVBoxLayout>
#include <Q3ListView>

using namespace KPIM;

KConfigWizard::KConfigWizard( QWidget *parent, bool modal )
  : KPageDialog( parent ), mPropagator( 0 ), mChangesPage( 0 )
{
  setModal( modal );
  init();
}

KConfigWizard::KConfigWizard( KConfigPropagator *propagator, QWidget *parent,
                              bool modal )
  : KPageDialog( parent ), mPropagator( propagator ), mChangesPage( 0 )
{
  setModal( modal );
  init();
}

KConfigWizard::~KConfigWizard()
{
  delete mPropagator;
}

void KConfigWizard::init()
{
  setFaceType( KPageDialog::Tree );
  setWindowTitle(
    KGlobal::mainComponent().aboutData()->programName().isEmpty()
    ? i18nc( "@title:window", "Configuration Wizard" )
    : KGlobal::mainComponent().aboutData()->programName() );
  setWindowIcon( KIcon("tools-wizard") );
  setButtons( Ok|Cancel );
  setDefaultButton( Ok );

  connect( this, SIGNAL( currentPageChanged(KPageWidgetItem *, KPageWidgetItem * )),
           SLOT( slotAboutToShowPage(KPageWidgetItem *, KPageWidgetItem *) ) );
  connect( this, SIGNAL(okClicked()),
           SLOT( slotOk()));
  QTimer::singleShot( 0, this, SLOT( readConfig() ) );
}

void KConfigWizard::setPropagator( KConfigPropagator *p )
{
  mPropagator = p;
}

void KConfigWizard::slotAboutToShowPage( KPageWidgetItem *page, KPageWidgetItem * )
{
  if ( page == mChangesPage ) {
    updateChanges();
  }
}

QWidget *KConfigWizard::createWizardPage( const QString &title )
{
  QFrame *page = new QFrame(this);
  addPage( page, title );
  return page;
}

void KConfigWizard::setupRulesPage()
{
  QFrame *page = new QFrame(this);
  KPageWidgetItem *item = addPage( page, i18nc( "@title:tab", "Rules" ) );
  item->setHeader( i18nc( "@title:window", "Set Up Rules" ) );
  //TODO: set item icon
  //rame *topFrame = new QFrame( this );
  QVBoxLayout *topLayout = new QVBoxLayout;
  page->setLayout(topLayout);
  mRuleView = new Q3ListView;
  topLayout->addWidget( mRuleView );

  mRuleView->addColumn( i18nc( "@title:column source file,group,entry", "Source" ) );
  mRuleView->addColumn( i18nc( "@title:column target file,group,entry", "Target" ) );
  mRuleView->addColumn( i18nc( "@title:column file,group,key,value", "Condition" ) );

  updateRules();
}

void KConfigWizard::updateRules()
{
  if ( !mPropagator ) {
    kError() << "KConfigWizard: No KConfigPropagator set.";
    return;
  }

  mRuleView->clear();

  const KConfigPropagator::Rule::List rules = mPropagator->rules();
  KConfigPropagator::Rule::List::ConstIterator it;
  for ( it = rules.constBegin(); it != rules.constEnd(); ++it ) {
    KConfigPropagator::Rule r = *it;
    QString source = r.sourceFile + '/' + r.sourceGroup + '/' +
                     r.sourceEntry;
    QString target = r.targetFile + '/' + r.targetGroup + '/' +
                     r.targetEntry;
    QString condition;
    KConfigPropagator::Condition c = r.condition;
    if ( c.isValid ) {
      condition = c.file + '/' + c.group + '/' + c.key + " = " + c.value;
    }
    new Q3ListViewItem( mRuleView, source, target, condition );
  }
}

void KConfigWizard::setupChangesPage()
{
  QFrame *page = new QFrame( this );
  KPageWidgetItem *item = addPage( page, i18nc( "@title:tab", "Changes" ) );
  item->setHeader( i18nc( "@title:window", "Set Up Changes" ) );
  //TODO: set item icon
  QVBoxLayout *topLayout = new QVBoxLayout;
  page->setLayout(topLayout);
  mChangeView = new Q3ListView;
  topLayout->addWidget( mChangeView );

  mChangeView->addColumn( i18nc( "@title:column change action", "Action" ) );
  mChangeView->addColumn( i18nc( "@title:column option to change", "Option" ) );
  mChangeView->addColumn( i18nc( "@title:column value for option", "Value" ) );
  mChangeView->setSorting( -1 );

  mChangesPage = item;
}

void KConfigWizard::updateChanges()
{
  kDebug() << "KConfigWizard::updateChanges()";

  if ( !mPropagator ) {
    kError() << "KConfigWizard: No KConfigPropagator set.";
    return;
  }

  usrWriteConfig();

  mPropagator->updateChanges();

  mChangeView->clear();

  KConfigPropagator::Change::List changes = mPropagator->changes();
  KConfigPropagator::Change *c;
  for ( c = changes.first(); c; c = changes.next() ) {
    new Q3ListViewItem( mChangeView, mChangeView->lastItem(), c->title(), c->arg1(), c->arg2() );
  }
}

void KConfigWizard::readConfig()
{
  kDebug() << "KConfigWizard::readConfig()";

  setEnabled( false );
  int result = KMessageBox::warningContinueCancel(
    0,
    i18nc( "@info", "Please make sure that the programs which are "
          "configured by the wizard do not run in parallel to the wizard; "
          "otherwise, changes done by the wizard could be lost." ),
    i18nc( "@title:window warn about running instances", "Warning" ),
    KGuiItem( i18nc( "@action:button", "Run Wizard Now" ) ),
    KStandardGuiItem::cancel(), "warning_running_instances" );
  if ( result != KMessageBox::Continue ) {
    qApp->quit();
  }
  setEnabled( true );

  usrReadConfig();
}

void KConfigWizard::slotOk()
{
  QString error = validate();
  if ( error.isNull() ) {
    usrWriteConfig();

    if ( !mPropagator ) {
      kError() << "KConfigWizard: No KConfigPropagator set.";
      return;
    } else {
      if ( mPropagator->skeleton() ) {
        mPropagator->skeleton()->writeConfig();
      }
      mPropagator->commit();
    }

    accept();
  } else {
    KMessageBox::sorry( this, error );
  }
}

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


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

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

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

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

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbPerBandVectorImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkShrinkImageFilter.h"

#include "otbWrapperParameter.h"
#include "otbWrapperOutputImageParameter.h"

namespace otb
{
namespace Wrapper
{

class MultiResolutionPyramid : public Application
{

public:
  /** Standard class typedefs. */
  typedef MultiResolutionPyramid        Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(MultiResolutionPyramid, otb::Application);

  /** Image and filters typedef */
  typedef itk::DiscreteGaussianImageFilter<FloatImageType,
                                           FloatImageType>         SmoothingImageFilterType;

  typedef otb::PerBandVectorImageFilter<FloatVectorImageType,
                                        FloatVectorImageType,
                                        SmoothingImageFilterType>   SmoothingVectorImageFilterType;

  typedef itk::ShrinkImageFilter<FloatVectorImageType,
                                 FloatVectorImageType>              ShrinkFilterType;

private:
  void DoInit()
  {
    SetName("MultiResolutionPyramid");
    SetDescription("Build a multi-resolution pyramid of the image.");

    // Documentation
    SetDocName("Multi Resolution Pyramid");
    SetDocLongDescription("This application builds a multi-resolution pyramid of the input image. User can specified the number of levels of the pyramid and the subsampling factor. To speed up the process, you can use the fast scheme option");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag("Conversion");
    AddDocTag(Tags::Manip);
    AddDocTag(Tags::Multi);
    AddDocTag("Util");

    AddParameter(ParameterType_InputImage, "in", "Input Image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out","will be used to get the prefix and the extension of the images to write");

    AddRAMParameter();

    AddParameter(ParameterType_Int, "level", "Number Of Levels");
    SetDefaultParameterInt("level", 1);
    SetParameterDescription( "level", "Number of levels in the pyramid (default is 1).");

    AddParameter(ParameterType_Int, "sfactor", "Subsampling factor");
    SetDefaultParameterInt("sfactor", 2);
    SetParameterDescription( "sfactor", "Subsampling factor between each level of the pyramid (default is 2).");

    AddParameter(ParameterType_Float,  "vfactor", "Variance factor");
    SetDefaultParameterFloat("vfactor", 0.6);
    SetParameterDescription( "vfactor", "Variance factor use in smoothing. It is multiplied by the subsampling factor of each level in the  pyramid (default is 0.6).");

    // Boolean Fast scheme
    AddParameter(ParameterType_Empty, "fast", "Use Fast Scheme");
    std::ostringstream desc;
    desc<<"If used, this option allows to speed-up computation by iteratively"
        <<" subsampling previous level of pyramid instead of processing the full input.";
    SetParameterDescription("fast", desc.str());
    MandatoryOff("fast");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("out", "multiResolutionImage.tif");
    SetDocExampleParameterValue("level", "1");
    SetDocExampleParameterValue("sfactor", "2");
    SetDocExampleParameterValue("vfactor", "0.6");
    SetDocExampleParameterValue("fast", "false");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here for the parameters : all are independent

    // Reinitialize the internal process used
  }

  void DoExecute()
  {
    // Initializing the process
    m_SmoothingFilter =  SmoothingVectorImageFilterType::New();
    m_ShrinkFilter    = ShrinkFilterType::New();

    // Extract Parameters
    unsigned int nbLevels     = GetParameterInt("level");
    unsigned int shrinkFactor = GetParameterInt("sfactor");
    double varianceFactor     = GetParameterFloat("vfactor");

    bool fastScheme = IsParameterEnabled("fast");

    // Get the input image
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");

    // Get the Initial Output Image FileName
    std::string path, fname, ext;
    std::string ofname = GetParameterString("out");

    // Get the extension and the prefix of the filename
    path  = itksys::SystemTools::GetFilenamePath(ofname);
    fname = itksys::SystemTools::GetFilenameWithoutExtension(ofname);
    ext   = itksys::SystemTools::GetFilenameExtension(ofname);

    unsigned int currentLevel = 1;
    unsigned int currentFactor = shrinkFactor;

    while(currentLevel <= nbLevels)
      {
      otbAppLogDEBUG( << "Processing level " << currentLevel
                      << " with shrink factor "<<currentFactor);

      m_SmoothingFilter->SetInput(inImage);

      // According to
      // http://www.ipol.im/pub/algo/gjmr_line_segment_detector/
      // This is a good balance between blur and aliasing
      double variance = varianceFactor * static_cast<double>(currentFactor);
      m_SmoothingFilter->GetFilter()->SetVariance(variance);

      m_ShrinkFilter->SetInput(m_SmoothingFilter->GetOutput());
      m_ShrinkFilter->SetShrinkFactors(currentFactor);

      if(!fastScheme)
        {
        currentFactor *= shrinkFactor;
        }
      else
        {
        std::cout <<"fast scheme enabled : not implemented for the moment " << std::endl;
        }

      // Create an output parameter to write the current output image
      OutputImageParameter::Pointer paramOut = OutputImageParameter::New();

      // build the current image filename
      std::ostringstream oss;
      if (!path.empty())
        {
        oss <<path<<"/";
        }
      oss <<fname<<"_"<<currentLevel<<ext;

      // writer label
      std::ostringstream osswriter;
      osswriter<< "writer (level "<< currentLevel<<")";

      // Set the filename of the current output image
      paramOut->SetFileName(oss.str());
      paramOut->SetValue(m_ShrinkFilter->GetOutput());
      paramOut->SetPixelType(this->GetParameterOutputImagePixelType("out"));
      // Add the current level to be written
      paramOut->InitializeWriters();
      AddProcess(paramOut->GetWriter(), osswriter.str());
      paramOut->Write();

      ++currentLevel;
      }

    // Disable this parameter since the images have already been produced
    DisableParameter("out");
  }

  SmoothingVectorImageFilterType::Pointer   m_SmoothingFilter;
  ShrinkFilterType::Pointer                 m_ShrinkFilter;
};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::MultiResolutionPyramid)
<commit_msg>BUG: multiresolution pyramid level parameter must not have negative value. ref mantis #864<commit_after>/*=========================================================================

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

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

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

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbPerBandVectorImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkShrinkImageFilter.h"

#include "otbWrapperParameter.h"
#include "otbWrapperOutputImageParameter.h"

namespace otb
{
namespace Wrapper
{

class MultiResolutionPyramid : public Application
{

public:
  /** Standard class typedefs. */
  typedef MultiResolutionPyramid        Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(MultiResolutionPyramid, otb::Application);

  /** Image and filters typedef */
  typedef itk::DiscreteGaussianImageFilter<FloatImageType,
                                           FloatImageType>         SmoothingImageFilterType;

  typedef otb::PerBandVectorImageFilter<FloatVectorImageType,
                                        FloatVectorImageType,
                                        SmoothingImageFilterType>   SmoothingVectorImageFilterType;

  typedef itk::ShrinkImageFilter<FloatVectorImageType,
                                 FloatVectorImageType>              ShrinkFilterType;

private:
  void DoInit()
  {
    SetName("MultiResolutionPyramid");
    SetDescription("Build a multi-resolution pyramid of the image.");

    // Documentation
    SetDocName("Multi Resolution Pyramid");
    SetDocLongDescription("This application builds a multi-resolution pyramid of the input image. User can specified the number of levels of the pyramid and the subsampling factor. To speed up the process, you can use the fast scheme option");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag("Conversion");
    AddDocTag(Tags::Manip);
    AddDocTag(Tags::Multi);
    AddDocTag("Util");

    AddParameter(ParameterType_InputImage, "in", "Input Image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out","will be used to get the prefix and the extension of the images to write");

    AddRAMParameter();

    AddParameter(ParameterType_Int, "level", "Number Of Levels");
    SetDefaultParameterInt("level", 1);
    SetParameterDescription( "level", "Number of levels in the pyramid (default is 1).");
    SetMinimumParameterIntValue("level", 1);

    AddParameter(ParameterType_Int, "sfactor", "Subsampling factor");
    SetDefaultParameterInt("sfactor", 2);
    SetParameterDescription( "sfactor", "Subsampling factor between each level of the pyramid (default is 2).");

    AddParameter(ParameterType_Float,  "vfactor", "Variance factor");
    SetDefaultParameterFloat("vfactor", 0.6);
    SetParameterDescription( "vfactor", "Variance factor use in smoothing. It is multiplied by the subsampling factor of each level in the  pyramid (default is 0.6).");

    // Boolean Fast scheme
    AddParameter(ParameterType_Empty, "fast", "Use Fast Scheme");
    std::ostringstream desc;
    desc<<"If used, this option allows to speed-up computation by iteratively"
        <<" subsampling previous level of pyramid instead of processing the full input.";
    SetParameterDescription("fast", desc.str());
    MandatoryOff("fast");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("out", "multiResolutionImage.tif");
    SetDocExampleParameterValue("level", "1");
    SetDocExampleParameterValue("sfactor", "2");
    SetDocExampleParameterValue("vfactor", "0.6");
    SetDocExampleParameterValue("fast", "false");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here for the parameters : all are independent

    // Reinitialize the internal process used
  }

  void DoExecute()
  {
    // Initializing the process
    m_SmoothingFilter =  SmoothingVectorImageFilterType::New();
    m_ShrinkFilter    = ShrinkFilterType::New();

    // Extract Parameters
    unsigned int nbLevels     = GetParameterInt("level");
    unsigned int shrinkFactor = GetParameterInt("sfactor");
    double varianceFactor     = GetParameterFloat("vfactor");

    bool fastScheme = IsParameterEnabled("fast");

    // Get the input image
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");

    // Get the Initial Output Image FileName
    std::string path, fname, ext;
    std::string ofname = GetParameterString("out");

    // Get the extension and the prefix of the filename
    path  = itksys::SystemTools::GetFilenamePath(ofname);
    fname = itksys::SystemTools::GetFilenameWithoutExtension(ofname);
    ext   = itksys::SystemTools::GetFilenameExtension(ofname);

    unsigned int currentLevel = 1;
    unsigned int currentFactor = shrinkFactor;

    while(currentLevel <= nbLevels)
      {
      otbAppLogDEBUG( << "Processing level " << currentLevel
                      << " with shrink factor "<<currentFactor);

      m_SmoothingFilter->SetInput(inImage);

      // According to
      // http://www.ipol.im/pub/algo/gjmr_line_segment_detector/
      // This is a good balance between blur and aliasing
      double variance = varianceFactor * static_cast<double>(currentFactor);
      m_SmoothingFilter->GetFilter()->SetVariance(variance);

      m_ShrinkFilter->SetInput(m_SmoothingFilter->GetOutput());
      m_ShrinkFilter->SetShrinkFactors(currentFactor);

      if(!fastScheme)
        {
        currentFactor *= shrinkFactor;
        }
      else
        {
        std::cout <<"fast scheme enabled : not implemented for the moment " << std::endl;
        }

      // Create an output parameter to write the current output image
      OutputImageParameter::Pointer paramOut = OutputImageParameter::New();

      // build the current image filename
      std::ostringstream oss;
      if (!path.empty())
        {
        oss <<path<<"/";
        }
      oss <<fname<<"_"<<currentLevel<<ext;

      // writer label
      std::ostringstream osswriter;
      osswriter<< "writer (level "<< currentLevel<<")";

      // Set the filename of the current output image
      paramOut->SetFileName(oss.str());
      paramOut->SetValue(m_ShrinkFilter->GetOutput());
      paramOut->SetPixelType(this->GetParameterOutputImagePixelType("out"));
      // Add the current level to be written
      paramOut->InitializeWriters();
      AddProcess(paramOut->GetWriter(), osswriter.str());
      paramOut->Write();

      ++currentLevel;
      }

    // Disable this parameter since the images have already been produced
    DisableParameter("out");
  }

  SmoothingVectorImageFilterType::Pointer   m_SmoothingFilter;
  ShrinkFilterType::Pointer                 m_ShrinkFilter;
};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::MultiResolutionPyramid)
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	largeobject.cxx
 *
 *   DESCRIPTION
 *      Implementation of the Large Objects interface
 *   Allows access to large objects directly, or though I/O streams
 *
 * Copyright (c) 2003-2004, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#include "pqxx/compiler.h"

#include <cerrno>
#include <stdexcept>

#include "libpq/libpq-fs.h"

#include "pqxx/largeobject"

using namespace PGSTD;
using namespace pqxx::internal::pq;

namespace
{

inline int StdModeToPQMode(ios::openmode mode)
{
  return ((mode & ios::in)  ? INV_READ  : 0) |
         ((mode & ios::out) ? INV_WRITE : 0);
}

inline int StdDirToPQDir(ios::seekdir dir) throw ()
{
  int pqdir;
  switch (dir)
  {
  case ios::beg: pqdir=SEEK_SET; break;
  case ios::cur: pqdir=SEEK_CUR; break;
  case ios::end: pqdir=SEEK_END; break;

  /* Default clause added for two reasons: one, to silence compiler warning
   * about values not handled in switch (due to tackiness in std headers), and
   * two, to help the optimizer recognize implementations where the numerical
   * values of dir and pqdir are always equal.
   */
  default: pqdir = dir; break;
  }

  return pqdir;
}

} // namespace

pqxx::largeobject::largeobject() throw () :
  m_ID(oid_none)
{
}

pqxx::largeobject::largeobject(dbtransaction &T) :
  m_ID()
{
  m_ID = lo_creat(RawConnection(T), INV_READ|INV_WRITE);
  if (m_ID == oid_none)
    throw runtime_error("Could not create large object: " +
	                string(strerror(errno)));
}

pqxx::largeobject::largeobject(dbtransaction &T, const string &File) :
  m_ID()
{
  m_ID = lo_import(RawConnection(T), File.c_str());
  if (m_ID == oid_none)
  {
    const int err = errno;
    throw runtime_error("Could not import file '" + File + "' "
	                "to large object: " + strerror(err));
  }
}

pqxx::largeobject::largeobject(const largeobjectaccess &O) throw () :
  m_ID(O.id())
{
}

void pqxx::largeobject::to_file(dbtransaction &T, const string &File) const
{
  if (lo_export(RawConnection(T), id(), File.c_str()) == -1)
    throw runtime_error("Could not export large object " + to_string(m_ID) + " "
	                "to file '" + File + "': " +
			Reason());
}

void pqxx::largeobject::remove(dbtransaction &T) const
{
  if (lo_unlink(RawConnection(T), id()) == -1)
    throw runtime_error("Could not delete large object " +
	                to_string(m_ID) + ": " +
			Reason());
}

string pqxx::largeobject::Reason() const
{
  return (id() == oid_none) ? "No object selected" : strerror(errno);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T, openmode mode) :
  largeobject(T),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T,
    					   oid O,
					   openmode mode) :
  largeobject(O),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T,
    					   largeobject O,
					   openmode mode) :
  largeobject(O),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T,
					   const string &File,
					   openmode mode) :
  largeobject(T, File),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::size_type
pqxx::largeobjectaccess::seek(size_type dest, seekdir dir)
{
  const size_type Result = cseek(dest, dir);
  if (Result == -1)
    throw runtime_error("Error seeking in large object: " + Reason());

  return Result;
}

long pqxx::largeobjectaccess::cseek(off_type dest, seekdir dir) throw ()
{
  return lo_lseek(RawConnection(), m_fd, dest, StdDirToPQDir(dir));
}

long pqxx::largeobjectaccess::cwrite(const char Buf[], size_type Len) throw ()
{
  return max(lo_write(RawConnection(), m_fd, const_cast<char *>(Buf), Len), -1);
}

long pqxx::largeobjectaccess::cread(char Buf[], size_type Bytes) throw ()
{
  return max(lo_read(RawConnection(), m_fd, Buf, Bytes), -1);
}

void pqxx::largeobjectaccess::write(const char Buf[], size_type Len)
{
  const long Bytes = cwrite(Buf, Len);
  if (Bytes < Len)
  {
    if (Bytes < 0)
      throw runtime_error("Error writing to large object "
                          "#" + to_string(id()) + ": " +
	                  Reason());
    if (Bytes == 0)
      throw runtime_error("Could not write to large object #" +
	                  to_string(id()) + ": " + Reason());

    throw runtime_error("Wanted to write " + to_string(Len) + " bytes "
	                "to large object #" + to_string(id()) + "; "
			"could only write " + to_string(Bytes));
  }
}

pqxx::largeobjectaccess::size_type
pqxx::largeobjectaccess::read(char Buf[], size_type Len)
{
  const long Bytes = cread(Buf, Len);
  if (Bytes < 0)
    throw runtime_error("Error reading from large object #" + to_string(id()) +
	                ": " + Reason());
  return Bytes;
}

void pqxx::largeobjectaccess::open(openmode mode)
{
  m_fd = lo_open(RawConnection(), id(), StdModeToPQMode(mode));
  if (m_fd < 0)
    throw runtime_error("Could not open large object " + to_string(id()) + ":"
			" " + Reason());
}

void pqxx::largeobjectaccess::close() throw ()
{
  if (m_fd >= 0) lo_close(RawConnection(), m_fd);
}

string pqxx::largeobjectaccess::Reason() const
{
  return (m_fd == -1) ? "No object opened" : largeobject::Reason();
}

void pqxx::largeobjectaccess::process_notice(const string &s) throw ()
{
  m_Trans.process_notice(s);
}

<commit_msg>Qualified min()/max() to catch any regressions of Visual C++ bug<commit_after>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	largeobject.cxx
 *
 *   DESCRIPTION
 *      Implementation of the Large Objects interface
 *   Allows access to large objects directly, or though I/O streams
 *
 * Copyright (c) 2003-2004, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#include "pqxx/compiler.h"

#include <cerrno>
#include <stdexcept>

#include "libpq/libpq-fs.h"

#include "pqxx/largeobject"

using namespace PGSTD;
using namespace pqxx::internal::pq;

namespace
{

inline int StdModeToPQMode(ios::openmode mode)
{
  return ((mode & ios::in)  ? INV_READ  : 0) |
         ((mode & ios::out) ? INV_WRITE : 0);
}

inline int StdDirToPQDir(ios::seekdir dir) throw ()
{
  int pqdir;
  switch (dir)
  {
  case ios::beg: pqdir=SEEK_SET; break;
  case ios::cur: pqdir=SEEK_CUR; break;
  case ios::end: pqdir=SEEK_END; break;

  /* Default clause added for two reasons: one, to silence compiler warning
   * about values not handled in switch (due to tackiness in std headers), and
   * two, to help the optimizer recognize implementations where the numerical
   * values of dir and pqdir are always equal.
   */
  default: pqdir = dir; break;
  }

  return pqdir;
}

} // namespace

pqxx::largeobject::largeobject() throw () :
  m_ID(oid_none)
{
}

pqxx::largeobject::largeobject(dbtransaction &T) :
  m_ID()
{
  m_ID = lo_creat(RawConnection(T), INV_READ|INV_WRITE);
  if (m_ID == oid_none)
    throw runtime_error("Could not create large object: " +
	                string(strerror(errno)));
}

pqxx::largeobject::largeobject(dbtransaction &T, const string &File) :
  m_ID()
{
  m_ID = lo_import(RawConnection(T), File.c_str());
  if (m_ID == oid_none)
  {
    const int err = errno;
    throw runtime_error("Could not import file '" + File + "' "
	                "to large object: " + strerror(err));
  }
}

pqxx::largeobject::largeobject(const largeobjectaccess &O) throw () :
  m_ID(O.id())
{
}

void pqxx::largeobject::to_file(dbtransaction &T, const string &File) const
{
  if (lo_export(RawConnection(T), id(), File.c_str()) == -1)
    throw runtime_error("Could not export large object " + to_string(m_ID) + " "
	                "to file '" + File + "': " +
			Reason());
}

void pqxx::largeobject::remove(dbtransaction &T) const
{
  if (lo_unlink(RawConnection(T), id()) == -1)
    throw runtime_error("Could not delete large object " +
	                to_string(m_ID) + ": " +
			Reason());
}

string pqxx::largeobject::Reason() const
{
  return (id() == oid_none) ? "No object selected" : strerror(errno);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T, openmode mode) :
  largeobject(T),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T,
    					   oid O,
					   openmode mode) :
  largeobject(O),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T,
    					   largeobject O,
					   openmode mode) :
  largeobject(O),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T,
					   const string &File,
					   openmode mode) :
  largeobject(T, File),
  m_Trans(T),
  m_fd(-1)
{
  open(mode);
}

pqxx::largeobjectaccess::size_type
pqxx::largeobjectaccess::seek(size_type dest, seekdir dir)
{
  const size_type Result = cseek(dest, dir);
  if (Result == -1)
    throw runtime_error("Error seeking in large object: " + Reason());

  return Result;
}

long pqxx::largeobjectaccess::cseek(off_type dest, seekdir dir) throw ()
{
  return lo_lseek(RawConnection(), m_fd, dest, StdDirToPQDir(dir));
}

long pqxx::largeobjectaccess::cwrite(const char Buf[], size_type Len) throw ()
{
  return
    PGSTD::max(lo_write(RawConnection(),m_fd,const_cast<char *>(Buf), Len), -1);
}

long pqxx::largeobjectaccess::cread(char Buf[], size_type Bytes) throw ()
{
  return PGSTD::max(lo_read(RawConnection(), m_fd, Buf, Bytes), -1);
}

void pqxx::largeobjectaccess::write(const char Buf[], size_type Len)
{
  const long Bytes = cwrite(Buf, Len);
  if (Bytes < Len)
  {
    if (Bytes < 0)
      throw runtime_error("Error writing to large object "
                          "#" + to_string(id()) + ": " +
	                  Reason());
    if (Bytes == 0)
      throw runtime_error("Could not write to large object #" +
	                  to_string(id()) + ": " + Reason());

    throw runtime_error("Wanted to write " + to_string(Len) + " bytes "
	                "to large object #" + to_string(id()) + "; "
			"could only write " + to_string(Bytes));
  }
}

pqxx::largeobjectaccess::size_type
pqxx::largeobjectaccess::read(char Buf[], size_type Len)
{
  const long Bytes = cread(Buf, Len);
  if (Bytes < 0)
    throw runtime_error("Error reading from large object #" + to_string(id()) +
	                ": " + Reason());
  return Bytes;
}

void pqxx::largeobjectaccess::open(openmode mode)
{
  m_fd = lo_open(RawConnection(), id(), StdModeToPQMode(mode));
  if (m_fd < 0)
    throw runtime_error("Could not open large object " + to_string(id()) + ":"
			" " + Reason());
}

void pqxx::largeobjectaccess::close() throw ()
{
  if (m_fd >= 0) lo_close(RawConnection(), m_fd);
}

string pqxx::largeobjectaccess::Reason() const
{
  return (m_fd == -1) ? "No object opened" : largeobject::Reason();
}

void pqxx::largeobjectaccess::process_notice(const string &s) throw ()
{
  m_Trans.process_notice(s);
}

<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QObject>
#include <QGraphicsLinearLayout>
#include <QGraphicsSceneMouseEvent>
#include <QSignalSpy>

#include <mcontainer.h>
#include "mcontainer_p.h"
#include <mcontainerview.h>
#include "views/mcontainerview_p.h"

#include "ut_mcontainer.h"
#include "mapplication.h"

#include "mcancelevent.h"

void Ut_MContainer::init()
{
    m_subject = new MContainer();
}

void Ut_MContainer::cleanup()
{
    delete m_subject;
    m_subject = 0;
}
MApplication *app;

void Ut_MContainer::initTestCase()
{
    static int argc = 1;
    static char *app_name[1] = { (char *) "./ut_mcontainer" };
    app = new MApplication(argc, app_name);
}

void Ut_MContainer::cleanupTestCase()
{
    delete app;
}

void Ut_MContainer::centralWidget()
{
    // check that there exists centralWidget
    QVERIFY(m_subject->centralWidget() != NULL);
}

void Ut_MContainer::setCentralWidget()
{
    MWidget *tmp = new MWidget();

    m_subject->setCentralWidget(tmp);

    // check that there exists centralWidget
    QVERIFY(m_subject->centralWidget() == tmp);

    delete tmp;
}

void Ut_MContainer::title()
{
    QString myQString("testing title()");

    m_subject->setTitle(myQString);
    QCOMPARE(m_subject->title(), myQString);
}

void Ut_MContainer::text()
{
    QString myQString("testing text()");

    m_subject->setText(myQString);
    QCOMPARE(m_subject->text(), myQString);
}

void Ut_MContainer::iconID()
{
    QString myIconID("testing iconID()");

    m_subject->setIconID(myIconID);
    QCOMPARE(m_subject->iconID(), myIconID);
}

void Ut_MContainer::headerVisible()
{
    // default state
    QVERIFY(m_subject->headerVisible() == true);

    m_subject->setHeaderVisible(false);

    QVERIFY(m_subject->headerVisible() == false);
}

void Ut_MContainer::toggleHeaderVisible()
{
    // default state
    QVERIFY(m_subject->headerVisible() == true);

    m_subject->toggleHeaderVisible();

    QVERIFY(m_subject->headerVisible() == false);

    m_subject->toggleHeaderVisible();

    QVERIFY(m_subject->headerVisible() == true);
}

void Ut_MContainer::toggleProgressIndicatorVisible()
{
    // default state
    QVERIFY(m_subject->isProgressIndicatorVisible() == false);

    m_subject->toggleProgressIndicatorVisible();

    QVERIFY(m_subject->isProgressIndicatorVisible() == true);

    m_subject->toggleProgressIndicatorVisible();

    QVERIFY(m_subject->isProgressIndicatorVisible() == false);
}

void Ut_MContainer::testCreatingViewImmediatelyInLayout()
{
    //Add the container to a layout then force the view to be created by calling minimumSize()
    QGraphicsLinearLayout layout(Qt::Horizontal);
    layout.addItem(m_subject);
    m_subject->minimumSize();

}
void Ut_MContainer::testCreatingViewImmediately()
{
    //Force the view to be created by calling minimumSize()
    //This checks BUG:126088 which causes a segmentation fault
    m_subject->minimumSize();
}

void Ut_MContainer::testCancelEvent()
{
    QSignalSpy spy(m_subject, SIGNAL(headerClicked()));

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
    m_subject->mousePressEvent(&mouseEvent);

    MCancelEvent event;
    m_subject->cancelEvent(&event);

    QVERIFY(spy.count() == 0);
}

// test all of the set/get with both visible and invisble header, because it should work for instance
// that one sets the e.g. iconID now and makes the header visible later

void Ut_MContainer::setTitleWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setTitle("title");

    QCOMPARE(m_subject->title(), QString("title"));
}

void Ut_MContainer::setTitleWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setTitle("title");

    QCOMPARE(m_subject->title(), QString("title"));
}

void Ut_MContainer::setIconIDWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setIconID("icon-m-framework-close");

    QCOMPARE(m_subject->iconID(), QString("icon-m-framework-close"));
}

void Ut_MContainer::setIconIDWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setIconID("icon-m-framework-close");

    QCOMPARE(m_subject->iconID(), QString("icon-m-framework-close"));
}

void Ut_MContainer::setTextWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setText("text");

    QCOMPARE(m_subject->text(), QString("text"));
}

void Ut_MContainer::setTextWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setText("text");

    QCOMPARE(m_subject->text(), QString("text"));
}

void Ut_MContainer::setProgressIndicatorVisible()
{
    m_subject->setProgressIndicatorVisible(true);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), true);
}

void Ut_MContainer::setProgressIndicatorInVisible()
{
    m_subject->setProgressIndicatorVisible(false);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), false);
}

void Ut_MContainer::setProgressIndicatorWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setProgressIndicatorVisible(true);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), true);
}

void Ut_MContainer::setProgressIndicatorWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setProgressIndicatorVisible(true);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), true);
}

QTEST_APPLESS_MAIN(Ut_MContainer)
<commit_msg>Fixes: MContainer setCentralWidget unit test.<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QObject>
#include <QGraphicsLinearLayout>
#include <QGraphicsSceneMouseEvent>
#include <QSignalSpy>

#include <mcontainer.h>
#include "mcontainer_p.h"
#include <mcontainerview.h>
#include "views/mcontainerview_p.h"

#include "ut_mcontainer.h"
#include "mapplication.h"

#include "mcancelevent.h"

void Ut_MContainer::init()
{
    m_subject = new MContainer();
}

void Ut_MContainer::cleanup()
{
    delete m_subject;
    m_subject = 0;
}
MApplication *app;

void Ut_MContainer::initTestCase()
{
    static int argc = 1;
    static char *app_name[1] = { (char *) "./ut_mcontainer" };
    app = new MApplication(argc, app_name);
}

void Ut_MContainer::cleanupTestCase()
{
    delete app;
}

void Ut_MContainer::centralWidget()
{
    // check that there exists centralWidget
    QVERIFY(m_subject->centralWidget() != NULL);
}

void Ut_MContainer::setCentralWidget()
{
    MWidget *tmp = new MWidget();

    m_subject->setCentralWidget(tmp);

    // check that there exists centralWidget
    QVERIFY(m_subject->centralWidget() == tmp);
}

void Ut_MContainer::title()
{
    QString myQString("testing title()");

    m_subject->setTitle(myQString);
    QCOMPARE(m_subject->title(), myQString);
}

void Ut_MContainer::text()
{
    QString myQString("testing text()");

    m_subject->setText(myQString);
    QCOMPARE(m_subject->text(), myQString);
}

void Ut_MContainer::iconID()
{
    QString myIconID("testing iconID()");

    m_subject->setIconID(myIconID);
    QCOMPARE(m_subject->iconID(), myIconID);
}

void Ut_MContainer::headerVisible()
{
    // default state
    QVERIFY(m_subject->headerVisible() == true);

    m_subject->setHeaderVisible(false);

    QVERIFY(m_subject->headerVisible() == false);
}

void Ut_MContainer::toggleHeaderVisible()
{
    // default state
    QVERIFY(m_subject->headerVisible() == true);

    m_subject->toggleHeaderVisible();

    QVERIFY(m_subject->headerVisible() == false);

    m_subject->toggleHeaderVisible();

    QVERIFY(m_subject->headerVisible() == true);
}

void Ut_MContainer::toggleProgressIndicatorVisible()
{
    // default state
    QVERIFY(m_subject->isProgressIndicatorVisible() == false);

    m_subject->toggleProgressIndicatorVisible();

    QVERIFY(m_subject->isProgressIndicatorVisible() == true);

    m_subject->toggleProgressIndicatorVisible();

    QVERIFY(m_subject->isProgressIndicatorVisible() == false);
}

void Ut_MContainer::testCreatingViewImmediatelyInLayout()
{
    //Add the container to a layout then force the view to be created by calling minimumSize()
    QGraphicsLinearLayout layout(Qt::Horizontal);
    layout.addItem(m_subject);
    m_subject->minimumSize();

}
void Ut_MContainer::testCreatingViewImmediately()
{
    //Force the view to be created by calling minimumSize()
    //This checks BUG:126088 which causes a segmentation fault
    m_subject->minimumSize();
}

void Ut_MContainer::testCancelEvent()
{
    QSignalSpy spy(m_subject, SIGNAL(headerClicked()));

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
    m_subject->mousePressEvent(&mouseEvent);

    MCancelEvent event;
    m_subject->cancelEvent(&event);

    QVERIFY(spy.count() == 0);
}

// test all of the set/get with both visible and invisble header, because it should work for instance
// that one sets the e.g. iconID now and makes the header visible later

void Ut_MContainer::setTitleWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setTitle("title");

    QCOMPARE(m_subject->title(), QString("title"));
}

void Ut_MContainer::setTitleWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setTitle("title");

    QCOMPARE(m_subject->title(), QString("title"));
}

void Ut_MContainer::setIconIDWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setIconID("icon-m-framework-close");

    QCOMPARE(m_subject->iconID(), QString("icon-m-framework-close"));
}

void Ut_MContainer::setIconIDWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setIconID("icon-m-framework-close");

    QCOMPARE(m_subject->iconID(), QString("icon-m-framework-close"));
}

void Ut_MContainer::setTextWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setText("text");

    QCOMPARE(m_subject->text(), QString("text"));
}

void Ut_MContainer::setTextWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setText("text");

    QCOMPARE(m_subject->text(), QString("text"));
}

void Ut_MContainer::setProgressIndicatorVisible()
{
    m_subject->setProgressIndicatorVisible(true);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), true);
}

void Ut_MContainer::setProgressIndicatorInVisible()
{
    m_subject->setProgressIndicatorVisible(false);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), false);
}

void Ut_MContainer::setProgressIndicatorWithHeaderVisible()
{
    m_subject->setHeaderVisible(true);
    m_subject->setProgressIndicatorVisible(true);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), true);
}

void Ut_MContainer::setProgressIndicatorWithHeaderInvisible()
{
    m_subject->setHeaderVisible(false);
    m_subject->setProgressIndicatorVisible(true);
    QCOMPARE(m_subject->isProgressIndicatorVisible(), true);
}

QTEST_APPLESS_MAIN(Ut_MContainer)
<|endoftext|>