<commit_before>/*************************************************************************
 *
 *  $RCSfile: languageoptions.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 10:23:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX
#include "languageoptions.hxx"
#endif
#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include "cjkoptions.hxx"
#endif
#ifndef _SVTOOLS_CTLOPTIONS_HXX
#include "ctloptions.hxx"
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

// global ----------------------------------------------------------------------

static ::osl::Mutex aALMutex;

// class SvtLanguageOptions ----------------------------------------------------

SvtLanguageOptions::SvtLanguageOptions( sal_Bool _bDontLoad )
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aALMutex );

    m_pCJKOptions = new SvtCJKOptions( _bDontLoad );
    m_pCTLOptions = new SvtCTLOptions( _bDontLoad );
}
//------------------------------------------------------------------------------
SvtLanguageOptions::~SvtLanguageOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aALMutex );

    delete m_pCJKOptions;
    delete m_pCTLOptions;
}
//------------------------------------------------------------------------------
// CJK options -----------------------------------------------------------------
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCJKFontEnabled() const
{
    return m_pCJKOptions->IsCJKFontEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalTextEnabled() const
{
    return m_pCJKOptions->IsVerticalTextEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAsianTypographyEnabled() const
{
    return m_pCJKOptions->IsAsianTypographyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsJapaneseFindEnabled() const
{
    return m_pCJKOptions->IsJapaneseFindEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsRubyEnabled() const
{
    return m_pCJKOptions->IsRubyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsChangeCaseMapEnabled() const
{
    return m_pCJKOptions->IsChangeCaseMapEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsDoubleLinesEnabled() const
{
    return m_pCJKOptions->IsDoubleLinesEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsEmphasisMarksEnabled() const
{
    return m_pCJKOptions->IsEmphasisMarksEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalCallOutEnabled() const
{
    return m_pCJKOptions->IsVerticalCallOutEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetAll( sal_Bool _bSet )
{
    m_pCJKOptions->SetAll( _bSet );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAnyEnabled() const
{
    return m_pCJKOptions->IsAnyEnabled();
}
//------------------------------------------------------------------------------
// CTL options -----------------------------------------------------------------
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLFontEnabled( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLFontEnabled() const
{
    return m_pCTLOptions->IsCTLFontEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLSequenceChecking( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLSequenceChecking() const
{
    return m_pCTLOptions->IsCTLSequenceChecking();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsReadOnly(SvtLanguageOptions::EOption eOption) const
{
    sal_Bool bReadOnly = sal_False;
    switch(eOption)
    {
        // cjk options
        case SvtLanguageOptions::E_CJKFONT          : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CJKFONT        ); break;
        case SvtLanguageOptions::E_VERTICALTEXT     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALTEXT   ); break;
        case SvtLanguageOptions::E_ASIANTYPOGRAPHY  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ASIANTYPOGRAPHY); break;
        case SvtLanguageOptions::E_JAPANESEFIND     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_JAPANESEFIND   ); break;
        case SvtLanguageOptions::E_RUBY             : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_RUBY           ); break;
        case SvtLanguageOptions::E_CHANGECASEMAP    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CHANGECASEMAP  ); break;
        case SvtLanguageOptions::E_DOUBLELINES      : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_DOUBLELINES    ); break;
        case SvtLanguageOptions::E_EMPHASISMARKS    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_EMPHASISMARKS  ); break;
        case SvtLanguageOptions::E_VERTICALCALLOUT  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALCALLOUT); break;
        case SvtLanguageOptions::E_ALLCJK           : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ALL            ); break;
        // ctl options
        case SvtLanguageOptions::E_CTLFONT              : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLFONT            ); break;
        case SvtLanguageOptions::E_CTLSEQUENCECHECKING  : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLSEQUENCECHECKING); break;
        case SvtLanguageOptions::E_CTLCURSORMOVEMENT    : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLCURSORMOVEMENT  ); break;
        case SvtLanguageOptions::E_CTLTEXTNUMERALS      : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLTEXTNUMERALS    ); break;
    }
    return bReadOnly;
}
// -----------------------------------------------------------------------------
// returns for a language the scripttype
sal_uInt16 SvtLanguageOptions::GetScriptTypeOfLanguage( sal_uInt16 nLang )
{
    if( LANGUAGE_DONTKNOW == nLang )
        nLang = LANGUAGE_ENGLISH_US;
    else if( LANGUAGE_SYSTEM == nLang  )
        nLang = Application::GetSettings().GetLanguage();

    USHORT nScript;
    switch( nLang )
    {
        // CJK
        case LANGUAGE_CHINESE:
        case LANGUAGE_CHINESE_TRADITIONAL:
        case LANGUAGE_CHINESE_SIMPLIFIED:
        case LANGUAGE_CHINESE_HONGKONG:
        case LANGUAGE_CHINESE_SINGAPORE:
        case LANGUAGE_CHINESE_MACAU:
        case LANGUAGE_JAPANESE:
        case LANGUAGE_KOREAN:
        case LANGUAGE_KOREAN_JOHAB:
            nScript = SCRIPTTYPE_ASIAN;
            break;

        // CTL
        case LANGUAGE_ARABIC:
        case LANGUAGE_ARABIC_SAUDI_ARABIA:
        case LANGUAGE_ARABIC_IRAQ:
        case LANGUAGE_ARABIC_EGYPT:
        case LANGUAGE_ARABIC_LIBYA:
        case LANGUAGE_ARABIC_ALGERIA:
        case LANGUAGE_ARABIC_MOROCCO:
        case LANGUAGE_ARABIC_TUNISIA:
        case LANGUAGE_ARABIC_OMAN:
        case LANGUAGE_ARABIC_YEMEN:
        case LANGUAGE_ARABIC_SYRIA:
        case LANGUAGE_ARABIC_JORDAN:
        case LANGUAGE_ARABIC_LEBANON:
        case LANGUAGE_ARABIC_KUWAIT:
        case LANGUAGE_ARABIC_UAE:
        case LANGUAGE_ARABIC_BAHRAIN:
        case LANGUAGE_ARABIC_QATAR:
        case LANGUAGE_HEBREW:
        case LANGUAGE_MARATHI:
        case LANGUAGE_PUNJABI:
        case LANGUAGE_GUJARATI:
        case LANGUAGE_HINDI:
        case LANGUAGE_KANNADA:
        case LANGUAGE_TAMIL:
        case LANGUAGE_TELUGU:
        case LANGUAGE_THAI:
        case LANGUAGE_URDU:
        case LANGUAGE_URDU_PAKISTAN:
        case LANGUAGE_URDU_INDIA:
        case LANGUAGE_VIETNAMESE: // not included in langtab.src?
            nScript = SCRIPTTYPE_COMPLEX;
            break;

// currently not knowing scripttype - defaultet to LATIN:
/*
#define LANGUAGE_AFRIKAANS                  0x0436
#define LANGUAGE_ARMENIAN                   0x042B
#define LANGUAGE_ASSAMESE                   0x044D
#define LANGUAGE_AZERI                      0x002C
#define LANGUAGE_AZERI_LATIN                0x042C
#define LANGUAGE_AZERI_CYRILLIC             0x082C
#define LANGUAGE_BASQUE                     0x042D
#define LANGUAGE_BELARUSIAN                 0x0423
#define LANGUAGE_BENGALI                    0x0445
#define LANGUAGE_INDONESIAN                 0x0421
#define LANGUAGE_KASHMIRI                   0x0460
#define LANGUAGE_KASHMIRI_INDIA             0x0860
#define LANGUAGE_KAZAK                      0x043F
#define LANGUAGE_KONKANI                    0x0457
#define LANGUAGE_LATVIAN                    0x0426
#define LANGUAGE_LITHUANIAN                 0x0427
#define LANGUAGE_LITHUANIAN_CLASSIC         0x0827
#define LANGUAGE_MACEDONIAN                 0x042F
#define LANGUAGE_MALAY                      0x003E
#define LANGUAGE_MALAY_MALAYSIA             0x043E
#define LANGUAGE_MALAY_BRUNEI_DARUSSALAM    0x083E
#define LANGUAGE_MALAYALAM                  0x044C
#define LANGUAGE_MANIPURI                   0x0458
#define LANGUAGE_NEPALI                     0x0461
#define LANGUAGE_NEPALI_INDIA               0x0861
#define LANGUAGE_ORIYA                      0x0448
#define LANGUAGE_SANSKRIT                   0x044F
#define LANGUAGE_SERBIAN                    0x041A
#define LANGUAGE_SERBIAN_LATIN              0x081A
#define LANGUAGE_SERBIAN_CYRILLIC           0x0C1A
#define LANGUAGE_SINDHI                     0x0459
#define LANGUAGE_SWAHILI                    0x5041
#define LANGUAGE_TATAR                      0x0444
#define LANGUAGE_TURKISH                    0x041F
#define LANGUAGE_UKRAINIAN                  0x0422
#define LANGUAGE_UZBEK                      0x0043
#define LANGUAGE_UZBEK_LATIN                0x0443
#define LANGUAGE_UZBEK_CYRILLIC             0x0843
*/

    default:
        nScript = SCRIPTTYPE_LATIN;
        break;
    }
    return nScript;
}
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS os9 (1.3.34); FILE MERGED 2003/05/07 12:04:18 os 1.3.34.2: RESYNC: (1.3-1.4); FILE MERGED 2003/04/30 12:51:24 os 1.3.34.1: #109029# notification of CTL configuration changes implemented<commit_after>/*************************************************************************
 *
 *  $RCSfile: languageoptions.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2003-05-22 09:03:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX
#include "languageoptions.hxx"
#endif
#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include <cjkoptions.hxx>
#endif
#ifndef _SVTOOLS_CTLOPTIONS_HXX
#include <ctloptions.hxx>
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

// global ----------------------------------------------------------------------

static ::osl::Mutex aALMutex;

// class SvtLanguageOptions ----------------------------------------------------

SvtLanguageOptions::SvtLanguageOptions( sal_Bool _bDontLoad )
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aALMutex );

    m_pCJKOptions = new SvtCJKOptions( _bDontLoad );
    m_pCTLOptions = new SvtCTLOptions( _bDontLoad );
    StartListening(*m_pCTLOptions);
}
//------------------------------------------------------------------------------
SvtLanguageOptions::~SvtLanguageOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( aALMutex );

    delete m_pCJKOptions;
    delete m_pCTLOptions;
}
//------------------------------------------------------------------------------
// CJK options -----------------------------------------------------------------
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCJKFontEnabled() const
{
    return m_pCJKOptions->IsCJKFontEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalTextEnabled() const
{
    return m_pCJKOptions->IsVerticalTextEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAsianTypographyEnabled() const
{
    return m_pCJKOptions->IsAsianTypographyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsJapaneseFindEnabled() const
{
    return m_pCJKOptions->IsJapaneseFindEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsRubyEnabled() const
{
    return m_pCJKOptions->IsRubyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsChangeCaseMapEnabled() const
{
    return m_pCJKOptions->IsChangeCaseMapEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsDoubleLinesEnabled() const
{
    return m_pCJKOptions->IsDoubleLinesEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsEmphasisMarksEnabled() const
{
    return m_pCJKOptions->IsEmphasisMarksEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalCallOutEnabled() const
{
    return m_pCJKOptions->IsVerticalCallOutEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetAll( sal_Bool _bSet )
{
    m_pCJKOptions->SetAll( _bSet );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAnyEnabled() const
{
    return m_pCJKOptions->IsAnyEnabled();
}
//------------------------------------------------------------------------------
// CTL options -----------------------------------------------------------------
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLFontEnabled( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLFontEnabled() const
{
    return m_pCTLOptions->IsCTLFontEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLSequenceChecking( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLSequenceChecking() const
{
    return m_pCTLOptions->IsCTLSequenceChecking();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsReadOnly(SvtLanguageOptions::EOption eOption) const
{
    sal_Bool bReadOnly = sal_False;
    switch(eOption)
    {
        // cjk options
        case SvtLanguageOptions::E_CJKFONT          : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CJKFONT        ); break;
        case SvtLanguageOptions::E_VERTICALTEXT     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALTEXT   ); break;
        case SvtLanguageOptions::E_ASIANTYPOGRAPHY  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ASIANTYPOGRAPHY); break;
        case SvtLanguageOptions::E_JAPANESEFIND     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_JAPANESEFIND   ); break;
        case SvtLanguageOptions::E_RUBY             : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_RUBY           ); break;
        case SvtLanguageOptions::E_CHANGECASEMAP    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CHANGECASEMAP  ); break;
        case SvtLanguageOptions::E_DOUBLELINES      : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_DOUBLELINES    ); break;
        case SvtLanguageOptions::E_EMPHASISMARKS    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_EMPHASISMARKS  ); break;
        case SvtLanguageOptions::E_VERTICALCALLOUT  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALCALLOUT); break;
        case SvtLanguageOptions::E_ALLCJK           : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ALL            ); break;
        // ctl options
        case SvtLanguageOptions::E_CTLFONT              : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLFONT            ); break;
        case SvtLanguageOptions::E_CTLSEQUENCECHECKING  : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLSEQUENCECHECKING); break;
        case SvtLanguageOptions::E_CTLCURSORMOVEMENT    : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLCURSORMOVEMENT  ); break;
        case SvtLanguageOptions::E_CTLTEXTNUMERALS      : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLTEXTNUMERALS    ); break;
    }
    return bReadOnly;
}
/* -----------------30.04.2003 11:03-----------------

 --------------------------------------------------*/
void SvtLanguageOptions::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    vos::OGuard aVclGuard( Application::GetSolarMutex() );
    Broadcast( rHint );
}

// -----------------------------------------------------------------------------
// returns for a language the scripttype
sal_uInt16 SvtLanguageOptions::GetScriptTypeOfLanguage( sal_uInt16 nLang )
{
    if( LANGUAGE_DONTKNOW == nLang )
        nLang = LANGUAGE_ENGLISH_US;
    else if( LANGUAGE_SYSTEM == nLang  )
        nLang = Application::GetSettings().GetLanguage();

    USHORT nScript;
    switch( nLang )
    {
        // CJK
        case LANGUAGE_CHINESE:
        case LANGUAGE_CHINESE_TRADITIONAL:
        case LANGUAGE_CHINESE_SIMPLIFIED:
        case LANGUAGE_CHINESE_HONGKONG:
        case LANGUAGE_CHINESE_SINGAPORE:
        case LANGUAGE_CHINESE_MACAU:
        case LANGUAGE_JAPANESE:
        case LANGUAGE_KOREAN:
        case LANGUAGE_KOREAN_JOHAB:
            nScript = SCRIPTTYPE_ASIAN;
            break;

        // CTL
        case LANGUAGE_ARABIC:
        case LANGUAGE_ARABIC_SAUDI_ARABIA:
        case LANGUAGE_ARABIC_IRAQ:
        case LANGUAGE_ARABIC_EGYPT:
        case LANGUAGE_ARABIC_LIBYA:
        case LANGUAGE_ARABIC_ALGERIA:
        case LANGUAGE_ARABIC_MOROCCO:
        case LANGUAGE_ARABIC_TUNISIA:
        case LANGUAGE_ARABIC_OMAN:
        case LANGUAGE_ARABIC_YEMEN:
        case LANGUAGE_ARABIC_SYRIA:
        case LANGUAGE_ARABIC_JORDAN:
        case LANGUAGE_ARABIC_LEBANON:
        case LANGUAGE_ARABIC_KUWAIT:
        case LANGUAGE_ARABIC_UAE:
        case LANGUAGE_ARABIC_BAHRAIN:
        case LANGUAGE_ARABIC_QATAR:
        case LANGUAGE_HEBREW:
        case LANGUAGE_MARATHI:
        case LANGUAGE_PUNJABI:
        case LANGUAGE_GUJARATI:
        case LANGUAGE_HINDI:
        case LANGUAGE_KANNADA:
        case LANGUAGE_TAMIL:
        case LANGUAGE_TELUGU:
        case LANGUAGE_THAI:
        case LANGUAGE_URDU:
        case LANGUAGE_URDU_PAKISTAN:
        case LANGUAGE_URDU_INDIA:
        case LANGUAGE_VIETNAMESE: // not included in langtab.src?
            nScript = SCRIPTTYPE_COMPLEX;
            break;

// currently not knowing scripttype - defaultet to LATIN:
/*
#define LANGUAGE_AFRIKAANS                  0x0436
#define LANGUAGE_ARMENIAN                   0x042B
#define LANGUAGE_ASSAMESE                   0x044D
#define LANGUAGE_AZERI                      0x002C
#define LANGUAGE_AZERI_LATIN                0x042C
#define LANGUAGE_AZERI_CYRILLIC             0x082C
#define LANGUAGE_BASQUE                     0x042D
#define LANGUAGE_BELARUSIAN                 0x0423
#define LANGUAGE_BENGALI                    0x0445
#define LANGUAGE_INDONESIAN                 0x0421
#define LANGUAGE_KASHMIRI                   0x0460
#define LANGUAGE_KASHMIRI_INDIA             0x0860
#define LANGUAGE_KAZAK                      0x043F
#define LANGUAGE_KONKANI                    0x0457
#define LANGUAGE_LATVIAN                    0x0426
#define LANGUAGE_LITHUANIAN                 0x0427
#define LANGUAGE_LITHUANIAN_CLASSIC         0x0827
#define LANGUAGE_MACEDONIAN                 0x042F
#define LANGUAGE_MALAY                      0x003E
#define LANGUAGE_MALAY_MALAYSIA             0x043E
#define LANGUAGE_MALAY_BRUNEI_DARUSSALAM    0x083E
#define LANGUAGE_MALAYALAM                  0x044C
#define LANGUAGE_MANIPURI                   0x0458
#define LANGUAGE_NEPALI                     0x0461
#define LANGUAGE_NEPALI_INDIA               0x0861
#define LANGUAGE_ORIYA                      0x0448
#define LANGUAGE_SANSKRIT                   0x044F
#define LANGUAGE_SERBIAN                    0x041A
#define LANGUAGE_SERBIAN_LATIN              0x081A
#define LANGUAGE_SERBIAN_CYRILLIC           0x0C1A
#define LANGUAGE_SINDHI                     0x0459
#define LANGUAGE_SWAHILI                    0x5041
#define LANGUAGE_TATAR                      0x0444
#define LANGUAGE_TURKISH                    0x041F
#define LANGUAGE_UKRAINIAN                  0x0422
#define LANGUAGE_UZBEK                      0x0043
#define LANGUAGE_UZBEK_LATIN                0x0443
#define LANGUAGE_UZBEK_CYRILLIC             0x0843
*/

    default:
        nScript = SCRIPTTYPE_LATIN;
        break;
    }
    return nScript;
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <cstring>

#include "helper.h"  // NOLINT(build/include)
#include "tiffio.h"  // NOLINT(build/include)

using ::sapi::IsOk;
using ::testing::Eq;
using ::testing::IsFalse;
using ::testing::IsTrue;
using ::testing::NotNull;

namespace {

struct ChannelLimits {
  uint8_t min_red;
  uint8_t max_red;
  uint8_t min_green;
  uint8_t max_green;
  uint8_t min_blue;
  uint8_t max_blue;
  uint8_t min_alpha;
  uint8_t max_alpha;
};

constexpr uint32_t kRawTileNumber = 9;
constexpr uint32_t kClusterSize = 6;
constexpr uint32_t kChannelsInPixel = 3;
constexpr uint32_t kTestCount = 3;
constexpr uint32_t kImageSize = 128 * 128;
constexpr uint32_t kClusterImageSize = 64 * 64;
using ClusterData = std::array<uint8_t, kClusterSize>;

constexpr std::array<std::pair<uint32_t, ClusterData>, kTestCount> kClusters = {
    {{0, {0, 0, 2, 0, 138, 139}},
     {64, {0, 0, 9, 6, 134, 119}},
     {128, {44, 40, 63, 59, 230, 95}}}};

constexpr std::array<std::pair<uint32_t, ChannelLimits>, kTestCount> kLimits = {
    {{0, {15, 18, 0, 0, 18, 41, 255, 255}},
     {64, {0, 0, 0, 0, 0, 2, 255, 255}},
     {512, {5, 6, 34, 36, 182, 196, 255, 255}}}};

bool CheckCluster(uint32_t cluster, const sapi::v::Array<uint8_t>& buffer,
                  const ClusterData& expected_cluster) {
  bool is_overrun = (buffer.GetSize() <= cluster * kClusterSize);
  EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";

  if (is_overrun) {
    return true;
  }

  auto* target = buffer.GetData() + cluster * kClusterSize;
  bool comp =
      !(std::memcmp(target, expected_cluster.data(), kClusterSize) == 0);

  // the image is split on 6-bit clusters because it has YCbCr color format
  EXPECT_THAT(comp, IsFalse())
      << "Cluster " << cluster << " did not match expected results.\n"
      << "Expect: " << expected_cluster[0] << "\t" << expected_cluster[1]
      << "\t" << expected_cluster[2] << "\t" << expected_cluster[3] << "\t"
      << expected_cluster[4] << "\t" << expected_cluster[5] << "\n"
      << "Got: " << target[0] << "\t" << target[1] << "\t" << target[2] << "\t"
      << target[3] << "\t" << target[4] << "\t" << target[5];

  return comp;
}

bool CheckRgbPixel(uint32_t pixel, const ChannelLimits& limits,
                   const sapi::v::Array<uint8_t>& buffer) {
  bool is_overrun = (buffer.GetSize() <= pixel * kChannelsInPixel);
  EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";

  if (is_overrun) {
    return true;
  }

  auto* rgb = buffer.GetData() + pixel * kChannelsInPixel;
  bool comp = !(rgb[0] >= limits.min_red && rgb[0] <= limits.max_red &&
                rgb[1] >= limits.min_green && rgb[1] <= limits.max_green &&
                rgb[2] >= limits.min_blue && rgb[2] <= limits.max_blue);

  EXPECT_THAT(comp, IsFalse())
      << "Pixel " << pixel << " did not match expected results.\n"
      << "Got R=" << rgb[0] << " (expected " << limits.min_red
      << "..=" << limits.max_red << "), G=" << rgb[1] << " (expected "
      << limits.min_green << "..=" << limits.max_green << "), B=" << rgb[2]
      << " (expected " << limits.min_blue << "..=" << limits.max_blue << ")";
  return comp;
}

bool CheckRgbaPixel(uint32_t pixel, const ChannelLimits& limits,
                    const sapi::v::Array<uint32_t>& buffer) {
  // RGBA images are upside down - adjust for normal ordering
  uint32_t adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128;

  bool is_overrun = (buffer.GetSize() <= adjusted_pixel);
  EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";

  if (is_overrun) {
    return true;
  }

  auto rgba = buffer[adjusted_pixel];
  bool comp = !(TIFFGetR(rgba) >= static_cast<unsigned>(limits.min_red) &&
                TIFFGetR(rgba) <= static_cast<unsigned>(limits.max_red) &&
                TIFFGetG(rgba) >= static_cast<unsigned>(limits.min_green) &&
                TIFFGetG(rgba) <= static_cast<unsigned>(limits.max_green) &&
                TIFFGetB(rgba) >= static_cast<unsigned>(limits.min_blue) &&
                TIFFGetB(rgba) <= static_cast<unsigned>(limits.max_blue) &&
                TIFFGetA(rgba) >= static_cast<unsigned>(limits.min_alpha) &&
                TIFFGetA(rgba) <= static_cast<unsigned>(limits.max_alpha));

  EXPECT_THAT(comp, IsFalse())
      << "Pixel " << pixel << " did not match expected results.\n"
      << "Got R=" << TIFFGetR(rgba) << " (expected " << limits.min_red
      << "..=" << limits.max_red << "), G=" << TIFFGetG(rgba) << " (expected "
      << limits.min_green << "..=" << limits.max_green
      << "), B=" << TIFFGetB(rgba) << " (expected " << limits.min_blue
      << "..=" << limits.max_blue << "), A=" << TIFFGetA(rgba) << " (expected "
      << limits.min_alpha << "..=" << limits.max_alpha << ")";
  return comp;
}

TEST(SandboxTest, RawDecode) {
  tsize_t sz;
  bool pixel_status = false;
  bool cluster_status = false;
  std::string srcfile = GetFilePath("quad-tile.jpg.tiff");

  TiffSapiSandbox sandbox(srcfile);
  ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";

  sapi::v::UShort h;
  sapi::v::UShort v;
  absl::StatusOr<TIFF*> status_or_tif;
  absl::StatusOr<int> status_or_int;
  absl::StatusOr<tmsize_t> status_or_long;

  TiffApi api(&sandbox);
  sapi::v::ConstCStr srcfile_var(srcfile.c_str());
  sapi::v::ConstCStr r_var("r");

  status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore());
  ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile;

  sapi::v::RemotePtr tif(status_or_tif.value());
  ASSERT_THAT(tif.GetValue(), NotNull())
      << "Could not open " << srcfile << ", TIFFOpen return NULL";

  status_or_int = api.TIFFGetField2(&tif, TIFFTAG_YCBCRSUBSAMPLING, h.PtrBoth(),
                                    v.PtrBoth());
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField2 fatal error";
  EXPECT_THAT(
      status_or_int.value() == 0 || h.GetValue() != 2 || v.GetValue() != 2,
      IsFalse())
      << "Could not retrieve subsampling tag";

  status_or_long = api.TIFFTileSize(&tif);
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFTileSize fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(kClusterImageSize * kClusterSize))
      << "Unexpected TileSize " << status_or_long.value() << ". Expected "
      << kClusterImageSize * kClusterSize << " bytes\n";
  sz = status_or_long.value();

  sapi::v::Array<uint8_t> buffer_(sz);
  // Read a tile in decompressed form, but still YCbCr subsampled
  status_or_long =
      api.TIFFReadEncodedTile(&tif, kRawTileNumber, buffer_.PtrBoth(), sz);
  ASSERT_THAT(status_or_long, IsOk()) << "TIFFReadEncodedTile fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(sz))
      << "Did not get expected result code from TIFFReadEncodedTile()("
      << (int)status_or_long.value() << " instead of " << (int)sz << ")";

  for (const auto& [id, data] : kClusters) {
    cluster_status |= CheckCluster(id, buffer_, data);
  }
  ASSERT_FALSE(cluster_status) << "Clusters did not match expected results";

  status_or_int =
      api.TIFFSetFieldU1(&tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
  EXPECT_THAT(status_or_int.value(), IsTrue())
      << "The JPEGCOLORMODE tag cannot be changed";

  status_or_long = api.TIFFTileSize(&tif);
  ASSERT_THAT(status_or_long, IsOk()) << "TIFFTileSize fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(kImageSize * kChannelsInPixel))
      << "Unexpected TileSize " << status_or_long.value() << ". Expected "
      << kImageSize * kChannelsInPixel << " bytes\n";
  sz = status_or_long.value();

  sapi::v::Array<uint8_t> buffer2_(sz);
  status_or_long =
      api.TIFFReadEncodedTile(&tif, kRawTileNumber, buffer2_.PtrBoth(), sz);
  ASSERT_THAT(status_or_long, IsOk()) << "TIFFReadEncodedTile fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(sz))
      << "Did not get expected result code from TIFFReadEncodedTile()("
      << status_or_long.value() << " instead of " << sz;

  for (const auto& [id, data] : kLimits) {
    pixel_status |= CheckRgbPixel(id, data, buffer2_);
  }

  ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error";

  status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore());
  ASSERT_THAT(status_or_tif, IsOk()) << "TIFFOpen fatal error";

  sapi::v::RemotePtr tif2(status_or_tif.value());
  ASSERT_THAT(tif2.GetValue(), NotNull())
      << "Could not open " << srcfile << ", TIFFOpen return NULL";

  sapi::v::Array<uint32_t> rgba_buffer_(kImageSize);

  status_or_int =
      api.TIFFReadRGBATile(&tif2, 1 * 128, 2 * 128, rgba_buffer_.PtrBoth());
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFReadRGBATile fatal error";
  EXPECT_THAT(status_or_int.value(), IsTrue())
      << "TIFFReadRGBATile() returned failure code";

  for (const auto& [id, data] : kLimits) {
    pixel_status |= CheckRgbaPixel(id, data, rgba_buffer_);
  }

  EXPECT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error";
  EXPECT_THAT(pixel_status, IsFalse()) << "wrong encoding";
}

}  // namespace
<commit_msg>move using to namespace<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <cstring>

#include "helper.h"  // NOLINT(build/include)
#include "tiffio.h"  // NOLINT(build/include)

namespace {

using ::sapi::IsOk;
using ::testing::Eq;
using ::testing::IsFalse;
using ::testing::IsTrue;
using ::testing::NotNull;

struct ChannelLimits {
  uint8_t min_red;
  uint8_t max_red;
  uint8_t min_green;
  uint8_t max_green;
  uint8_t min_blue;
  uint8_t max_blue;
  uint8_t min_alpha;
  uint8_t max_alpha;
};

constexpr uint32_t kRawTileNumber = 9;
constexpr uint32_t kClusterSize = 6;
constexpr uint32_t kChannelsInPixel = 3;
constexpr uint32_t kTestCount = 3;
constexpr uint32_t kImageSize = 128 * 128;
constexpr uint32_t kClusterImageSize = 64 * 64;
using ClusterData = std::array<uint8_t, kClusterSize>;

constexpr std::array<std::pair<uint32_t, ClusterData>, kTestCount> kClusters = {
    {{0, {0, 0, 2, 0, 138, 139}},
     {64, {0, 0, 9, 6, 134, 119}},
     {128, {44, 40, 63, 59, 230, 95}}}};

constexpr std::array<std::pair<uint32_t, ChannelLimits>, kTestCount> kLimits = {
    {{0, {15, 18, 0, 0, 18, 41, 255, 255}},
     {64, {0, 0, 0, 0, 0, 2, 255, 255}},
     {512, {5, 6, 34, 36, 182, 196, 255, 255}}}};

bool CheckCluster(uint32_t cluster, const sapi::v::Array<uint8_t>& buffer,
                  const ClusterData& expected_cluster) {
  bool is_overrun = (buffer.GetSize() <= cluster * kClusterSize);
  EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";

  if (is_overrun) {
    return true;
  }

  auto* target = buffer.GetData() + cluster * kClusterSize;
  bool comp =
      !(std::memcmp(target, expected_cluster.data(), kClusterSize) == 0);

  // the image is split on 6-bit clusters because it has YCbCr color format
  EXPECT_THAT(comp, IsFalse())
      << "Cluster " << cluster << " did not match expected results.\n"
      << "Expect: " << expected_cluster[0] << "\t" << expected_cluster[1]
      << "\t" << expected_cluster[2] << "\t" << expected_cluster[3] << "\t"
      << expected_cluster[4] << "\t" << expected_cluster[5] << "\n"
      << "Got: " << target[0] << "\t" << target[1] << "\t" << target[2] << "\t"
      << target[3] << "\t" << target[4] << "\t" << target[5];

  return comp;
}

bool CheckRgbPixel(uint32_t pixel, const ChannelLimits& limits,
                   const sapi::v::Array<uint8_t>& buffer) {
  bool is_overrun = (buffer.GetSize() <= pixel * kChannelsInPixel);
  EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";

  if (is_overrun) {
    return true;
  }

  auto* rgb = buffer.GetData() + pixel * kChannelsInPixel;
  bool comp = !(rgb[0] >= limits.min_red && rgb[0] <= limits.max_red &&
                rgb[1] >= limits.min_green && rgb[1] <= limits.max_green &&
                rgb[2] >= limits.min_blue && rgb[2] <= limits.max_blue);

  EXPECT_THAT(comp, IsFalse())
      << "Pixel " << pixel << " did not match expected results.\n"
      << "Got R=" << rgb[0] << " (expected " << limits.min_red
      << "..=" << limits.max_red << "), G=" << rgb[1] << " (expected "
      << limits.min_green << "..=" << limits.max_green << "), B=" << rgb[2]
      << " (expected " << limits.min_blue << "..=" << limits.max_blue << ")";
  return comp;
}

bool CheckRgbaPixel(uint32_t pixel, const ChannelLimits& limits,
                    const sapi::v::Array<uint32_t>& buffer) {
  // RGBA images are upside down - adjust for normal ordering
  uint32_t adjusted_pixel = pixel % 128 + (127 - (pixel / 128)) * 128;

  bool is_overrun = (buffer.GetSize() <= adjusted_pixel);
  EXPECT_THAT(is_overrun, IsFalse()) << "Overrun";

  if (is_overrun) {
    return true;
  }

  auto rgba = buffer[adjusted_pixel];
  bool comp = !(TIFFGetR(rgba) >= static_cast<unsigned>(limits.min_red) &&
                TIFFGetR(rgba) <= static_cast<unsigned>(limits.max_red) &&
                TIFFGetG(rgba) >= static_cast<unsigned>(limits.min_green) &&
                TIFFGetG(rgba) <= static_cast<unsigned>(limits.max_green) &&
                TIFFGetB(rgba) >= static_cast<unsigned>(limits.min_blue) &&
                TIFFGetB(rgba) <= static_cast<unsigned>(limits.max_blue) &&
                TIFFGetA(rgba) >= static_cast<unsigned>(limits.min_alpha) &&
                TIFFGetA(rgba) <= static_cast<unsigned>(limits.max_alpha));

  EXPECT_THAT(comp, IsFalse())
      << "Pixel " << pixel << " did not match expected results.\n"
      << "Got R=" << TIFFGetR(rgba) << " (expected " << limits.min_red
      << "..=" << limits.max_red << "), G=" << TIFFGetG(rgba) << " (expected "
      << limits.min_green << "..=" << limits.max_green
      << "), B=" << TIFFGetB(rgba) << " (expected " << limits.min_blue
      << "..=" << limits.max_blue << "), A=" << TIFFGetA(rgba) << " (expected "
      << limits.min_alpha << "..=" << limits.max_alpha << ")";
  return comp;
}

TEST(SandboxTest, RawDecode) {
  tsize_t sz;
  bool pixel_status = false;
  bool cluster_status = false;
  std::string srcfile = GetFilePath("quad-tile.jpg.tiff");

  TiffSapiSandbox sandbox(srcfile);
  ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";

  sapi::v::UShort h;
  sapi::v::UShort v;
  absl::StatusOr<TIFF*> status_or_tif;
  absl::StatusOr<int> status_or_int;
  absl::StatusOr<tmsize_t> status_or_long;

  TiffApi api(&sandbox);
  sapi::v::ConstCStr srcfile_var(srcfile.c_str());
  sapi::v::ConstCStr r_var("r");

  status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore());
  ASSERT_THAT(status_or_tif, IsOk()) << "Could not open " << srcfile;

  sapi::v::RemotePtr tif(status_or_tif.value());
  ASSERT_THAT(tif.GetValue(), NotNull())
      << "Could not open " << srcfile << ", TIFFOpen return NULL";

  status_or_int = api.TIFFGetField2(&tif, TIFFTAG_YCBCRSUBSAMPLING, h.PtrBoth(),
                                    v.PtrBoth());
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFGetField2 fatal error";
  EXPECT_THAT(
      status_or_int.value() == 0 || h.GetValue() != 2 || v.GetValue() != 2,
      IsFalse())
      << "Could not retrieve subsampling tag";

  status_or_long = api.TIFFTileSize(&tif);
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFTileSize fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(kClusterImageSize * kClusterSize))
      << "Unexpected TileSize " << status_or_long.value() << ". Expected "
      << kClusterImageSize * kClusterSize << " bytes\n";
  sz = status_or_long.value();

  sapi::v::Array<uint8_t> buffer_(sz);
  // Read a tile in decompressed form, but still YCbCr subsampled
  status_or_long =
      api.TIFFReadEncodedTile(&tif, kRawTileNumber, buffer_.PtrBoth(), sz);
  ASSERT_THAT(status_or_long, IsOk()) << "TIFFReadEncodedTile fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(sz))
      << "Did not get expected result code from TIFFReadEncodedTile()("
      << (int)status_or_long.value() << " instead of " << (int)sz << ")";

  for (const auto& [id, data] : kClusters) {
    cluster_status |= CheckCluster(id, buffer_, data);
  }
  ASSERT_FALSE(cluster_status) << "Clusters did not match expected results";

  status_or_int =
      api.TIFFSetFieldU1(&tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFSetFieldU1 fatal error";
  EXPECT_THAT(status_or_int.value(), IsTrue())
      << "The JPEGCOLORMODE tag cannot be changed";

  status_or_long = api.TIFFTileSize(&tif);
  ASSERT_THAT(status_or_long, IsOk()) << "TIFFTileSize fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(kImageSize * kChannelsInPixel))
      << "Unexpected TileSize " << status_or_long.value() << ". Expected "
      << kImageSize * kChannelsInPixel << " bytes\n";
  sz = status_or_long.value();

  sapi::v::Array<uint8_t> buffer2_(sz);
  status_or_long =
      api.TIFFReadEncodedTile(&tif, kRawTileNumber, buffer2_.PtrBoth(), sz);
  ASSERT_THAT(status_or_long, IsOk()) << "TIFFReadEncodedTile fatal error";
  EXPECT_THAT(status_or_long.value(), Eq(sz))
      << "Did not get expected result code from TIFFReadEncodedTile()("
      << status_or_long.value() << " instead of " << sz;

  for (const auto& [id, data] : kLimits) {
    pixel_status |= CheckRgbPixel(id, data, buffer2_);
  }

  ASSERT_THAT(api.TIFFClose(&tif), IsOk()) << "TIFFClose fatal error";

  status_or_tif = api.TIFFOpen(srcfile_var.PtrBefore(), r_var.PtrBefore());
  ASSERT_THAT(status_or_tif, IsOk()) << "TIFFOpen fatal error";

  sapi::v::RemotePtr tif2(status_or_tif.value());
  ASSERT_THAT(tif2.GetValue(), NotNull())
      << "Could not open " << srcfile << ", TIFFOpen return NULL";

  sapi::v::Array<uint32_t> rgba_buffer_(kImageSize);

  status_or_int =
      api.TIFFReadRGBATile(&tif2, 1 * 128, 2 * 128, rgba_buffer_.PtrBoth());
  ASSERT_THAT(status_or_int, IsOk()) << "TIFFReadRGBATile fatal error";
  EXPECT_THAT(status_or_int.value(), IsTrue())
      << "TIFFReadRGBATile() returned failure code";

  for (const auto& [id, data] : kLimits) {
    pixel_status |= CheckRgbaPixel(id, data, rgba_buffer_);
  }

  EXPECT_THAT(api.TIFFClose(&tif2), IsOk()) << "TIFFClose fatal error";
  EXPECT_THAT(pixel_status, IsFalse()) << "wrong encoding";
}

}  // namespace
<|endoftext|>


<commit_before>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.com>
 *  Copyright (C) 2018  Serge Bazanski <q3k@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "treemodel.h"
#include "log.h"

NEXTPNR_NAMESPACE_BEGIN

namespace TreeModel {

// converts 'aa123bb432' -> ['aa', '123', 'bb', '432']
std::vector<QString> IdStringList::alphaNumSplit(const QString &str)
{
    std::vector<QString> res;
    QString current_part;

    bool number = true;
    for (const auto c : str) {
        if (current_part.size() == 0 && res.size() == 0) {
            current_part.push_back(c);
            number = c.isNumber();
            continue;
        }

        if (number != c.isNumber()) {
            number = c.isNumber();
            res.push_back(current_part);
            current_part.clear();
        }

        current_part.push_back(c);
    }

    res.push_back(current_part);

    return res;
}

void IdStringList::updateElements(Context *ctx, std::vector<IdString> elements)
{
    bool changed = false;

    // For any elements that are not yet in managed_, created them.
    std::unordered_set<IdString> element_set;
    for (auto elem : elements) {
        element_set.insert(elem);
        auto existing = managed_.find(elem);
        if (existing == managed_.end()) {
            auto item = new IdStringItem(ctx, elem, this, child_type_);
            managed_.emplace(elem, std::unique_ptr<IdStringItem>(item));
            changed = true;
        }
    }

    // For any elements that are in managed_ but not in new, delete them.
    auto it = managed_.begin();
    while (it != managed_.end()) {
        if (element_set.count(it->first) != 0) {
            ++it;
        } else {
            it = managed_.erase(it);
            changed = true;
        }
    }

    // Return early if there are no changes.
    if (!changed)
        return;

    // Rebuild children list.
    children_.clear();
    for (auto &pair : managed_) {
        if (element_set.count(pair.first) != 0) {
            children_.push_back(pair.second.get());
        }
    }

    // Sort new children
    std::sort(children_.begin(), children_.end(), [&](const Item *a, const Item *b) {
        auto parts_a = alphaNumSplit(a->name());
        auto parts_b = alphaNumSplit(b->name());

        // Short-circuit for different part count.
        if (parts_a.size() != parts_b.size()) {
            return parts_a.size() < parts_b.size();
        }

        for (size_t i = 0; i < parts_a.size(); i++) {
            auto &part_a = parts_a.at(i);
            auto &part_b = parts_b.at(i);

            bool a_is_number, b_is_number;
            int a_number = part_a.toInt(&a_is_number);
            int b_number = part_b.toInt(&b_is_number);

            // If both parts are numbers, compare numerically.
            // If they're equal, continue to next part.
            if (a_is_number && b_is_number) {
                if (a_number != b_number) {
                    return a_number < b_number;
                } else {
                    continue;
                }
            }

            // For different alpha/nonalpha types, make numeric parts appear
            // first.
            if (a_is_number != b_is_number) {
                return a_is_number;
            }

            // If both parts are numbers, compare lexically.
            // If they're equal, continue to next part.
            if (part_a == part_b) {
                continue;
            }
            return part_a < part_b;
        }

        // Same string.
        return false;
    });
}

void IdStringList::search(QList<Item *> &results, QString text, int limit)
{
    for (const auto &child : children_) {
        if (limit != -1 && results.size() > limit)
            return;

        if (child->name().contains(text))
            results.push_back(child);
    }
}

Model::Model(QObject *parent) : QAbstractItemModel(parent), root_(new Item("Elements", nullptr)) {}

Model::~Model() {}

void Model::loadData(Context *ctx, std::unique_ptr<Item> data)
{
    beginResetModel();
    ctx_ = ctx;
    root_ = std::move(data);
    endResetModel();
}

void Model::updateElements(std::vector<IdString> elements)
{
    if (!ctx_)
        return;

    beginResetModel();
    root_->updateElements(ctx_, elements);
    endResetModel();
}

int Model::rowCount(const QModelIndex &parent) const { return nodeFromIndex(parent)->count(); }

int Model::columnCount(const QModelIndex &parent) const { return 1; }

QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
    Item *node = nodeFromIndex(parent);
    if (row >= node->count())
        return QModelIndex();

    return createIndex(row, column, node->child(row));
}

QModelIndex Model::parent(const QModelIndex &child) const
{
    Item *parent = nodeFromIndex(child)->parent();
    if (parent == root_.get())
        return QModelIndex();
    Item *node = parent->parent();
    return createIndex(node->indexOf(parent), 0, parent);
}

QVariant Model::data(const QModelIndex &index, int role) const
{
    if (index.column() != 0)
        return QVariant();
    if (role != Qt::DisplayRole)
        return QVariant();
    Item *node = nodeFromIndex(index);
    return node->name();
}

QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_UNUSED(section);
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return QString("Items");

    return QVariant();
}

Item *Model::nodeFromIndex(const QModelIndex &idx) const
{
    if (idx.isValid())
        return (Item *)idx.internalPointer();
    return root_.get();
}

Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
    Item *node = nodeFromIndex(index);
    return Qt::ItemIsEnabled | (node->type() != ElementType::NONE ? Qt::ItemIsSelectable : Qt::NoItemFlags);
}

void Model::fetchMore(const QModelIndex &parent)
{
    if (ctx_ == nullptr)
        return;

    std::lock_guard<std::mutex> lock_ui(ctx_->ui_mutex);
    std::lock_guard<std::mutex> lock(ctx_->mutex);

    nodeFromIndex(parent)->fetchMore();
}

bool Model::canFetchMore(const QModelIndex &parent) const { return nodeFromIndex(parent)->canFetchMore(); }

QList<QModelIndex> Model::search(QString text)
{
    const int limit = 500;
    QList<Item *> list;
    root_->search(list, text, limit);

    QList<QModelIndex> res;
    for (auto i : list) {
        res.push_back(indexFromNode(i));
    }
    return res;
}

}; // namespace TreeModel

NEXTPNR_NAMESPACE_END
<commit_msg>gui: Fix sorting order in TreeModel.<commit_after>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.com>
 *  Copyright (C) 2018  Serge Bazanski <q3k@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "treemodel.h"
#include "log.h"

NEXTPNR_NAMESPACE_BEGIN

namespace TreeModel {

// converts 'aa123bb432' -> ['aa', '123', 'bb', '432']
std::vector<QString> IdStringList::alphaNumSplit(const QString &str)
{
    std::vector<QString> res;
    QString current_part;

    bool number = true;
    for (const auto c : str) {
        if (current_part.size() == 0 && res.size() == 0) {
            current_part.push_back(c);
            number = c.isNumber();
            continue;
        }

        if (number != c.isNumber()) {
            number = c.isNumber();
            res.push_back(current_part);
            current_part.clear();
        }

        current_part.push_back(c);
    }

    res.push_back(current_part);

    return res;
}

void IdStringList::updateElements(Context *ctx, std::vector<IdString> elements)
{
    bool changed = false;

    // For any elements that are not yet in managed_, created them.
    std::unordered_set<IdString> element_set;
    for (auto elem : elements) {
        element_set.insert(elem);
        auto existing = managed_.find(elem);
        if (existing == managed_.end()) {
            auto item = new IdStringItem(ctx, elem, this, child_type_);
            managed_.emplace(elem, std::unique_ptr<IdStringItem>(item));
            changed = true;
        }
    }

    // For any elements that are in managed_ but not in new, delete them.
    auto it = managed_.begin();
    while (it != managed_.end()) {
        if (element_set.count(it->first) != 0) {
            ++it;
        } else {
            it = managed_.erase(it);
            changed = true;
        }
    }

    // Return early if there are no changes.
    if (!changed)
        return;

    // Rebuild children list.
    children_.clear();
    for (auto &pair : managed_) {
        if (element_set.count(pair.first) != 0) {
            children_.push_back(pair.second.get());
        }
    }

    // Sort new children
    std::sort(children_.begin(), children_.end(), [&](const Item *a, const Item *b) {
        auto parts_a = alphaNumSplit(a->name());
        auto parts_b = alphaNumSplit(b->name());

        for (size_t i = 0; i < parts_a.size() && i < parts_b.size(); i++) {
            auto &part_a = parts_a.at(i);
            auto &part_b = parts_b.at(i);

            bool a_is_number, b_is_number;
            int a_number = part_a.toInt(&a_is_number);
            int b_number = part_b.toInt(&b_is_number);

            // If both parts are numbers, compare numerically.
            // If they're equal, continue to next part.
            if (a_is_number && b_is_number) {
                if (a_number != b_number) {
                    return a_number < b_number;
                } else {
                    continue;
                }
            }

            // For different alpha/nonalpha types, make numeric parts appear
            // first.
            if (a_is_number != b_is_number) {
                return a_is_number;
            }

            // If both parts are numbers, compare lexically.
            // If they're equal, continue to next part.
            if (part_a == part_b) {
                continue;
            }
            return part_a < part_b;
        }

        // One string is equal to or a subset of the other, compare length.
        return parts_a.size() < parts_b.size();
    });
}

void IdStringList::search(QList<Item *> &results, QString text, int limit)
{
    for (const auto &child : children_) {
        if (limit != -1 && results.size() > limit)
            return;

        if (child->name().contains(text))
            results.push_back(child);
    }
}

Model::Model(QObject *parent) : QAbstractItemModel(parent), root_(new Item("Elements", nullptr)) {}

Model::~Model() {}

void Model::loadData(Context *ctx, std::unique_ptr<Item> data)
{
    beginResetModel();
    ctx_ = ctx;
    root_ = std::move(data);
    endResetModel();
}

void Model::updateElements(std::vector<IdString> elements)
{
    if (!ctx_)
        return;

    beginResetModel();
    root_->updateElements(ctx_, elements);
    endResetModel();
}

int Model::rowCount(const QModelIndex &parent) const { return nodeFromIndex(parent)->count(); }

int Model::columnCount(const QModelIndex &parent) const { return 1; }

QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
    Item *node = nodeFromIndex(parent);
    if (row >= node->count())
        return QModelIndex();

    return createIndex(row, column, node->child(row));
}

QModelIndex Model::parent(const QModelIndex &child) const
{
    Item *parent = nodeFromIndex(child)->parent();
    if (parent == root_.get())
        return QModelIndex();
    Item *node = parent->parent();
    return createIndex(node->indexOf(parent), 0, parent);
}

QVariant Model::data(const QModelIndex &index, int role) const
{
    if (index.column() != 0)
        return QVariant();
    if (role != Qt::DisplayRole)
        return QVariant();
    Item *node = nodeFromIndex(index);
    return node->name();
}

QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_UNUSED(section);
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return QString("Items");

    return QVariant();
}

Item *Model::nodeFromIndex(const QModelIndex &idx) const
{
    if (idx.isValid())
        return (Item *)idx.internalPointer();
    return root_.get();
}

Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
    Item *node = nodeFromIndex(index);
    return Qt::ItemIsEnabled | (node->type() != ElementType::NONE ? Qt::ItemIsSelectable : Qt::NoItemFlags);
}

void Model::fetchMore(const QModelIndex &parent)
{
    if (ctx_ == nullptr)
        return;

    std::lock_guard<std::mutex> lock_ui(ctx_->ui_mutex);
    std::lock_guard<std::mutex> lock(ctx_->mutex);

    nodeFromIndex(parent)->fetchMore();
}

bool Model::canFetchMore(const QModelIndex &parent) const { return nodeFromIndex(parent)->canFetchMore(); }

QList<QModelIndex> Model::search(QString text)
{
    const int limit = 500;
    QList<Item *> list;
    root_->search(list, text, limit);

    QList<QModelIndex> res;
    for (auto i : list) {
        res.push_back(indexFromNode(i));
    }
    return res;
}

}; // namespace TreeModel

NEXTPNR_NAMESPACE_END
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: optHeaderTabListbox.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 04:29:04 $
 *
 *  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_svx.hxx"

#ifdef SVX_DLLIMPLEMENTATION
#undef SVX_DLLIMPLEMENTATION
#endif

#ifndef SVX_OPTHEADERTABLISTBOX_HXX
#include "optHeaderTabListbox.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _HEADBAR_HXX
#include <svtools/headbar.hxx>
#endif

namespace svx
{
// class OptLBoxString_Impl ----------------------------------------------

class OptLBoxString_Impl : public SvLBoxString
{
public:
    OptLBoxString_Impl( SvLBoxEntry* pEntry, USHORT nFlags, const String& rTxt ) :
        SvLBoxString( pEntry, nFlags, rTxt ) {}

    virtual void Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags, SvLBoxEntry* pEntry );
};

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

void OptLBoxString_Impl::Paint( const Point& rPos, SvLBox& rDev, USHORT, SvLBoxEntry* pEntry )
{
    Font aOldFont( rDev.GetFont() );
    Font aFont( aOldFont );
    //detect readonly state by asking for a valid Image
    if(pEntry && !(!((OptHeaderTabListBox&)rDev).GetCollapsedEntryBmp(pEntry)))
        aFont.SetColor( Application::GetSettings().GetStyleSettings().GetDeactiveTextColor() );
    rDev.SetFont( aFont );
    rDev.DrawText( rPos, GetText() );
    rDev.SetFont( aOldFont );
}
// -----------------------------------------------------------------------------

OptHeaderTabListBox::OptHeaderTabListBox( Window* pParent, WinBits nWinStyle ) :

    SvHeaderTabListBox( pParent, nWinStyle )
{
}

// -----------------------------------------------------------------------
void OptHeaderTabListBox::InitEntry( SvLBoxEntry* pEntry, const XubString& rTxt,
                                     const Image& rImg1, const Image& rImg2 )
{
    SvTabListBox::InitEntry( pEntry, rTxt, rImg1, rImg2 );
    USHORT _nTabCount = TabCount();

    for ( USHORT nCol = 1; nCol < _nTabCount; ++nCol )
    {
        // alle Spalten mit eigener Klasse initialisieren (Spalte 0 == Bitmap)
        SvLBoxString* pCol = (SvLBoxString*)pEntry->GetItem( nCol );
        OptLBoxString_Impl* pStr = new OptLBoxString_Impl( pEntry, 0, pCol->GetText() );
        pEntry->ReplaceItem( pStr, nCol );
    }
}

} // namespace svx
<commit_msg>INTEGRATION: CWS jl49 (1.7.148); FILE MERGED 2006/11/30 13:45:54 sb 1.7.148.1: #i70481# Extended SvLBoxButton.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: optHeaderTabListbox.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ihi $ $Date: 2006-12-20 14:11:45 $
 *
 *  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_svx.hxx"

#ifdef SVX_DLLIMPLEMENTATION
#undef SVX_DLLIMPLEMENTATION
#endif

#ifndef SVX_OPTHEADERTABLISTBOX_HXX
#include "optHeaderTabListbox.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _HEADBAR_HXX
#include <svtools/headbar.hxx>
#endif

namespace svx
{
// class OptLBoxString_Impl ----------------------------------------------

class OptLBoxString_Impl : public SvLBoxString
{
public:
    OptLBoxString_Impl( SvLBoxEntry* pEntry, USHORT nFlags, const String& rTxt ) :
        SvLBoxString( pEntry, nFlags, rTxt ) {}

    virtual void Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags, SvLBoxEntry* pEntry );
};

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

void OptLBoxString_Impl::Paint( const Point& rPos, SvLBox& rDev, USHORT, SvLBoxEntry* pEntry )
{
    Font aOldFont( rDev.GetFont() );
    Font aFont( aOldFont );
    //detect readonly state by asking for a valid Image
    if(pEntry && !(!((OptHeaderTabListBox&)rDev).GetCollapsedEntryBmp(pEntry)))
        aFont.SetColor( Application::GetSettings().GetStyleSettings().GetDeactiveTextColor() );
    rDev.SetFont( aFont );
    rDev.DrawText( rPos, GetText() );
    rDev.SetFont( aOldFont );
}
// -----------------------------------------------------------------------------

OptHeaderTabListBox::OptHeaderTabListBox( Window* pParent, WinBits nWinStyle ) :

    SvHeaderTabListBox( pParent, nWinStyle )
{
}

// -----------------------------------------------------------------------
void OptHeaderTabListBox::InitEntry( SvLBoxEntry* pEntry, const XubString& rTxt,
                                     const Image& rImg1, const Image& rImg2,
                                     SvLBoxButtonKind eButtonKind )
{
    SvTabListBox::InitEntry( pEntry, rTxt, rImg1, rImg2, eButtonKind );
    USHORT _nTabCount = TabCount();

    for ( USHORT nCol = 1; nCol < _nTabCount; ++nCol )
    {
        // alle Spalten mit eigener Klasse initialisieren (Spalte 0 == Bitmap)
        SvLBoxString* pCol = (SvLBoxString*)pEntry->GetItem( nCol );
        OptLBoxString_Impl* pStr = new OptLBoxString_Impl( pEntry, 0, pCol->GetText() );
        pEntry->ReplaceItem( pStr, nCol );
    }
}

} // namespace svx
<|endoftext|>


<commit_before>#include "sshworker.h"
#include "sshclient.h"
#include <QEventLoop>

SshWorker::SshWorker(QObject *parent, bool detached) : QThread(parent)
{
    _prepared = false;
    if(detached)
    {
        _contype = Qt::BlockingQueuedConnection;
        QEventLoop wait;
        QObject::connect(this, &SshWorker::threadReady, &wait, &QEventLoop::quit);
        start();
        wait.exec();
    }
    else
    {
        _contype = Qt::DirectConnection;
        _client = new SshClient();
        QObject::connect(_client, &SshClient::xfer_rate,                   this,    &SshWorker::xferRate);
        QObject::connect(_client, &SshClient::sFtpXfer,                    this,    &SshWorker::sFtpXfer);
        emit threadReady();
    }
}

SshWorker::~SshWorker()
{
    if(_contype == Qt::BlockingQueuedConnection)
    {
        QEventLoop wait;
        QObject::connect(this, &SshWorker::finished, &wait, &QEventLoop::quit);
        emit askQuit();
        wait.exec();
    }
}

bool SshWorker::getSshConnected() const
{
    bool ret;
    QMetaObject::invokeMethod( _client, "getSshConnected", _contype, Q_RETURN_ARG(bool, ret));
    return ret;
}

void SshWorker::setKeys(const QString &publicKey, const QString &privateKey)
{
    QMetaObject::invokeMethod( _client, "setKeys", _contype, Q_ARG( const QString, publicKey ), Q_ARG( const QString, privateKey ) );
}

bool SshWorker::loadKnownHosts(const QString &file)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "loadKnownHosts", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( const QString, file ) );
    return ret;
}

int SshWorker::connectToHost(const QString &username, const QString &hostname, quint16 port, bool lock, bool checkHostKey, unsigned int retry)
{
    int ret;
    QMetaObject::invokeMethod( _client, "connectToHost", _contype, Q_RETURN_ARG(int, ret), Q_ARG(QString, username), Q_ARG(QString, hostname), Q_ARG(quint16, port), Q_ARG(bool, lock), Q_ARG(bool, checkHostKey), Q_ARG(unsigned int, retry) );
    return ret;
}

void SshWorker::prepareConnectToHost(const QString &username, const QString &hostname, quint16 port, bool lock, bool checkHostKey, unsigned int retry)
{
    _username = username;
    _hostname = hostname;
    _port = port;
    _lock = lock;
    _checkHostKey = checkHostKey;
    _retry = retry;
    _prepared = true;
}

int SshWorker::connectToHost()
{
    if(_prepared) return connectToHost(_username, _hostname, _port, _lock, _checkHostKey, _retry);
    else return -1;
}

void SshWorker::disconnectFromHost()
{
    QMetaObject::invokeMethod( _client, "disconnectFromHost", _contype);
}

QString SshWorker::runCommand(QString command)
{
    QString ret;
    QMetaObject::invokeMethod( _client, "runCommand", _contype, Q_RETURN_ARG(QString, ret), Q_ARG( QString, command ) );
    return ret;
}

quint16 SshWorker::openLocalPortForwarding(QString servicename, quint16 port, quint16 bind)
{
    quint16 ret;
    QMetaObject::invokeMethod( _client, "openLocalPortForwarding", _contype, Q_RETURN_ARG(quint16, ret), Q_ARG( QString, servicename ), Q_ARG( quint16, port ), Q_ARG( quint16, bind ) );
    return ret;
}

quint16 SshWorker::openRemotePortForwarding(QString servicename, quint16 port)
{
    quint16 ret;
    QMetaObject::invokeMethod( _client, "openRemotePortForwarding", _contype, Q_RETURN_ARG(quint16, ret), Q_ARG( QString, servicename ), Q_ARG( quint16, port ) );
    return ret;
}

void SshWorker::closePortForwarding(QString servicename)
{
    QMetaObject::invokeMethod( _client, "closePortForwarding", _contype, Q_ARG( QString, servicename ) );
}

QString SshWorker::sendFile(QString src, QString dst)
{
    QString ret;
    QMetaObject::invokeMethod( _client, "sendFile", _contype, Q_RETURN_ARG(QString, ret), Q_ARG( QString, src ), Q_ARG( QString, dst ) );
    return ret;
}

void SshWorker::setPassphrase(const QString &pass)
{
    QMetaObject::invokeMethod( _client, "setPassphrase", _contype, Q_ARG( QString, pass ) );
}

bool SshWorker::saveKnownHosts(const QString &file)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "saveKnownHosts", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, file ) );
    return ret;
}

bool SshWorker::addKnownHost(const QString &hostname, const SshKey &key)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "addKnownHost", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, hostname ), Q_ARG( SshKey, key ) );
    return ret;
}

void SshWorker::enableSFTP()
{
    QMetaObject::invokeMethod( _client, "enableSFTP", _contype );
}

QString SshWorker::send(QString source, QString dest)
{
    QString ret;
    QMetaObject::invokeMethod( _client, "send", _contype, Q_RETURN_ARG(QString, ret), Q_ARG( QString, source ), Q_ARG( QString, dest ) );
    return ret;
}

bool SshWorker::get(QString source, QString dest, bool override)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "get", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, source ), Q_ARG( QString, dest ), Q_ARG( bool, override ) );
    return ret;
}

int SshWorker::mkdir(QString dest)
{
    int ret;
    QMetaObject::invokeMethod( _client, "mkdir", _contype,  Q_RETURN_ARG(int, ret), Q_ARG( QString, dest ) );
    return ret;
}

QStringList SshWorker::readdir(QString d)
{
    QStringList ret;
    QMetaObject::invokeMethod( _client, "readdir", _contype, Q_RETURN_ARG(QStringList, ret), Q_ARG( QString, d ) );
    return ret;
}

bool SshWorker::isDir(QString d)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "isDir", _contype,  Q_RETURN_ARG(bool, ret), Q_ARG( QString, d ) );
    return ret;
}

bool SshWorker::isFile(QString d)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "isFile", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, d ) );
    return ret;
}

int SshWorker::mkpath(QString dest)
{
    int ret;
    QMetaObject::invokeMethod( _client, "mkpath", _contype, Q_RETURN_ARG(int, ret), Q_ARG( QString, dest ) );
    return ret;
}

bool SshWorker::unlink(QString d)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "unlink", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, d ) );
    return ret;
}

quint64 SshWorker::filesize(QString d)
{
    quint64 ret;
    QMetaObject::invokeMethod( _client, "filesize", Qt::QueuedConnection, Q_RETURN_ARG(quint64, ret), Q_ARG( QString, d ) );
    return ret;
}

void SshWorker::xferRate(qint64 tx, qint64 rx)
{
    emit xfer_rate(tx, rx);
}

void SshWorker::run()
{
    connect(this, &SshWorker::askQuit, this, &SshWorker::quit, Qt::QueuedConnection);
    _client = new SshClient();
    QObject::connect(_client, &SshClient::xfer_rate,                   this,    &SshWorker::xferRate);
    QObject::connect(_client, &SshClient::sFtpXfer,                    this,    &SshWorker::sFtpXfer);

    emit threadReady();
    exec();

#if defined(DEBUG_SSHWORKER)
    qDebug() << "DEBUG : SshWorker thread terminated " << " in Thread " << QThread::currentThread();
#endif
}
<commit_msg>Add a way to disable MultiThread (I saw some bug with Windows, no problems with iOS Android Linux)<commit_after>#include "sshworker.h"
#include "sshclient.h"
#include <QEventLoop>

SshWorker::SshWorker(QObject *parent, bool detached) : QThread(parent)
{
#if defined(DISABLE_MULTITHREAD_SSH_WORKER)
    detached = false;
#endif
    _prepared = false;
    if(detached)
    {
        _contype = Qt::BlockingQueuedConnection;
        QEventLoop wait;
        QObject::connect(this, &SshWorker::threadReady, &wait, &QEventLoop::quit);
        start();
        wait.exec();
    }
    else
    {
        _contype = Qt::DirectConnection;
        _client = new SshClient();
        QObject::connect(_client, &SshClient::xfer_rate,                   this,    &SshWorker::xferRate);
        QObject::connect(_client, &SshClient::sFtpXfer,                    this,    &SshWorker::sFtpXfer);
        emit threadReady();
    }
}

SshWorker::~SshWorker()
{
    if(_contype == Qt::BlockingQueuedConnection)
    {
        QEventLoop wait;
        QObject::connect(this, &SshWorker::finished, &wait, &QEventLoop::quit);
        emit askQuit();
        wait.exec();
    }
}

bool SshWorker::getSshConnected() const
{
    bool ret;
    QMetaObject::invokeMethod( _client, "getSshConnected", _contype, Q_RETURN_ARG(bool, ret));
    return ret;
}

void SshWorker::setKeys(const QString &publicKey, const QString &privateKey)
{
    QMetaObject::invokeMethod( _client, "setKeys", _contype, Q_ARG( const QString, publicKey ), Q_ARG( const QString, privateKey ) );
}

bool SshWorker::loadKnownHosts(const QString &file)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "loadKnownHosts", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( const QString, file ) );
    return ret;
}

int SshWorker::connectToHost(const QString &username, const QString &hostname, quint16 port, bool lock, bool checkHostKey, unsigned int retry)
{
    int ret;
    QMetaObject::invokeMethod( _client, "connectToHost", _contype, Q_RETURN_ARG(int, ret), Q_ARG(QString, username), Q_ARG(QString, hostname), Q_ARG(quint16, port), Q_ARG(bool, lock), Q_ARG(bool, checkHostKey), Q_ARG(unsigned int, retry) );
    return ret;
}

void SshWorker::prepareConnectToHost(const QString &username, const QString &hostname, quint16 port, bool lock, bool checkHostKey, unsigned int retry)
{
    _username = username;
    _hostname = hostname;
    _port = port;
    _lock = lock;
    _checkHostKey = checkHostKey;
    _retry = retry;
    _prepared = true;
}

int SshWorker::connectToHost()
{
    if(_prepared) return connectToHost(_username, _hostname, _port, _lock, _checkHostKey, _retry);
    else return -1;
}

void SshWorker::disconnectFromHost()
{
    QMetaObject::invokeMethod( _client, "disconnectFromHost", _contype);
}

QString SshWorker::runCommand(QString command)
{
    QString ret;
    QMetaObject::invokeMethod( _client, "runCommand", _contype, Q_RETURN_ARG(QString, ret), Q_ARG( QString, command ) );
    return ret;
}

quint16 SshWorker::openLocalPortForwarding(QString servicename, quint16 port, quint16 bind)
{
    quint16 ret;
    QMetaObject::invokeMethod( _client, "openLocalPortForwarding", _contype, Q_RETURN_ARG(quint16, ret), Q_ARG( QString, servicename ), Q_ARG( quint16, port ), Q_ARG( quint16, bind ) );
    return ret;
}

quint16 SshWorker::openRemotePortForwarding(QString servicename, quint16 port)
{
    quint16 ret;
    QMetaObject::invokeMethod( _client, "openRemotePortForwarding", _contype, Q_RETURN_ARG(quint16, ret), Q_ARG( QString, servicename ), Q_ARG( quint16, port ) );
    return ret;
}

void SshWorker::closePortForwarding(QString servicename)
{
    QMetaObject::invokeMethod( _client, "closePortForwarding", _contype, Q_ARG( QString, servicename ) );
}

QString SshWorker::sendFile(QString src, QString dst)
{
    QString ret;
    QMetaObject::invokeMethod( _client, "sendFile", _contype, Q_RETURN_ARG(QString, ret), Q_ARG( QString, src ), Q_ARG( QString, dst ) );
    return ret;
}

void SshWorker::setPassphrase(const QString &pass)
{
    QMetaObject::invokeMethod( _client, "setPassphrase", _contype, Q_ARG( QString, pass ) );
}

bool SshWorker::saveKnownHosts(const QString &file)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "saveKnownHosts", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, file ) );
    return ret;
}

bool SshWorker::addKnownHost(const QString &hostname, const SshKey &key)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "addKnownHost", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, hostname ), Q_ARG( SshKey, key ) );
    return ret;
}

void SshWorker::enableSFTP()
{
    QMetaObject::invokeMethod( _client, "enableSFTP", _contype );
}

QString SshWorker::send(QString source, QString dest)
{
    QString ret;
    QMetaObject::invokeMethod( _client, "send", _contype, Q_RETURN_ARG(QString, ret), Q_ARG( QString, source ), Q_ARG( QString, dest ) );
    return ret;
}

bool SshWorker::get(QString source, QString dest, bool override)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "get", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, source ), Q_ARG( QString, dest ), Q_ARG( bool, override ) );
    return ret;
}

int SshWorker::mkdir(QString dest)
{
    int ret;
    QMetaObject::invokeMethod( _client, "mkdir", _contype,  Q_RETURN_ARG(int, ret), Q_ARG( QString, dest ) );
    return ret;
}

QStringList SshWorker::readdir(QString d)
{
    QStringList ret;
    QMetaObject::invokeMethod( _client, "readdir", _contype, Q_RETURN_ARG(QStringList, ret), Q_ARG( QString, d ) );
    return ret;
}

bool SshWorker::isDir(QString d)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "isDir", _contype,  Q_RETURN_ARG(bool, ret), Q_ARG( QString, d ) );
    return ret;
}

bool SshWorker::isFile(QString d)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "isFile", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, d ) );
    return ret;
}

int SshWorker::mkpath(QString dest)
{
    int ret;
    QMetaObject::invokeMethod( _client, "mkpath", _contype, Q_RETURN_ARG(int, ret), Q_ARG( QString, dest ) );
    return ret;
}

bool SshWorker::unlink(QString d)
{
    bool ret;
    QMetaObject::invokeMethod( _client, "unlink", _contype, Q_RETURN_ARG(bool, ret), Q_ARG( QString, d ) );
    return ret;
}

quint64 SshWorker::filesize(QString d)
{
    quint64 ret;
    QMetaObject::invokeMethod( _client, "filesize", Qt::QueuedConnection, Q_RETURN_ARG(quint64, ret), Q_ARG( QString, d ) );
    return ret;
}

void SshWorker::xferRate(qint64 tx, qint64 rx)
{
    emit xfer_rate(tx, rx);
}

void SshWorker::run()
{
    connect(this, &SshWorker::askQuit, this, &SshWorker::quit, Qt::QueuedConnection);
    _client = new SshClient();
    QObject::connect(_client, &SshClient::xfer_rate,                   this,    &SshWorker::xferRate);
    QObject::connect(_client, &SshClient::sFtpXfer,                    this,    &SshWorker::sFtpXfer);

    emit threadReady();
    exec();

#if defined(DEBUG_SSHWORKER)
    qDebug() << "DEBUG : SshWorker thread terminated " << " in Thread " << QThread::currentThread();
#endif
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: test "x`uname -m|sed 's,i.86,i386,'`" = "xi386" || cat %s | %cling -Xclang -verify | FileCheck %s
// Not running on 32 bit due to aggregate return in getWithDtor(); see ROOT-5860

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/StoredValueRef.h"

cling::StoredValueRef V;
V // CHECK: (cling::StoredValueRef) <<<invalid>>> @0x{{.*}}

gCling->evaluate("return 1;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int) 1]

// Returns must put the result in the StoredValueRef.
bool cond = true;
gCling->evaluate("if (cond) return \"true\"; else return 0;", V);
V // CHECK: (cling::StoredValueRef) boxes [(const char [5]) "true"]
gCling->evaluate("cond = false; if (cond) return \"true\"; else return 0;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int) 0]

long LongV = 17;
gCling->evaluate("LongV;", V);
V // CHECK: (cling::StoredValueRef) boxes [(long) 17]

int* IntP = (int*)0x12;
gCling->evaluate("IntP;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

cling::StoredValueRef Result;
gCling->evaluate("V", Result);
// Here we check what happens for record type like cling::StoredValueRef; they are returned by reference.
Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef) boxes [(int *) 0x12]]
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

// Savannah #96277
gCling->evaluate("gCling->declare(\"double sin(double);\"); double one = sin(3.141/2);", V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]

gCling->process("double one = sin(3.141/2);", &V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]
one // CHECK: (double) 1.000
int one; // expected-error {{redefinition of 'one' with a different type: 'int' vs 'double'}} expected-note {{previous definition is here}}

// Make sure that PR#98434 doesn't get reintroduced.
.rawInput
void f(int) { return; }
.rawInput

gCling->evaluate("f", V);
V.isValid() //CHECK: {{\([_]B|b}}ool) true
// end PR#98434

// Check lifetime of objects in StoredValue
.rawInput 1
struct WithDtor {
   static int fgCount;
   WithDtor() { ++fgCount; }
   WithDtor(const WithDtor&) { ++fgCount; }
   ~WithDtor() { --fgCount; }
};
int WithDtor::fgCount = 0;
WithDtor getWithDtor() { return WithDtor(); }
#include <vector>
std::vector<WithDtor> getWithDtorVec() { std::vector<WithDtor> ret; ret.resize(7); return ret; }
.rawInput 0

cling::StoredValueRef* VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtor()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(WithDtor) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 1
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0

// Check destructor call for templates
VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtorVec()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(std::vector<WithDtor>) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 7
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0
<commit_msg>The test should be run on 32 bit finally.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling -Xclang -verify | FileCheck %s

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/StoredValueRef.h"

cling::StoredValueRef V;
V // CHECK: (cling::StoredValueRef) <<<invalid>>> @0x{{.*}}

gCling->evaluate("return 1;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int) 1]

// Returns must put the result in the StoredValueRef.
bool cond = true;
gCling->evaluate("if (cond) return \"true\"; else return 0;", V);
V // CHECK: (cling::StoredValueRef) boxes [(const char [5]) "true"]
gCling->evaluate("cond = false; if (cond) return \"true\"; else return 0;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int) 0]

long LongV = 17;
gCling->evaluate("LongV;", V);
V // CHECK: (cling::StoredValueRef) boxes [(long) 17]

int* IntP = (int*)0x12;
gCling->evaluate("IntP;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

cling::StoredValueRef Result;
gCling->evaluate("V", Result);
// Here we check what happens for record type like cling::StoredValueRef; they are returned by reference.
Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef) boxes [(int *) 0x12]]
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

// Savannah #96277
gCling->evaluate("gCling->declare(\"double sin(double);\"); double one = sin(3.141/2);", V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]

gCling->process("double one = sin(3.141/2);", &V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]
one // CHECK: (double) 1.000
int one; // expected-error {{redefinition of 'one' with a different type: 'int' vs 'double'}} expected-note {{previous definition is here}}

// Make sure that PR#98434 doesn't get reintroduced.
.rawInput
void f(int) { return; }
.rawInput

gCling->evaluate("f", V);
V.isValid() //CHECK: {{\([_]B|b}}ool) true
// end PR#98434

// Check lifetime of objects in StoredValue
.rawInput 1
struct WithDtor {
   static int fgCount;
   WithDtor() { ++fgCount; }
   WithDtor(const WithDtor&) { ++fgCount; }
   ~WithDtor() { --fgCount; }
};
int WithDtor::fgCount = 0;
WithDtor getWithDtor() { return WithDtor(); }
#include <vector>
std::vector<WithDtor> getWithDtorVec() { std::vector<WithDtor> ret; ret.resize(7); return ret; }
.rawInput 0

cling::StoredValueRef* VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtor()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(WithDtor) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 1
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0

// Check destructor call for templates
VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtorVec()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(std::vector<WithDtor>) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 7
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0
<|endoftext|>