<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/platform_thread.h"
#include "base/win_util.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "chrome_mini_installer.h"

namespace {
class MiniInstallTest : public testing::Test {
   protected:
    void CleanTheSystem() {
      ChromeMiniInstaller userinstall(mini_installer_constants::kUserInstall);
      userinstall.UnInstall();
      if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
        ChromeMiniInstaller systeminstall(
                            mini_installer_constants::kSystemInstall);
        systeminstall.UnInstall();
      }
    }
    virtual void SetUp() {
      CleanTheSystem();
    }

    virtual void TearDown() {
      PlatformThread::Sleep(2000);
      CleanTheSystem();
    }
  };
};

TEST_F(MiniInstallTest, FullInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallFullInstaller();
}

// Will enable this test after bug#9593 gets fixed.
TEST_F(MiniInstallTest, DISABLED_DifferentialInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallDifferentialInstaller();
}

TEST_F(MiniInstallTest, DISABLED_StandaloneInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallStandaloneIntaller();
}

TEST_F(MiniInstallTest, MiniInstallerOverChromeMetaInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.OverInstall();
}

TEST_F(MiniInstallTest, DISABLED_MiniInstallerSystemInstallTest) {
  if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
    ChromeMiniInstaller installer(mini_installer_constants::kSystemInstall);
    installer.Install();
  }
}

TEST_F(MiniInstallTest, MiniInstallerUserInstallTest) {
  if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
    ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
    installer.Install();
  }
}

TEST(InstallUtilTests, MiniInstallTestValidWindowsVersion) {
  // We run the tests on all supported OSes.
  // Make sure the code agrees.
  EXPECT_TRUE(InstallUtil::IsOSSupported());
}
<commit_msg>Disabling the test again. This time the test doesn't fail at mulitple places. It fails at only one place. investigating... Review URL: http://codereview.chromium.org/102003<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/platform_thread.h"
#include "base/win_util.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "chrome_mini_installer.h"

namespace {
class MiniInstallTest : public testing::Test {
   protected:
    void CleanTheSystem() {
      ChromeMiniInstaller userinstall(mini_installer_constants::kUserInstall);
      userinstall.UnInstall();
      if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
        ChromeMiniInstaller systeminstall(
                            mini_installer_constants::kSystemInstall);
        systeminstall.UnInstall();
      }
    }
    virtual void SetUp() {
      CleanTheSystem();
    }

    virtual void TearDown() {
      PlatformThread::Sleep(2000);
      CleanTheSystem();
    }
  };
};

TEST_F(MiniInstallTest, FullInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallFullInstaller();
}

// Will enable this test after bug#9593 gets fixed.
TEST_F(MiniInstallTest, DISABLED_DifferentialInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallDifferentialInstaller();
}

TEST_F(MiniInstallTest, DISABLED_StandaloneInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.InstallStandaloneIntaller();
}

TEST_F(MiniInstallTest, MiniInstallerOverChromeMetaInstallerTest) {
  ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
  installer.OverInstall();
}

TEST_F(MiniInstallTest, DISABLED_MiniInstallerSystemInstallTest) {
  if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
    ChromeMiniInstaller installer(mini_installer_constants::kSystemInstall);
    installer.Install();
  }
}

TEST_F(MiniInstallTest, DISABLED_MiniInstallerUserInstallTest) {
  if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
    ChromeMiniInstaller installer(mini_installer_constants::kUserInstall);
    installer.Install();
  }
}

TEST(InstallUtilTests, MiniInstallTestValidWindowsVersion) {
  // We run the tests on all supported OSes.
  // Make sure the code agrees.
  EXPECT_TRUE(InstallUtil::IsOSSupported());
}
<|endoftext|>


<commit_before>#ifndef INCLUDED_SROOK_DIGITS_VALUES
#define INCLUDED_SROOK_DIGITS_VALUES

#include<utility>
#include<memory>
#include<vector>
#include<cmath>
#include<algorithm>

#if __has_include(<boost/utility.hpp>)
#if __has_include(<boost/mpl/if.hpp>)
#include<boost/utility.hpp>
#include<boost/mpl/if.hpp>
using boost::noncopyable;
using boost::mpl::if_c;
#else
// self made boost noncopyable
namespace srook{
	class noncopyable{
	noncopyable(const noncopyable&)=delete;
	noncopyable& operator=(const noncopyable&)=delete;
protected:
	noncopyable()=default;
	~noncopyable()=default;
};

// self made boost.mpl.if_c
template<bool Condition,typename T1,typename T2>
struct if_c{
	using type=T2;
};
template<typename T1,typename T2>
struct if_c<true,T1,T2>{
	using type=T1;
};
} // namespace srook
using srook::noncopyable;
using srook::if_c;
#endif
#endif

namespace srook{
namespace srook_adl{ // protection from unintended ADL
inline namespace v1{

template<bool Condition,typename T1,typename T2>
using if_c_t=typename if_c<Condition,T1,T2>::type;

template<typename _Tp,class Not>
constexpr bool not_truely_type_v=!std::is_same<typename std::decay<_Tp>::type,Not>::value;

template<typename ResultType>
struct digits_values final:private noncopyable{
	using result_type=ResultType;

	digits_values()=default;

	template<class _Tp>
	using Check_t=typename std::enable_if<not_truely_type_v<_Tp,digits_values>&&
		!std::is_class<typename std::decay<_Tp>::type>::value&&
		not_truely_type_v<_Tp,float>&&
		not_truely_type_v<_Tp,double>>::type;

	template<class _Tp,class=Check_t<_Tp>>
	digits_values(_Tp x)
		:v(digit_calculation(x)?digit_calculation(x):1,digit_calculation(x)<=1?x:0)
	{
		const auto digit_=digit_calculation(x);
		if(!(digit_<=1)){
			auto ten_v=static_cast<std::size_t>(std::pow(10,digit_-1));
			for(std::size_t i=0; i<v.size(); ++i){
				v[i]=x/ten_v;
				x%=ten_v;
				ten_v/=10;
			}
		}
	}

	digits_values(digits_values&& oth)
	{
		v=std::move(oth.v);
	}

	digits_values& operator=(digits_values&&)=default;

	template<class _Tp,class=Check_t<_Tp>>
	digits_values& operator=(_Tp x)
	{
		auto digit_=digit_calculation(x);
		v.resize(digit_);
		if(!(digit_<=1)){
			auto ten_v=static_cast<std::size_t>(std::pow(10,digit_-1));
			for(std::size_t i=0; i<v.size(); ++i){
				v[i]=x/ten_v;
				x%=ten_v;
				ten_v/=10;
			}
		}
	}

	result_type operator[](const std::size_t& index)const
	{return v.at(index);}

	digits_values operator+(digits_values& oth)
	{
		const auto this_size=digit();
		const auto oth_size=oth.digit();
		const auto max_v=std::max(this_size,oth_size);

		digits_values result;
		result.v.reserve(max_v);
		std::copy(max_v==this_size?cbegin():oth.cbegin(),max_v==this_size?cend():oth.cend(),std::back_inserter(result.v));

		using bigger_type=
			if_c_t<
			sizeof(typename std::remove_reference<decltype(oth)>::type::result_type) < sizeof(result_type),
			result_type,
			typename std::remove_reference<decltype(oth)>::type::result_type
			>;

		if(max_v==this_size){
			std::size_t counter=0;
			for(auto& i:oth)
				result.v[counter++]+=i;
		}else{
			std::size_t counter=0;
			for(auto& i:v)
				result.v[counter++]+=i;
		}

		return result;
	}

	typename std::vector<result_type>::const_iterator cbegin()const{return v.cbegin();}
	typename std::vector<result_type>::const_iterator cend()const{return v.cend();}
	typename std::vector<result_type>::iterator begin(){return v.begin();}
	typename std::vector<result_type>::iterator end(){return v.end();}
	typename std::vector<result_type>::reverse_iterator rbegin(){return v.rbegin();}
	typename std::vector<result_type>::reverse_iterator rend(){return v.rend();}

	inline std::size_t digit()const{return v.size();}

	auto real_value()
	{
		auto digit_=digit();
		auto ten_v=static_cast<std::size_t>(std::pow(10,digit_-1));
		unsigned long long int result=0;

		for(std::size_t i=0; i<digit_; ++i){
			result+=v[i]*ten_v;
			ten_v/=10;
		}
		return result;
	}
private:
	std::size_t digit_calculation(unsigned long long int x)const
	{return std::log10(x)+1;}

	template<typename Pointed_type>
	std::size_t digit_calculation(Pointed_type x)const
	{
		std::size_t result=0;
		for(; x!=0; ++result)x/=10;
		return result;
	}

	std::vector<result_type> v;
};

} // inline namespace v1
} // namespace srook_adl

template<class _Tp=unsigned short int>
using digits_values=srook_adl::digits_values<_Tp>;

} // namespace srook
#endif // include guard
<commit_msg>small fix<commit_after>#ifndef INCLUDED_SROOK_DIGITS_VALUES
#define INCLUDED_SROOK_DIGITS_VALUES

#include<utility>
#include<memory>
#include<vector>
#include<cmath>
#include<algorithm>

#if __has_include(<boost/utility.hpp>)
#if __has_include(<boost/mpl/if.hpp>)
#include<boost/utility.hpp>
#include<boost/mpl/if.hpp>
using boost::noncopyable;
using boost::mpl::if_c;
#else
// self made boost noncopyable
namespace srook{
	class noncopyable{
	noncopyable(const noncopyable&)=delete;
	noncopyable& operator=(const noncopyable&)=delete;
protected:
	noncopyable()=default;
	~noncopyable()=default;
};

// self made boost.mpl.if_c
template<bool Condition,typename T1,typename T2>
struct if_c{
	using type=T2;
};
template<typename T1,typename T2>
struct if_c<true,T1,T2>{
	using type=T1;
};
} // namespace srook
using srook::noncopyable;
using srook::if_c;
#endif
#endif

namespace srook{
namespace srook_adl{ // protection from unintended ADL
inline namespace v1{

template<bool Condition,typename T1,typename T2>
using if_c_t=typename if_c<Condition,T1,T2>::type;

template<typename _Tp,class Not>
constexpr bool not_truely_type_v=!std::is_same<typename std::decay<_Tp>::type,Not>::value;

template<typename ResultType>
struct digits_values final:private noncopyable{
	using result_type=ResultType;

	digits_values()=default;

	template<class _Tp>
	using Check_t=typename std::enable_if<not_truely_type_v<_Tp,digits_values>&&
		!std::is_class<typename std::decay<_Tp>::type>::value&&
		not_truely_type_v<_Tp,float>&&
		not_truely_type_v<_Tp,double>>::type;

	template<class _Tp,class=Check_t<_Tp>>
	digits_values(_Tp x)
		:v(digit_calculation(x)?digit_calculation(x):1,digit_calculation(x)<=1?x:0)
	{
		const auto digit_=digit_calculation(x);
		if(!(digit_<=1)){
			auto ten_v=static_cast<std::size_t>(std::pow(10,digit_-1));
			for(std::size_t i=0; i<v.size(); ++i){
				v[i]=x/ten_v;
				x%=ten_v;
				ten_v/=10;
			}
		}
	}

	digits_values(digits_values&& oth)
	{
		v=std::move(oth.v);
	}

	digits_values& operator=(digits_values&&)=default;

	template<class _Tp,class=Check_t<_Tp>>
	digits_values& operator=(_Tp x)
	{
		auto digit_=digit_calculation(x);
		v.resize(digit_);
		if(!(digit_<=1)){
			auto ten_v=static_cast<std::size_t>(std::pow(10,digit_-1));
			for(std::size_t i=0; i<v.size(); ++i){
				v[i]=x/ten_v;
				x%=ten_v;
				ten_v/=10;
			}
		}
	}

	result_type operator[](const std::size_t& index)const
	{return v.at(index);}

	template<typename _ResultType>
	digits_values operator+(const digits_values<_ResultType>& oth)
	{
		const auto this_size=digit();
		const auto oth_size=oth.digit();
		const auto max_v=std::max(this_size,oth_size);

		using bigger_type=if_c_t<sizeof(_ResultType) < sizeof(result_type),result_type,_ResultType>;

		digits_values<bigger_type> result;
		result.v.reserve(max_v);

		if(max_v==this_size){
			std::copy(cbegin(),cend(),std::back_inserter(result.v));
			std::size_t counter=0;
			for(auto i=oth.cbegin(); i!=oth.cend(); ++i)result.v[counter++]+=*i;
		}else{
			std::copy(oth.cbegin(),oth.cend(),std::back_inserter(result.v));
			std::size_t counter=0;
			for(auto i=cbegin(); i!=cend(); ++i)result.v[counter++]+=*i;
		}

		return result;
	}

	template<typename _ResultType>
	digits_values diff(const digits_values<_ResultType>& oth)
	{}

	typename std::vector<result_type>::const_iterator cbegin()const{return v.cbegin();}
	typename std::vector<result_type>::const_iterator cend()const{return v.cend();}
	typename std::vector<result_type>::iterator begin(){return v.begin();}
	typename std::vector<result_type>::iterator end(){return v.end();}
	typename std::vector<result_type>::reverse_iterator rbegin(){return v.rbegin();}
	typename std::vector<result_type>::reverse_iterator rend(){return v.rend();}

	inline std::size_t digit()const{return v.size();}

	auto real_value()
	{
		auto digit_=digit();
		auto ten_v=static_cast<std::size_t>(std::pow(10,digit_-1));
		unsigned long long int result=0;

		for(std::size_t i=0; i<digit_; ++i){
			result+=v[i]*ten_v;
			ten_v/=10;
		}
		return result;
	}
private:
	std::size_t digit_calculation(unsigned long long int x)const
	{return std::log10(x)+1;}

	template<typename Pointed_type>
	std::size_t digit_calculation(Pointed_type x)const
	{
		std::size_t result=0;
		for(; x!=0; ++result)x/=10;
		return result;
	}

	std::vector<result_type> v;
};

} // inline namespace v1
} // namespace srook_adl

template<class _Tp=unsigned short int>
using digits_values=srook_adl::digits_values<_Tp>;

} // namespace srook
#endif // include guard
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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.
 *
 ************************************************************************/

 #ifndef MATHTYPE_HXX
#define MATHTYPE_HXX

#include "node.hxx"
#include "eqnolefilehdr.hxx"

#include <sot/storage.hxx>

#include <set>

class SfxMedium;

class MathTypeFont
{
public:
    sal_uInt8 nTface;
    sal_uInt8 nStyle;
    MathTypeFont() : nTface(0),nStyle(0) {}
    MathTypeFont(sal_uInt8 nFace) : nTface(nFace),nStyle(0) {}
    void AppendStyleToText(String &rS);
};

struct LessMathTypeFont
{
    sal_Bool operator() (const MathTypeFont &rValue1,
        const MathTypeFont &rValue2) const
    {
        return rValue1.nTface < rValue2.nTface;
    }
};

typedef ::std::set< MathTypeFont, LessMathTypeFont > MathTypeFontSet;

class MathType
{
public:
    MathType(String &rIn) :
        rRet(rIn), nHAlign(0), nVAlign(0), nDefaultSize(12),
        nLSize(0), nDSize(0), nCurSize(0), nLastSize(0), bIsSilent(sal_False)
    {
        Init();
    }

    MathType(String &rIn,SmNode *pIn) :
        rRet(rIn), pTree(pIn), nHAlign(2), nVAlign(0), nInsertion(0), nDefaultSize(12),
        nLSize(0), nDSize(0), nCurSize(0), nLastSize(0), nSpec(0), bIsSilent(sal_False)
    {
        Init();
    }

    int Parse( SotStorage* pStor );
    int ConvertFromStarMath( SfxMedium& rMedium );

private:
/*Ver 2 Header*/
    sal_uInt8 nVersion;
    sal_uInt8 nPlatform;
    sal_uInt8 nProduct;
    sal_uInt8 nProdVersion;
    sal_uInt8 nProdSubVersion;

    SvStorageStream *pS;

    void Init();

    int HandleRecords(int nLevel=0,sal_uInt8 nSelector=0xFF,
        sal_uInt8 nVariation=0xFF,int nRows=0,int nCols=0);
    sal_Bool HandleSize(sal_Int16 nLSize,sal_Int16 nDSize, int &rSetSize);
    void HandleAlign(sal_uInt8 nHAlign,sal_uInt8 nVAlign, int &rSetAlign);
    int HandlePile(int &rSetAlign,int nLevel,sal_uInt8 nSelector,
        sal_uInt8 nVariation);
    int HandleMatrix(int nLevel,sal_uInt8 nSelector,sal_uInt8 nVariarion);
    void HandleMatrixSeperator(int nMatrixRows,int nMatrixCols,int &rCurCol,
        int &rCurRow);
    int HandleTemplate(int nLevel,sal_uInt8 &rSelector,sal_uInt8 &rVariation,
        xub_StrLen &rLastTemplateBracket);
    void HandleEmblishments();
    void HandleSetSize();
    int HandleChar(xub_StrLen &rTextStart,int &rSetSize,int nLevel,
        sal_uInt8 nTag,sal_uInt8 nSelector,sal_uInt8 nVariation,
        sal_Bool bSilent);
    void HandleNudge();
    int xfLMOVE(sal_uInt8 nTest) const {return nTest&0x80;}
    int xfAUTO(sal_uInt8 nTest) const {return nTest&0x10;}
    int xfEMBELL(sal_uInt8 nTest) const {return nTest&0x20;}
    int xfNULL(sal_uInt8 nTest) const {return nTest&0x10;}
    int xfLSPACE(sal_uInt8 nTest) const {return nTest&0x40;}
    int xfRULER(sal_uInt8 nTest) const {return nTest&0x20;}

    sal_uInt8 HandleNodes(SmNode *pNode,int nLevel=0);
    int StartTemplate(sal_uInt16 nSelector,sal_uInt16 nVariation=0);
    void EndTemplate(int nOldPendingAttributes);
    void HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel);
    void HandleTable(SmNode *pNode,int nLevel);
    void HandleRoot(SmNode *pNode,int nLevel);
    void HandleSubSupScript(SmNode *pNode,int nLevel);
    sal_uInt8 HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel,
        sal_uLong *pPos=NULL,sal_Bool bTest=sal_True);
    void HandleFractions(SmNode *pNode,int nLevel);
    void HandleBrace(SmNode *pNode,int nLevel);
    void HandleVerticalBrace(SmNode *pNode,int nLevel);
    void HandleOperator(SmNode *pNode,int nLevel);
    sal_Bool HandleLim(SmNode *pNode,int nLevel);
    void HandleMAlign(SmNode *pNode,int nLevel);
    void HandleMath(SmNode *pNode,int nLevel);
    void HandleText(SmNode *pNode,int nLevel);
    void HandleAttributes(SmNode *pNode,int nLevel);
    void TypeFaceToString(String &rRet,sal_uInt8 nFace);

    String &rRet;
    SmNode *pTree;

    sal_uInt8 nHAlign;
    sal_uInt8 nVAlign;

    int nPendingAttributes;
    sal_uLong nInsertion;

    sal_Int16 aSizeTable[7];
    sal_Int16 nDefaultSize;
    sal_Int16 nLSize;
    sal_Int16 nDSize;
    sal_Int16 nCurSize;
    sal_Int16 nLastSize;
    sal_uInt8 nSpec;
    sal_Bool bIsSilent, bIsReInterpBrace;
    String sPost;
    xub_StrLen nPostSup;
    xub_StrLen nPostlSup;
    sal_uInt8 nTypeFace;
    MathTypeFontSet aUserStyles;

    enum MTOKENS {END,LINE,CHAR,TMPL,PILE,MATRIX,EMBEL,RULER,FONT,SIZE};
    enum MTEMPLATES
    {
        tmANGLE,tmPAREN,tmBRACE,tmBRACK,tmBAR,tmDBAR,tmFLOOR,tmCEILING,
        tmLBLB,tmRBRB,tmRBLB,tmLBRP,tmLPRB,tmROOT,tmFRACT,tmSCRIPT,tmUBAR,
        tmOBAR,tmLARROW,tmRARROW,tmBARROW,tmSINT,tmDINT,tmTINT,tmSSINT,
        tmDSINT,tmTSINT,tmUHBRACE,tmLHBRACE,tmSUM
    };
public:
    static sal_Bool LookupChar(sal_Unicode nChar,String &rRet,
        sal_uInt8 nVersion=3,sal_uInt8 nTypeFace=0);
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>valgrind: init nTypeFace<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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.
 *
 ************************************************************************/

 #ifndef MATHTYPE_HXX
#define MATHTYPE_HXX

#include "node.hxx"
#include "eqnolefilehdr.hxx"

#include <sot/storage.hxx>

#include <set>

class SfxMedium;

class MathTypeFont
{
public:
    sal_uInt8 nTface;
    sal_uInt8 nStyle;
    MathTypeFont() : nTface(0),nStyle(0) {}
    MathTypeFont(sal_uInt8 nFace) : nTface(nFace),nStyle(0) {}
    void AppendStyleToText(String &rS);
};

struct LessMathTypeFont
{
    sal_Bool operator() (const MathTypeFont &rValue1,
        const MathTypeFont &rValue2) const
    {
        return rValue1.nTface < rValue2.nTface;
    }
};

typedef ::std::set< MathTypeFont, LessMathTypeFont > MathTypeFontSet;

class MathType
{
public:
    MathType(String &rIn) :
        rRet(rIn), nHAlign(0), nVAlign(0), nDefaultSize(12),
        nLSize(0), nDSize(0), nCurSize(0), nLastSize(0), bIsSilent(sal_False),
        nTypeFace(0)
    {
        Init();
    }

    MathType(String &rIn,SmNode *pIn) :
        rRet(rIn), pTree(pIn), nHAlign(2), nVAlign(0), nInsertion(0), nDefaultSize(12),
        nLSize(0), nDSize(0), nCurSize(0), nLastSize(0), nSpec(0), bIsSilent(sal_False),
        nTypeFace(0)
    {
        Init();
    }

    int Parse( SotStorage* pStor );
    int ConvertFromStarMath( SfxMedium& rMedium );

private:
/*Ver 2 Header*/
    sal_uInt8 nVersion;
    sal_uInt8 nPlatform;
    sal_uInt8 nProduct;
    sal_uInt8 nProdVersion;
    sal_uInt8 nProdSubVersion;

    SvStorageStream *pS;

    void Init();

    int HandleRecords(int nLevel=0,sal_uInt8 nSelector=0xFF,
        sal_uInt8 nVariation=0xFF,int nRows=0,int nCols=0);
    sal_Bool HandleSize(sal_Int16 nLSize,sal_Int16 nDSize, int &rSetSize);
    void HandleAlign(sal_uInt8 nHAlign,sal_uInt8 nVAlign, int &rSetAlign);
    int HandlePile(int &rSetAlign,int nLevel,sal_uInt8 nSelector,
        sal_uInt8 nVariation);
    int HandleMatrix(int nLevel,sal_uInt8 nSelector,sal_uInt8 nVariarion);
    void HandleMatrixSeperator(int nMatrixRows,int nMatrixCols,int &rCurCol,
        int &rCurRow);
    int HandleTemplate(int nLevel,sal_uInt8 &rSelector,sal_uInt8 &rVariation,
        xub_StrLen &rLastTemplateBracket);
    void HandleEmblishments();
    void HandleSetSize();
    int HandleChar(xub_StrLen &rTextStart,int &rSetSize,int nLevel,
        sal_uInt8 nTag,sal_uInt8 nSelector,sal_uInt8 nVariation,
        sal_Bool bSilent);
    void HandleNudge();
    int xfLMOVE(sal_uInt8 nTest) const {return nTest&0x80;}
    int xfAUTO(sal_uInt8 nTest) const {return nTest&0x10;}
    int xfEMBELL(sal_uInt8 nTest) const {return nTest&0x20;}
    int xfNULL(sal_uInt8 nTest) const {return nTest&0x10;}
    int xfLSPACE(sal_uInt8 nTest) const {return nTest&0x40;}
    int xfRULER(sal_uInt8 nTest) const {return nTest&0x20;}

    sal_uInt8 HandleNodes(SmNode *pNode,int nLevel=0);
    int StartTemplate(sal_uInt16 nSelector,sal_uInt16 nVariation=0);
    void EndTemplate(int nOldPendingAttributes);
    void HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel);
    void HandleTable(SmNode *pNode,int nLevel);
    void HandleRoot(SmNode *pNode,int nLevel);
    void HandleSubSupScript(SmNode *pNode,int nLevel);
    sal_uInt8 HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel,
        sal_uLong *pPos=NULL,sal_Bool bTest=sal_True);
    void HandleFractions(SmNode *pNode,int nLevel);
    void HandleBrace(SmNode *pNode,int nLevel);
    void HandleVerticalBrace(SmNode *pNode,int nLevel);
    void HandleOperator(SmNode *pNode,int nLevel);
    sal_Bool HandleLim(SmNode *pNode,int nLevel);
    void HandleMAlign(SmNode *pNode,int nLevel);
    void HandleMath(SmNode *pNode,int nLevel);
    void HandleText(SmNode *pNode,int nLevel);
    void HandleAttributes(SmNode *pNode,int nLevel);
    void TypeFaceToString(String &rRet,sal_uInt8 nFace);

    String &rRet;
    SmNode *pTree;

    sal_uInt8 nHAlign;
    sal_uInt8 nVAlign;

    int nPendingAttributes;
    sal_uLong nInsertion;

    sal_Int16 aSizeTable[7];
    sal_Int16 nDefaultSize;
    sal_Int16 nLSize;
    sal_Int16 nDSize;
    sal_Int16 nCurSize;
    sal_Int16 nLastSize;
    sal_uInt8 nSpec;
    sal_Bool bIsSilent, bIsReInterpBrace;
    String sPost;
    xub_StrLen nPostSup;
    xub_StrLen nPostlSup;
    sal_uInt8 nTypeFace;
    MathTypeFontSet aUserStyles;

    enum MTOKENS {END,LINE,CHAR,TMPL,PILE,MATRIX,EMBEL,RULER,FONT,SIZE};
    enum MTEMPLATES
    {
        tmANGLE,tmPAREN,tmBRACE,tmBRACK,tmBAR,tmDBAR,tmFLOOR,tmCEILING,
        tmLBLB,tmRBRB,tmRBLB,tmLBRP,tmLPRB,tmROOT,tmFRACT,tmSCRIPT,tmUBAR,
        tmOBAR,tmLARROW,tmRARROW,tmBARROW,tmSINT,tmDINT,tmTINT,tmSSINT,
        tmDSINT,tmTSINT,tmUHBRACE,tmLHBRACE,tmSUM
    };
public:
    static sal_Bool LookupChar(sal_Unicode nChar,String &rRet,
        sal_uInt8 nVersion=3,sal_uInt8 nTypeFace=0);
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


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

Generate all strings of n bits
==============================

Ref - ADS 2.12

--------------------------------------------------------------------------------

Problem
=======
Generate all strings of n bits. Assume A[0...n-1] is an array of size n.

--------------------------------------------------------------------------------

Algorithm
=========
1) Every bit can take two values, 0s and 1s.
2) Start from end of string and set current bit as 0 and 1.
3) Call recursively.

--------------------------------------------------------------------------------

Time Complexity
===============
O(2^n)

--------------------------------------------------------------------------------

Output
======
000
100
010
110
001
101
011
111

*******************************************************************************/

#include <stdio.h>

char A[3];

void genString(int n) {
    if (n == 0) {
        printf("%s\n", A);
    }
    else    {
        A[n - 1] = '0';
        genString(n - 1);
        A[n - 1] = '1';
        genString(n - 1);
    }
}

int main()  {
    genString(3);
    return 0;
}
<commit_msg>Add K-ary strings<commit_after>/*******************************************************************************

Generate all strings of n bits
==============================

Ref - ADS 2.12

--------------------------------------------------------------------------------

Problem
=======
Generate all strings of n bits. Assume A[0...n-1] is an array of size n.

--------------------------------------------------------------------------------

Algorithm
=========
1) Every bit can take two values, 0s and 1s.
2) Start from end of string and set current bit as 0 and 1.
3) Call recursively.

--------------------------------------------------------------------------------

Time Complexity
===============
O(2^n)
O(k^n)

--------------------------------------------------------------------------------

Output
======
Binary strings:
000
100
010
110
001
101
011
111

K-ary strings:
000
100
200
010
110
210
020
120
220
001
101
201
011
111
211
021
121
221
002
102
202
012
112
212
022
122
222

*******************************************************************************/

#include <stdio.h>

char A[3];

void genString(int n) {
    if (n == 0) {
        printf("%s\n", A);
    }
    else    {
        A[n - 1] = '0';
        genString(n - 1);
        A[n - 1] = '1';
        genString(n - 1);
    }
}

void genKString(int n, int k)   {
    if (n == 0) {
        printf("%s\n", A);
    }
    else    {
        for (int j = 0; j < k; j++) {
            A[n - 1] = '0' + j;
            genKString(n - 1, k);
        }
    }
}

int main()  {
    printf("Binary strings:\n");
    genString(3);
    printf("\nK-ary strings:\n");
    genKString(3, 3);
    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: zipexcptn.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2007-03-26 13:48:35 $
 *
 *  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"

#ifndef GLOBAL_HXX_INCLUDED
#include "internal/global.hxx"
#endif

#ifndef ZIPEXCPTN_HXX_INCLUDED
#include "zipexcptn.hxx"
#endif

//------------------------------------------
/**
*/
RuntimeException::RuntimeException(int Error) :
    m_Error(Error)
{
}

//------------------------------------------
/**
*/
RuntimeException::~RuntimeException() throw()
{
}

//------------------------------------------
/**
*/
int RuntimeException::GetErrorCode() const
{
    return m_Error;
}

//------------------------------------------
/**
*/
ZipException::ZipException(int Error) :
    RuntimeException(Error)
{
}

//------------------------------------------
/**
*/
const char* ZipException::what() const throw()
{
    return 0;
}

//------------------------------------------
/**
*/
Win32Exception::Win32Exception(int Error) :
    RuntimeException(Error),
    m_MsgBuff(0)
{
}

//------------------------------------------
/**
*/
Win32Exception::~Win32Exception() throw()
{
    if (m_MsgBuff)
        LocalFree(m_MsgBuff);
}

//------------------------------------------
/**
*/
const char* Win32Exception::what() const throw()
{
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetErrorCode(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &m_MsgBuff,
        0,
        NULL);

    return reinterpret_cast<char*>(m_MsgBuff);
}

//------------------------------------------
/**
*/
ZipContentMissException::ZipContentMissException(int Error) :
    ZipException(Error)
{
}

//------------------------------------------
/**
*/
AccessViolationException::AccessViolationException(int Error) :
    Win32Exception(Error)
{
}

//------------------------------------------
/**
*/
IOException::IOException(int Error) :
    Win32Exception(Error)
{
}
<commit_msg>INTEGRATION: CWS os2port02 (1.6.40); FILE MERGED 2007/10/04 19:45:58 ydario 1.6.40.1: Issue number: i82034 Submitted by: ydario Reviewed by:  ydario Commit of changes for OS/2 CWS source code integration.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: zipexcptn.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-02 13:11:26 $
 *
 *  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"

#ifndef GLOBAL_HXX_INCLUDED
#include "internal/global.hxx"
#endif

#ifndef ZIPEXCPTN_HXX_INCLUDED
#include "zipexcptn.hxx"
#endif

//------------------------------------------
/**
*/
RuntimeException::RuntimeException(int Error) :
    m_Error(Error)
{
}

//------------------------------------------
/**
*/
RuntimeException::~RuntimeException() throw()
{
}

//------------------------------------------
/**
*/
int RuntimeException::GetErrorCode() const
{
    return m_Error;
}

//------------------------------------------
/**
*/
ZipException::ZipException(int Error) :
    RuntimeException(Error)
{
}

//------------------------------------------
/**
*/
const char* ZipException::what() const throw()
{
    return 0;
}

//------------------------------------------
/**
*/
Win32Exception::Win32Exception(int Error) :
    RuntimeException(Error),
    m_MsgBuff(0)
{
}

//------------------------------------------
/**
*/
Win32Exception::~Win32Exception() throw()
{
#ifndef OS2
    if (m_MsgBuff)
        LocalFree(m_MsgBuff);
#endif
}

//------------------------------------------
/**
*/
const char* Win32Exception::what() const throw()
{
#ifdef OS2
    return "Win32Exception!";
#else
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetErrorCode(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &m_MsgBuff,
        0,
        NULL);

    return reinterpret_cast<char*>(m_MsgBuff);
#endif
}

//------------------------------------------
/**
*/
ZipContentMissException::ZipContentMissException(int Error) :
    ZipException(Error)
{
}

//------------------------------------------
/**
*/
AccessViolationException::AccessViolationException(int Error) :
    Win32Exception(Error)
{
}

//------------------------------------------
/**
*/
IOException::IOException(int Error) :
    Win32Exception(Error)
{
}
<|endoftext|>


<commit_before>#ifdef _DEBUG
#include <iostream>
#include <boost/format.hpp>
#endif

#include <vector>
#include <algorithm>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <data_type.hpp>
#include <sort_algorithm/compare.hpp>
#include <sort_algorithm/adjacent.hpp>
#include <sort_algorithm/compare.hpp>
#include <sort_algorithm/yrange2.hpp>
#include <gui.hpp>

// 2値座標系式から1値座標系式に変えながら和
// 指定した範囲の配列の和を返す
int yrange2::array_sum(return_type const& array_, int const x, int const y, int const height, int const width) const
{
    int sum = 0;
    for(int i=0; i<height; ++i)
    {
        for(int j=0; j<width; ++j)
        {
            auto const& target_point = array_[y + i][x + j];
			if (target_point.x == std::numeric_limits<int>::max() && target_point.y == std::numeric_limits<int>::max()) return -1;
			else
            {
                auto const point = target_point.y * width + target_point.x;
                sum += (point > 1000) ? 777 : point;
            }
        }
    }
    return sum;
}

/*縦列単位で入れ替え*/
void yrange2::column_replacement(answer_type_y & answer)
{
	int const sepx = data_.split_num.first;
	int const sepy = data_.split_num.second;
	uint_fast64_t good_val;
	std::vector<std::vector<point_type> > good_matrix(sepy, std::vector<point_type>(sepx));
	good_matrix = answer.points;
	good_val = form_evaluate(comp_,good_matrix);

	for (int i = 0; i < sepx; ++i){
		for (int j = 0; j < sepy; ++j){
			answer.points[j].insert(answer.points[j].begin(), answer.points[j][sepx - 1]);
			answer.points[j].pop_back();
		}
		auto const temp_score = form_evaluate(comp_, answer.points);
		if (good_val>temp_score){
			good_val = temp_score;
			good_matrix = answer.points;
		}
	}
	answer.points = good_matrix;
	answer.score = good_val;
}

/*横列単位で入れ替え*/
void yrange2::row_replacement(answer_type_y& answer)
{
	int const sepx = data_.split_num.first;
	int const sepy = data_.split_num.second;
	uint_fast64_t good_val;
	std::vector<std::vector<point_type> > good_matrix(sepy, std::vector<point_type>(sepx));
	std::vector<point_type> temp_vec;
	good_matrix = answer.points;
	good_val = form_evaluate(comp_,answer.points);
	for (int i = 0; i < sepy; ++i){
		answer.points.insert(answer.points.begin(), answer.points[sepy - 1]);
		answer.points.pop_back();
		auto const temp_score = form_evaluate(comp_, answer.points);
		if (good_val>temp_score){
			good_val = temp_score;
			good_matrix = answer.points;
		}
	}
	answer.points = good_matrix;
	answer.score = good_val;
}

//cv::matの塊にする
cv::Mat yrange2::combine_image(answer_type_y const& answer)
{
	int const one_picx = data_.size.first / data_.split_num.first;
	int const one_picy = data_.size.second / data_.split_num.second;

	splitter sp;//どこからか持ってきてたsplitter
	split_image_type splitted = sp.split_image(data_);
	cv::Mat comb_pic(cv::Size(data_.size.first, data_.size.second), CV_8UC3);
	for (int i = 0; i < data_.split_num.second; ++i){
		for (int j = 0; j < data_.split_num.first; ++j){
			cv::Rect roi_rect(j*one_picx, i*one_picy, one_picx, one_picy);
			cv::Mat roi_mat(comb_pic, roi_rect);
			splitted[answer.points[i][j].y][answer.points[i][j].x].copyTo(roi_mat);
		}
	}
	return std::move(comb_pic.clone());
}

yrange2::yrange2(question_raw_data const& data, compared_type const& comp)
    : data_(data), comp_(comp), adjacent_data_(select_minimum(comp))
{
}

std::vector<std::vector<std::vector<point_type>>> yrange2::operator() ()
{
	auto const width = data_.split_num.first;
	auto const height = data_.split_num.second;

	auto const exists = [height, width](point_type const& p)
	{
		return 0 <= p.x && p.x < width && 0 <= p.y && p.y < height;
	};

	std::vector<std::vector<point_type>> sorted_matrix(
		height * 2 - 1,
		std::vector<point_type>(
		width * 2 - 1,
		{ std::numeric_limits<int>::max(), std::numeric_limits<int>::max() }
		)
		);

	std::vector<answer_type_y> answer;
	splitter sp;

	//すべてのピースから並べ始めるためのループ
	for (int c_y = 0; c_y < height; ++c_y) for (int c_x = 0; c_x < width; ++c_x)
	{
		sorted_matrix[height - 1][width - 1] = point_type{ c_x, c_y };

		//上に見ていく
		for (int i = 0; i < height - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1 - i][width - 1];
			sorted_matrix[height - 2 - i][width - 1] = adjacent_data_[adjacent.y][adjacent.x].up;
			if (sorted_matrix[height - 2 - i][width - 1].y < 0 || sorted_matrix[height - 2 - i][width - 1].y >= height) break;
		}
		//下に見ていく
		for (int i = 0; i < height - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1 + i][width - 1];
			sorted_matrix[height + i][width - 1] = adjacent_data_[adjacent.y][adjacent.x].down;
			if (sorted_matrix[height + i][width - 1].y < 0 || sorted_matrix[height + i][width - 1].y >= height) break;
		}
		//右に見ていく
		for (int i = 0; i < width - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1][width - 1 + i];
			sorted_matrix[height - 1][width + i] = adjacent_data_[adjacent.y][adjacent.x].right;
			if (sorted_matrix[height - 1][width + i].x < 0 || sorted_matrix[height - 1][width + i].x >= width) break;
		}
		//左に見ていく
		for (int i = 0; i < width - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1][width - 1 - i];
			sorted_matrix[height - 1][width - 2 - i] = adjacent_data_[adjacent.y][adjacent.x].left;
			if (sorted_matrix[height - 1][width - 2 - i].x < 0 || sorted_matrix[height - 1][width - 2 - i].x >= width) break;
		}

		//中心を除き上に向かってループ，右に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height - i - 1][width + j - 1];
			auto const& upper = sorted_matrix[height - i - 2][width + j - 1];
			auto const& right = sorted_matrix[height - i - 1][width + j];

			if (exists(center) && exists(upper) && exists(right))
				sorted_matrix[height - i - 2][width + j] = ur_choose(comp_, upper, center, right);
			else
				break;
		}
		//中心を除き上に向かってループ，左に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height - i - 1][width - j - 1];
			auto const& upper = sorted_matrix[height - i - 2][width - j - 1];
			auto const& left = sorted_matrix[height - i - 1][width - j - 2];

			if (exists(center) && exists(upper) && exists(left))
				sorted_matrix[height - i - 2][width - j - 2] = ul_choose(comp_, upper, left, center);
			else
				break;
		}
		//中心を除き下に向かってループ，右に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height + i - 1][width + j - 1];
			auto const& lower = sorted_matrix[height + i][width + j - 1];
			auto const& right = sorted_matrix[height + i - 1][width + j];

			if (exists(center) && exists(lower) && exists(right))
				sorted_matrix[height + i][width + j] = dr_choose(comp_, center, right, lower);
			else
				break;
		}
		//中心を除き下に向かってループ，左に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height + i - 1][width - j - 1];
			auto const& lower = sorted_matrix[height + i][width - j - 1];
			auto const& left = sorted_matrix[height + i - 1][width - j - 2];

			if (exists(center) && exists(lower) && exists(left))
				sorted_matrix[height + i][width  - j - 2] = dl_choose(comp_, left, center, lower);
			else
				break;
		}

		for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x)
		{
			if (array_sum(sorted_matrix, x, y, height, width) == ((width*height - 1)*(width*height) / 2) && get_kind_num(data_, sorted_matrix, x, y) == width*height)
			{
				std::vector<std::vector<point_type>> one_answer(height, std::vector<point_type>(width));
				for (int i = 0; i < height; i++) for (int j = 0; j < width; j++)
				{
					one_answer[i][j] = sorted_matrix[y + i][x + j];
				}
				answer_type_y temp;
				temp.points = one_answer;
				answer.push_back(std::move(temp));
			}
		}
	}

	//現段階で重複しているものは1つに絞る
	// unique()を使う準備としてソートが必要
	std::sort(answer.begin(), answer.end(), [](answer_type_y a, answer_type_y b){return a.points < b.points; });
	// unique()をしただけでは後ろにゴミが残るので、eraseで削除する
	answer.erase(std::unique(answer.begin(), answer.end()), answer.end());

	//#########################################################yrange2.5#########################################################//

	//縦入れ替え，横入れ替え
	for (auto &matrix : answer){
		row_replacement(matrix);
		column_replacement(matrix);
		row_replacement(matrix);
	}

	//もっかいやっとく
	std::sort(answer.begin(), answer.end(), [](answer_type_y a, answer_type_y b){return a.points < b.points; });
	answer.erase(std::unique(answer.begin(), answer.end()), answer.end());

	//無駄に多く返してもしょうがないので枝抜き
	std::sort(answer.begin(), answer.end(), [](answer_type_y a, answer_type_y b){return a.score < b.score; });
	if (answer.size() >= 3) answer.resize(3);

	//一枚のcv::Matにする
	for (auto& one_answer : answer)
	{
		one_answer.mat_image = std::move(combine_image(one_answer));
	}

#ifdef _DEBUG
    std::cout << "There are " << answer.size() << " solutions" << std::endl;
	for (auto const& one_answer : answer)
	{
		for (int i = 0; i < one_answer.points.size(); ++i)
		{
			for (int j = 0; j < one_answer.points.at(0).size(); ++j)
			{
				auto const& data = one_answer.points[i][j];
				std::cout << boost::format("(%2d,%2d) ") % data.x % data.y;
			}
			std::cout << "\n";
		}
		std::cout << "score = " << one_answer.score << std::endl;
	}
	gui::show_image(data_, comp_, answer);
#endif

	//TODO:ここどうにかしよう
	std::vector<return_type> return_vec;
	for (auto const& one_answer : answer)
	{
		return_vec.push_back(std::move(one_answer.points));
	}
	return return_vec;
}
<commit_msg>パラメータ調整に対応<commit_after>#ifdef _DEBUG
#include <iostream>
#include <boost/format.hpp>
#endif

#include <vector>
#include <algorithm>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <data_type.hpp>
#include <sort_algorithm/compare.hpp>
#include <sort_algorithm/adjacent.hpp>
#include <sort_algorithm/compare.hpp>
#include <sort_algorithm/yrange2.hpp>
#include <gui.hpp>

// 2値座標系式から1値座標系式に変えながら和
// 指定した範囲の配列の和を返す
int yrange2::array_sum(return_type const& array_, int const x, int const y, int const height, int const width) const
{
    int sum = 0;
    for(int i=0; i<height; ++i)
    {
        for(int j=0; j<width; ++j)
        {
            auto const& target_point = array_[y + i][x + j];
			if (target_point.x == std::numeric_limits<int>::max() && target_point.y == std::numeric_limits<int>::max()) return -1;
			else
            {
                auto const point = target_point.y * width + target_point.x;
                sum += (point > 1000) ? 777 : point;
            }
        }
    }
    return sum;
}

/*縦列単位で入れ替え*/
void yrange2::column_replacement(answer_type_y & answer)
{
	int const sepx = data_.split_num.first;
	int const sepy = data_.split_num.second;
	uint_fast64_t good_val;
	std::vector<std::vector<point_type> > good_matrix(sepy, std::vector<point_type>(sepx));
	good_matrix = answer.points;
	good_val = form_evaluate(comp_,good_matrix);

	for (int i = 0; i < sepx; ++i){
		for (int j = 0; j < sepy; ++j){
			answer.points[j].insert(answer.points[j].begin(), answer.points[j][sepx - 1]);
			answer.points[j].pop_back();
		}
		auto const temp_score = form_evaluate(comp_, answer.points);
		if (good_val>temp_score){
			good_val = temp_score;
			good_matrix = answer.points;
		}
	}
	answer.points = good_matrix;
	answer.score = good_val;
}

/*横列単位で入れ替え*/
void yrange2::row_replacement(answer_type_y& answer)
{
	int const sepx = data_.split_num.first;
	int const sepy = data_.split_num.second;
	uint_fast64_t good_val;
	std::vector<std::vector<point_type> > good_matrix(sepy, std::vector<point_type>(sepx));
	std::vector<point_type> temp_vec;
	good_matrix = answer.points;
	good_val = form_evaluate(comp_,answer.points);
	for (int i = 0; i < sepy; ++i){
		answer.points.insert(answer.points.begin(), answer.points[sepy - 1]);
		answer.points.pop_back();
		auto const temp_score = form_evaluate(comp_, answer.points);
		if (good_val>temp_score){
			good_val = temp_score;
			good_matrix = answer.points;
		}
	}
	answer.points = good_matrix;
	answer.score = good_val;
}

//cv::matの塊にする
cv::Mat yrange2::combine_image(answer_type_y const& answer)
{
	int const one_picx = data_.size.first / data_.split_num.first;
	int const one_picy = data_.size.second / data_.split_num.second;

	splitter sp;//どこからか持ってきてたsplitter
	split_image_type splitted = sp.split_image(data_);
	cv::Mat comb_pic(cv::Size(data_.size.first, data_.size.second), CV_8UC3);
	for (int i = 0; i < data_.split_num.second; ++i){
		for (int j = 0; j < data_.split_num.first; ++j){
			cv::Rect roi_rect(j*one_picx, i*one_picy, one_picx, one_picy);
			cv::Mat roi_mat(comb_pic, roi_rect);
			splitted[answer.points[i][j].y][answer.points[i][j].x].copyTo(roi_mat);
		}
	}
	return std::move(comb_pic.clone());
}

yrange2::yrange2(question_raw_data const& data, compared_type const& comp)
    : data_(data), comp_(comp), adjacent_data_(select_minimum(comp))
{
}

std::vector<std::vector<std::vector<point_type>>> yrange2::operator() ()
{
	auto const width = data_.split_num.first;
	auto const height = data_.split_num.second;
	int constexpr yrange2_show_ans = 8;

	auto const exists = [height, width](point_type const& p)
	{
		return 0 <= p.x && p.x < width && 0 <= p.y && p.y < height;
	};

	std::vector<std::vector<point_type>> sorted_matrix(
		height * 2 - 1,
		std::vector<point_type>(
		width * 2 - 1,
		{ std::numeric_limits<int>::max(), std::numeric_limits<int>::max() }
		)
		);

	std::vector<answer_type_y> answer;
	splitter sp;

	//すべてのピースから並べ始めるためのループ
	for (int c_y = 0; c_y < height; ++c_y) for (int c_x = 0; c_x < width; ++c_x)
	{
		sorted_matrix[height - 1][width - 1] = point_type{ c_x, c_y };

		//上に見ていく
		for (int i = 0; i < height - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1 - i][width - 1];
			sorted_matrix[height - 2 - i][width - 1] = adjacent_data_[adjacent.y][adjacent.x].up;
			if (sorted_matrix[height - 2 - i][width - 1].y < 0 || sorted_matrix[height - 2 - i][width - 1].y >= height) break;
		}
		//下に見ていく
		for (int i = 0; i < height - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1 + i][width - 1];
			sorted_matrix[height + i][width - 1] = adjacent_data_[adjacent.y][adjacent.x].down;
			if (sorted_matrix[height + i][width - 1].y < 0 || sorted_matrix[height + i][width - 1].y >= height) break;
		}
		//右に見ていく
		for (int i = 0; i < width - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1][width - 1 + i];
			sorted_matrix[height - 1][width + i] = adjacent_data_[adjacent.y][adjacent.x].right;
			if (sorted_matrix[height - 1][width + i].x < 0 || sorted_matrix[height - 1][width + i].x >= width) break;
		}
		//左に見ていく
		for (int i = 0; i < width - 1; ++i)
		{
			auto const& adjacent = sorted_matrix[height - 1][width - 1 - i];
			sorted_matrix[height - 1][width - 2 - i] = adjacent_data_[adjacent.y][adjacent.x].left;
			if (sorted_matrix[height - 1][width - 2 - i].x < 0 || sorted_matrix[height - 1][width - 2 - i].x >= width) break;
		}

		//中心を除き上に向かってループ，右に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height - i - 1][width + j - 1];
			auto const& upper = sorted_matrix[height - i - 2][width + j - 1];
			auto const& right = sorted_matrix[height - i - 1][width + j];

			if (exists(center) && exists(upper) && exists(right))
				sorted_matrix[height - i - 2][width + j] = ur_choose(comp_, upper, center, right);
			else
				break;
		}
		//中心を除き上に向かってループ，左に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height - i - 1][width - j - 1];
			auto const& upper = sorted_matrix[height - i - 2][width - j - 1];
			auto const& left = sorted_matrix[height - i - 1][width - j - 2];

			if (exists(center) && exists(upper) && exists(left))
				sorted_matrix[height - i - 2][width - j - 2] = ul_choose(comp_, upper, left, center);
			else
				break;
		}
		//中心を除き下に向かってループ，右に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height + i - 1][width + j - 1];
			auto const& lower = sorted_matrix[height + i][width + j - 1];
			auto const& right = sorted_matrix[height + i - 1][width + j];

			if (exists(center) && exists(lower) && exists(right))
				sorted_matrix[height + i][width + j] = dr_choose(comp_, center, right, lower);
			else
				break;
		}
		//中心を除き下に向かってループ，左に見ていく
		for (int i = 0; i < height - 1; ++i) for (int j = 0; j < width - 1; ++j)
		{
			auto const& center = sorted_matrix[height + i - 1][width - j - 1];
			auto const& lower = sorted_matrix[height + i][width - j - 1];
			auto const& left = sorted_matrix[height + i - 1][width - j - 2];

			if (exists(center) && exists(lower) && exists(left))
				sorted_matrix[height + i][width  - j - 2] = dl_choose(comp_, left, center, lower);
			else
				break;
		}

		for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x)
		{
			if (array_sum(sorted_matrix, x, y, height, width) == ((width*height - 1)*(width*height) / 2) && get_kind_num(data_, sorted_matrix, x, y) == width*height)
			{
				std::vector<std::vector<point_type>> one_answer(height, std::vector<point_type>(width));
				for (int i = 0; i < height; i++) for (int j = 0; j < width; j++)
				{
					one_answer[i][j] = sorted_matrix[y + i][x + j];
				}
				answer_type_y temp;
				temp.points = one_answer;
				answer.push_back(std::move(temp));
			}
		}
	}

	//現段階で重複しているものは1つに絞る
	// unique()を使う準備としてソートが必要
	std::sort(answer.begin(), answer.end(), [](answer_type_y a, answer_type_y b){return a.points < b.points; });
	// unique()をしただけでは後ろにゴミが残るので、eraseで削除する
	answer.erase(std::unique(answer.begin(), answer.end()), answer.end());

	//#########################################################yrange2.5#########################################################//

	//縦入れ替え，横入れ替え
	for (auto &matrix : answer){
		row_replacement(matrix);
		column_replacement(matrix);
		row_replacement(matrix);
	}

	//もっかいやっとく
	std::sort(answer.begin(), answer.end(), [](answer_type_y a, answer_type_y b){return a.points < b.points; });
	answer.erase(std::unique(answer.begin(), answer.end()), answer.end());

	//無駄に多く返してもしょうがないので枝抜き
	int const yrange2_ans = answer.size();
	std::sort(answer.begin(), answer.end(), [](answer_type_y a, answer_type_y b){return a.score < b.score; });
	if (answer.size() >= yrange2_show_ans) answer.resize(yrange2_show_ans);

	//一枚のcv::Matにする
	for (auto& one_answer : answer)
	{
		one_answer.mat_image = std::move(combine_image(one_answer));
	}

#ifdef _DEBUG
    std::cout << "There are " << yrange2_ans << " solutions" << std::endl;
	for (auto const& one_answer : answer)
	{
		for (int i = 0; i < one_answer.points.size(); ++i)
		{
			for (int j = 0; j < one_answer.points.at(0).size(); ++j)
			{
				auto const& data = one_answer.points[i][j];
				std::cout << boost::format("(%2d,%2d) ") % data.x % data.y;
			}
			std::cout << "\n";
		}
		std::cout << "score = " << one_answer.score << std::endl;
	}
	gui::show_image(data_, comp_, answer);
#endif

	//TODO:ここどうにかしよう
	std::vector<return_type> return_vec;
	for (auto const& one_answer : answer)
	{
		return_vec.push_back(std::move(one_answer.points));
	}
	return return_vec;
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "cpasterplugin.h"

#include "ui_pasteselect.h"

#include "splitter.h"
#include "view.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/messageoutputwindow.h>
#include <coreplugin/uniqueidmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/itexteditor.h>

#include <QtCore/QtPlugin>
#include <QtCore/QDebug>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QClipboard>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QMainWindow>
#include <QtGui/QListWidget>

using namespace CodePaster;
using namespace Core;
using namespace TextEditor;

CodepasterPlugin::CodepasterPlugin()
    : m_settingsPage(0), m_fetcher(0), m_poster(0)
{
}

CodepasterPlugin::~CodepasterPlugin()
{
    if (m_settingsPage) {
        removeObject(m_settingsPage);
        delete m_settingsPage;
        m_settingsPage = 0;
    }
}

bool CodepasterPlugin::initialize(const QStringList &arguments, QString *error_message)
{
    Q_UNUSED(arguments);
    Q_UNUSED(error_message);

    // Create the globalcontext list to register actions accordingly
    QList<int> globalcontext;
    globalcontext << UniqueIDManager::instance()->uniqueIdentifier(Core::Constants::C_GLOBAL);

    // Create the settings Page
    m_settingsPage = new SettingsPage();
    addObject(m_settingsPage);

    //register actions
    Core::ActionManager *actionManager = ICore::instance()->actionManager();

    Core::ActionContainer *toolsContainer =
        actionManager->actionContainer(Core::Constants::M_TOOLS);

    Core::ActionContainer *cpContainer =
        actionManager->createMenu(QLatin1String("CodePaster"));
    cpContainer->menu()->setTitle(tr("&CodePaster"));
    toolsContainer->addMenu(cpContainer);

    Core::Command *command;

    m_postAction = new QAction(tr("Paste snippet..."), this);
    command = actionManager->registerAction(m_postAction, "CodePaster.post", globalcontext);
    command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+P")));
    connect(m_postAction, SIGNAL(triggered()), this, SLOT(post()));
    cpContainer->addAction(command);

    m_fetchAction = new QAction(tr("Fetch snippet..."), this);
    command = actionManager->registerAction(m_fetchAction, "CodePaster.fetch", globalcontext);
    command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+F")));
    connect(m_fetchAction, SIGNAL(triggered()), this, SLOT(fetch()));
    cpContainer->addAction(command);

    return true;
}

void CodepasterPlugin::extensionsInitialized()
{
    m_projectExplorer = ExtensionSystem::PluginManager::instance()
        ->getObject<ProjectExplorer::ProjectExplorerPlugin>();
}

QString CodepasterPlugin::serverUrl() const
{
    QString url = m_settingsPage->serverUrl().toString();
    if (url.startsWith("http://"))
        url = url.mid(7);
    if (url.endsWith('/'))
        url.chop(1);
    return url;
}

void CodepasterPlugin::post()
{
    if (m_poster)
        delete m_poster;
    IEditor* editor = EditorManager::instance()->currentEditor();
    ITextEditor* textEditor = qobject_cast<ITextEditor*>(editor);
    if (!textEditor)
        return;

    QString data = textEditor->selectedText();
    if (!data.isEmpty()) {
        QChar *uc = data.data();
        QChar *e = uc + data.size();

        for (; uc != e; ++uc) {
            switch (uc->unicode()) {
            case 0xfdd0: // QTextBeginningOfFrame
            case 0xfdd1: // QTextEndOfFrame
            case QChar::ParagraphSeparator:
            case QChar::LineSeparator:
                *uc = QLatin1Char('\n');
                break;
            case QChar::Nbsp:
                *uc = QLatin1Char(' ');
                break;
            default:
                ;
            }
        }
    } else
        data = textEditor->contents();

    FileDataList lst = splitDiffToFiles(data.toLatin1());
    QString username = m_settingsPage->username();
    QString description;
    QString comment;

    View view(0);
    if (!view.show(username, description, comment, lst))
        return; // User canceled post

    username = view.getUser();
    description = view.getDescription();
    comment = view.getComment();
    data = view.getContent();

    // Submit to codepaster

    m_poster = new CustomPoster(serverUrl());

    // Copied from cpaster. Otherwise lineendings will screw up
    if (!data.contains("\r\n")) {
        if (data.contains('\n'))
            data.replace('\n', "\r\n");
        else if (data.contains('\r'))
            data.replace('\r', "\r\n");
    }
    m_poster->post(description, comment, data, username);
}

void CodepasterPlugin::fetch()
{
    if (m_fetcher)
        delete m_fetcher;
    m_fetcher = new CustomFetcher(serverUrl());

    QDialog dialog;
    Ui_PasteSelectDialog ui;
    ui.setupUi(&dialog);

    ui.listWidget->addItems(QStringList() << "Waiting for items");
    ui.listWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
    ui.listWidget->setFrameStyle(QFrame::NoFrame);
    m_fetcher->list(ui.listWidget);

    int result = dialog.exec();
    if (!result)
        return;
    bool ok;
    QStringList list = ui.pasteEdit->text().split(QLatin1Char(' '));
    int pasteID = !list.isEmpty() ? list.first().toInt(&ok) : -1;
    if (!ok || pasteID <= 0)
        return;

    delete m_fetcher;
    m_fetcher = new CustomFetcher(serverUrl());
    m_fetcher->fetch(pasteID);
}

CustomFetcher::CustomFetcher(const QString &host)
        : Fetcher(host)
        , m_host(host)
        , m_listWidget(0)
        , m_id(-1)
        , m_customError(false)
{
    // cpaster calls QCoreApplication::exit which we want to avoid here
    disconnect(this, SIGNAL(requestFinished(int,bool))
              ,this, SLOT(gotRequestFinished(int,bool)));
    connect(this, SIGNAL(requestFinished(int,bool))
                    , SLOT(customRequestFinished(int,bool)));
}

void CustomFetcher::customRequestFinished(int, bool error)
{
    m_customError = error;
    if (m_customError || hadError()) {
        QMessageBox::warning(0, QLatin1String("CodePaster Error")
                             , QLatin1String("Could not fetch code")
                             , QMessageBox::Ok);
        return;
    }

    QByteArray data = body();
    if (!m_listWidget) {
        QString title = QString::fromLatin1("Code Paster: %1").arg(m_id);
        EditorManager::instance()->newFile(Core::Constants::K_DEFAULT_TEXT_EDITOR, &title, data);
    } else {
        m_listWidget->clear();
        QStringList lines = QString(data).split(QLatin1Char('\n'));
        m_listWidget->addItems(lines);
        m_listWidget = 0;
    }
}

int CustomFetcher::fetch(int pasteID)
{
    m_id = pasteID;
    return Fetcher::fetch(pasteID);
}

void CustomFetcher::list(QListWidget* list)
{
    m_listWidget = list;
    QString url = QLatin1String("http://");
    url += m_host;
    url += QLatin1String("/?command=browse&format=raw");
    Fetcher::fetch(url);
}

CustomPoster::CustomPoster(const QString &host, bool copyToClipboard, bool displayOutput)
    : Poster(host), m_copy(copyToClipboard), m_output(displayOutput)
{
    // cpaster calls QCoreApplication::exit which we want to avoid here
    disconnect(this, SIGNAL(requestFinished(int,bool)),
              this, SLOT(gotRequestFinished(int,bool)));
    connect(this, SIGNAL(requestFinished(int,bool)),
                  SLOT(customRequestFinished(int,bool)));
}

void CustomPoster::customRequestFinished(int, bool error)
{
    if (!error) {
        if (m_copy)
            QApplication::clipboard()->setText(pastedUrl());
        ICore::instance()->messageManager()->printToOutputPane(pastedUrl(), m_output);
    } else
        QMessageBox::warning(0, "Code Paster Error", "Some error occured while posting", QMessageBox::Ok);
#if 0 // Figure out how to access
    Core::Internal::MessageOutputWindow* messageWindow =
            ExtensionSystem::PluginManager::instance()->getObject<Core::Internal::MessageOutputWindow>();
    if (!messageWindow)
        qDebug() << "Pasted at:" << pastedUrl();

    messageWindow->append(pastedUrl());
    messageWindow->setFocus();
#endif
}

Q_EXPORT_PLUGIN(CodepasterPlugin)
<commit_msg>    Fixes:    cpaster: fix potential double deletion test<commit_after>/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "cpasterplugin.h"

#include "ui_pasteselect.h"

#include "splitter.h"
#include "view.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/messageoutputwindow.h>
#include <coreplugin/uniqueidmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/itexteditor.h>

#include <QtCore/QtPlugin>
#include <QtCore/QDebug>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QClipboard>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QMainWindow>
#include <QtGui/QListWidget>

using namespace CodePaster;
using namespace Core;
using namespace TextEditor;

CodepasterPlugin::CodepasterPlugin()
    : m_settingsPage(0), m_fetcher(0), m_poster(0)
{
}

CodepasterPlugin::~CodepasterPlugin()
{
    if (m_settingsPage) {
        removeObject(m_settingsPage);
        delete m_settingsPage;
        m_settingsPage = 0;
    }
}

bool CodepasterPlugin::initialize(const QStringList &arguments, QString *error_message)
{
    Q_UNUSED(arguments);
    Q_UNUSED(error_message);

    // Create the globalcontext list to register actions accordingly
    QList<int> globalcontext;
    globalcontext << UniqueIDManager::instance()->uniqueIdentifier(Core::Constants::C_GLOBAL);

    // Create the settings Page
    m_settingsPage = new SettingsPage();
    addObject(m_settingsPage);

    //register actions
    Core::ActionManager *actionManager = ICore::instance()->actionManager();

    Core::ActionContainer *toolsContainer =
        actionManager->actionContainer(Core::Constants::M_TOOLS);

    Core::ActionContainer *cpContainer =
        actionManager->createMenu(QLatin1String("CodePaster"));
    cpContainer->menu()->setTitle(tr("&CodePaster"));
    toolsContainer->addMenu(cpContainer);

    Core::Command *command;

    m_postAction = new QAction(tr("Paste snippet..."), this);
    command = actionManager->registerAction(m_postAction, "CodePaster.post", globalcontext);
    command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+P")));
    connect(m_postAction, SIGNAL(triggered()), this, SLOT(post()));
    cpContainer->addAction(command);

    m_fetchAction = new QAction(tr("Fetch snippet..."), this);
    command = actionManager->registerAction(m_fetchAction, "CodePaster.fetch", globalcontext);
    command->setDefaultKeySequence(QKeySequence(tr("Alt+C,Alt+F")));
    connect(m_fetchAction, SIGNAL(triggered()), this, SLOT(fetch()));
    cpContainer->addAction(command);

    return true;
}

void CodepasterPlugin::extensionsInitialized()
{
    m_projectExplorer = ExtensionSystem::PluginManager::instance()
        ->getObject<ProjectExplorer::ProjectExplorerPlugin>();
}

QString CodepasterPlugin::serverUrl() const
{
    QString url = m_settingsPage->serverUrl().toString();
    if (url.startsWith("http://"))
        url = url.mid(7);
    if (url.endsWith('/'))
        url.chop(1);
    return url;
}

void CodepasterPlugin::post()
{
    // FIXME: The whole m_poster thing is de facto a simple function call.
    if (m_poster) {
        delete m_poster;
        m_poster = 0;
    }
    IEditor* editor = EditorManager::instance()->currentEditor();
    ITextEditor* textEditor = qobject_cast<ITextEditor*>(editor);
    if (!textEditor)
        return;

    QString data = textEditor->selectedText();
    if (!data.isEmpty()) {
        QChar *uc = data.data();
        QChar *e = uc + data.size();

        for (; uc != e; ++uc) {
            switch (uc->unicode()) {
            case 0xfdd0: // QTextBeginningOfFrame
            case 0xfdd1: // QTextEndOfFrame
            case QChar::ParagraphSeparator:
            case QChar::LineSeparator:
                *uc = QLatin1Char('\n');
                break;
            case QChar::Nbsp:
                *uc = QLatin1Char(' ');
                break;
            default:
                ;
            }
        }
    } else
        data = textEditor->contents();

    FileDataList lst = splitDiffToFiles(data.toLatin1());
    QString username = m_settingsPage->username();
    QString description;
    QString comment;

    View view(0);
    if (!view.show(username, description, comment, lst))
        return; // User canceled post

    username = view.getUser();
    description = view.getDescription();
    comment = view.getComment();
    data = view.getContent();

    // Submit to codepaster

    m_poster = new CustomPoster(serverUrl());

    // Copied from cpaster. Otherwise lineendings will screw up
    if (!data.contains("\r\n")) {
        if (data.contains('\n'))
            data.replace('\n', "\r\n");
        else if (data.contains('\r'))
            data.replace('\r', "\r\n");
    }
    m_poster->post(description, comment, data, username);
}

void CodepasterPlugin::fetch()
{
    if (m_fetcher) {
        delete m_fetcher;
        m_fetcher = 0;
    }
    m_fetcher = new CustomFetcher(serverUrl());

    QDialog dialog;
    Ui_PasteSelectDialog ui;
    ui.setupUi(&dialog);

    ui.listWidget->addItems(QStringList() << "Waiting for items");
    ui.listWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
    ui.listWidget->setFrameStyle(QFrame::NoFrame);
    m_fetcher->list(ui.listWidget);

    int result = dialog.exec();
    if (!result)
        return;
    bool ok;
    QStringList list = ui.pasteEdit->text().split(QLatin1Char(' '));
    int pasteID = !list.isEmpty() ? list.first().toInt(&ok) : -1;
    if (!ok || pasteID <= 0)
        return;

    delete m_fetcher;
    m_fetcher = new CustomFetcher(serverUrl());
    m_fetcher->fetch(pasteID);
}

CustomFetcher::CustomFetcher(const QString &host)
        : Fetcher(host)
        , m_host(host)
        , m_listWidget(0)
        , m_id(-1)
        , m_customError(false)
{
    // cpaster calls QCoreApplication::exit which we want to avoid here
    disconnect(this, SIGNAL(requestFinished(int,bool))
              ,this, SLOT(gotRequestFinished(int,bool)));
    connect(this, SIGNAL(requestFinished(int,bool))
                    , SLOT(customRequestFinished(int,bool)));
}

void CustomFetcher::customRequestFinished(int, bool error)
{
    m_customError = error;
    if (m_customError || hadError()) {
        QMessageBox::warning(0, QLatin1String("CodePaster Error")
                             , QLatin1String("Could not fetch code")
                             , QMessageBox::Ok);
        return;
    }

    QByteArray data = body();
    if (!m_listWidget) {
        QString title = QString::fromLatin1("Code Paster: %1").arg(m_id);
        EditorManager::instance()->newFile(Core::Constants::K_DEFAULT_TEXT_EDITOR, &title, data);
    } else {
        m_listWidget->clear();
        QStringList lines = QString(data).split(QLatin1Char('\n'));
        m_listWidget->addItems(lines);
        m_listWidget = 0;
    }
}

int CustomFetcher::fetch(int pasteID)
{
    m_id = pasteID;
    return Fetcher::fetch(pasteID);
}

void CustomFetcher::list(QListWidget* list)
{
    m_listWidget = list;
    QString url = QLatin1String("http://");
    url += m_host;
    url += QLatin1String("/?command=browse&format=raw");
    Fetcher::fetch(url);
}

CustomPoster::CustomPoster(const QString &host, bool copyToClipboard, bool displayOutput)
    : Poster(host), m_copy(copyToClipboard), m_output(displayOutput)
{
    // cpaster calls QCoreApplication::exit which we want to avoid here
    disconnect(this, SIGNAL(requestFinished(int,bool)),
              this, SLOT(gotRequestFinished(int,bool)));
    connect(this, SIGNAL(requestFinished(int,bool)),
                  SLOT(customRequestFinished(int,bool)));
}

void CustomPoster::customRequestFinished(int, bool error)
{
    if (!error) {
        if (m_copy)
            QApplication::clipboard()->setText(pastedUrl());
        ICore::instance()->messageManager()->printToOutputPane(pastedUrl(), m_output);
    } else
        QMessageBox::warning(0, "Code Paster Error", "Some error occured while posting", QMessageBox::Ok);
#if 0 // Figure out how to access
    Core::Internal::MessageOutputWindow* messageWindow =
            ExtensionSystem::PluginManager::instance()->getObject<Core::Internal::MessageOutputWindow>();
    if (!messageWindow)
        qDebug() << "Pasted at:" << pastedUrl();

    messageWindow->append(pastedUrl());
    messageWindow->setFocus();
#endif
}

Q_EXPORT_PLUGIN(CodepasterPlugin)
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2018 Igor Zinken - http://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "sequencer.h"
#include "audioengine.h"
#include <utilities/utils.h>
#include <vector>

namespace MWEngine {

/* static member intialization */

bool Sequencer::playing           = false;
BulkCacher* Sequencer::bulkCacher = new BulkCacher( true );
std::vector<BaseInstrument*> Sequencer::instruments;

/* public methods */

int Sequencer::registerInstrument( BaseInstrument* instrument )
{
    int index       = -1;
    bool wasPresent = false; // prevent double addition

    for ( int i = 0; i < instruments.size(); i++ )
    {
        if ( instruments.at( i ) == instrument )
            wasPresent = true;
    }

    if ( !wasPresent ) {
        instruments.push_back( instrument );
        index = instruments.size() - 1;
    }
    return index; // the index this instrument is registered at
}

bool Sequencer::unregisterInstrument( BaseInstrument* instrument )
{
    for ( int i = 0; i < instruments.size(); i++ )
    {
        if ( instruments.at( i ) == instrument )
        {
            instruments.erase( instruments.begin() + i );
            return true;
        }
    }
    return false;
}

bool Sequencer::getAudioEvents( std::vector<AudioChannel*>* channels, int bufferPosition,
                                int bufferSize, bool addLiveInstruments, bool flushChannels )
{
    channels->clear();

    int bufferEnd    = bufferPosition + ( bufferSize - 1 );          // the highest SampleEnd value we'll query
    bool loopStarted = bufferEnd > AudioEngine::max_buffer_position; // whether this request exceeds the min_buffer_position - max_buffer_position range

    int i, l;

    // note we update the channels mix properties here as they might change during playback

    for ( i = 0, l = ( int ) instruments.size(); i < l; ++i )
    {
        BaseInstrument* instrument      = instruments.at( i );
        AudioChannel* instrumentChannel = instrument->audioChannel;

        // clear previous channel contents when requested
        if ( flushChannels )
            instrumentChannel->reset();

        if ( !instrumentChannel->muted )
        {
            if ( playing )
                collectSequencedEvents( instrument, bufferPosition, bufferEnd );

            if ( addLiveInstruments && instrument->hasLiveEvents() )
                collectLiveEvents( instrument );

            channels->push_back( instrumentChannel );
        }
    }
    return loopStarted;
}

void Sequencer::updateEvents()
{
    for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i )
        instruments.at( i )->updateEvents();
}

void Sequencer::clearEvents()
{
    for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i )
        instruments.at( i )->clearEvents();
}

/**
 * used by the getAudioEvents-method of the sequencer, this validates
 * the present AudioEvents against the requested position
 * and updates and flushes the removal queue
 *
 * @param instrument     {BaseInstrument*} instrument to gather events from
 * @param bufferPosition {int} the current buffers start pointer
 * @param bufferEnd      {int} the current buffers end pointer
 */
void Sequencer::collectSequencedEvents( BaseInstrument* instrument, int bufferPosition, int bufferEnd )
{
    if ( !instrument->hasEvents() )
        return;

    AudioChannel* channel                     = instrument->audioChannel;
    std::vector<BaseAudioEvent*>* audioEvents = instrument->getEvents();

    // removal queue
    std::vector<BaseAudioEvent*> removes;

    // channel has an internal loop (e.g. drum machine) ? recalculate requested
    // buffer position by subtracting all measures above the first

    if ( channel->maxBufferPosition > 0 )
    {
        int samplesPerBar = AudioEngine::samples_per_bar;

        while ( bufferPosition >= channel->maxBufferPosition )
        {
            bufferPosition -= samplesPerBar;
            bufferEnd      -= samplesPerBar;
        }
    }

    int i = 0, amount = ( int ) audioEvents->size();
    for ( ; i < amount; i++ )
    {
        BaseAudioEvent* audioEvent = audioEvents->at( i );

        if ( audioEvent->isEnabled() )
        {
            int eventStart = audioEvent->getEventStart();
            int eventEnd   = audioEvent->getEventEnd();

            if (( eventStart >= bufferPosition && eventStart <= bufferEnd ) ||
                ( eventStart <  bufferPosition && eventEnd >= bufferPosition ))
            {
                if ( !audioEvent->isDeletable())
                    channel->addEvent( audioEvent );
                else
                    removes.push_back( audioEvent );
            }
        }
    }
    // removal queue filled ? process it so we can safely
    // remove "deleted" AudioEvents without errors occurring
    if ( removes.size() > 0 )
    {
        for ( i = 0; i < removes.size(); i++ )
        {
            BaseAudioEvent* audioEvent = removes[ i ];
            instrument->removeEvent( audioEvent, false );
        }
    }
}

void Sequencer::collectLiveEvents( BaseInstrument* instrument )
{
    AudioChannel* channel                    = instrument->audioChannel;
    std::vector<BaseAudioEvent*>* liveEvents = instrument->getLiveEvents();

    // removal queue
    std::vector<BaseAudioEvent*> removes;

    for ( int i = 0; i < liveEvents->size(); i++ )
    {
        BaseAudioEvent* audioEvent = liveEvents->at( i );

        if ( !audioEvent->isDeletable())
            channel->addLiveEvent( audioEvent );
        else
            removes.push_back( audioEvent );
    }
    // removal queue filled ? process it so we can safely
    // remove "deleted" AudioEvents without errors occurring
    if ( removes.size() > 0 )
    {
        for ( int i = 0; i < removes.size(); i++ )
        {
            BaseAudioEvent* audioEvent = removes[ i ];
            instrument->removeEvent( audioEvent, true );
        }
    }
}

/**
 * used by the cacheAudioEventsForMeasure-method, this collects
 * all AudioEvents in the requested measure for entry into the BulkCacher
 *
 * @param bufferPosition {int} the desired measures buffers start pointer
 * @param bufferEnd      {int} the desired measures buffers end pointer
 *
 * @return {std::vector<BaseCacheableAudioEvent*>}
 */
std::vector<BaseCacheableAudioEvent*>* Sequencer::collectCacheableSequencerEvents( int bufferPosition, int bufferEnd )
{
    std::vector<BaseCacheableAudioEvent*>* events = new std::vector<BaseCacheableAudioEvent*>();

    for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i )
    {
        std::vector<BaseAudioEvent*>* audioEvents = instruments.at( i )->getEvents();
        int amount = ( int ) audioEvents->size();

        for ( int j = 0; j < amount; j++ )
        {
            BaseAudioEvent* audioEvent = audioEvents->at( j );

            // if event is an instance of BaseCacheableAudioEvent add it to the list
            if ( dynamic_cast<BaseCacheableAudioEvent*>( audioEvent ) != nullptr )
            {
                int eventStart = audioEvent->getEventStart();
                int eventEnd   = audioEvent->getEventEnd();

                if (( eventStart >= bufferPosition && eventStart <= bufferEnd ) ||
                    ( eventStart <  bufferPosition && eventEnd >= bufferPosition ))
                {
                    if ( !audioEvent->isDeletable())
                        events->push_back(( BaseCacheableAudioEvent* ) audioEvent );
                }
            }
        }
    }
    return events;
}

} // E.O namespace MWEngine
<commit_msg>Fixed issue where sequencer could crash when disposing of events in outside thread<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2019 Igor Zinken - http://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "sequencer.h"
#include "audioengine.h"
#include <utilities/utils.h>
#include <vector>

namespace MWEngine {

/* static member intialization */

bool Sequencer::playing           = false;
BulkCacher* Sequencer::bulkCacher = new BulkCacher( true );
std::vector<BaseInstrument*> Sequencer::instruments;

/* public methods */

int Sequencer::registerInstrument( BaseInstrument* instrument )
{
    int index       = -1;
    bool wasPresent = false; // prevent double addition

    for ( int i = 0; i < instruments.size(); i++ )
    {
        if ( instruments.at( i ) == instrument )
            wasPresent = true;
    }

    if ( !wasPresent ) {
        instruments.push_back( instrument );
        index = instruments.size() - 1;
    }
    return index; // the index this instrument is registered at
}

bool Sequencer::unregisterInstrument( BaseInstrument* instrument )
{
    for ( int i = 0; i < instruments.size(); i++ )
    {
        if ( instruments.at( i ) == instrument )
        {
            instruments.erase( instruments.begin() + i );
            return true;
        }
    }
    return false;
}

bool Sequencer::getAudioEvents( std::vector<AudioChannel*>* channels, int bufferPosition,
                                int bufferSize, bool addLiveInstruments, bool flushChannels )
{
    channels->clear();

    int bufferEnd    = bufferPosition + ( bufferSize - 1 );          // the highest SampleEnd value we'll query
    bool loopStarted = bufferEnd > AudioEngine::max_buffer_position; // whether this request exceeds the min_buffer_position - max_buffer_position range

    int i, l;

    // note we update the channels mix properties here as they might change during playback

    for ( i = 0, l = ( int ) instruments.size(); i < l; ++i )
    {
        BaseInstrument* instrument      = instruments.at( i );
        AudioChannel* instrumentChannel = instrument->audioChannel;

        // clear previous channel contents when requested
        if ( flushChannels )
            instrumentChannel->reset();

        if ( !instrumentChannel->muted )
        {
            if ( playing )
                collectSequencedEvents( instrument, bufferPosition, bufferEnd );

            if ( addLiveInstruments && instrument->hasLiveEvents() )
                collectLiveEvents( instrument );

            channels->push_back( instrumentChannel );
        }
    }
    return loopStarted;
}

void Sequencer::updateEvents()
{
    for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i )
        instruments.at( i )->updateEvents();
}

void Sequencer::clearEvents()
{
    for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i )
        instruments.at( i )->clearEvents();
}

/**
 * used by the getAudioEvents-method of the sequencer, this validates
 * the present AudioEvents against the requested position
 * and updates and flushes the removal queue
 *
 * @param instrument     {BaseInstrument*} instrument to gather events from
 * @param bufferPosition {int} the current buffers start pointer
 * @param bufferEnd      {int} the current buffers end pointer
 */
void Sequencer::collectSequencedEvents( BaseInstrument* instrument, int bufferPosition, int bufferEnd )
{
    if ( !instrument->hasEvents() )
        return;

    AudioChannel* channel                     = instrument->audioChannel;
    std::vector<BaseAudioEvent*>* audioEvents = instrument->getEvents();

    // removal queue
    std::vector<BaseAudioEvent*> removes;

    // channel has an internal loop (e.g. drum machine) ? recalculate requested
    // buffer position by subtracting all measures above the first

    if ( channel->maxBufferPosition > 0 )
    {
        int samplesPerBar = AudioEngine::samples_per_bar;

        while ( bufferPosition >= channel->maxBufferPosition )
        {
            bufferPosition -= samplesPerBar;
            bufferEnd      -= samplesPerBar;
        }
    }

    int i = 0;
    for ( ; i < audioEvents->size(); i++ )
    {
        BaseAudioEvent* audioEvent = audioEvents->at( i );

        if ( audioEvent->isEnabled() )
        {
            int eventStart = audioEvent->getEventStart();
            int eventEnd   = audioEvent->getEventEnd();

            if (( eventStart >= bufferPosition && eventStart <= bufferEnd ) ||
                ( eventStart <  bufferPosition && eventEnd >= bufferPosition ))
            {
                if ( !audioEvent->isDeletable())
                    channel->addEvent( audioEvent );
                else
                    removes.push_back( audioEvent );
            }
        }
    }
    // removal queue filled ? process it so we can safely
    // remove "deleted" AudioEvents without errors occurring
    if ( removes.size() > 0 )
    {
        for ( i = 0; i < removes.size(); i++ )
        {
            BaseAudioEvent* audioEvent = removes[ i ];
            instrument->removeEvent( audioEvent, false );
        }
    }
}

void Sequencer::collectLiveEvents( BaseInstrument* instrument )
{
    AudioChannel* channel                    = instrument->audioChannel;
    std::vector<BaseAudioEvent*>* liveEvents = instrument->getLiveEvents();

    // removal queue
    std::vector<BaseAudioEvent*> removes;

    for ( int i = 0; i < liveEvents->size(); i++ )
    {
        BaseAudioEvent* audioEvent = liveEvents->at( i );

        if ( !audioEvent->isDeletable())
            channel->addLiveEvent( audioEvent );
        else
            removes.push_back( audioEvent );
    }
    // removal queue filled ? process it so we can safely
    // remove "deleted" AudioEvents without errors occurring
    if ( removes.size() > 0 )
    {
        for ( int i = 0; i < removes.size(); i++ )
        {
            BaseAudioEvent* audioEvent = removes[ i ];
            instrument->removeEvent( audioEvent, true );
        }
    }
}

/**
 * used by the cacheAudioEventsForMeasure-method, this collects
 * all AudioEvents in the requested measure for entry into the BulkCacher
 *
 * @param bufferPosition {int} the desired measures buffers start pointer
 * @param bufferEnd      {int} the desired measures buffers end pointer
 *
 * @return {std::vector<BaseCacheableAudioEvent*>}
 */
std::vector<BaseCacheableAudioEvent*>* Sequencer::collectCacheableSequencerEvents( int bufferPosition, int bufferEnd )
{
    std::vector<BaseCacheableAudioEvent*>* events = new std::vector<BaseCacheableAudioEvent*>();

    for ( int i = 0, l = ( int ) instruments.size(); i < l; ++i )
    {
        std::vector<BaseAudioEvent*>* audioEvents = instruments.at( i )->getEvents();
        for ( int j = 0; j < audioEvents->size(); j++ )
        {
            BaseAudioEvent* audioEvent = audioEvents->at( j );

            // if event is an instance of BaseCacheableAudioEvent add it to the list
            if ( dynamic_cast<BaseCacheableAudioEvent*>( audioEvent ) != nullptr )
            {
                int eventStart = audioEvent->getEventStart();
                int eventEnd   = audioEvent->getEventEnd();

                if (( eventStart >= bufferPosition && eventStart <= bufferEnd ) ||
                    ( eventStart <  bufferPosition && eventEnd >= bufferPosition ))
                {
                    if ( !audioEvent->isDeletable())
                        events->push_back(( BaseCacheableAudioEvent* ) audioEvent );
                }
            }
        }
    }
    return events;
}

} // E.O namespace MWEngine
<|endoftext|>