<commit_before>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// 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 <iomanip>
#include <iostream>

#include "gtest/gtest.h"

#include "BitFunnel/Index/Factories.h"
#include "BitFunnel/Index/IIngestor.h"
#include "BitFunnel/Index/IShard.h"
#include "BitFunnel/Index/ISimpleIndex.h"
#include "BitFunnel/Index/RowIdSequence.h"
#include "BitFunnel/Utilities/Factories.h"  // TODO: only for diagnosticStream. Remove.
#include "ByteCodeInterpreter.h"
#include "CodeVerifierBase.h"
#include "ResultsBuffer.h"

namespace BitFunnel
{
    static const ShardId c_shardId = 0;
    static const Term::StreamId c_streamId = 0;

    // TODO: move this method somewhere.
    static uint64_t lzcnt(uint64_t value)
    {
#ifdef _MSC_VER
        return __lzcnt64(value);
#elif __LZCNT__
        return __lzcnt64(value);
#else
        // DESIGN NOTE: this is undefined if the input operand i 0. We currently
        // only call lzcnt in one place, where we've prevously gauranteed that
        // the input isn't 0. This is not safe to use in the general case.
        return static_cast<uint64_t>(__builtin_clzll(value));
#endif
    }

    CodeVerifierBase::CodeVerifierBase(ISimpleIndex const & index,
                                       Rank initialRank)
      : m_index(index),
        m_initialRank(initialRank),
        m_slices(index.GetIngestor().GetShard(c_shardId).GetSliceBuffers()),
        m_resultsCount(0),
        m_verboseMode(false),
        m_expectNoResults(false)
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        auto & sliceBuffers = shard.GetSliceBuffers();
        auto iterationsPerSlice = GetIterationsPerSlice();
        auto iterationCount = iterationsPerSlice * sliceBuffers.size();

        for (size_t i = 0; i < iterationCount; ++i)
        {
            m_iterationValues.push_back(i);
        }
    }

    void CodeVerifierBase::VerboseMode(bool mode)
    {
        m_verboseMode = mode;
    }

    void CodeVerifierBase::ExpectNoResults()
    {
        m_expectNoResults = true;
    }

    std::vector<size_t> const & CodeVerifierBase::GetIterations() const
    {
        return m_iterationValues;
    }

    size_t CodeVerifierBase::GetSliceNumber(size_t iteration) const
    {
        return iteration / GetIterationsPerSlice();
    }

    size_t CodeVerifierBase::GetOffset(size_t iteration) const
    {
        return iteration % GetIterationsPerSlice();
    }

    size_t CodeVerifierBase::GetIterationsPerSlice() const
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        return shard.GetSliceCapacity() >> 6 >> m_initialRank;
    }

    void CodeVerifierBase::DeclareRow(char const * text)
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        m_rowOffsets.push_back(
            GetRowOffset(
                text,
                c_streamId,
                m_index.GetConfiguration(),
                m_index.GetTermTable0(),
                shard));
    }

    uint64_t CodeVerifierBase::GetRowData(size_t row, size_t offset, size_t slice)
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        auto const & slices = shard.GetSliceBuffers();
        char const * sliceBuffer = reinterpret_cast<char const *>(slices[slice]);
        uint64_t const * rowPtr =
            reinterpret_cast<uint64_t const *>(sliceBuffer + m_rowOffsets[row]);
        return rowPtr[offset];
    }

    // The class is configured by adding a sequence of of records
    // describing the expected interactions betweeen the matcher and its
    // IResultsProcessor. Each call to Add() corresponds to expectation
    // that the matcher will invoke IResultsProcessor::AddResult(). The
    // accumulator and offset parameters to Add() are the expected
    // parameters to AddResult().
    //
    // The usage pattern for IResultsProcessor is a sequence of calls
    // to AddResult() interspersed with calls to FinishIteration().
    // The call to FinishIteration() provides the void* slice buffer
    // pointer that is applicable to the sequence of calls to AddResult()
    // since the previous call to FinishIteration() (or the start of
    // the matching algorithm if there was no previous call to
    // FinishIteration().
    //
    // The third parameter of the Add() method indicates the slice
    // that expected to be passed on the next call to FinishIteration.
    // The slice parameter is a size_t index into an array of slice
    // buffer pointers associated with the index.
    //
    void CodeVerifierBase::ExpectResult(uint64_t accumulator,
                                        size_t offset,
                                        size_t sliceNumber)
    {
        //// TODO: Remove temporary debugging output.
        //std::cout
        //    << "ExpectResult("
        //    << std::hex << accumulator << std::dec
        //    << ", "
        //    << offset
        //    << ", "
        //    << sliceNumber
        //    << ")"
        //    << std::endl;

        size_t bitPos = 63;
        void * sliceBuffer = m_slices[sliceNumber];

        while (accumulator != 0)
        {
            uint64_t count = lzcnt(accumulator);
            accumulator <<= count;
            bitPos -= count;

            DocIndex docIndex = offset * c_bitsPerQuadword + bitPos;
            DocumentHandle handle =
                Factories::CreateDocumentHandle(sliceBuffer, docIndex);

            if (handle.IsActive())
            {
                DocId id = handle.GetDocId();
                //// TODO: Remove temporary debugging output.
                //std::cout << "  " << id << std::endl;

                if (m_expected.find(id) != m_expected.end())
                {
                    std::cout << "  Duplicate id " << id << std::endl;
                }

                m_expected.insert(id);
            }

            accumulator <<= 1;
            --bitPos;
        }
    }

    void CodeVerifierBase::CheckResults(ResultsBuffer const & results)
    {
        for (auto result : results)
        {
            DocumentHandle handle =
                Factories::CreateDocumentHandle(result.m_slice, result.m_index);

            if (handle.IsActive())
            {
                DocId doc = handle.GetDocId();

                // TODO: Remove temporary debugging output.
                //std::cout
                //    << "  ==> " << doc << std::endl;

                m_observed.insert(doc);
            }
        }

        ASSERT_EQ(m_expected.size(), m_observed.size())
            << "Inconsistent match counts.";

        for (DocId d : m_expected)
        {
            auto it = m_observed.find(d);
            ASSERT_TRUE(it != m_observed.end())
                << "Expected docId "
                << d
                << " not found.";
        }
    }

    //
    // static methods
    //

    RowId CodeVerifierBase::GetFirstRow(ITermTable const & termTable,
                                          Term term)
    {
        RowIdSequence rows(term, termTable);

        auto it = rows.begin();
        // TODO: Implement operator << for RowIdSequence::const_iterator.
        //CHECK_NE(it, rows.end())
        //    << "Expected at least one row.";

        RowId row = *it;

        ++it;
        // TODO: Implement operator << for RowIdSequence::const_iterator.
        //CHECK_EQ(it, rows.end())
        //    << "Expected no more than one row.";

        return row;
    }

    ptrdiff_t CodeVerifierBase::GetRowOffset(
        char const * text,
        Term::StreamId stream,
        IConfiguration const & config,
        ITermTable const & termTable,
        IShard const & shard)
    {
        Term term(text, stream, config);
        RowId row = GetFirstRow(termTable, term);
        return shard.GetRowOffset(row);
    }
}
<commit_msg>Reduce CodeVerifierBase testcase spam.<commit_after>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// 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 <iomanip>
#include <iostream>

#include "gtest/gtest.h"

#include "BitFunnel/Index/Factories.h"
#include "BitFunnel/Index/IIngestor.h"
#include "BitFunnel/Index/IShard.h"
#include "BitFunnel/Index/ISimpleIndex.h"
#include "BitFunnel/Index/RowIdSequence.h"
#include "BitFunnel/Utilities/Factories.h"  // TODO: only for diagnosticStream. Remove.
#include "ByteCodeInterpreter.h"
#include "CodeVerifierBase.h"
#include "ResultsBuffer.h"

namespace BitFunnel
{
    static const ShardId c_shardId = 0;
    static const Term::StreamId c_streamId = 0;

    // TODO: move this method somewhere.
    static uint64_t lzcnt(uint64_t value)
    {
#ifdef _MSC_VER
        return __lzcnt64(value);
#elif __LZCNT__
        return __lzcnt64(value);
#else
        // DESIGN NOTE: this is undefined if the input operand i 0. We currently
        // only call lzcnt in one place, where we've prevously gauranteed that
        // the input isn't 0. This is not safe to use in the general case.
        return static_cast<uint64_t>(__builtin_clzll(value));
#endif
    }

    CodeVerifierBase::CodeVerifierBase(ISimpleIndex const & index,
                                       Rank initialRank)
      : m_index(index),
        m_initialRank(initialRank),
        m_slices(index.GetIngestor().GetShard(c_shardId).GetSliceBuffers()),
        m_resultsCount(0),
        m_verboseMode(false),
        m_expectNoResults(false)
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        auto & sliceBuffers = shard.GetSliceBuffers();
        auto iterationsPerSlice = GetIterationsPerSlice();
        auto iterationCount = iterationsPerSlice * sliceBuffers.size();

        for (size_t i = 0; i < iterationCount; ++i)
        {
            m_iterationValues.push_back(i);
        }
    }

    void CodeVerifierBase::VerboseMode(bool mode)
    {
        m_verboseMode = mode;
    }

    void CodeVerifierBase::ExpectNoResults()
    {
        m_expectNoResults = true;
    }

    std::vector<size_t> const & CodeVerifierBase::GetIterations() const
    {
        return m_iterationValues;
    }

    size_t CodeVerifierBase::GetSliceNumber(size_t iteration) const
    {
        return iteration / GetIterationsPerSlice();
    }

    size_t CodeVerifierBase::GetOffset(size_t iteration) const
    {
        return iteration % GetIterationsPerSlice();
    }

    size_t CodeVerifierBase::GetIterationsPerSlice() const
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        return shard.GetSliceCapacity() >> 6 >> m_initialRank;
    }

    void CodeVerifierBase::DeclareRow(char const * text)
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        m_rowOffsets.push_back(
            GetRowOffset(
                text,
                c_streamId,
                m_index.GetConfiguration(),
                m_index.GetTermTable0(),
                shard));
    }

    uint64_t CodeVerifierBase::GetRowData(size_t row, size_t offset, size_t slice)
    {
        auto & shard = m_index.GetIngestor().GetShard(c_shardId);
        auto const & slices = shard.GetSliceBuffers();
        char const * sliceBuffer = reinterpret_cast<char const *>(slices[slice]);
        uint64_t const * rowPtr =
            reinterpret_cast<uint64_t const *>(sliceBuffer + m_rowOffsets[row]);
        return rowPtr[offset];
    }

    // The class is configured by adding a sequence of of records
    // describing the expected interactions betweeen the matcher and its
    // IResultsProcessor. Each call to Add() corresponds to expectation
    // that the matcher will invoke IResultsProcessor::AddResult(). The
    // accumulator and offset parameters to Add() are the expected
    // parameters to AddResult().
    //
    // The usage pattern for IResultsProcessor is a sequence of calls
    // to AddResult() interspersed with calls to FinishIteration().
    // The call to FinishIteration() provides the void* slice buffer
    // pointer that is applicable to the sequence of calls to AddResult()
    // since the previous call to FinishIteration() (or the start of
    // the matching algorithm if there was no previous call to
    // FinishIteration().
    //
    // The third parameter of the Add() method indicates the slice
    // that expected to be passed on the next call to FinishIteration.
    // The slice parameter is a size_t index into an array of slice
    // buffer pointers associated with the index.
    //
    void CodeVerifierBase::ExpectResult(uint64_t accumulator,
                                        size_t offset,
                                        size_t sliceNumber)
    {
        //// TODO: Remove temporary debugging output.
        //std::cout
        //    << "ExpectResult("
        //    << std::hex << accumulator << std::dec
        //    << ", "
        //    << offset
        //    << ", "
        //    << sliceNumber
        //    << ")"
        //    << std::endl;

        size_t bitPos = 63;
        void * sliceBuffer = m_slices[sliceNumber];

        while (accumulator != 0)
        {
            uint64_t count = lzcnt(accumulator);
            accumulator <<= count;
            bitPos -= count;

            DocIndex docIndex = offset * c_bitsPerQuadword + bitPos;
            DocumentHandle handle =
                Factories::CreateDocumentHandle(sliceBuffer, docIndex);

            if (handle.IsActive())
            {
                DocId id = handle.GetDocId();
                //// TODO: Remove temporary debugging output.
                //std::cout << "  " << id << std::endl;

                if (m_expected.find(id) != m_expected.end())
                {
                    // std::cout << "  Duplicate id " << id << std::endl;
                }

                m_expected.insert(id);
            }

            accumulator <<= 1;
            --bitPos;
        }
    }

    void CodeVerifierBase::CheckResults(ResultsBuffer const & results)
    {
        for (auto result : results)
        {
            DocumentHandle handle =
                Factories::CreateDocumentHandle(result.m_slice, result.m_index);

            if (handle.IsActive())
            {
                DocId doc = handle.GetDocId();

                // TODO: Remove temporary debugging output.
                //std::cout
                //    << "  ==> " << doc << std::endl;

                m_observed.insert(doc);
            }
        }

        ASSERT_EQ(m_expected.size(), m_observed.size())
            << "Inconsistent match counts.";

        for (DocId d : m_expected)
        {
            auto it = m_observed.find(d);
            ASSERT_TRUE(it != m_observed.end())
                << "Expected docId "
                << d
                << " not found.";
        }
    }

    //
    // static methods
    //

    RowId CodeVerifierBase::GetFirstRow(ITermTable const & termTable,
                                          Term term)
    {
        RowIdSequence rows(term, termTable);

        auto it = rows.begin();
        // TODO: Implement operator << for RowIdSequence::const_iterator.
        //CHECK_NE(it, rows.end())
        //    << "Expected at least one row.";

        RowId row = *it;

        ++it;
        // TODO: Implement operator << for RowIdSequence::const_iterator.
        //CHECK_EQ(it, rows.end())
        //    << "Expected no more than one row.";

        return row;
    }

    ptrdiff_t CodeVerifierBase::GetRowOffset(
        char const * text,
        Term::StreamId stream,
        IConfiguration const & config,
        ITermTable const & termTable,
        IShard const & shard)
    {
        Term term(text, stream, config);
        RowId row = GetFirstRow(termTable, term);
        return shard.GetRowOffset(row);
    }
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in
 *	  the documentation and/or other materials provided with the
 *	  distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.	IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "TraceListenerDefault.hpp"

#include <PlatformSupport/PrintWriter.hpp>

#include <DOMSupport/DOMServices.hpp>

#include <XPath/NodeRefListBase.hpp>
#include <XPath/XPath.hpp>

#include "Constants.hpp"
#include "ElemTextLiteral.hpp"
#include "ElemTemplate.hpp"
#include "GenerateEvent.hpp"
#include "SelectionEvent.hpp"
#include "StylesheetRoot.hpp"
#include "TracerEvent.hpp"

TraceListenerDefault::TraceListenerDefault(
			PrintWriter&	thePrintWriter,
			bool			traceTemplates,
			bool			traceElements,
			bool			traceGeneration,
			bool			traceSelection) :
	m_printWriter(thePrintWriter),
	m_traceTemplates(traceTemplates),
	m_traceElements(traceElements),
	m_traceGeneration(traceGeneration),
	m_traceSelection(traceSelection)
{
}

TraceListenerDefault::~TraceListenerDefault()
{
}

void
TraceListenerDefault::trace(const TracerEvent&	ev)
{
	switch(ev.m_styleNode.getXSLToken())
	{
	case Constants::ELEMNAME_TEXTLITERALRESULT:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("    "));

			const ElemTextLiteral&	etl = static_cast<const ElemTextLiteral&>(ev.m_styleNode);

			m_printWriter.println(c_wstr(etl.getText()), etl.getText().size());
		}
		break;

	case Constants::ELEMNAME_TEMPLATE:
		if(m_traceTemplates == true || m_traceElements == true)
		{
			const ElemTemplate&		et = static_cast<const ElemTemplate&>(ev.m_styleNode);

			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());

			const XPath* const	theMatchPattern =
				et.getMatchPattern();

			if(0 != theMatchPattern)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING(" match=\""));
				m_printWriter.print(theMatchPattern->getExpression().getCurrentPattern());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			const QName&	theName = et.getName();

			if(theName.isEmpty() == false)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("name=\""));

				const XalanDOMString&	theNamespace =
					theName.getNamespace();

				if (isEmpty(theNamespace) == false)
				{
					m_printWriter.print(theNamespace);
					m_printWriter.print(':');
				}

				m_printWriter.print(theName.getLocalPart());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			m_printWriter.println();
		}
		break;

	default:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.println(ev.m_styleNode.getElementName());
		}
		break;
	}
}

void
TraceListenerDefault::selected(const SelectionEvent&	ev)
{
    if(m_traceSelection == true)
    {
		const ElemTemplateElement&	ete = ev.m_styleNode;

		if(ev.m_styleNode.getLineNumber() == 0)
		{
			// You may not have line numbers if the selection is occuring from a
			// default template.

			ElemTemplateElement* const	parent = ete.getParentNodeElem();

			if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRootRule())
			{
				m_printWriter.print("(default root rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultTextRule())
			{
				m_printWriter.print("(default text rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRule())
			{
				m_printWriter.print("(default rule) ");
			}
		}
		else
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(", ");
		}

		m_printWriter.print(ete.getElementName());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
		m_printWriter.print(ev.m_attributeName);
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("=\""));
		m_printWriter.print(ev.m_xpath.getExpression().getCurrentPattern());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("\": "));

		if(ev.m_selection->getType() == XObject::eTypeNodeSet)
		{
			m_printWriter.println();

			const NodeRefListBase&	nl = ev.m_selection->nodeset();

			const unsigned int	n = nl.getLength();

			if(n == 0)
			{
				m_printWriter.println(XALAN_STATIC_UCODE_STRING("     [empty node list]"));
			}
			else
			{
				for(unsigned int i = 0; i < n; i++)
				{
					m_printWriter.print(XALAN_STATIC_UCODE_STRING("     "));
					m_printWriter.println(DOMServices::getNodeData(*nl.item(i)));
				}
			}
		}
		else
		{
			m_printWriter.println(ev.m_selection->str());
		}
    }
}

void
TraceListenerDefault::generated(const GenerateEvent&	ev)
{
	if(m_traceGeneration == true)
	{
		switch(ev.m_eventType)
		{
		case GenerateEvent::EVENTTYPE_STARTDOCUMENT:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("STARTDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_ENDDOCUMENT:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENDDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_STARTELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("STARTELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_ENDELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("ENDELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_CHARACTERS:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CHARACTERS: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_CDATA:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CDATA: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_COMMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("COMMENT: "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_PI:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("PI: "));
			m_printWriter.print(ev.m_name);
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_ENTITYREF:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENTITYREF: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_IGNORABLEWHITESPACE:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("IGNORABLEWHITESPACE"));
			break;
		}
	}
}
<commit_msg>Fixed minor formatting glitch.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in
 *	  the documentation and/or other materials provided with the
 *	  distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.	IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "TraceListenerDefault.hpp"

#include <PlatformSupport/PrintWriter.hpp>

#include <DOMSupport/DOMServices.hpp>

#include <XPath/NodeRefListBase.hpp>
#include <XPath/XPath.hpp>

#include "Constants.hpp"
#include "ElemTextLiteral.hpp"
#include "ElemTemplate.hpp"
#include "GenerateEvent.hpp"
#include "SelectionEvent.hpp"
#include "StylesheetRoot.hpp"
#include "TracerEvent.hpp"

TraceListenerDefault::TraceListenerDefault(
			PrintWriter&	thePrintWriter,
			bool			traceTemplates,
			bool			traceElements,
			bool			traceGeneration,
			bool			traceSelection) :
	m_printWriter(thePrintWriter),
	m_traceTemplates(traceTemplates),
	m_traceElements(traceElements),
	m_traceGeneration(traceGeneration),
	m_traceSelection(traceSelection)
{
}

TraceListenerDefault::~TraceListenerDefault()
{
}

void
TraceListenerDefault::trace(const TracerEvent&	ev)
{
	switch(ev.m_styleNode.getXSLToken())
	{
	case Constants::ELEMNAME_TEXTLITERALRESULT:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("    "));

			const ElemTextLiteral&	etl = static_cast<const ElemTextLiteral&>(ev.m_styleNode);

			m_printWriter.println(c_wstr(etl.getText()), etl.getText().size());
		}
		break;

	case Constants::ELEMNAME_TEMPLATE:
		if(m_traceTemplates == true || m_traceElements == true)
		{
			const ElemTemplate&		et = static_cast<const ElemTemplate&>(ev.m_styleNode);

			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());

			const XPath* const	theMatchPattern =
				et.getMatchPattern();

			if(0 != theMatchPattern)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING(" match=\""));
				m_printWriter.print(theMatchPattern->getExpression().getCurrentPattern());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			const QName&	theName = et.getName();

			if(theName.isEmpty() == false)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("name=\""));

				const XalanDOMString&	theNamespace =
					theName.getNamespace();

				if (isEmpty(theNamespace) == false)
				{
					m_printWriter.print(theNamespace);
					m_printWriter.print(':');
				}

				m_printWriter.print(theName.getLocalPart());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			m_printWriter.println();
		}
		break;

	default:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.println(ev.m_styleNode.getElementName());
		}
		break;
	}
}

void
TraceListenerDefault::selected(const SelectionEvent&	ev)
{
    if(m_traceSelection == true)
    {
		const ElemTemplateElement&	ete = ev.m_styleNode;

		if(ev.m_styleNode.getLineNumber() == 0)
		{
			// You may not have line numbers if the selection is occuring from a
			// default template.

			ElemTemplateElement* const	parent = ete.getParentNodeElem();

			if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRootRule())
			{
				m_printWriter.print("(default root rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultTextRule())
			{
				m_printWriter.print("(default text rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRule())
			{
				m_printWriter.print("(default rule) ");
			}
		}
		else
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(", ");
		}

		m_printWriter.print(ete.getElementName());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
		m_printWriter.print(ev.m_attributeName);
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("=\""));
		m_printWriter.print(ev.m_xpath.getExpression().getCurrentPattern());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("\": "));

		if(ev.m_selection->getType() == XObject::eTypeNodeSet)
		{
			m_printWriter.println();

			const NodeRefListBase&	nl = ev.m_selection->nodeset();

			const unsigned int	n = nl.getLength();

			if(n == 0)
			{
				m_printWriter.println(XALAN_STATIC_UCODE_STRING("     [empty node list]"));
			}
			else
			{
				for(unsigned int i = 0; i < n; i++)
				{
					m_printWriter.print(XALAN_STATIC_UCODE_STRING("     "));
					m_printWriter.println(DOMServices::getNodeData(*nl.item(i)));
				}
			}
		}
		else
		{
			m_printWriter.println(ev.m_selection->str());
		}
    }
}

void
TraceListenerDefault::generated(const GenerateEvent&	ev)
{
	if(m_traceGeneration == true)
	{
		switch(ev.m_eventType)
		{
		case GenerateEvent::EVENTTYPE_STARTDOCUMENT:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("STARTDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_ENDDOCUMENT:
			m_printWriter.println();
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENDDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_STARTELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("STARTELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_ENDELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("ENDELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_CHARACTERS:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CHARACTERS: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_CDATA:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CDATA: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_COMMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("COMMENT: "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_PI:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("PI: "));
			m_printWriter.print(ev.m_name);
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_ENTITYREF:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENTITYREF: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_IGNORABLEWHITESPACE:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("IGNORABLEWHITESPACE"));
			break;
		}
	}
}
<|endoftext|>


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

  Library: XNAT/Core

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

#include "ctkXnatDataModel.h"
#include "ctkXnatListModel.h"
#include "ctkXnatProject.h"
#include "ctkXnatSubject.h"
#include "ctkXnatExperiment.h"
#include "ctkXnatScanFolder.h"
#include "ctkXnatScan.h"

#include <iostream>
#include <typeinfo>

#include <QDebug>

//----------------------------------------------------------------------------
ctkXnatListModel::ctkXnatListModel()
  : RootObject(0)
{
}

//----------------------------------------------------------------------------
void ctkXnatListModel::setRootObject(ctkXnatObject* root)
{
  RootObject = root;
}

//----------------------------------------------------------------------------
ctkXnatObject* ctkXnatListModel::rootObject()
{
  return RootObject;
}

//----------------------------------------------------------------------------
int ctkXnatListModel::rowCount(const QModelIndex& /*parent*/) const
{
  if (!RootObject) return 0;
  return RootObject->children().size();
}

//----------------------------------------------------------------------------
QVariant ctkXnatListModel::data(const QModelIndex& index, int role) const
{
  if (!RootObject) return QVariant();

  if (role == Qt::DisplayRole)
  {
    ctkXnatObject* child = RootObject->children().at(index.row());
    if (!child)
    {
      qWarning() << "child at index" << index << "is NULL!";
    }
    else
    {
      QString displayData = child->name();
      if (displayData.isEmpty())
      {
        displayData = child->id();
      }
      return displayData;
    }
  }
  else if (role == Qt::UserRole)
  {
    return QVariant::fromValue(RootObject->children().at(index.row()));
  }
  return QVariant();
}

//----------------------------------------------------------------------------
QVariant ctkXnatListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int role) const
{
  if (role == Qt::DisplayRole)
  {
    if (!RootObject) return QString("Unavailable");

    return RootObject->childDataType();
  }
  return QVariant();
}
<commit_msg>Use same way to display data like in the ctkXnatTreeModel<commit_after>/*=============================================================================

  Library: XNAT/Core

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

#include "ctkXnatDataModel.h"
#include "ctkXnatListModel.h"
#include "ctkXnatProject.h"
#include "ctkXnatSubject.h"
#include "ctkXnatExperiment.h"
#include "ctkXnatScanFolder.h"
#include "ctkXnatScan.h"

#include <iostream>
#include <typeinfo>

#include <QDebug>

//----------------------------------------------------------------------------
ctkXnatListModel::ctkXnatListModel()
  : RootObject(0)
{
}

//----------------------------------------------------------------------------
void ctkXnatListModel::setRootObject(ctkXnatObject* root)
{
  RootObject = root;
}

//----------------------------------------------------------------------------
ctkXnatObject* ctkXnatListModel::rootObject()
{
  return RootObject;
}

//----------------------------------------------------------------------------
int ctkXnatListModel::rowCount(const QModelIndex& /*parent*/) const
{
  if (!RootObject) return 0;
  return RootObject->children().size();
}

//----------------------------------------------------------------------------
QVariant ctkXnatListModel::data(const QModelIndex& index, int role) const
{
  if (!RootObject) return QVariant();

  if (role == Qt::DisplayRole)
  {
    ctkXnatObject* child = RootObject->children().at(index.row());
    QString displayData = child->name();
    if (displayData.isEmpty())
    {
      displayData = child->property("label");
    }
    return displayData;
  }
  else if (role == Qt::UserRole)
  {
    return QVariant::fromValue(RootObject->children().at(index.row()));
  }
  return QVariant();
}

//----------------------------------------------------------------------------
QVariant ctkXnatListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int role) const
{
  if (role == Qt::DisplayRole)
  {
    if (!RootObject) return QString("Unavailable");

    return RootObject->childDataType();
  }
  return QVariant();
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// AliFemtoGammaMonitorAlpha - A correlation function that analyzes           //
// two particle correlations with respect to the angle between two particles  //
// and pseudorapidity (eta) difference                                        //
//                                                                            //
// Authors: Elena Rogochaya Adam.Kisiel@cern.ch                               //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#include "AliFemtoCorrFctnGammaMonitorAlpha.h"
//#include "AliFemtoHisto.hh"
#include <cstdio>
#include <TMath.h>

#ifdef __ROOT__
ClassImp(AliFemtoCorrFctnGammaMonitorAlpha)
#endif

//____________________________
AliFemtoCorrFctnGammaMonitorAlpha::AliFemtoCorrFctnGammaMonitorAlpha(const char* title, const int& aMinvBins=20, const int& aDAlphaBins=20):
  AliFemtoCorrFctn(),
  fNumPMinvDAlpha(0),
  fDenPMinvDAlpha(0),
  fNumNMinvDAlpha(0),
  fDenNMinvDAlpha(0)
{
  // set up numerator
  char tTitNumD[101] = "NumPMinvAlpha";
  strncat(tTitNumD,title, 100);
  fNumPMinvDAlpha = new TH2D(tTitNumD,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);
  // set up denominator
  char tTitDenD[101] = "DenPMinvAlpha";
  strncat(tTitDenD,title, 100);
  fDenPMinvDAlpha = new TH2D(tTitDenD,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);

  // set up numerator
  char tTitNumR[101] = "NumNMinvAlpha";
  strncat(tTitNumR,title, 100);
  fNumNMinvDAlpha = new TH2D(tTitNumR,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);
  // set up denominator
  char tTitDenR[101] = "DenNMinvAlpha";
  strncat(tTitDenR,title, 100);
  fDenNMinvDAlpha = new TH2D(tTitDenR,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);

  // to enable error bar calculation...
  fNumPMinvDAlpha->Sumw2();
  fDenPMinvDAlpha->Sumw2();
  fNumNMinvDAlpha->Sumw2();
  fDenNMinvDAlpha->Sumw2();
}

//____________________________
AliFemtoCorrFctnGammaMonitorAlpha::AliFemtoCorrFctnGammaMonitorAlpha(const AliFemtoCorrFctnGammaMonitorAlpha& aCorrFctn) :
  AliFemtoCorrFctn(),
  fNumPMinvDAlpha(0),
  fDenPMinvDAlpha(0),
  fNumNMinvDAlpha(0),
  fDenNMinvDAlpha(0)
{
  // copy constructor
  if (aCorrFctn.fNumPMinvDAlpha)
    fNumPMinvDAlpha = new TH2D(*aCorrFctn.fNumPMinvDAlpha);
  else
    fNumPMinvDAlpha = 0;
  if (aCorrFctn.fDenPMinvDAlpha)
    fDenPMinvDAlpha = new TH2D(*aCorrFctn.fDenPMinvDAlpha);
  else
    fDenPMinvDAlpha = 0;

  if (aCorrFctn.fNumNMinvDAlpha)
    fNumNMinvDAlpha = new TH2D(*aCorrFctn.fNumNMinvDAlpha);
  else
    fNumNMinvDAlpha = 0;
  if (aCorrFctn.fDenNMinvDAlpha)
    fDenNMinvDAlpha = new TH2D(*aCorrFctn.fDenNMinvDAlpha);
  else
    fDenNMinvDAlpha = 0;

}
//____________________________
AliFemtoCorrFctnGammaMonitorAlpha::~AliFemtoCorrFctnGammaMonitorAlpha(){
  // destructor
  delete fNumPMinvDAlpha;
  delete fDenPMinvDAlpha;
  delete fNumNMinvDAlpha;
  delete fDenNMinvDAlpha;
}
//_________________________
AliFemtoCorrFctnGammaMonitorAlpha& AliFemtoCorrFctnGammaMonitorAlpha::operator=(const AliFemtoCorrFctnGammaMonitorAlpha& aCorrFctn)
{
  // assignment operator
  if (this == &aCorrFctn)
    return *this;

  if (aCorrFctn.fNumPMinvDAlpha)
    fNumPMinvDAlpha = new TH2D(*aCorrFctn.fNumPMinvDAlpha);
  else
    fNumPMinvDAlpha = 0;
  if (aCorrFctn.fDenPMinvDAlpha)
    fDenPMinvDAlpha = new TH2D(*aCorrFctn.fDenPMinvDAlpha);
  else
    fDenPMinvDAlpha = 0;

  if (aCorrFctn.fNumNMinvDAlpha)
    fNumNMinvDAlpha = new TH2D(*aCorrFctn.fNumNMinvDAlpha);
  else
    fNumNMinvDAlpha = 0;
  if (aCorrFctn.fDenNMinvDAlpha)
    fDenNMinvDAlpha = new TH2D(*aCorrFctn.fDenNMinvDAlpha);
  else
    fDenNMinvDAlpha = 0;

  return *this;
}
//_________________________
void AliFemtoCorrFctnGammaMonitorAlpha::Finish(){
  // here is where we should normalize, fit, etc...
  // we should NOT Draw() the histos (as I had done it below),
  // since we want to insulate ourselves from root at this level
  // of the code.  Do it instead at root command line with browser.
  //  mShareNumerator->Draw();
  //mShareDenominator->Draw();
  //mRatio->Draw();

}

//____________________________
AliFemtoString AliFemtoCorrFctnGammaMonitorAlpha::Report()
{
  // create report
  AliFemtoString report = "Gamma MonitorAlpha Function Report:\n";
  report += Form("Number of entries in numerator:\t%E\n",fNumPMinvDAlpha->GetEntries());
  report += Form("Number of entries in denominator:\t%E\n",fDenPMinvDAlpha->GetEntries());
  //  report += mCoulombWeight->Report();

  return report;
}
//____________________________
void AliFemtoCorrFctnGammaMonitorAlpha::AddRealPair( AliFemtoPair* pair){
  // add real (effect) pair
  double me = 0.000511;

  double dalpha = TMath::Abs((  pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x()
		   + pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y()
		   + pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()
			       )/pair->Track1()->Track()->P().Mag()/pair->Track2()->Track()->P().Mag());

  double e1 = TMath::Sqrt(me*me + pair->Track1()->Track()->P().Mag2());
  double e2 = TMath::Sqrt(me*me + pair->Track2()->Track()->P().Mag2());

  double minv = (2*me*me + 2*(e1*e2 -
			     pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x() -
			     pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y() -
					 pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()));

  double sminv = TMath::Sqrt(minv);

  if (pair->KSide()>0.0) {
    fNumPMinvDAlpha->Fill(sminv, dalpha);
  }
  else {
    fNumNMinvDAlpha->Fill(sminv, dalpha);
  }
}
//____________________________
void AliFemtoCorrFctnGammaMonitorAlpha::AddMixedPair( AliFemtoPair* pair){
  // add mixed (background) pair
  double me = 0.000511;

  double dalpha = TMath::Abs((  pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x()
		   + pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y()
		   + pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()
				)/pair->Track1()->Track()->P().Mag()/pair->Track2()->Track()->P().Mag());

  double e1 = TMath::Sqrt(me*me + pair->Track1()->Track()->P().Mag2());
  double e2 = TMath::Sqrt(me*me + pair->Track2()->Track()->P().Mag2());

  double minv = (2*me*me + 2*(e1*e2 -
			     pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x() -
			     pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y() -
					 pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()));

  double sminv = TMath::Sqrt(minv);

  if (pair->KSide()>0.0) {
    fDenPMinvDAlpha->Fill(sminv, dalpha);
  }
  else {
    fDenNMinvDAlpha->Fill(sminv, dalpha);
  }
}

void AliFemtoCorrFctnGammaMonitorAlpha::WriteHistos()
{
  // Write out result histograms
  fNumPMinvDAlpha->Write();
  fDenPMinvDAlpha->Write();
  fNumNMinvDAlpha->Write();
  fDenNMinvDAlpha->Write();
}

TList* AliFemtoCorrFctnGammaMonitorAlpha::GetOutputList()
{
  // Prepare the list of objects to be written to the output
  TList *tOutputList = new TList();

  tOutputList->Add(fNumPMinvDAlpha);
  tOutputList->Add(fDenPMinvDAlpha);
  tOutputList->Add(fNumNMinvDAlpha);
  tOutputList->Add(fDenNMinvDAlpha);

  return tOutputList;
}
<commit_msg>AliFemtoCorrFctnGammaMonitorAlpha - Code clean<commit_after>////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// AliFemtoGammaMonitorAlpha - A correlation function that analyzes           //
// two particle correlations with respect to the angle between two particles  //
// and pseudorapidity (eta) difference                                        //
//                                                                            //
// Authors: Elena Rogochaya Adam.Kisiel@cern.ch                               //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#include "AliFemtoCorrFctnGammaMonitorAlpha.h"
//#include "AliFemtoHisto.hh"
#include <cstdio>
#include <TMath.h>

#ifdef __ROOT__
ClassImp(AliFemtoCorrFctnGammaMonitorAlpha)
#endif

//____________________________
AliFemtoCorrFctnGammaMonitorAlpha::AliFemtoCorrFctnGammaMonitorAlpha(const char* title, const int& aMinvBins=20, const int& aDAlphaBins=20):
  AliFemtoCorrFctn(),
  fNumPMinvDAlpha(0),
  fDenPMinvDAlpha(0),
  fNumNMinvDAlpha(0),
  fDenNMinvDAlpha(0)
{
  // set up numerator
  char tTitNumD[101] = "NumPMinvAlpha";
  strncat(tTitNumD,title, 100);
  fNumPMinvDAlpha = new TH2D(tTitNumD,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);
  // set up denominator
  char tTitDenD[101] = "DenPMinvAlpha";
  strncat(tTitDenD,title, 100);
  fDenPMinvDAlpha = new TH2D(tTitDenD,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);

  // set up numerator
  char tTitNumR[101] = "NumNMinvAlpha";
  strncat(tTitNumR,title, 100);
  fNumNMinvDAlpha = new TH2D(tTitNumR,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);
  // set up denominator
  char tTitDenR[101] = "DenNMinvAlpha";
  strncat(tTitDenR,title, 100);
  fDenNMinvDAlpha = new TH2D(tTitDenR,title,aMinvBins,0.0,1.0,aDAlphaBins,0.996,1.0);

  // to enable error bar calculation...
  fNumPMinvDAlpha->Sumw2();
  fDenPMinvDAlpha->Sumw2();
  fNumNMinvDAlpha->Sumw2();
  fDenNMinvDAlpha->Sumw2();
}

//____________________________
AliFemtoCorrFctnGammaMonitorAlpha::AliFemtoCorrFctnGammaMonitorAlpha(const AliFemtoCorrFctnGammaMonitorAlpha& aCorrFctn) :
  AliFemtoCorrFctn(),
  fNumPMinvDAlpha(nullptr),
  fDenPMinvDAlpha(nullptr),
  fNumNMinvDAlpha(nullptr),
  fDenNMinvDAlpha(nullptr)
{
  // copy constructor
  fNumPMinvDAlpha = new TH2D(*aCorrFctn.fNumPMinvDAlpha);
  fDenPMinvDAlpha = new TH2D(*aCorrFctn.fDenPMinvDAlpha);
  fNumNMinvDAlpha = new TH2D(*aCorrFctn.fNumNMinvDAlpha);
  fDenNMinvDAlpha = new TH2D(*aCorrFctn.fDenNMinvDAlpha);
}
//____________________________
AliFemtoCorrFctnGammaMonitorAlpha::~AliFemtoCorrFctnGammaMonitorAlpha(){
  // destructor
  delete fNumPMinvDAlpha;
  delete fDenPMinvDAlpha;
  delete fNumNMinvDAlpha;
  delete fDenNMinvDAlpha;
}
//_________________________
AliFemtoCorrFctnGammaMonitorAlpha& AliFemtoCorrFctnGammaMonitorAlpha::operator=(const AliFemtoCorrFctnGammaMonitorAlpha& aCorrFctn)
{
  // assignment operator
  if (this == &aCorrFctn)
    return *this;

  *fNumPMinvDAlpha = *aCorrFctn.fNumPMinvDAlpha;
  *fDenPMinvDAlpha = *aCorrFctn.fDenPMinvDAlpha;
  *fNumNMinvDAlpha = *aCorrFctn.fNumNMinvDAlpha;
  *fDenNMinvDAlpha = *aCorrFctn.fDenNMinvDAlpha;

  return *this;
}
//_________________________
void AliFemtoCorrFctnGammaMonitorAlpha::Finish()
{
  // here is where we should normalize, fit, etc...
  // we should NOT Draw() the histos (as I had done it below),
  // since we want to insulate ourselves from root at this level
  // of the code.  Do it instead at root command line with browser.
  //  mShareNumerator->Draw();
  //mShareDenominator->Draw();
  //mRatio->Draw();
}

//____________________________
AliFemtoString AliFemtoCorrFctnGammaMonitorAlpha::Report()
{
  // create report
  AliFemtoString report = "Gamma MonitorAlpha Function Report:\n";
  report += Form("Number of entries in numerator:\t%E\n",fNumPMinvDAlpha->GetEntries());
  report += Form("Number of entries in denominator:\t%E\n",fDenPMinvDAlpha->GetEntries());
  //  report += mCoulombWeight->Report();

  return report;
}
//____________________________
void AliFemtoCorrFctnGammaMonitorAlpha::AddRealPair( AliFemtoPair* pair){
  // add real (effect) pair
  double me = 0.000511;

  double dalpha = TMath::Abs((  pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x()
		   + pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y()
		   + pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()
			       )/pair->Track1()->Track()->P().Mag()/pair->Track2()->Track()->P().Mag());

  double e1 = TMath::Sqrt(me*me + pair->Track1()->Track()->P().Mag2());
  double e2 = TMath::Sqrt(me*me + pair->Track2()->Track()->P().Mag2());

  double minv = (2*me*me + 2*(e1*e2 -
			     pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x() -
			     pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y() -
					 pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()));

  double sminv = TMath::Sqrt(minv);

  if (pair->KSide()>0.0) {
    fNumPMinvDAlpha->Fill(sminv, dalpha);
  }
  else {
    fNumNMinvDAlpha->Fill(sminv, dalpha);
  }
}
//____________________________
void AliFemtoCorrFctnGammaMonitorAlpha::AddMixedPair( AliFemtoPair* pair){
  // add mixed (background) pair
  double me = 0.000511;

  double dalpha = TMath::Abs((  pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x()
		   + pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y()
		   + pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()
				)/pair->Track1()->Track()->P().Mag()/pair->Track2()->Track()->P().Mag());

  double e1 = TMath::Sqrt(me*me + pair->Track1()->Track()->P().Mag2());
  double e2 = TMath::Sqrt(me*me + pair->Track2()->Track()->P().Mag2());

  double minv = (2*me*me + 2*(e1*e2 -
			     pair->Track1()->Track()->P().x()*pair->Track2()->Track()->P().x() -
			     pair->Track1()->Track()->P().y()*pair->Track2()->Track()->P().y() -
					 pair->Track1()->Track()->P().z()*pair->Track2()->Track()->P().z()));

  double sminv = TMath::Sqrt(minv);

  if (pair->KSide()>0.0) {
    fDenPMinvDAlpha->Fill(sminv, dalpha);
  }
  else {
    fDenNMinvDAlpha->Fill(sminv, dalpha);
  }
}

void AliFemtoCorrFctnGammaMonitorAlpha::WriteHistos()
{
  // Write out result histograms
  fNumPMinvDAlpha->Write();
  fDenPMinvDAlpha->Write();
  fNumNMinvDAlpha->Write();
  fDenNMinvDAlpha->Write();
}

TList* AliFemtoCorrFctnGammaMonitorAlpha::GetOutputList()
{
  // Prepare the list of objects to be written to the output
  TList *tOutputList = new TList();

  tOutputList->Add(fNumPMinvDAlpha);
  tOutputList->Add(fDenPMinvDAlpha);
  tOutputList->Add(fNumNMinvDAlpha);
  tOutputList->Add(fDenNMinvDAlpha);

  return tOutputList;
}
<|endoftext|>


<commit_before><commit_msg>Refactor<commit_after><|endoftext|>


<commit_before>#include <cstring>
#include <string>

#include <VBE/config.hpp>
#include <VBE/graphics/OpenGL.hpp>
#include <VBE/graphics/Shader.hpp>
#include <VBE/graphics/ShaderProgram.hpp>
#include <VBE/graphics/Uniform.hpp>
#include <VBE/system/Log.hpp>
#include <VBE/system/Storage.hpp>

GLuint ShaderProgram::current(0);

ShaderProgram::ShaderProgram() : programHandle(0) {
}

ShaderProgram::ShaderProgram(std::initializer_list<std::pair<Shader::Type, std::string>> shaders) {

	GL_ASSERT(programHandle = glCreateProgram());

	std::vector<Shader> parts;
	for(const auto& s : shaders) {
		Shader shader(s.first, s.second);
		shader.attach(programHandle);
		parts.push_back(std::move(shader));
	}

	link();
	retrieveProgramInfo();
}

ShaderProgram::~ShaderProgram() {
	if(programHandle != 0)
		GL_ASSERT(glDeleteProgram(programHandle));
	for(std::map<std::string, Uniform*>::iterator it = uniforms.begin(); it != uniforms.end(); ++it)
		delete it->second;
}

ShaderProgram::ShaderProgram(const std::string &vert, const std::string &frag) :
	ShaderProgram({std::pair<Shader::Type, std::string>(Shader::Type::Vertex, vert),
				  std::pair<Shader::Type, std::string>(Shader::Type::Fragment, frag)}) {
}

ShaderProgram::ShaderProgram(std::unique_ptr<std::istream> vert, std::unique_ptr<std::istream> frag) :
	ShaderProgram(Storage::readToString(std::move(vert)),
				  Storage::readToString(std::move(frag))) {
}

#ifndef VBE_GLES2
ShaderProgram::ShaderProgram(const std::string& vert, const std::string& geom, const std::string& frag)
	: ShaderProgram({std::pair<Shader::Type, std::string>(Shader::Type::Vertex, vert),
					std::pair<Shader::Type, std::string>(Shader::Type::Geometry, geom),
					std::pair<Shader::Type, std::string>(Shader::Type::Fragment, frag)}) {
}

ShaderProgram::ShaderProgram(const std::string& vert, const std::string& tessControl, const std::string& tessEval, const std::string& geom, const std::string& frag)
	: ShaderProgram({std::pair<Shader::Type, std::string>(Shader::Type::Vertex, vert),
					std::pair<Shader::Type, std::string>(Shader::Type::TessControl, tessControl),
					std::pair<Shader::Type, std::string>(Shader::Type::TessEval, tessEval),
					std::pair<Shader::Type, std::string>(Shader::Type::Geometry, geom),
					std::pair<Shader::Type, std::string>(Shader::Type::Fragment, frag)}) {
}

ShaderProgram::ShaderProgram(std::unique_ptr<std::istream> vert, std::unique_ptr<std::istream> geom, std::unique_ptr<std::istream> frag) :
	ShaderProgram(Storage::readToString(std::move(vert)),
				  Storage::readToString(std::move(geom)),
				  Storage::readToString(std::move(frag))) {
}
ShaderProgram::ShaderProgram(std::unique_ptr<std::istream> vert, std::unique_ptr<std::istream> tessControl, std::unique_ptr<std::istream> tessEval, std::unique_ptr<std::istream> geom, std::unique_ptr<std::istream> frag) :
	ShaderProgram(Storage::readToString(std::move(vert)),
				  Storage::readToString(std::move(tessControl)),
				  Storage::readToString(std::move(tessEval)),
				  Storage::readToString(std::move(geom)),
				  Storage::readToString(std::move(frag))) {
}
#endif

void ShaderProgram::printInfoLog() {
	VBE_ASSERT(programHandle != 0, "Trying to query nullptr program");
	int length = 0;
	GL_ASSERT(glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &length));
	if (length > 1) {
		GLchar* infoLog = new GLchar[length];
		GL_ASSERT(glGetProgramInfoLog(programHandle, length, nullptr, infoLog));
		VBE_LOG(infoLog );
		delete[] infoLog;
	}
}

void ShaderProgram::use() const {
	VBE_ASSERT(programHandle != 0, "Trying to use null program");
	if(current != programHandle) {
		current = programHandle;
		GL_ASSERT(glUseProgram(programHandle));
	}
	for(std::map<std::string, Uniform*>::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
		it->second->ready();
}

bool ShaderProgram::hasUniform(const std::string &name) const {
	return uniforms.find(name) != uniforms.end();
}

Uniform* ShaderProgram::uniform(const std::string &name) const {
	VBE_ASSERT(uniforms.find(name) != uniforms.end(), "Trying to retrieve unexisting uniform " << name);
	VBE_ASSERT(programHandle != 0, "Trying to retrieve uniform from nullptr program");
	return uniforms.at(name);
}

void ShaderProgram::link() {
	GL_ASSERT(glLinkProgram(programHandle));
	//CHECK FOR LINK SUCCESS
	GLint success;
	GL_ASSERT(glGetProgramiv(programHandle, GL_LINK_STATUS, &success));
	if (success != GL_TRUE) {
		printInfoLog();
		VBE_ASSERT(false, "Linking program failed" );
	}
	VBE_DLOG( " - Linked program successfully. PROGRAMID: " << programHandle );
}

void ShaderProgram::retrieveProgramInfo() {
	//RETRIEVE ATTRIBUTE DATA
	GLint activeAttributes;
	GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTES, &activeAttributes));
	if (activeAttributes > 0) {
		GLint length;
		GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length));
		if (length > 0) {
			GLchar* attribName = new GLchar[length + 1];
			GLint attribSize;
			GLenum attribType;
			GLint attribLocation;
			for (int i = 0; i < activeAttributes; ++i) {
				// Query attribute info.
				GL_ASSERT(glGetActiveAttrib(programHandle, i, length, nullptr, &attribSize, &attribType, attribName));
				attribName[length] = '\0';

				// Query the pre-assigned attribute location.
				attribLocation = glGetAttribLocation(programHandle, attribName);

				// Assign the vertex attribute mapping for the effect.
				attributes[attribName] = attribLocation;
			}
			delete[] attribName;
		}
	}

	//RETRIEVE UNIFORM INFO
	GLint activeUniforms;
	GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_UNIFORMS, &activeUniforms));
	if (activeUniforms > 0) {
		GLint length;
		GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length));
		if (length > 0) {
			GLchar* uniformName = new GLchar[length + 1];
			GLint uniformSize;
			GLenum uniformType;
			GLint uniformLocation;
			unsigned int texUnit = 0;
			for (int i = 0; i < activeUniforms; ++i) {
				// Query uniform info.
				GL_ASSERT(glGetActiveUniform(programHandle, i, length, nullptr, &uniformSize, &uniformType, uniformName));
				uniformName[length] = '\0';  // nullptr terminate
				if (uniformSize > 1 && length > 3) {
					// This is an array uniform. I'm stripping array indexers off it since GL does not
					// seem to be consistent across different drivers/implementations in how it returns
					// array uniforms. On some systems it will return "u_matrixArray", while on others
					// it will return "u_matrixArray[0]".

					//TODO rewrite this using std::string please
					char* c = strrchr(uniformName, '[');
					if (c) *c = '\0';
				}

				// Query the pre-assigned uniform location.
				uniformLocation = glGetUniformLocation(programHandle, uniformName);
				VBE_ASSERT(glGetError() == GL_NO_ERROR, "Failed to get uniform location");
				Uniform* uniform = new Uniform(uniformSize, uniformType, uniformLocation);
				if(Uniform::isSampler(uniformType)) uniform->texUnit = texUnit++;
				uniforms[uniformName] = uniform;
			}
			delete[] uniformName;
		}
	}

	//PRINT ATTRIBUTE INFO
	VBE_DLOG(" - Printing attribute info:" );
	for(std::map<std::string, GLint>::iterator it = attributes.begin(); it != attributes.end(); ++it) {
		VBE_DLOG("  - Name: " << it->first);
		VBE_DLOG( "    Location: " << it->second);
	}

	//PRINT UNIFORM INFO
	VBE_DLOG(" - Printing uniform info:" );
	for(std::map<std::string, Uniform*>::iterator it = uniforms.begin(); it != uniforms.end(); ++it) {
		VBE_DLOG("  - Name: " << it->first);
		it->second->log();
	}
}

ShaderProgram::ShaderProgram(ShaderProgram&& rhs) : ShaderProgram() {
	using std::swap;
	swap(*this, rhs);
}

ShaderProgram& ShaderProgram::operator=(ShaderProgram&& rhs) {
	using std::swap;
	swap(*this, rhs);
	return *this;
}

void swap(ShaderProgram& a, ShaderProgram& b) {
	using std::swap;

	swap(a.attributes, b.attributes);
	swap(a.uniforms, b.uniforms);
	swap(a.programHandle, b.programHandle);
}

<commit_msg>Use range for.<commit_after>#include <cstring>
#include <string>

#include <VBE/config.hpp>
#include <VBE/graphics/OpenGL.hpp>
#include <VBE/graphics/Shader.hpp>
#include <VBE/graphics/ShaderProgram.hpp>
#include <VBE/graphics/Uniform.hpp>
#include <VBE/system/Log.hpp>
#include <VBE/system/Storage.hpp>

GLuint ShaderProgram::current(0);

ShaderProgram::ShaderProgram() : programHandle(0) {
}

ShaderProgram::ShaderProgram(std::initializer_list<std::pair<Shader::Type, std::string>> shaders) {

	GL_ASSERT(programHandle = glCreateProgram());

	std::vector<Shader> parts;
	for(const auto& s : shaders) {
		Shader shader(s.first, s.second);
		shader.attach(programHandle);
		parts.push_back(std::move(shader));
	}

	link();
	retrieveProgramInfo();
}

ShaderProgram::~ShaderProgram() {
	if(programHandle != 0)
		GL_ASSERT(glDeleteProgram(programHandle));
	for(const auto& e : uniforms)
		delete e.second;
}

ShaderProgram::ShaderProgram(const std::string &vert, const std::string &frag) :
	ShaderProgram({std::pair<Shader::Type, std::string>(Shader::Type::Vertex, vert),
				  std::pair<Shader::Type, std::string>(Shader::Type::Fragment, frag)}) {
}

ShaderProgram::ShaderProgram(std::unique_ptr<std::istream> vert, std::unique_ptr<std::istream> frag) :
	ShaderProgram(Storage::readToString(std::move(vert)),
				  Storage::readToString(std::move(frag))) {
}

#ifndef VBE_GLES2
ShaderProgram::ShaderProgram(const std::string& vert, const std::string& geom, const std::string& frag)
	: ShaderProgram({std::pair<Shader::Type, std::string>(Shader::Type::Vertex, vert),
					std::pair<Shader::Type, std::string>(Shader::Type::Geometry, geom),
					std::pair<Shader::Type, std::string>(Shader::Type::Fragment, frag)}) {
}

ShaderProgram::ShaderProgram(const std::string& vert, const std::string& tessControl, const std::string& tessEval, const std::string& geom, const std::string& frag)
	: ShaderProgram({std::pair<Shader::Type, std::string>(Shader::Type::Vertex, vert),
					std::pair<Shader::Type, std::string>(Shader::Type::TessControl, tessControl),
					std::pair<Shader::Type, std::string>(Shader::Type::TessEval, tessEval),
					std::pair<Shader::Type, std::string>(Shader::Type::Geometry, geom),
					std::pair<Shader::Type, std::string>(Shader::Type::Fragment, frag)}) {
}

ShaderProgram::ShaderProgram(std::unique_ptr<std::istream> vert, std::unique_ptr<std::istream> geom, std::unique_ptr<std::istream> frag) :
	ShaderProgram(Storage::readToString(std::move(vert)),
				  Storage::readToString(std::move(geom)),
				  Storage::readToString(std::move(frag))) {
}
ShaderProgram::ShaderProgram(std::unique_ptr<std::istream> vert, std::unique_ptr<std::istream> tessControl, std::unique_ptr<std::istream> tessEval, std::unique_ptr<std::istream> geom, std::unique_ptr<std::istream> frag) :
	ShaderProgram(Storage::readToString(std::move(vert)),
				  Storage::readToString(std::move(tessControl)),
				  Storage::readToString(std::move(tessEval)),
				  Storage::readToString(std::move(geom)),
				  Storage::readToString(std::move(frag))) {
}
#endif

void ShaderProgram::printInfoLog() {
	VBE_ASSERT(programHandle != 0, "Trying to query nullptr program");
	int length = 0;
	GL_ASSERT(glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &length));
	if (length > 1) {
		GLchar* infoLog = new GLchar[length];
		GL_ASSERT(glGetProgramInfoLog(programHandle, length, nullptr, infoLog));
		VBE_LOG(infoLog );
		delete[] infoLog;
	}
}

void ShaderProgram::use() const {
	VBE_ASSERT(programHandle != 0, "Trying to use null program");
	if(current != programHandle) {
		current = programHandle;
		GL_ASSERT(glUseProgram(programHandle));
	}
	for(std::map<std::string, Uniform*>::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
		it->second->ready();
}

bool ShaderProgram::hasUniform(const std::string &name) const {
	return uniforms.find(name) != uniforms.end();
}

Uniform* ShaderProgram::uniform(const std::string &name) const {
	VBE_ASSERT(uniforms.find(name) != uniforms.end(), "Trying to retrieve unexisting uniform " << name);
	VBE_ASSERT(programHandle != 0, "Trying to retrieve uniform from nullptr program");
	return uniforms.at(name);
}

void ShaderProgram::link() {
	GL_ASSERT(glLinkProgram(programHandle));
	//CHECK FOR LINK SUCCESS
	GLint success;
	GL_ASSERT(glGetProgramiv(programHandle, GL_LINK_STATUS, &success));
	if (success != GL_TRUE) {
		printInfoLog();
		VBE_ASSERT(false, "Linking program failed" );
	}
	VBE_DLOG( " - Linked program successfully. PROGRAMID: " << programHandle );
}

void ShaderProgram::retrieveProgramInfo() {
	//RETRIEVE ATTRIBUTE DATA
	GLint activeAttributes;
	GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTES, &activeAttributes));
	if (activeAttributes > 0) {
		GLint length;
		GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length));
		if (length > 0) {
			GLchar* attribName = new GLchar[length + 1];
			GLint attribSize;
			GLenum attribType;
			GLint attribLocation;
			for (int i = 0; i < activeAttributes; ++i) {
				// Query attribute info.
				GL_ASSERT(glGetActiveAttrib(programHandle, i, length, nullptr, &attribSize, &attribType, attribName));
				attribName[length] = '\0';

				// Query the pre-assigned attribute location.
				attribLocation = glGetAttribLocation(programHandle, attribName);

				// Assign the vertex attribute mapping for the effect.
				attributes[attribName] = attribLocation;
			}
			delete[] attribName;
		}
	}

	//RETRIEVE UNIFORM INFO
	GLint activeUniforms;
	GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_UNIFORMS, &activeUniforms));
	if (activeUniforms > 0) {
		GLint length;
		GL_ASSERT(glGetProgramiv(programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length));
		if (length > 0) {
			GLchar* uniformName = new GLchar[length + 1];
			GLint uniformSize;
			GLenum uniformType;
			GLint uniformLocation;
			unsigned int texUnit = 0;
			for (int i = 0; i < activeUniforms; ++i) {
				// Query uniform info.
				GL_ASSERT(glGetActiveUniform(programHandle, i, length, nullptr, &uniformSize, &uniformType, uniformName));
				uniformName[length] = '\0';  // nullptr terminate
				if (uniformSize > 1 && length > 3) {
					// This is an array uniform. I'm stripping array indexers off it since GL does not
					// seem to be consistent across different drivers/implementations in how it returns
					// array uniforms. On some systems it will return "u_matrixArray", while on others
					// it will return "u_matrixArray[0]".

					//TODO rewrite this using std::string please
					char* c = strrchr(uniformName, '[');
					if (c) *c = '\0';
				}

				// Query the pre-assigned uniform location.
				uniformLocation = glGetUniformLocation(programHandle, uniformName);
				VBE_ASSERT(glGetError() == GL_NO_ERROR, "Failed to get uniform location");
				Uniform* uniform = new Uniform(uniformSize, uniformType, uniformLocation);
				if(Uniform::isSampler(uniformType)) uniform->texUnit = texUnit++;
				uniforms[uniformName] = uniform;
			}
			delete[] uniformName;
		}
	}

	//PRINT ATTRIBUTE INFO
	VBE_DLOG(" - Printing attribute info:" );
	for(std::map<std::string, GLint>::iterator it = attributes.begin(); it != attributes.end(); ++it) {
		VBE_DLOG("  - Name: " << it->first);
		VBE_DLOG( "    Location: " << it->second);
	}

	//PRINT UNIFORM INFO
	VBE_DLOG(" - Printing uniform info:" );
	for(std::map<std::string, Uniform*>::iterator it = uniforms.begin(); it != uniforms.end(); ++it) {
		VBE_DLOG("  - Name: " << it->first);
		it->second->log();
	}
}

ShaderProgram::ShaderProgram(ShaderProgram&& rhs) : ShaderProgram() {
	using std::swap;
	swap(*this, rhs);
}

ShaderProgram& ShaderProgram::operator=(ShaderProgram&& rhs) {
	using std::swap;
	swap(*this, rhs);
	return *this;
}

void swap(ShaderProgram& a, ShaderProgram& b) {
	using std::swap;

	swap(a.attributes, b.attributes);
	swap(a.uniforms, b.uniforms);
	swap(a.programHandle, b.programHandle);
}

<|endoftext|>


<commit_before><commit_msg>Partial revert of previous change to improve hardware AAC decoder performance, increasing the input buffer size so dramatically accidentally broke streaming performance.<commit_after><|endoftext|>


<commit_before><commit_msg>Back to the previous coding way (using the macro with the goto).<commit_after><|endoftext|>


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

Program:   Insight Segmentation & Registration Toolkit
Module:    itkOtsuMultipleThresholdsCalculatorTest.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
#include "itkWin32Header.h"#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkHistogram.h"
#include "itkOtsuMultipleThresholdsCalculator.h"

int itkOtsuMultipleThresholdsCalculatorTest(int, char*[])
{
  typedef float MeasurementType ;
  typedef itk::Statistics::Histogram< MeasurementType, 1 > HistogramType ;
  HistogramType::Pointer histogram = HistogramType::New() ;

  // initialize histogram
  HistogramType::SizeType size;
  size.Fill(64) ;
  HistogramType::MeasurementVectorType lowerBound ;
  HistogramType::MeasurementVectorType upperBound ;
  lowerBound[0] = 0.0 ;
  upperBound[0] = 64.0 ;

  histogram->Initialize(size, lowerBound, upperBound ) ;

  // create vector of values.
  typedef std::vector<MeasurementType> ValuesVectorType;
  ValuesVectorType values;
  values.push_back(8.0);
  values.push_back(16.0);
  values.push_back(32.0);
  values.push_back(48.0);

  MeasurementType range = 2.0;

  // create histogram with samples at values +- range.
  for (HistogramType::Iterator iter = histogram->Begin(); iter != histogram->End(); ++iter)
    {
    HistogramType::MeasurementType measurement = iter.GetMeasurementVector()[0];

    for (ValuesVectorType::const_iterator viter = values.begin(); viter != values.end(); ++viter)
      {
      if (measurement > (*viter-range) && measurement <  (*viter+range))
        {
        iter.SetFrequency(1.0);
        }
      }
    }

  // Compute numberOfValues - 1 thresholds.
  unsigned long numberOfThresholds = values.size() - 1;

  typedef itk::OtsuMultipleThresholdsCalculator<HistogramType>  OtsuMultipleThresholdCalculatorType;

  OtsuMultipleThresholdCalculatorType::Pointer otsuThresholdCalculator = OtsuMultipleThresholdCalculatorType::New();

  otsuThresholdCalculator->SetInputHistogram(histogram.GetPointer());
  otsuThresholdCalculator->SetNumberOfThresholds(numberOfThresholds);

  try
    {
    otsuThresholdCalculator->Update();
    }
  catch(itk::ExceptionObject & exp)
    {
    std::cerr << exp << std::endl;
    }

  OtsuMultipleThresholdCalculatorType::OutputType otsuThresholds = otsuThresholdCalculator->GetOutput();

  bool passed = true;

  // Check if thresholds correctly separate values.
  for (unsigned long j = 0; j<numberOfThresholds; ++j)
    {
    if (otsuThresholds[j] < values[j] || otsuThresholds[j] > values[j+1])
      {
      passed = false;
      break;
      }
    }

  if (!passed)
    {
      std::cout << "Test failed." << std::endl;
      std::cout << otsuThresholdCalculator << std::endl;
      return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>COMP: typo.<commit_after>/*=========================================================================

Program:   Insight Segmentation & Registration Toolkit
Module:    itkOtsuMultipleThresholdsCalculatorTest.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
#include "itkWin32Header.h"
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkHistogram.h"
#include "itkOtsuMultipleThresholdsCalculator.h"

int itkOtsuMultipleThresholdsCalculatorTest(int, char*[])
{
  typedef float MeasurementType ;
  typedef itk::Statistics::Histogram< MeasurementType, 1 > HistogramType ;
  HistogramType::Pointer histogram = HistogramType::New() ;

  // initialize histogram
  HistogramType::SizeType size;
  size.Fill(64) ;
  HistogramType::MeasurementVectorType lowerBound ;
  HistogramType::MeasurementVectorType upperBound ;
  lowerBound[0] = 0.0 ;
  upperBound[0] = 64.0 ;

  histogram->Initialize(size, lowerBound, upperBound ) ;

  // create vector of values.
  typedef std::vector<MeasurementType> ValuesVectorType;
  ValuesVectorType values;
  values.push_back(8.0);
  values.push_back(16.0);
  values.push_back(32.0);
  values.push_back(48.0);

  MeasurementType range = 2.0;

  // create histogram with samples at values +- range.
  for (HistogramType::Iterator iter = histogram->Begin(); iter != histogram->End(); ++iter)
    {
    HistogramType::MeasurementType measurement = iter.GetMeasurementVector()[0];

    for (ValuesVectorType::const_iterator viter = values.begin(); viter != values.end(); ++viter)
      {
      if (measurement > (*viter-range) && measurement <  (*viter+range))
        {
        iter.SetFrequency(1.0);
        }
      }
    }

  // Compute numberOfValues - 1 thresholds.
  unsigned long numberOfThresholds = values.size() - 1;

  typedef itk::OtsuMultipleThresholdsCalculator<HistogramType>  OtsuMultipleThresholdCalculatorType;

  OtsuMultipleThresholdCalculatorType::Pointer otsuThresholdCalculator = OtsuMultipleThresholdCalculatorType::New();

  otsuThresholdCalculator->SetInputHistogram(histogram.GetPointer());
  otsuThresholdCalculator->SetNumberOfThresholds(numberOfThresholds);

  try
    {
    otsuThresholdCalculator->Update();
    }
  catch(itk::ExceptionObject & exp)
    {
    std::cerr << exp << std::endl;
    }

  OtsuMultipleThresholdCalculatorType::OutputType otsuThresholds = otsuThresholdCalculator->GetOutput();

  bool passed = true;

  // Check if thresholds correctly separate values.
  for (unsigned long j = 0; j<numberOfThresholds; ++j)
    {
    if (otsuThresholds[j] < values[j] || otsuThresholds[j] > values[j+1])
      {
      passed = false;
      break;
      }
    }

  if (!passed)
    {
      std::cout << "Test failed." << std::endl;
      std::cout << otsuThresholdCalculator << std::endl;
      return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2013-2017 University of Amsterdam
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program.  If not, see
// <http://www.gnu.org/licenses/>.
//

#include "tabbar.h"
#include <QMessageBox>
#include "preferencesdialog.h"
#include "widgets/ribbonbutton.h"
#include "module.h"

using namespace std;

TabBar::TabBar(QWidget *parent) :
	QWidget(parent)
{

	_helpTab = NULL;

	_background = new QWidget(this);
	_background->setObjectName("background");

	_backgroundLayout = new QGridLayout(this);
	_backgroundLayout->setMargin(0);
	_backgroundLayout->addWidget(_background);

	_layout = new QHBoxLayout(_background);
	_layout->setMargin(0);
	_background->setLayout(_layout);

	setLayout(_backgroundLayout);

	_layout->addStretch(1);

	_aboutDialog = new AboutDialog(this);
	_preferencesDialog = new PreferencesDialog(this);
	_modulesButton = NULL;
}

QStringList TabBar::getCurrentModules()
{
	QStringList result;
	foreach (QPushButton *button, _tabButtons)
	{
		QString name = button->objectName();
		if (Module::isModuleName(name))
			result.append(name);
	}

	return result;
}

void TabBar::addModulesPlusButton()
{
	QPushButton *button = new QPushButton("", this);
	button->setToolTip("Load module");
	button->setIcon(QIcon(":/icons/addition.png"));
	_modulesButton = button;
	_signalModulesMapper = new QSignalMapper(this);
	connect(_modulesButton, SIGNAL(pressed()), this, SLOT(handleModuleButton()));

	QStringList currentModules = getCurrentModules();

	//Modules menu
	QMenu *modulesmenu   = new QMenu(this);

	for (auto it = Module::AllModules.begin(); it != Module::AllModules.end(); ++it)
	{
		const Module& module = it->second;
#ifndef QT_DEBUG
		if (module.released())
		{
#endif
			QAction *action = new QAction(module.displayName(),modulesmenu);
			QString name = module.name();
			action->setObjectName(name);
			action->setCheckable(true);
			action->setChecked(currentModules.indexOf(name) >= 0);
			modulesmenu->addAction(action);
			_signalModulesMapper->setMapping(action, name);
			connect(action, SIGNAL(triggered()), _signalModulesMapper, SLOT(map()));
#ifndef QT_DEBUG
		}
#endif
	}
	connect(_signalModulesMapper, SIGNAL(mapped(QString)), this, SLOT(toggleModule(QString)));
	modulesmenu->acceptDrops();
	button->setMenu(modulesmenu);
	_layout->insertWidget(_tabButtons.size(), button);

	button->setStyleSheet("border-top-left-radius:4px;border-top-right-radius:4px;");
	button->setObjectName("Modules");
	button->setCheckable(true);
	connect(button, SIGNAL(clicked()), this, SLOT(tabSelectedHandler()));

	_tabButtons.append(button);
}

void TabBar::addTab(QString name)
{
	foreach (QPushButton *button, _tabButtons)
	{
		if (button->objectName() == name)
			return;
	}

	QPushButton *button = new QPushButton(name, this);

	if (Module::isModuleName(name))
	{
		button->setText(Module::getModule(name).displayName());
		_layout->insertWidget(_tabButtons.size()-1, button);
	}
	else
		_layout->insertWidget(_tabButtons.size(), button);

	button->setStyleSheet("border-top-left-radius:4px;border-top-right-radius:4px;");
	if (_tabButtons.size() == 0)
		button->setObjectName("first"); //just to give it the proper (blue) stylesheet
	else
		button->setObjectName(name);

	button->setCheckable(true);
	connect(button, SIGNAL(clicked()), this, SLOT(tabSelectedHandler()));

	_tabButtons.append(button);
	button->clicked();

}

void TabBar::removeTab(QString tabName)
{
	QPushButton *lastbutton = NULL;
	bool removeactive = false;
	QString currentTabName = (_currentTab ? _currentTab->objectName() : QString());
	foreach (QPushButton *button, _tabButtons)
	{
		QString buttonName = button->objectName();
		if (buttonName == tabName)
		{
			if (buttonName == currentTabName)
				removeactive = true;
			_tabButtons.removeAll(button);
			delete button;
			if (lastbutton && removeactive)
			{
				if (lastbutton->objectName() == "first")
				{
					// Check whether another available module exists
					foreach (QPushButton *button2, _tabButtons)
					{
						if (Module::isModuleName(button2->objectName()))
						{
							lastbutton = button2;
							break;
						}
					}
				}
				_currentTab = lastbutton;
				if (Module::isModuleName(_currentTab->objectName()))
					_currentModule = _currentTab;
				_currentTab->clicked();
			}

			return;
		}
		if (buttonName != "Modules")
			lastbutton = button;
	}
}

void TabBar::init()
{
	setFocusPolicy(Qt::NoFocus);
	addTab("File");
	addModulesPlusButton();
	addTab("Common"); // Common module must be added after the Plus Button,in order to set it at the right place
	setModulePlusMenu(); // A a check to Common in the menu

	RibbonButton *rb = new RibbonButton();
	rb->setIcon(QIcon(":/icons/summarize.svg"));
	rb->setPopupMode(QToolButton::InstantPopup);
	rb->setProperty("button-type", "summarize");
	rb->setMinimumSize(30,0);
	rb->setToolTip("Options");
	_layout->setContentsMargins(0,0,2,0);

	QMenu  *optionsmenu   = new QMenu(this);

	QAction *act_about = new QAction("About",optionsmenu);
	QAction *act_extrahelp = new QAction("Help",optionsmenu);
	QAction *act_preferences = new QAction("Preferences",optionsmenu);

	// About
	act_about->setObjectName("About");
	optionsmenu->addAction(act_about);
	optionsmenu->addSeparator();

	//Special Help
	act_extrahelp->setObjectName("Special Help");
	act_extrahelp->setCheckable(true);
	act_extrahelp->setChecked(false);
	optionsmenu->addAction(act_extrahelp);
	optionsmenu->addSeparator();

	// Preferences
	act_preferences->setObjectName("Preferences");
	optionsmenu->addAction(act_preferences);
	optionsmenu->addSeparator();

	optionsmenu->acceptDrops();

	rb->setMenu(optionsmenu);
	_layout->addWidget(rb);

	//Slots preferences
	connect(act_about, SIGNAL(triggered()), this, SLOT(showAbout()));
	connect(act_preferences, SIGNAL(triggered()), this, SLOT(showPreferences()));
	connect(act_extrahelp, SIGNAL(triggered()), this, SLOT(toggleHelp()));

}

void TabBar::showAbout()
{
	_aboutDialog->show();
	_aboutDialog->raise();
	_aboutDialog->activateWindow();
	//The last function performs the same operation as clicking the mouse on the title bar
	//If you want to ensure that the window is stacked on top as well you should also call raise(). 	//Note that the window must be visible, otherwise activateWindow() has no effect.
}

void TabBar::showPreferences()
{
	_preferencesDialog->show();
	_preferencesDialog->raise();
	_preferencesDialog->activateWindow();
}

void TabBar::toggleHelp()
{
	static bool on;
	on = ! on;
	helpToggledHandler(on);
}

void TabBar::setModulePlusMenu(QStringList usedModules)
{
	QStringList currentModules = getCurrentModules();
	foreach (QAction *action, _modulesButton->menu()->actions())
	{
		QString moduleName = action->objectName();
		if (usedModules.contains(moduleName))
		{
			if (!action->isChecked())
				action->setChecked(true);
			if (!currentModules.contains(moduleName))
				addTab(moduleName);
			action->setEnabled(false);
		}
		else
		{
			action->setEnabled(true);
			action->setChecked(currentModules.contains(moduleName));
		}
	}
}

void TabBar::toggleModule(QString name)
{
	bool on = true;
	foreach (QAction *action, _modulesButton->menu()->actions())
	{
		if (action->objectName() == name)
			on = action->isChecked();
	}
	if (on)
		addTab(name);
	else
		removeTab(name);
}

void TabBar::handleModuleButton()
{
	if (_modulesButton != NULL)
		_modulesButton->setAttribute(Qt::WA_UnderMouse, false);
}

int TabBar::count() const
{
	return _tabButtons.length();
}

PreferencesDialog *TabBar::getPreferencesDialog()
{
	return _preferencesDialog;
}

void TabBar::setCurrentModuleActive()
{
	if (!_currentModule)
		setCurrentTab(_currentModule->objectName());
}

void TabBar::setExactPValues(bool exactPValues)
{
	emit setExactPValuesHandler(exactPValues);
}

void TabBar::setFixDecimals(QString numDecimals)
{
	emit setFixDecimalsHandler(numDecimals);
}

void TabBar::emptyValuesChanged()
{
	emit emptyValuesChangedHandler();
}

void TabBar::setCurrentTab(QString name)
{
	int i = 0, index = -1;

	foreach (QPushButton *button, _tabButtons)
	{
		if (button->objectName() == name)
		{
			button->setChecked(true);
			index = i;
			_currentTab = button;
			if (Module::isModuleName(name))
				_currentModule = button;
		}
		else
			button->setChecked(false);

		i++;
	}

	if (index >= 0)
		emit currentChanged(index);
}

void TabBar::tabSelectedHandler()
{
	QObject *source = this->sender();
	setCurrentTab(source->objectName());
}

QString TabBar::getCurrentActiveTab()
{
	return _currentTab->objectName();
}

void TabBar::helpToggledHandler(bool on)
{
	emit helpToggled(on);
}
<commit_msg>Small changes for module tabs<commit_after>//
// Copyright (C) 2013-2017 University of Amsterdam
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program.  If not, see
// <http://www.gnu.org/licenses/>.
//

#include "tabbar.h"
#include <QMessageBox>
#include "preferencesdialog.h"
#include "widgets/ribbonbutton.h"
#include "module.h"

using namespace std;

TabBar::TabBar(QWidget *parent) :
	QWidget(parent)
{

	_helpTab = NULL;

	_background = new QWidget(this);
	_background->setObjectName("background");

	_backgroundLayout = new QGridLayout(this);
	_backgroundLayout->setMargin(0);
	_backgroundLayout->addWidget(_background);

	_layout = new QHBoxLayout(_background);
	_layout->setMargin(0);
	_background->setLayout(_layout);

	setLayout(_backgroundLayout);

	_layout->addStretch(1);

	_aboutDialog = new AboutDialog(this);
	_preferencesDialog = new PreferencesDialog(this);
	_modulesButton = NULL;
}

QStringList TabBar::getCurrentModules()
{
	QStringList result;
	foreach (QPushButton *button, _tabButtons)
	{
		QString name = button->objectName();
		if (Module::isModuleName(name))
			result.append(name);
	}

	return result;
}

void TabBar::addModulesPlusButton()
{
	QPushButton *button = new QPushButton("", this);
	button->setToolTip("Load module");
	button->setIcon(QIcon(":/icons/addition.png"));
	_modulesButton = button;
	_signalModulesMapper = new QSignalMapper(this);
	connect(_modulesButton, SIGNAL(pressed()), this, SLOT(handleModuleButton()));

	QStringList currentModules = getCurrentModules();

	//Modules menu
	QMenu *modulesmenu   = new QMenu(this);

	for (auto it = Module::AllModules.begin(); it != Module::AllModules.end(); ++it)
	{
		const Module& module = it->second;
#ifndef QT_DEBUG
		if (module.released())
		{
#endif
			QAction *action = new QAction(module.displayName(),modulesmenu);
			QString name = module.name();
			action->setObjectName(name);
			action->setCheckable(true);
			action->setChecked(currentModules.indexOf(name) >= 0);
			modulesmenu->addAction(action);
			_signalModulesMapper->setMapping(action, name);
			connect(action, SIGNAL(triggered()), _signalModulesMapper, SLOT(map()));
#ifndef QT_DEBUG
		}
#endif
	}
	connect(_signalModulesMapper, SIGNAL(mapped(QString)), this, SLOT(toggleModule(QString)));
	modulesmenu->acceptDrops();
	button->setMenu(modulesmenu);
	_layout->insertWidget(_tabButtons.size(), button);

	button->setStyleSheet("border-top-left-radius:4px;border-top-right-radius:4px;");
	button->setObjectName("Modules");
	button->setCheckable(true);
	connect(button, SIGNAL(clicked()), this, SLOT(tabSelectedHandler()));

	_tabButtons.append(button);
}

void TabBar::addTab(QString name)
{
	foreach (QPushButton *button, _tabButtons)
	{
		if (button->objectName() == name)
			return;
	}

	QPushButton *button = new QPushButton(name, this);

	if (Module::isModuleName(name))
	{
		button->setText(Module::getModule(name).displayName());
		_layout->insertWidget(_tabButtons.size()-1, button);
		_currentModule = button;
	}
	else
		_layout->insertWidget(_tabButtons.size(), button);

	button->setStyleSheet("border-top-left-radius:4px;border-top-right-radius:4px;");
	if (_tabButtons.size() == 0)
		button->setObjectName("first"); //just to give it the proper (blue) stylesheet
	else
		button->setObjectName(name);

	button->setCheckable(true);
	connect(button, SIGNAL(clicked()), this, SLOT(tabSelectedHandler()));

	_tabButtons.append(button);
	button->clicked();

}

void TabBar::removeTab(QString tabName)
{
	QPushButton *lastButton = NULL;
	// Init lastButton in case with first button.
	foreach (QPushButton *button, _tabButtons)
		if (button->objectName() == "first")
			lastButton = button;

	foreach (QPushButton *button, _tabButtons)
	{
		QString buttonName = button->objectName();
		if (buttonName == tabName)
		{
			if (lastButton->objectName() == "first")
			{
				// Check whether another available module exists
				foreach (QPushButton *button2, _tabButtons)
					if (button2 != button && Module::isModuleName(button2->objectName()))
						lastButton = button2;
			}
			if (button == _currentTab)
			{
				_currentTab = lastButton;
				_currentTab->clicked();
			}
			if (button == _currentModule)
			{
				if (Module::isModuleName(lastButton->objectName()))
					_currentModule = lastButton;
				else
					_currentModule = NULL;
			}
			_tabButtons.removeAll(button);
			delete button;

			return;
		}
		if (buttonName != "Modules")
			lastButton = button;
	}
}

void TabBar::init()
{
	setFocusPolicy(Qt::NoFocus);
	addTab("File");
	addModulesPlusButton();
	addTab("Common"); // Common module must be added after the Plus Button,in order to set it at the right place
	setModulePlusMenu(); // A a check to Common in the menu

	RibbonButton *rb = new RibbonButton();
	rb->setIcon(QIcon(":/icons/summarize.svg"));
	rb->setPopupMode(QToolButton::InstantPopup);
	rb->setProperty("button-type", "summarize");
	rb->setMinimumSize(30,0);
	rb->setToolTip("Options");
	_layout->setContentsMargins(0,0,2,0);

	QMenu  *optionsmenu   = new QMenu(this);

	QAction *act_about = new QAction("About",optionsmenu);
	QAction *act_extrahelp = new QAction("Help",optionsmenu);
	QAction *act_preferences = new QAction("Preferences",optionsmenu);

	// About
	act_about->setObjectName("About");
	optionsmenu->addAction(act_about);
	optionsmenu->addSeparator();

	//Special Help
	act_extrahelp->setObjectName("Special Help");
	act_extrahelp->setCheckable(true);
	act_extrahelp->setChecked(false);
	optionsmenu->addAction(act_extrahelp);
	optionsmenu->addSeparator();

	// Preferences
	act_preferences->setObjectName("Preferences");
	optionsmenu->addAction(act_preferences);
	optionsmenu->addSeparator();

	optionsmenu->acceptDrops();

	rb->setMenu(optionsmenu);
	_layout->addWidget(rb);

	//Slots preferences
	connect(act_about, SIGNAL(triggered()), this, SLOT(showAbout()));
	connect(act_preferences, SIGNAL(triggered()), this, SLOT(showPreferences()));
	connect(act_extrahelp, SIGNAL(triggered()), this, SLOT(toggleHelp()));

}

void TabBar::showAbout()
{
	_aboutDialog->show();
	_aboutDialog->raise();
	_aboutDialog->activateWindow();
	//The last function performs the same operation as clicking the mouse on the title bar
	//If you want to ensure that the window is stacked on top as well you should also call raise(). 	//Note that the window must be visible, otherwise activateWindow() has no effect.
}

void TabBar::showPreferences()
{
	_preferencesDialog->show();
	_preferencesDialog->raise();
	_preferencesDialog->activateWindow();
}

void TabBar::toggleHelp()
{
	static bool on;
	on = ! on;
	helpToggledHandler(on);
}

void TabBar::setModulePlusMenu(QStringList usedModules)
{
	QStringList currentModules = getCurrentModules();
	foreach (QAction *action, _modulesButton->menu()->actions())
	{
		QString moduleName = action->objectName();
		if (usedModules.contains(moduleName))
		{
			if (!action->isChecked())
				action->setChecked(true);
			if (!currentModules.contains(moduleName))
				addTab(moduleName);
			action->setEnabled(false);
		}
		else
		{
			action->setEnabled(true);
			action->setChecked(currentModules.contains(moduleName));
		}
	}
}

void TabBar::toggleModule(QString name)
{
	bool on = true;
	foreach (QAction *action, _modulesButton->menu()->actions())
	{
		if (action->objectName() == name)
			on = action->isChecked();
	}
	if (on)
		addTab(name);
	else
		removeTab(name);
}

void TabBar::handleModuleButton()
{
	if (_modulesButton != NULL)
		_modulesButton->setAttribute(Qt::WA_UnderMouse, false);
}

int TabBar::count() const
{
	return _tabButtons.length();
}

PreferencesDialog *TabBar::getPreferencesDialog()
{
	return _preferencesDialog;
}

void TabBar::setCurrentModuleActive()
{
	if (_currentModule)
		setCurrentTab(_currentModule->objectName());
}

void TabBar::setExactPValues(bool exactPValues)
{
	emit setExactPValuesHandler(exactPValues);
}

void TabBar::setFixDecimals(QString numDecimals)
{
	emit setFixDecimalsHandler(numDecimals);
}

void TabBar::emptyValuesChanged()
{
	emit emptyValuesChangedHandler();
}

void TabBar::setCurrentTab(QString name)
{
	int i = 0, index = -1;

	foreach (QPushButton *button, _tabButtons)
	{
		if (button->objectName() == name)
		{
			button->setChecked(true);
			index = i;
			_currentTab = button;
			if (Module::isModuleName(name))
				_currentModule = button;
		}
		else
			button->setChecked(false);

		i++;
	}

	if (index >= 0)
		emit currentChanged(index);
}

void TabBar::tabSelectedHandler()
{
	QObject *source = this->sender();
	setCurrentTab(source->objectName());
}

QString TabBar::getCurrentActiveTab()
{
	return _currentTab ? _currentTab->objectName() : QString();
}

void TabBar::helpToggledHandler(bool on)
{
	emit helpToggled(on);
}
<|endoftext|>