<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/util/ValueStackOf.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  ContentSpecNode: Copy Constructor
//
//  Note: this copy constructor has dependency on various get*() methods
//        and shall be placed after those method's declaration.
//        aka inline function compilation error on AIX 4.2, xlC 3 r ev.1
// ---------------------------------------------------------------------------

ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :
    XSerializable(toCopy)
    , XMemory(toCopy)
    , fMemoryManager(toCopy.fMemoryManager)
    , fElement(0)
    , fElementDecl(toCopy.fElementDecl)
    , fFirst(0)
    , fSecond(0)
    , fType(toCopy.fType)
    , fAdoptFirst(true)
    , fAdoptSecond(true)
    , fMinOccurs(toCopy.fMinOccurs)
    , fMaxOccurs(toCopy.fMaxOccurs)
{
    const QName* tempElement = toCopy.getElement();
    if (tempElement)
        fElement = new (fMemoryManager) QName(*tempElement);

    const ContentSpecNode *tmp = toCopy.getFirst();
    if (tmp)
        fFirst = new (fMemoryManager) ContentSpecNode(*tmp);

    tmp = toCopy.getSecond();
    if (tmp)
        fSecond = new (fMemoryManager) ContentSpecNode(*tmp);
}

ContentSpecNode::~ContentSpecNode()
{
    // Delete our children, avoiding recursive cleanup
    if (fAdoptFirst && fFirst) {
		deleteChildNode(fFirst);
    }

    if (fAdoptSecond && fSecond) {
		deleteChildNode(fSecond);
    }

    delete fElement;
}

void ContentSpecNode::deleteChildNode(ContentSpecNode* node)
{
	ValueStackOf<ContentSpecNode*> toBeDeleted(10, fMemoryManager);
	toBeDeleted.push(node);
	while(!toBeDeleted.empty())
	{
		ContentSpecNode* node = toBeDeleted.pop();
		if(node==0)
			continue;
		if(node->isFirstAdopted())
			toBeDeleted.push(node->orphanFirst());
		if(node->isSecondAdopted())
			toBeDeleted.push(node->orphanSecond());
		delete node;
	}
}

class formatNodeHolder
{
public:
	formatNodeHolder(const ContentSpecNode* n, const ContentSpecNode::NodeTypes p, XMLCh c) : node(n), parentType(p), character(c) {}
	formatNodeHolder& operator =(const formatNodeHolder* other)
	{
		node=other->node;
		parentType=other->parentType;
		character=other->character;
	}

	const ContentSpecNode* node;
	ContentSpecNode::NodeTypes parentType;
	XMLCh character;
};

// ---------------------------------------------------------------------------
//  Local methods
// ---------------------------------------------------------------------------
static void formatNode( const   ContentSpecNode* const      curNode
                        ,       XMLBuffer&                  bufToFill
						,		MemoryManager* const		memMgr)
{
    if (!curNode)
        return;

	ValueStackOf<formatNodeHolder> toBeProcessed(10, memMgr);
	toBeProcessed.push(formatNodeHolder(curNode, ContentSpecNode::UnknownType, 0));

	while(!toBeProcessed.empty())
	{
		formatNodeHolder item=toBeProcessed.pop();
		if(item.character!=0)
		{
			bufToFill.append(item.character);
			continue;
		}
		const ContentSpecNode* curNode = item.node;
		if(!curNode)
			continue;
		const ContentSpecNode::NodeTypes parentType = item.parentType;
		const ContentSpecNode* first = curNode->getFirst();
		const ContentSpecNode* second = curNode->getSecond();
		const ContentSpecNode::NodeTypes curType = curNode->getType();

		// Get the type of the first node
		const ContentSpecNode::NodeTypes firstType = first ?
													 first->getType() :
													 ContentSpecNode::Leaf;

		// Calculate the parens flag for the rep nodes
		bool doRepParens = false;
		if (((firstType != ContentSpecNode::Leaf)
				&& (parentType != ContentSpecNode::UnknownType))
		||  ((firstType == ContentSpecNode::Leaf)
				&& (parentType == ContentSpecNode::UnknownType)))
		{
			doRepParens = true;
		}

		// Now handle our type
		switch(curType & 0x0f)
		{
			case ContentSpecNode::Leaf :
				if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
					bufToFill.append(XMLElementDecl::fgPCDataElemName);
				else
				{
					bufToFill.append(curNode->getElement()->getRawName());
					// show the + and * modifiers also when we have a non-infinite number of repetitions
					if(curNode->getMinOccurs()==0 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
						bufToFill.append(chAsterisk);
					else if(curNode->getMinOccurs()==0 && curNode->getMaxOccurs()==1)
						bufToFill.append(chQuestion);
					else if(curNode->getMinOccurs()==1 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
						bufToFill.append(chPlus);
				}
				break;

			case ContentSpecNode::ZeroOrOne :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chQuestion));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::ZeroOrMore :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chAsterisk));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::OneOrMore :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chPlus));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::Choice :
				if ((parentType & 0x0f) != (curType & 0x0f))
					bufToFill.append(chOpenParen);

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				if(second!=NULL)
				{
					toBeProcessed.push(formatNodeHolder(second, curType, 0));
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chPipe));
				}
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::Sequence :
				if ((parentType & 0x0f) != (curType & 0x0f))
					bufToFill.append(chOpenParen);

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				if(second!=NULL)
				{
					toBeProcessed.push(formatNodeHolder(second, curType, 0));
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chComma));
				}
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::All :
				if ((parentType & 0x0f) != (curType & 0x0f))
				{
					bufToFill.append(chLatin_A);
					bufToFill.append(chLatin_l);
					bufToFill.append(chLatin_l);
					bufToFill.append(chOpenParen);
				}

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(second, curType, 0));
				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chComma));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;
		}
	}
}

// ---------------------------------------------------------------------------
//  ContentSpecNode: Miscellaneous
// ---------------------------------------------------------------------------
void ContentSpecNode::formatSpec(XMLBuffer&      bufToFill) const
{
    // Clean out the buffer first
    bufToFill.reset();

    if (fType == ContentSpecNode::Leaf)
        bufToFill.append(chOpenParen);
    formatNode
    (
        this
		, bufToFill
        , fMemoryManager
    );
    if (fType == ContentSpecNode::Leaf)
        bufToFill.append(chCloseParen);
}

int ContentSpecNode::getMinTotalRange() const {

    int min = fMinOccurs;

    if ((fType & 0x0f) == ContentSpecNode::Sequence
        || fType == ContentSpecNode::All
        || (fType & 0x0f) == ContentSpecNode::Choice) {

        int minFirst = fFirst->getMinTotalRange();

        if (fSecond) {

            int minSecond = fSecond->getMinTotalRange();

            if ((fType & 0x0f) == ContentSpecNode::Choice) {
                min = min * ((minFirst < minSecond)? minFirst : minSecond);
            }
            else {
                min = min * (minFirst + minSecond);
            }
        }
        else
            min = min * minFirst;
    }

    return min;
}

int ContentSpecNode::getMaxTotalRange() const {

    int max = fMaxOccurs;

    if (max == SchemaSymbols::XSD_UNBOUNDED) {
         return SchemaSymbols::XSD_UNBOUNDED;
    }

    if ((fType & 0x0f) == ContentSpecNode::Sequence
        || fType == ContentSpecNode::All
        || (fType & 0x0f) == ContentSpecNode::Choice) {

        int maxFirst = fFirst->getMaxTotalRange();

        if (maxFirst == SchemaSymbols::XSD_UNBOUNDED) {
             return SchemaSymbols::XSD_UNBOUNDED;
        }

        if (fSecond) {

            int maxSecond = fSecond->getMaxTotalRange();

            if (maxSecond == SchemaSymbols::XSD_UNBOUNDED) {
                return SchemaSymbols::XSD_UNBOUNDED;
            }
            else {

                if ((fType & 0x0f) == ContentSpecNode::Choice) {
                    max = max * ((maxFirst > maxSecond) ? maxFirst : maxSecond);
                }
                else {
                    max = max * (maxFirst + maxSecond);
                }
            }
        }
        else {
            max = max * maxFirst;
        }
    }

    return max;
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(ContentSpecNode)

void ContentSpecNode::serialize(XSerializeEngine& serEng)
{
    /***
     *  Since fElement, fFirst, fSecond are NOT created by the default
     *  constructor, we need to create them dynamically.
     ***/

    if (serEng.isStoring())
    {
        serEng<<fElement;
        XMLElementDecl::storeElementDecl(serEng, fElementDecl);
        serEng<<fFirst;
        serEng<<fSecond;

        serEng<<(int)fType;
        serEng<<fAdoptFirst;
        serEng<<fAdoptSecond;
        serEng<<fMinOccurs;
        serEng<<fMaxOccurs;
    }
    else
    {
        serEng>>fElement;
        fElementDecl = XMLElementDecl::loadElementDecl(serEng);
        serEng>>fFirst;
        serEng>>fSecond;

        int type;
        serEng>>type;
        fType = (NodeTypes)type;

        serEng>>fAdoptFirst;
        serEng>>fAdoptSecond;
        serEng>>fMinOccurs;
        serEng>>fMaxOccurs;
    }

}

XERCES_CPP_NAMESPACE_END

<commit_msg>Add return statement to copy constructor (XERCESC-2001)<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/util/ValueStackOf.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  ContentSpecNode: Copy Constructor
//
//  Note: this copy constructor has dependency on various get*() methods
//        and shall be placed after those method's declaration.
//        aka inline function compilation error on AIX 4.2, xlC 3 r ev.1
// ---------------------------------------------------------------------------

ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :
    XSerializable(toCopy)
    , XMemory(toCopy)
    , fMemoryManager(toCopy.fMemoryManager)
    , fElement(0)
    , fElementDecl(toCopy.fElementDecl)
    , fFirst(0)
    , fSecond(0)
    , fType(toCopy.fType)
    , fAdoptFirst(true)
    , fAdoptSecond(true)
    , fMinOccurs(toCopy.fMinOccurs)
    , fMaxOccurs(toCopy.fMaxOccurs)
{
    const QName* tempElement = toCopy.getElement();
    if (tempElement)
        fElement = new (fMemoryManager) QName(*tempElement);

    const ContentSpecNode *tmp = toCopy.getFirst();
    if (tmp)
        fFirst = new (fMemoryManager) ContentSpecNode(*tmp);

    tmp = toCopy.getSecond();
    if (tmp)
        fSecond = new (fMemoryManager) ContentSpecNode(*tmp);
}

ContentSpecNode::~ContentSpecNode()
{
    // Delete our children, avoiding recursive cleanup
    if (fAdoptFirst && fFirst) {
		deleteChildNode(fFirst);
    }

    if (fAdoptSecond && fSecond) {
		deleteChildNode(fSecond);
    }

    delete fElement;
}

void ContentSpecNode::deleteChildNode(ContentSpecNode* node)
{
	ValueStackOf<ContentSpecNode*> toBeDeleted(10, fMemoryManager);
	toBeDeleted.push(node);
	while(!toBeDeleted.empty())
	{
		ContentSpecNode* node = toBeDeleted.pop();
		if(node==0)
			continue;
		if(node->isFirstAdopted())
			toBeDeleted.push(node->orphanFirst());
		if(node->isSecondAdopted())
			toBeDeleted.push(node->orphanSecond());
		delete node;
	}
}

class formatNodeHolder
{
public:
	formatNodeHolder(const ContentSpecNode* n, const ContentSpecNode::NodeTypes p, XMLCh c) : node(n), parentType(p), character(c) {}
	formatNodeHolder& operator =(const formatNodeHolder* other)
	{
		node=other->node;
		parentType=other->parentType;
		character=other->character;
		return *this;
	}

	const ContentSpecNode* node;
	ContentSpecNode::NodeTypes parentType;
	XMLCh character;
};

// ---------------------------------------------------------------------------
//  Local methods
// ---------------------------------------------------------------------------
static void formatNode( const   ContentSpecNode* const      curNode
                        ,       XMLBuffer&                  bufToFill
						,		MemoryManager* const		memMgr)
{
    if (!curNode)
        return;

	ValueStackOf<formatNodeHolder> toBeProcessed(10, memMgr);
	toBeProcessed.push(formatNodeHolder(curNode, ContentSpecNode::UnknownType, 0));

	while(!toBeProcessed.empty())
	{
		formatNodeHolder item=toBeProcessed.pop();
		if(item.character!=0)
		{
			bufToFill.append(item.character);
			continue;
		}
		const ContentSpecNode* curNode = item.node;
		if(!curNode)
			continue;
		const ContentSpecNode::NodeTypes parentType = item.parentType;
		const ContentSpecNode* first = curNode->getFirst();
		const ContentSpecNode* second = curNode->getSecond();
		const ContentSpecNode::NodeTypes curType = curNode->getType();

		// Get the type of the first node
		const ContentSpecNode::NodeTypes firstType = first ?
													 first->getType() :
													 ContentSpecNode::Leaf;

		// Calculate the parens flag for the rep nodes
		bool doRepParens = false;
		if (((firstType != ContentSpecNode::Leaf)
				&& (parentType != ContentSpecNode::UnknownType))
		||  ((firstType == ContentSpecNode::Leaf)
				&& (parentType == ContentSpecNode::UnknownType)))
		{
			doRepParens = true;
		}

		// Now handle our type
		switch(curType & 0x0f)
		{
			case ContentSpecNode::Leaf :
				if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
					bufToFill.append(XMLElementDecl::fgPCDataElemName);
				else
				{
					bufToFill.append(curNode->getElement()->getRawName());
					// show the + and * modifiers also when we have a non-infinite number of repetitions
					if(curNode->getMinOccurs()==0 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
						bufToFill.append(chAsterisk);
					else if(curNode->getMinOccurs()==0 && curNode->getMaxOccurs()==1)
						bufToFill.append(chQuestion);
					else if(curNode->getMinOccurs()==1 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
						bufToFill.append(chPlus);
				}
				break;

			case ContentSpecNode::ZeroOrOne :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chQuestion));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::ZeroOrMore :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chAsterisk));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::OneOrMore :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chPlus));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::Choice :
				if ((parentType & 0x0f) != (curType & 0x0f))
					bufToFill.append(chOpenParen);

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				if(second!=NULL)
				{
					toBeProcessed.push(formatNodeHolder(second, curType, 0));
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chPipe));
				}
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::Sequence :
				if ((parentType & 0x0f) != (curType & 0x0f))
					bufToFill.append(chOpenParen);

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				if(second!=NULL)
				{
					toBeProcessed.push(formatNodeHolder(second, curType, 0));
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chComma));
				}
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::All :
				if ((parentType & 0x0f) != (curType & 0x0f))
				{
					bufToFill.append(chLatin_A);
					bufToFill.append(chLatin_l);
					bufToFill.append(chLatin_l);
					bufToFill.append(chOpenParen);
				}

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(second, curType, 0));
				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chComma));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;
		}
	}
}

// ---------------------------------------------------------------------------
//  ContentSpecNode: Miscellaneous
// ---------------------------------------------------------------------------
void ContentSpecNode::formatSpec(XMLBuffer&      bufToFill) const
{
    // Clean out the buffer first
    bufToFill.reset();

    if (fType == ContentSpecNode::Leaf)
        bufToFill.append(chOpenParen);
    formatNode
    (
        this
		, bufToFill
        , fMemoryManager
    );
    if (fType == ContentSpecNode::Leaf)
        bufToFill.append(chCloseParen);
}

int ContentSpecNode::getMinTotalRange() const {

    int min = fMinOccurs;

    if ((fType & 0x0f) == ContentSpecNode::Sequence
        || fType == ContentSpecNode::All
        || (fType & 0x0f) == ContentSpecNode::Choice) {

        int minFirst = fFirst->getMinTotalRange();

        if (fSecond) {

            int minSecond = fSecond->getMinTotalRange();

            if ((fType & 0x0f) == ContentSpecNode::Choice) {
                min = min * ((minFirst < minSecond)? minFirst : minSecond);
            }
            else {
                min = min * (minFirst + minSecond);
            }
        }
        else
            min = min * minFirst;
    }

    return min;
}

int ContentSpecNode::getMaxTotalRange() const {

    int max = fMaxOccurs;

    if (max == SchemaSymbols::XSD_UNBOUNDED) {
         return SchemaSymbols::XSD_UNBOUNDED;
    }

    if ((fType & 0x0f) == ContentSpecNode::Sequence
        || fType == ContentSpecNode::All
        || (fType & 0x0f) == ContentSpecNode::Choice) {

        int maxFirst = fFirst->getMaxTotalRange();

        if (maxFirst == SchemaSymbols::XSD_UNBOUNDED) {
             return SchemaSymbols::XSD_UNBOUNDED;
        }

        if (fSecond) {

            int maxSecond = fSecond->getMaxTotalRange();

            if (maxSecond == SchemaSymbols::XSD_UNBOUNDED) {
                return SchemaSymbols::XSD_UNBOUNDED;
            }
            else {

                if ((fType & 0x0f) == ContentSpecNode::Choice) {
                    max = max * ((maxFirst > maxSecond) ? maxFirst : maxSecond);
                }
                else {
                    max = max * (maxFirst + maxSecond);
                }
            }
        }
        else {
            max = max * maxFirst;
        }
    }

    return max;
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(ContentSpecNode)

void ContentSpecNode::serialize(XSerializeEngine& serEng)
{
    /***
     *  Since fElement, fFirst, fSecond are NOT created by the default
     *  constructor, we need to create them dynamically.
     ***/

    if (serEng.isStoring())
    {
        serEng<<fElement;
        XMLElementDecl::storeElementDecl(serEng, fElementDecl);
        serEng<<fFirst;
        serEng<<fSecond;

        serEng<<(int)fType;
        serEng<<fAdoptFirst;
        serEng<<fAdoptSecond;
        serEng<<fMinOccurs;
        serEng<<fMaxOccurs;
    }
    else
    {
        serEng>>fElement;
        fElementDecl = XMLElementDecl::loadElementDecl(serEng);
        serEng>>fFirst;
        serEng>>fSecond;

        int type;
        serEng>>type;
        fType = (NodeTypes)type;

        serEng>>fAdoptFirst;
        serEng>>fAdoptSecond;
        serEng>>fMinOccurs;
        serEng>>fMaxOccurs;
    }

}

XERCES_CPP_NAMESPACE_END

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
 * License: https://github.com/dbartolini/crown/blob/master/LICENSE
 */

#include "core/containers/hash_map.h"
#include "core/json/json_object.h"
#include "core/json/sjson.h"
#include "core/memory/temp_allocator.h"
#include "core/strings/string_id.h"
#include "core/strings/string_stream.h"
#include "device/console_server.h"

namespace crown
{
ConsoleServer::ConsoleServer(Allocator& a)
	: _clients(a)
	, _commands(a)
{
}

void ConsoleServer::listen(u16 port, bool wait)
{
	_server.bind(port);
	_server.listen(5);

	if (wait)
	{
		AcceptResult ar;
		TCPSocket client;
		do
		{
			ar = _server.accept(client);
		}
		while (ar.error != AcceptResult::SUCCESS);

		array::push_back(_clients, client);
	}
}

void ConsoleServer::shutdown()
{
	for (u32 i = 0; i < array::size(_clients); ++i)
		_clients[i].close();

	_server.close();
}

void ConsoleServer::send(TCPSocket client, const char* json)
{
	u32 len = strlen32(json);
	client.write(&len, 4);
	client.write(json, len);
}

void ConsoleServer::error(TCPSocket client, const char* msg)
{
	TempAllocator4096 ta;
	StringStream ss(ta);
	ss << "{\"type\":\"error\",\"message\":\"" << msg << "\"}";
	send(client, string_stream::c_str(ss));
}

void ConsoleServer::log(LogSeverity::Enum sev, const char* system, const char* msg)
{
	const char* severity_map[] = { "info", "warning", "error" };
	CE_STATIC_ASSERT(countof(severity_map) == LogSeverity::COUNT);

	TempAllocator4096 ta;
	StringStream ss(ta);

	ss << "{\"type\":\"message\",\"severity\":\"";
	ss << severity_map[sev];
	ss << "\",\"system\":\"";
	ss << system;
	ss << "\",\"message\":\"";

	// Sanitize msg
	const char* ch = msg;
	for (; *ch; ch++)
	{
		if (*ch == '"' || *ch == '\\')
			ss << "\\";
		ss << *ch;
	}
	ss << "\"}";

	send(string_stream::c_str(ss));
}

void ConsoleServer::send(const char* json)
{
	for (u32 i = 0; i < array::size(_clients); ++i)
		send(_clients[i], json);
}

void ConsoleServer::update()
{
	TCPSocket client;
	AcceptResult ar = _server.accept_nonblock(client);
	if (ar.error == AcceptResult::SUCCESS)
		array::push_back(_clients, client);

	TempAllocator256 alloc;
	Array<u32> to_remove(alloc);

	// Update all clients
	for (u32 i = 0; i < array::size(_clients); ++i)
	{
		for (;;)
		{
			u32 msg_len = 0;
			ReadResult rr = _clients[i].read_nonblock(&msg_len, 4);

			if (rr.error == ReadResult::WOULDBLOCK)
				break;

			if (rr.error != ReadResult::SUCCESS)
			{
				array::push_back(to_remove, i);
				break;
			}

			// Read message
			TempAllocator4096 ta;
			Array<char> msg(ta);
			array::resize(msg, msg_len + 1);
			rr = _clients[i].read(array::begin(msg), msg_len);
			array::push_back(msg, '\0');

			if (rr.error != ReadResult::SUCCESS)
			{
				array::push_back(to_remove, i);
				break;
			}

			// Process message
			JsonObject obj(ta);
			sjson::parse(array::begin(msg), obj);

			Command cmd;
			cmd.function = NULL;
			cmd.user_data = NULL;
			cmd = hash_map::get(_commands
				, sjson::parse_string_id(obj["type"])
				, cmd
				);

			if (cmd.function)
				cmd.function(*this, _clients[i], array::begin(msg), cmd.user_data);
			else
				error(_clients[i], "Unknown command");
		}
	}

	// Remove clients
	for (u32 i = 0; i < array::size(to_remove); ++i)
	{
		const u32 last = array::size(_clients) - 1;
		const u32 c = to_remove[i];

		_clients[c].close();
		_clients[c] = _clients[last];
		array::pop_back(_clients);
	}
}

void ConsoleServer::register_command(const char* type, CommandFunction function, void* user_data)
{
	CE_ENSURE(NULL != type);
	CE_ENSURE(NULL != function);

	Command cmd;
	cmd.function = function;
	cmd.user_data = user_data;

	hash_map::set(_commands, StringId32(type), cmd);
}

namespace console_server_globals
{
	ConsoleServer* _console_server = NULL;

	void init()
	{
		_console_server = CE_NEW(default_allocator(), ConsoleServer)(default_allocator());
	}

	void shutdown()
	{
		_console_server->shutdown();
		CE_DELETE(default_allocator(), _console_server);
		_console_server = NULL;
	}

} // namespace console_server_globals

ConsoleServer* console_server()
{
	return console_server_globals::_console_server;
}

} // namespace crown
<commit_msg>device: correctly terminate string buffer<commit_after>/*
 * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
 * License: https://github.com/dbartolini/crown/blob/master/LICENSE
 */

#include "core/containers/hash_map.h"
#include "core/json/json_object.h"
#include "core/json/sjson.h"
#include "core/memory/temp_allocator.h"
#include "core/strings/string_id.h"
#include "core/strings/string_stream.h"
#include "device/console_server.h"

namespace crown
{
ConsoleServer::ConsoleServer(Allocator& a)
	: _clients(a)
	, _commands(a)
{
}

void ConsoleServer::listen(u16 port, bool wait)
{
	_server.bind(port);
	_server.listen(5);

	if (wait)
	{
		AcceptResult ar;
		TCPSocket client;
		do
		{
			ar = _server.accept(client);
		}
		while (ar.error != AcceptResult::SUCCESS);

		array::push_back(_clients, client);
	}
}

void ConsoleServer::shutdown()
{
	for (u32 i = 0; i < array::size(_clients); ++i)
		_clients[i].close();

	_server.close();
}

void ConsoleServer::send(TCPSocket client, const char* json)
{
	u32 len = strlen32(json);
	client.write(&len, 4);
	client.write(json, len);
}

void ConsoleServer::error(TCPSocket client, const char* msg)
{
	TempAllocator4096 ta;
	StringStream ss(ta);
	ss << "{\"type\":\"error\",\"message\":\"" << msg << "\"}";
	send(client, string_stream::c_str(ss));
}

void ConsoleServer::log(LogSeverity::Enum sev, const char* system, const char* msg)
{
	const char* severity_map[] = { "info", "warning", "error" };
	CE_STATIC_ASSERT(countof(severity_map) == LogSeverity::COUNT);

	TempAllocator4096 ta;
	StringStream ss(ta);

	ss << "{\"type\":\"message\",\"severity\":\"";
	ss << severity_map[sev];
	ss << "\",\"system\":\"";
	ss << system;
	ss << "\",\"message\":\"";

	// Sanitize msg
	const char* ch = msg;
	for (; *ch; ch++)
	{
		if (*ch == '"' || *ch == '\\')
			ss << "\\";
		ss << *ch;
	}
	ss << "\"}";

	send(string_stream::c_str(ss));
}

void ConsoleServer::send(const char* json)
{
	for (u32 i = 0; i < array::size(_clients); ++i)
		send(_clients[i], json);
}

void ConsoleServer::update()
{
	TCPSocket client;
	AcceptResult ar = _server.accept_nonblock(client);
	if (ar.error == AcceptResult::SUCCESS)
		array::push_back(_clients, client);

	TempAllocator256 alloc;
	Array<u32> to_remove(alloc);

	// Update all clients
	for (u32 i = 0; i < array::size(_clients); ++i)
	{
		for (;;)
		{
			u32 msg_len = 0;
			ReadResult rr = _clients[i].read_nonblock(&msg_len, 4);

			if (rr.error == ReadResult::WOULDBLOCK)
				break;

			if (rr.error != ReadResult::SUCCESS)
			{
				array::push_back(to_remove, i);
				break;
			}

			// Read message
			TempAllocator4096 ta;
			Array<char> msg(ta);
			array::resize(msg, msg_len + 1);
			rr = _clients[i].read(array::begin(msg), msg_len);
			msg[msg_len] = '\0';

			if (rr.error != ReadResult::SUCCESS)
			{
				array::push_back(to_remove, i);
				break;
			}

			// Process message
			JsonObject obj(ta);
			sjson::parse(array::begin(msg), obj);

			Command cmd;
			cmd.function = NULL;
			cmd.user_data = NULL;
			cmd = hash_map::get(_commands
				, sjson::parse_string_id(obj["type"])
				, cmd
				);

			if (cmd.function)
				cmd.function(*this, _clients[i], array::begin(msg), cmd.user_data);
			else
				error(_clients[i], "Unknown command");
		}
	}

	// Remove clients
	for (u32 i = 0; i < array::size(to_remove); ++i)
	{
		const u32 last = array::size(_clients) - 1;
		const u32 c = to_remove[i];

		_clients[c].close();
		_clients[c] = _clients[last];
		array::pop_back(_clients);
	}
}

void ConsoleServer::register_command(const char* type, CommandFunction function, void* user_data)
{
	CE_ENSURE(NULL != type);
	CE_ENSURE(NULL != function);

	Command cmd;
	cmd.function = function;
	cmd.user_data = user_data;

	hash_map::set(_commands, StringId32(type), cmd);
}

namespace console_server_globals
{
	ConsoleServer* _console_server = NULL;

	void init()
	{
		_console_server = CE_NEW(default_allocator(), ConsoleServer)(default_allocator());
	}

	void shutdown()
	{
		_console_server->shutdown();
		CE_DELETE(default_allocator(), _console_server);
		_console_server = NULL;
	}

} // namespace console_server_globals

ConsoleServer* console_server()
{
	return console_server_globals::_console_server;
}

} // namespace crown
<|endoftext|>


<commit_before>#include <PCU.h>
#include "phRestart.h"
#include <apf.h>
#include "phIO.h"
#include "ph.h"
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <cassert>

namespace ph {

/* in_size is the number of dofs for the data array
   and out_size is the number of dofs in the field.
   they are unequal when we read a restart file
   and want to add more dofs for the next restart files */

void attachField(
    apf::Mesh* m,
    const char* fieldname,
    double* data,
    int in_size,
    int out_size)
{
  if (!(in_size <= out_size))
    fprintf(stderr, "field \"%s\" in_size %d out_size %d\n", fieldname, in_size, out_size);
  assert(in_size <= out_size);
  apf::Field* f = apf::createPackedField(m, fieldname, out_size);
  size_t n = m->count(0);
  apf::NewArray<double> c(out_size);
  apf::MeshEntity* e;
  size_t i = 0;
  apf::MeshIterator* it = m->begin(0);
  while ((e = m->iterate(it))) {
    for (int j = 0; j < in_size; ++j)
      c[j] = data[j * n + i];
    apf::setComponents(f, e, 0, &c[0]);
    ++i;
  }
  m->end(it);
  assert(i == n);
}

/* convenience wrapper, in most cases in_size=out_size */
void attachField(
    apf::Mesh* m,
    const char* fieldname,
    double* data,
    int size)
{
  attachField(m, fieldname, data, size, size);
}

void detachField(
    apf::Field* f,
    double*& data,
    int& size)
{
  apf::Mesh* m = apf::getMesh(f);
  size = apf::countComponents(f);
  size_t n = m->count(0);
  apf::NewArray<double> c(size);
  data = (double*)malloc(sizeof(double) * size * m->count(0));
  apf::MeshEntity* e;
  size_t i = 0;
  apf::MeshIterator* it = m->begin(0);
  while ((e = m->iterate(it))) {
    apf::getComponents(f, e, 0, &c[0]);
    for (int j = 0; j < size; ++j)
      data[j * n + i] = c[j];
    ++i;
  }
  m->end(it);
  assert(i == n);
  apf::destroyField(f);
}

void detachField(
    apf::Mesh* m,
    const char* fieldname,
    double*& data,
    int& size)
{
  apf::Field* f = m->findField(fieldname);
  assert(f);
  detachField(f, data, size);
}

int readAndAttachField(
    Input& in,
    FILE* f,
    apf::Mesh* m,
    int swap)
{
  double* data;
  int nodes, vars, step;
  char hname[1024];
  const char* anyfield = "";
  int ret = ph_read_field(f, anyfield, swap,
      &data, &nodes, &vars, &step, hname);
  /* no field was found or the field has an empty data block */
  if(ret==0 || ret==1) return ret;
  assert(nodes == static_cast<int>(m->count(0)));
  assert(step == in.timeStepNumber);
  int out_size = vars;
  if ( std::string(hname) == std::string("solution") )
    out_size = in.ensa_dof;
  attachField(m, hname, data, vars, out_size);
  free(data);
  return 1;
}

void detachAndWriteField(
    Input& in,
    apf::Mesh* m,
    FILE* f,
    const char* fieldname)
{
  double* data;
  int size;
  detachField(m, fieldname, data, size);
  ph_write_field(f, fieldname, data, m->count(0), size, in.timeStepNumber);
  free(data);
}

/* silliest darn fields I ever did see */
static double* buildMappingPartId(apf::Mesh* m)
{
  int n = m->count(0);
  /* malloc instead of new[] for consistency with ph_read_field */
  double* data = (double*)malloc(sizeof(double) * n);
  int self = PCU_Comm_Self();
  for (int i = 0; i < n; ++i)
    data[i] = self;
  return data;
}
static double* buildMappingVtxId(apf::Mesh* m)
{
  int n = m->count(0);
  /* malloc instead of new[] for consistency with ph_read_field */
  double* data = (double*)malloc(sizeof(double) * n);
  for (int i = 0; i < n; ++i)
    data[i] = i;
  return data;
}

static std::string buildRestartFileName(std::string prefix, int step)
{
  std::stringstream ss;
  int rank = PCU_Comm_Self() + 1;
  ss << prefix << '.' << step << '.' << rank;
  return ss.str();
}

void readAndAttachFields(Input& in, apf::Mesh* m) {
  double t0 = PCU_Time();
  setupInputSubdir(in.restartFileName);
  std::string filename = buildRestartFileName(in.restartFileName, in.timeStepNumber);
  FILE* f = in.openfile_read(in, filename.c_str());
  if (!f) {
    fprintf(stderr,"failed to open \"%s\"!\n", filename.c_str());
    abort();
  }
  int swap = ph_should_swap(f);
  while( readAndAttachField(in,f,m,swap) ); /* inf loop?? */
  fclose(f);
  double t1 = PCU_Time();
  if (!PCU_Comm_Self())
    printf("fields read and attached in %f seconds\n", t1 - t0);
}

void buildMapping(apf::Mesh* m)
{
  double* mapping = buildMappingPartId(m);
  attachField(m, "mapping_partid", mapping, 1);
  free(mapping);
  mapping = buildMappingVtxId(m);
  attachField(m, "mapping_vtxid", mapping, 1);
  free(mapping);
}

void attachZeroSolution(Input& in, apf::Mesh* m)
{
  int vars = in.ensa_dof;
  int nodes = m->count(0);
  double* data = new double[nodes * vars]();
  attachField(m, "solution", data, vars);
  delete [] data;
}

void detachAndWriteSolution(Input& in, Output& out, apf::Mesh* m, std::string path)
{
  double t0 = PCU_Time();
  path += buildRestartFileName("restart", in.timeStepNumber);
  FILE* f = out.openfile_write(out, path.c_str());
  if (!f) {
    fprintf(stderr,"failed to open \"%s\"!\n", path.c_str());
    abort();
  }
  ph_write_preamble(f);
  int nodes = m->count(0);
  ph_write_header(f, "number of modes", 0, 1, &nodes);
  ph_write_header(f, "number of variables", 0, 1, &in.ensa_dof);
  apf::Field* errField = m->findField("errors");
  if (errField)
    apf::destroyField(errField);
  if (m->findField("solution"))
    detachAndWriteField(in, m, f, "solution");
  if (in.displacementMigration)
    detachAndWriteField(in, m, f, "displacement");
  if (in.dwalMigration)
    detachAndWriteField(in, m, f, "dwal");
  if (in.buildMapping) {
    detachAndWriteField(in, m, f, "mapping_partid");
    detachAndWriteField(in, m, f, "mapping_vtxid");
  }
  /* detach any remaining fields */
  while(m->countFields())
    apf::destroyField( m->getField(0) );
  fclose(f);
  double t1 = PCU_Time();
  if (!PCU_Comm_Self())
    printf("solution written in %f seconds\n", t1 - t0);
}

}
<commit_msg>try to ignore PHASTA array VOF solution<commit_after>#include <PCU.h>
#include "phRestart.h"
#include <apf.h>
#include "phIO.h"
#include "ph.h"
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <cassert>

namespace ph {

/* in_size is the number of dofs for the data array
   and out_size is the number of dofs in the field.
   they are unequal when we read a restart file
   and want to add more dofs for the next restart files */

void attachField(
    apf::Mesh* m,
    const char* fieldname,
    double* data,
    int in_size,
    int out_size)
{
  if (!(in_size <= out_size))
    fprintf(stderr, "field \"%s\" in_size %d out_size %d\n", fieldname, in_size, out_size);
  assert(in_size <= out_size);
  apf::Field* f = apf::createPackedField(m, fieldname, out_size);
  size_t n = m->count(0);
  apf::NewArray<double> c(out_size);
  apf::MeshEntity* e;
  size_t i = 0;
  apf::MeshIterator* it = m->begin(0);
  while ((e = m->iterate(it))) {
    for (int j = 0; j < in_size; ++j)
      c[j] = data[j * n + i];
    apf::setComponents(f, e, 0, &c[0]);
    ++i;
  }
  m->end(it);
  assert(i == n);
}

/* convenience wrapper, in most cases in_size=out_size */
void attachField(
    apf::Mesh* m,
    const char* fieldname,
    double* data,
    int size)
{
  attachField(m, fieldname, data, size, size);
}

void detachField(
    apf::Field* f,
    double*& data,
    int& size)
{
  apf::Mesh* m = apf::getMesh(f);
  size = apf::countComponents(f);
  size_t n = m->count(0);
  apf::NewArray<double> c(size);
  data = (double*)malloc(sizeof(double) * size * m->count(0));
  apf::MeshEntity* e;
  size_t i = 0;
  apf::MeshIterator* it = m->begin(0);
  while ((e = m->iterate(it))) {
    apf::getComponents(f, e, 0, &c[0]);
    for (int j = 0; j < size; ++j)
      data[j * n + i] = c[j];
    ++i;
  }
  m->end(it);
  assert(i == n);
  apf::destroyField(f);
}

void detachField(
    apf::Mesh* m,
    const char* fieldname,
    double*& data,
    int& size)
{
  apf::Field* f = m->findField(fieldname);
  assert(f);
  detachField(f, data, size);
}

int readAndAttachField(
    Input& in,
    FILE* f,
    apf::Mesh* m,
    int swap)
{
  double* data;
  int nodes, vars, step;
  char hname[1024];
  const char* anyfield = "";
  int ret = ph_read_field(f, anyfield, swap,
      &data, &nodes, &vars, &step, hname);
  /* no field was found or the field has an empty data block */
  if(ret==0 || ret==1)
    return ret;
  if ( std::string(hname) == std::string("VOF solution") )
    return 1;
  assert(nodes == static_cast<int>(m->count(0)));
  assert(step == in.timeStepNumber);
  int out_size = vars;
  if ( std::string(hname) == std::string("solution") )
    out_size = in.ensa_dof;
  attachField(m, hname, data, vars, out_size);
  free(data);
  return 1;
}

void detachAndWriteField(
    Input& in,
    apf::Mesh* m,
    FILE* f,
    const char* fieldname)
{
  double* data;
  int size;
  detachField(m, fieldname, data, size);
  ph_write_field(f, fieldname, data, m->count(0), size, in.timeStepNumber);
  free(data);
}

/* silliest darn fields I ever did see */
static double* buildMappingPartId(apf::Mesh* m)
{
  int n = m->count(0);
  /* malloc instead of new[] for consistency with ph_read_field */
  double* data = (double*)malloc(sizeof(double) * n);
  int self = PCU_Comm_Self();
  for (int i = 0; i < n; ++i)
    data[i] = self;
  return data;
}
static double* buildMappingVtxId(apf::Mesh* m)
{
  int n = m->count(0);
  /* malloc instead of new[] for consistency with ph_read_field */
  double* data = (double*)malloc(sizeof(double) * n);
  for (int i = 0; i < n; ++i)
    data[i] = i;
  return data;
}

static std::string buildRestartFileName(std::string prefix, int step)
{
  std::stringstream ss;
  int rank = PCU_Comm_Self() + 1;
  ss << prefix << '.' << step << '.' << rank;
  return ss.str();
}

void readAndAttachFields(Input& in, apf::Mesh* m) {
  double t0 = PCU_Time();
  setupInputSubdir(in.restartFileName);
  std::string filename = buildRestartFileName(in.restartFileName, in.timeStepNumber);
  FILE* f = in.openfile_read(in, filename.c_str());
  if (!f) {
    fprintf(stderr,"failed to open \"%s\"!\n", filename.c_str());
    abort();
  }
  int swap = ph_should_swap(f);
  /* stops when ph_read_field returns 0 */
  while( readAndAttachField(in,f,m,swap) );
  fclose(f);
  double t1 = PCU_Time();
  if (!PCU_Comm_Self())
    printf("fields read and attached in %f seconds\n", t1 - t0);
}

void buildMapping(apf::Mesh* m)
{
  double* mapping = buildMappingPartId(m);
  attachField(m, "mapping_partid", mapping, 1);
  free(mapping);
  mapping = buildMappingVtxId(m);
  attachField(m, "mapping_vtxid", mapping, 1);
  free(mapping);
}

void attachZeroSolution(Input& in, apf::Mesh* m)
{
  int vars = in.ensa_dof;
  int nodes = m->count(0);
  double* data = new double[nodes * vars]();
  attachField(m, "solution", data, vars);
  delete [] data;
}

void detachAndWriteSolution(Input& in, Output& out, apf::Mesh* m, std::string path)
{
  double t0 = PCU_Time();
  path += buildRestartFileName("restart", in.timeStepNumber);
  FILE* f = out.openfile_write(out, path.c_str());
  if (!f) {
    fprintf(stderr,"failed to open \"%s\"!\n", path.c_str());
    abort();
  }
  ph_write_preamble(f);
  int nodes = m->count(0);
  ph_write_header(f, "number of modes", 0, 1, &nodes);
  ph_write_header(f, "number of variables", 0, 1, &in.ensa_dof);
  apf::Field* errField = m->findField("errors");
  if (errField)
    apf::destroyField(errField);
  if (m->findField("solution"))
    detachAndWriteField(in, m, f, "solution");
  if (in.displacementMigration)
    detachAndWriteField(in, m, f, "displacement");
  if (in.dwalMigration)
    detachAndWriteField(in, m, f, "dwal");
  if (in.buildMapping) {
    detachAndWriteField(in, m, f, "mapping_partid");
    detachAndWriteField(in, m, f, "mapping_vtxid");
  }
  /* detach any remaining fields */
  while(m->countFields())
    apf::destroyField( m->getField(0) );
  fclose(f);
  double t1 = PCU_Time();
  if (!PCU_Comm_Self())
    printf("solution written in %f seconds\n", t1 - t0);
}

}
<|endoftext|>


<commit_before>#include "robotpath.h"

RobotPath::RobotPath(RobotGridMatrix *Maze, QList<QPoint> botOnePath, QList<QPoint> botTwoPath){
    this->botOnePath = &botOnePath;
    this->botTwoPath = &botTwoPath;

    for(int r=0; r < 8; r++)
        for(int c=0; c < 10; c++)
            this->Maze[r][c] = Maze->Maze[r][c];
    //this->Maze = Maze->Maze;
    Robot bot1, bot2;
    {
        bot1.Pos     = QPoint(9,0);
        bot1.Dir     = DOWN;
        bot1.PrevDir = DEFAULT;
        this->botOnePath->append(bot1.Pos);
        qDebug("ACTUAL: Maze[%d][%d] {0}",bot1.Pos.x(),bot1.Pos.y());
    }
    {
        bot2.Pos     = QPoint(9,7);
        bot2.Dir     = UP;
        bot2.PrevDir = DEFAULT;
        this->botTwoPath->append(bot2.Pos);
    }

    int t=1;
    while((bot1.Pos != QPoint(0,7))) {
        this->FindDirection(bot1, 1);
        this->MakeStep(bot1);
        qDebug("ACTUAL: Maze[%d][%d] {%d}",bot1.Pos.x(),bot1.Pos.y(),t);
        this->botOnePath->append(bot1.Pos);
        if(t > 20) break;
        t++;
    }
  /*
    while((bot2.Pos != QPoint(0,0))) {
    //for(int t; t < 10; t++) {
        bot2.Dir = this->FindDirection(bot2, BOT2);
        this->MakeStep(&bot2); qDebug("hire2 %d",t);
        this->botTwoPath->append(bot2.Pos);
    }*/
}

RobotPath::RobotPath(Map maze, QList<QPoint> botOnePath, QList<QPoint> botTwoPath) {
    this->botOnePath = &botOnePath;
    this->botTwoPath = &botTwoPath;
    this->map        = &maze;

    Robot bot1, bot2;
    {
        bot1.ID      = 1;
        bot1.Pos     = QPoint(9,0);
        bot1.Dir     = DOWN;
        bot1.PrevDir = DEFAULT;
        this->botOnePath->append(bot1.Pos);
        qDebug("ACTUAL: Maze[%d][%d] {0}",bot1.Pos.x(),bot1.Pos.y());
    }
    {
        bot2.ID      = 2;
        bot2.Pos     = QPoint(9,7);
        bot2.Dir     = UP;
        bot2.PrevDir = DEFAULT;
        this->botTwoPath->append(bot2.Pos);
    }
    while((bot1.Pos != QPoint(0,7))) {
        this->Movement(bot1);
        this->botOnePath->append(bot1.Pos);
        qDebug("ACTUAL: MAZE[%d][%d]",bot1.Pos.x(),bot1.Pos.y());
    }
}

void RobotPath::Movement(Robot &bot) {
    switch(bot.ID) {
        case 1: {
            if(this->map->popValue(QPoint_LEFT+bot.Pos) == bot.ID || this->map->popValue(QPoint_LEFT+bot.Pos) == SHARED) {
                if(bot.PrevDir != RIGHT) {
                    bot.PrevDir = bot.Dir = LEFT;
                    bot.Pos    += QPoint_LEFT;
                    return;
                }
            }
            if(this->map->popValue(QPoint_DOWN+bot.Pos) == bot.ID || this->map->popValue(QPoint_DOWN+bot.Pos) == SHARED) {
                if(bot.PrevDir != UP) {
                    bot.PrevDir = bot.Dir = DOWN;
                    bot.Pos    += QPoint_DOWN;
                    return;
                }
            }
            if(this->map->popValue(QPoint_UP+bot.Pos) == bot.ID || this->map->popValue(QPoint_UP+bot.Pos) == SHARED) {
                if(bot.PrevDir != DOWN) {
                    bot.PrevDir = bot.Dir = UP;
                    bot.Pos    += QPoint_UP;
                    return;
                }
            }
            if(this->map->popValue(QPoint_RIGHT+bot.Pos) == bot.ID || this->map->popValue(QPoint_RIGHT+bot.Pos) == SHARED) {
                if(bot.PrevDir != LEFT) {
                    bot.PrevDir = bot.Dir = RIGHT;
                    bot.Pos    += QPoint_RIGHT;
                    return;
                }
            }
        } break;
        case 2: {
            if(this->map->popValue(QPoint_LEFT+bot.Pos) == bot.ID || this->map->popValue(QPoint_LEFT+bot.Pos) == SHARED) {
                if(bot.PrevDir != RIGHT) {
                    bot.PrevDir = bot.Dir = LEFT;
                    bot.Pos    += QPoint_LEFT;
                    return;
                }
            }
            if(this->map->popValue(QPoint_UP+bot.Pos) == bot.ID || this->map->popValue(QPoint_UP+bot.Pos) == SHARED) {
                if(bot.PrevDir != DOWN) {
                    bot.PrevDir = bot.Dir = UP;
                    bot.Pos    += QPoint_UP;
                    return;
                }
            }
            if(this->map->popValue(QPoint_DOWN+bot.Pos) == bot.ID || this->map->popValue(QPoint_DOWN+bot.Pos) == SHARED) {
                if(bot.PrevDir != UP) {
                    bot.PrevDir = bot.Dir = DOWN;
                    bot.Pos    += QPoint_DOWN;
                    return;
                }
            }
            if(this->map->popValue(QPoint_RIGHT+bot.Pos) == bot.ID || this->map->popValue(QPoint_RIGHT+bot.Pos) == SHARED) {
                if(bot.PrevDir != LEFT) {
                    bot.PrevDir = bot.Dir = RIGHT;
                    bot.Pos    += QPoint_RIGHT;
                    return;
                }
            }
        } break;
    }
}

RobotPath::~RobotPath(){}

void RobotPath::FindDirection(Robot& BOT, int Elem){
    int x,y;
    x = BOT.Pos.x(); // position swap
    y = BOT.Pos.y(); // position swap

    switch(Elem) {
        case 1: {
                    if(this->Maze[x][y-1] == Elem || this->Maze[x][y-1] == SHARED) {
                        qDebug("LEFT: Maze[%d][%d] == %d",y-1,x,this->Maze[x][y-1]);
                        if(BOT.PrevDir != RIGHT) {
                            BOT.PrevDir = BOT.Dir;
                            BOT.Dir = LEFT;
                            return;
                        }
                    }
                    if(this->Maze[x+1][y] == Elem || this->Maze[x+1][y] == SHARED) {
                        qDebug("DOWN: Maze[%d][%d] == %d",y,x+1,this->Maze[x+1][y]);
                        if(BOT.PrevDir != UP) {
                           BOT.PrevDir = BOT.Dir;
                           BOT.Dir = DOWN;
                           return;
                        }
                    }
                    if(this->Maze[x-1][y] == Elem || this->Maze[x-1][y] == SHARED) {
                        qDebug("UP: Maze[%d][%d] == %d",x-1,y,this->Maze[x-1][y]);
                        if(BOT.PrevDir != DOWN) {
                            BOT.PrevDir = BOT.Dir;
                            BOT.Dir = UP;
                            return;
                        }

                    }
                    if(this->Maze[x][y+1] == Elem || this->Maze[x][y+1] == SHARED) {
                        qDebug("RIGHT: Maze[%d][%d] == %d",x,y+1,this->Maze[x][y+1]);
                        if(BOT.PrevDir != LEFT) {
                            BOT.PrevDir = BOT.Dir;
                            BOT.Dir = RIGHT;
                            return;
                        }
                    }
         }
    }

    //BOT.Dir = LEFT;
}

void RobotPath::MakeStep(Robot& BOT){
    switch(BOT.Dir){
        case    UP: BOT.Pos.rx()--; break;
        case  DOWN: BOT.Pos.rx()++; break;
        case  LEFT: BOT.Pos.ry()--; break;
        case RIGHT: BOT.Pos.ry()++; break;
    }
    BOT.Dir = DEFAULT;
}
<commit_msg>added the save of second movement position<commit_after>#include "robotpath.h"

RobotPath::RobotPath(RobotGridMatrix *Maze, QList<QPoint> botOnePath, QList<QPoint> botTwoPath){
    this->botOnePath = &botOnePath;
    this->botTwoPath = &botTwoPath;

    for(int r=0; r < 8; r++)
        for(int c=0; c < 10; c++)
            this->Maze[r][c] = Maze->Maze[r][c];
    //this->Maze = Maze->Maze;
    Robot bot1, bot2;
    {
        bot1.Pos     = QPoint(9,0);
        bot1.Dir     = DOWN;
        bot1.PrevDir = DEFAULT;
        this->botOnePath->append(bot1.Pos);
        qDebug("ACTUAL: Maze[%d][%d] {0}",bot1.Pos.x(),bot1.Pos.y());
    }
    {
        bot2.Pos     = QPoint(9,7);
        bot2.Dir     = UP;
        bot2.PrevDir = DEFAULT;
        this->botTwoPath->append(bot2.Pos);
    }

    int t=1;
    while((bot1.Pos != QPoint(0,7))) {
        this->FindDirection(bot1, 1);
        this->MakeStep(bot1);
        qDebug("ACTUAL: Maze[%d][%d] {%d}",bot1.Pos.x(),bot1.Pos.y(),t);
        this->botOnePath->append(bot1.Pos);
        if(t > 20) break;
        t++;
    }
  /*
    while((bot2.Pos != QPoint(0,0))) {
    //for(int t; t < 10; t++) {
        bot2.Dir = this->FindDirection(bot2, BOT2);
        this->MakeStep(&bot2); qDebug("hire2 %d",t);
        this->botTwoPath->append(bot2.Pos);
    }*/
}

RobotPath::RobotPath(Map maze, QList<QPoint> botOnePath, QList<QPoint> botTwoPath) {
    this->botOnePath = &botOnePath;
    this->botTwoPath = &botTwoPath;
    this->map        = &maze;

    Robot bot1, bot2;
    {
        bot1.ID      = 1;
        bot1.Pos     = QPoint(9,0);
        bot1.Dir     = DOWN;
        bot1.PrevDir = DEFAULT;
        this->botOnePath->append(bot1.Pos);
        qDebug("ACTUAL: Maze[%d][%d] {0}",bot1.Pos.x(),bot1.Pos.y());
    }
    {
        bot2.ID      = 2;
        bot2.Pos     = QPoint(9,7);
        bot2.Dir     = UP;
        bot2.PrevDir = DEFAULT;
        this->botTwoPath->append(bot2.Pos);
    }
    while((bot1.Pos != QPoint(0,7))) {
        this->Movement(bot1);
        this->botOnePath->append(bot1.Pos);
        qDebug("ACTUAL: MAZE[%d][%d]",bot1.Pos.x(),bot1.Pos.y());
    }

    while((bot2.Pos != QPoint(0,0))) {
        this->Movement(bot2);
        this->botOnePath->append(bot2.Pos);
        qDebug("ACTUAL2: MAZE[%d][%d]",bot2.Pos.x(),bot2.Pos.y());
    }
}

void RobotPath::Movement(Robot &bot) {
    switch(bot.ID) {
        case 1: {
            if(this->map->popValue(QPoint_LEFT+bot.Pos) == bot.ID || this->map->popValue(QPoint_LEFT+bot.Pos) == SHARED) {
                if(bot.PrevDir != RIGHT) {
                    bot.PrevDir = bot.Dir = LEFT;
                    bot.Pos    += QPoint_LEFT;
                    return;
                }
            }
            if(this->map->popValue(QPoint_DOWN+bot.Pos) == bot.ID || this->map->popValue(QPoint_DOWN+bot.Pos) == SHARED) {
                if(bot.PrevDir != UP) {
                    bot.PrevDir = bot.Dir = DOWN;
                    bot.Pos    += QPoint_DOWN;
                    return;
                }
            }
            if(this->map->popValue(QPoint_UP+bot.Pos) == bot.ID || this->map->popValue(QPoint_UP+bot.Pos) == SHARED) {
                if(bot.PrevDir != DOWN) {
                    bot.PrevDir = bot.Dir = UP;
                    bot.Pos    += QPoint_UP;
                    return;
                }
            }
            if(this->map->popValue(QPoint_RIGHT+bot.Pos) == bot.ID || this->map->popValue(QPoint_RIGHT+bot.Pos) == SHARED) {
                if(bot.PrevDir != LEFT) {
                    bot.PrevDir = bot.Dir = RIGHT;
                    bot.Pos    += QPoint_RIGHT;
                    return;
                }
            }
        } break;
        case 2: {
            if(this->map->popValue(QPoint_LEFT+bot.Pos) == bot.ID || this->map->popValue(QPoint_LEFT+bot.Pos) == SHARED) {
                if(bot.PrevDir != RIGHT) {
                    bot.PrevDir = bot.Dir = LEFT;
                    bot.Pos    += QPoint_LEFT;
                    return;
                }
            }
            if(this->map->popValue(QPoint_UP+bot.Pos) == bot.ID || this->map->popValue(QPoint_UP+bot.Pos) == SHARED) {
                if(bot.PrevDir != DOWN) {
                    bot.PrevDir = bot.Dir = UP;
                    bot.Pos    += QPoint_UP;
                    return;
                }
            }
            if(this->map->popValue(QPoint_DOWN+bot.Pos) == bot.ID || this->map->popValue(QPoint_DOWN+bot.Pos) == SHARED) {
                if(bot.PrevDir != UP) {
                    bot.PrevDir = bot.Dir = DOWN;
                    bot.Pos    += QPoint_DOWN;
                    return;
                }
            }
            if(this->map->popValue(QPoint_RIGHT+bot.Pos) == bot.ID || this->map->popValue(QPoint_RIGHT+bot.Pos) == SHARED) {
                if(bot.PrevDir != LEFT) {
                    bot.PrevDir = bot.Dir = RIGHT;
                    bot.Pos    += QPoint_RIGHT;
                    return;
                }
            }
        } break;
    }
}

RobotPath::~RobotPath(){}

void RobotPath::FindDirection(Robot& BOT, int Elem){
    int x,y;
    x = BOT.Pos.x(); // position swap
    y = BOT.Pos.y(); // position swap

    switch(Elem) {
        case 1: {
                    if(this->Maze[x][y-1] == Elem || this->Maze[x][y-1] == SHARED) {
                        qDebug("LEFT: Maze[%d][%d] == %d",y-1,x,this->Maze[x][y-1]);
                        if(BOT.PrevDir != RIGHT) {
                            BOT.PrevDir = BOT.Dir;
                            BOT.Dir = LEFT;
                            return;
                        }
                    }
                    if(this->Maze[x+1][y] == Elem || this->Maze[x+1][y] == SHARED) {
                        qDebug("DOWN: Maze[%d][%d] == %d",y,x+1,this->Maze[x+1][y]);
                        if(BOT.PrevDir != UP) {
                           BOT.PrevDir = BOT.Dir;
                           BOT.Dir = DOWN;
                           return;
                        }
                    }
                    if(this->Maze[x-1][y] == Elem || this->Maze[x-1][y] == SHARED) {
                        qDebug("UP: Maze[%d][%d] == %d",x-1,y,this->Maze[x-1][y]);
                        if(BOT.PrevDir != DOWN) {
                            BOT.PrevDir = BOT.Dir;
                            BOT.Dir = UP;
                            return;
                        }

                    }
                    if(this->Maze[x][y+1] == Elem || this->Maze[x][y+1] == SHARED) {
                        qDebug("RIGHT: Maze[%d][%d] == %d",x,y+1,this->Maze[x][y+1]);
                        if(BOT.PrevDir != LEFT) {
                            BOT.PrevDir = BOT.Dir;
                            BOT.Dir = RIGHT;
                            return;
                        }
                    }
         }
    }

    //BOT.Dir = LEFT;
}

void RobotPath::MakeStep(Robot& BOT){
    switch(BOT.Dir){
        case    UP: BOT.Pos.rx()--; break;
        case  DOWN: BOT.Pos.rx()++; break;
        case  LEFT: BOT.Pos.ry()--; break;
        case RIGHT: BOT.Pos.ry()++; break;
    }
    BOT.Dir = DEFAULT;
}
<|endoftext|>


<commit_before>/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */
#include "InsertPropertyPanel.hxx"
#include "InsertPropertyPanel.hrc"
#include "sfx2/sidebar/CommandInfoProvider.hxx"

#include <sfx2/sidebar/Theme.hxx>
#include <sfx2/sidebar/Tools.hxx>
#include <sfx2/sidebar/ControlFactory.hxx>

#include <svx/dialmgr.hxx>
#include <svtools/miscopt.hxx>
#include <svtools/generictoolboxcontroller.hxx>
#include <vcl/toolbox.hxx>
#include <sfx2/tbxctrl.hxx>
#include <framework/sfxhelperfunctions.hxx>
#include <framework/imageproducer.hxx>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/basemutex.hxx>

#include <com/sun/star/frame/XStatusListener.hpp>

using namespace css;
using namespace cssu;
using ::rtl::OUString;

namespace svx { namespace sidebar {

InsertPropertyPanel::InsertPropertyPanel (
    Window* pParent,
    const cssu::Reference<css::frame::XFrame>& rxFrame)
    :   Control(pParent, SVX_RES(RID_SIDEBAR_INSERT_PANEL)),
        mpStandardShapesBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)),
        mpStandardShapesToolBox(sfx2::sidebar::ControlFactory::CreateToolBox(
                mpStandardShapesBackground.get(),
                SVX_RES(TB_INSERT_STANDARD))),
        mpCustomShapesBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)),
        mpCustomShapesToolBox(sfx2::sidebar::ControlFactory::CreateToolBox(
                mpCustomShapesBackground.get(),
                SVX_RES(TB_INSERT_CUSTOM))),
        maControllers(),
        mxFrame(rxFrame)
{
    SetupToolBox(*mpStandardShapesToolBox);
    SetupToolBox(*mpCustomShapesToolBox);
    FreeResource();

    UpdateIcons();

    mpStandardShapesToolBox->Show();
    mpCustomShapesToolBox->Show();

    // Listen to all tool box selection events.
    Window* pTopWindow = pParent;
    while (pTopWindow->GetParent() != NULL)
        pTopWindow = pTopWindow->GetParent();
    pTopWindow->AddChildEventListener(LINK(this, InsertPropertyPanel, WindowEventListener));
}

InsertPropertyPanel::~InsertPropertyPanel (void)
{
    ControllerContainer aControllers;
    aControllers.swap(maControllers);
    for (ControllerContainer::iterator iController(aControllers.begin()), iEnd(aControllers.end());
         iController!=iEnd;
         ++iController)
    {
        Reference<lang::XComponent> xComponent (iController->second.mxController, UNO_QUERY);
        if (xComponent.is())
            xComponent->dispose();
    }

    // Remove window child listener.
    Window* pTopWindow = this;
    while (pTopWindow->GetParent() != NULL)
        pTopWindow = pTopWindow->GetParent();
    pTopWindow->RemoveChildEventListener(LINK(this, InsertPropertyPanel, WindowEventListener));

    mpStandardShapesToolBox.reset();
    mpCustomShapesToolBox.reset();
    mpStandardShapesBackground.reset();
    mpCustomShapesBackground.reset();
}

void InsertPropertyPanel::SetupToolBox (ToolBox& rToolBox)
{
    const sal_uInt16 nItemCount (rToolBox.GetItemCount());
    for (sal_uInt16 nItemIndex=0; nItemIndex<nItemCount; ++nItemIndex)
        CreateController(rToolBox.GetItemId(nItemIndex));

    rToolBox.SetDropdownClickHdl(LINK(this, InsertPropertyPanel, DropDownClickHandler));
    rToolBox.SetClickHdl(LINK(this, InsertPropertyPanel, ClickHandler));
    rToolBox.SetDoubleClickHdl(LINK(this, InsertPropertyPanel, DoubleClickHandler));
    rToolBox.SetSelectHdl(LINK(this, InsertPropertyPanel, SelectHandler));
    rToolBox.SetActivateHdl(LINK(this, InsertPropertyPanel, ActivateToolBox));
    rToolBox.SetDeactivateHdl(LINK(this, InsertPropertyPanel, DeactivateToolBox));

    rToolBox.SetSizePixel(rToolBox.CalcWindowSizePixel());
}

IMPL_LINK(InsertPropertyPanel, DropDownClickHandler, ToolBox*, pToolBox)
{
    if (pToolBox != NULL)
    {
        Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
        if (xController.is())
        {
            Reference<awt::XWindow> xWindow = xController->createPopupWindow();
            if (xWindow.is() )
                xWindow->setFocus();
        }
    }
    return 1;
}

IMPL_LINK(InsertPropertyPanel, ClickHandler, ToolBox*, pToolBox)
{
    if (pToolBox == NULL)
        return 0;

    Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
    if (xController.is())
        xController->click();

    return 1;
}

IMPL_LINK(InsertPropertyPanel, DoubleClickHandler, ToolBox*, pToolBox)
{
    if (pToolBox == NULL)
        return 0;

    Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
    if (xController.is())
        xController->doubleClick();

    return 1;
}

IMPL_LINK(InsertPropertyPanel, SelectHandler, ToolBox*, pToolBox)
{
    if (pToolBox == NULL)
        return 0;

    Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
    if (xController.is())
        xController->execute((sal_Int16)pToolBox->GetModifier());

    return 1;
}

IMPL_LINK(InsertPropertyPanel, WindowEventListener, VclSimpleEvent*, pEvent)
{
    // We will be getting a lot of window events (well, basically all
    // of them), so reject early everything that is not connected to
    // toolbox selection.
    if (pEvent == NULL)
        return 1;
    if ( ! pEvent->ISA(VclWindowEvent))
        return 1;
    if (pEvent->GetId() != VCLEVENT_TOOLBOX_SELECT)
        return 1;

    ToolBox* pToolBox = dynamic_cast<ToolBox*>(dynamic_cast<VclWindowEvent*>(pEvent)->GetWindow());
    if (pToolBox == NULL)
        return 1;

    // Extract name of (sub)toolbar from help id.
    OUString sToolbarName (rtl::OStringToOUString(pToolBox->GetHelpId(), RTL_TEXTENCODING_UTF8));
    if (sToolbarName.getLength() == 0)
        return 1;
    const util::URL aURL (sfx2::sidebar::Tools::GetURL(sToolbarName));
    if (aURL.Path.getLength() == 0)
        return 1;

    // Get item id.
    sal_uInt16 nId = pToolBox->GetCurItemId();
    if (nId == 0)
        return 1;

    // Get toolbar controller.
    const sal_uInt16 nItemId (GetItemIdForSubToolbarName(aURL.Path));
    Reference<frame::XSubToolbarController> xController (GetControllerForItemId(nItemId), UNO_QUERY);
    if ( ! xController.is())
        return 1;

    const OUString sCommand (pToolBox->GetItemCommand(nId));
    ControllerContainer::iterator iController (maControllers.find(nItemId));
    if (iController != maControllers.end())
        iController->second.msCurrentCommand = sCommand;
    xController->functionSelected(sCommand);

    const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge());
    Image aImage (framework::GetImageFromURL(mxFrame, sCommand, bBigImages));
    pToolBox->SetItemImage(iController->first, aImage);

    return 1;
}

IMPL_LINK(InsertPropertyPanel, ActivateToolBox, ToolBox*, EMPTYARG)
{
    return 1;
}

IMPL_LINK(InsertPropertyPanel, DeactivateToolBox, ToolBox*, EMPTYARG)
{
    return 1;
}

void InsertPropertyPanel::CreateController (
    const sal_uInt16 nItemId)
{
    ToolBox* pToolBox = GetToolBoxForItemId(nItemId);
    if (pToolBox != NULL)
    {
        ItemDescriptor aDescriptor;

        const OUString sCommandName (pToolBox->GetItemCommand(nItemId));

        // Create a controller for the new item.
        aDescriptor.mxController.set(
            static_cast<XWeak*>(::framework::CreateToolBoxController(
                    mxFrame,
                    pToolBox,
                    nItemId,
                    sCommandName)),
            UNO_QUERY);
        if ( ! aDescriptor.mxController.is())
            aDescriptor.mxController.set(
                static_cast<XWeak*>(new svt::GenericToolboxController(
                        ::comphelper::getProcessServiceFactory(),
                        mxFrame,
                        pToolBox,
                        nItemId,
                        sCommandName)),
                UNO_QUERY);
        if ( ! aDescriptor.mxController.is())
            return;

        // Get dispatch object for the command.
        aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(sCommandName);
        aDescriptor.msCurrentCommand = sCommandName;
        aDescriptor.mxDispatch = sfx2::sidebar::Tools::GetDispatch(mxFrame, aDescriptor.maURL);
        if ( ! aDescriptor.mxDispatch.is())
            return;

        // Initialize the controller with eg a service factory.
        Reference<lang::XInitialization> xInitialization (aDescriptor.mxController, UNO_QUERY);
        if (xInitialization.is())
        {
            beans::PropertyValue aPropValue;
            std::vector<Any> aPropertyVector;

            aPropValue.Name = A2S("Frame");
            aPropValue.Value <<= mxFrame;
            aPropertyVector.push_back(makeAny(aPropValue));

            aPropValue.Name = A2S("ServiceManager");
            aPropValue.Value <<= ::comphelper::getProcessServiceFactory();
            aPropertyVector.push_back(makeAny(aPropValue));

            aPropValue.Name = A2S("CommandURL");
            aPropValue.Value <<= sCommandName;
            aPropertyVector.push_back(makeAny(aPropValue));

            Sequence<Any> aArgs (comphelper::containerToSequence(aPropertyVector));
            xInitialization->initialize(aArgs);
        }

        Reference<util::XUpdatable> xUpdatable (aDescriptor.mxController, UNO_QUERY);
        if (xUpdatable.is())
            xUpdatable->update();

        // Add label.
        const OUString sLabel (sfx2::sidebar::CommandInfoProvider::Instance().GetLabelForCommand(
                sCommandName,
                mxFrame));
        pToolBox->SetQuickHelpText(nItemId, sLabel);

        // Add item to toolbox.
        pToolBox->EnableItem(nItemId);
        maControllers.insert(::std::make_pair(nItemId, aDescriptor));
    }
}

ToolBox* InsertPropertyPanel::GetToolBoxForItemId (const sal_uInt16 nItemId) const
{
    switch(nItemId)
    {
        case TBI_STANDARD_LINE:
        case TBI_STANDARD_ARROW:
        case TBI_STANDARD_RECTANGLE:
        case TBI_STANDARD_ELLIPSE:
        case TBI_STANDARD_TEXT:
        case TBI_STANDARD_LINES:
        case TBI_STANDARD_CONNECTORS:
        case TBI_STANDARD_ARROWS:
            return mpStandardShapesToolBox.get();

        case TBI_CUSTOM_BASICS:
        case TBI_CUSTOM_SYMBOLS:
        case TBI_CUSTOM_ARROWS:
        case TBI_CUSTOM_FLOWCHARTS:
        case TBI_CUSTOM_CALLOUTS:
        case TBI_CUSTOM_STARS:
            return mpCustomShapesToolBox.get();

        default:
            return NULL;
    }
}

Reference<frame::XToolbarController> InsertPropertyPanel::GetControllerForItemId (const sal_uInt16 nItemId) const
{
    ControllerContainer::const_iterator iController (maControllers.find(nItemId));
    if (iController != maControllers.end())
        return iController->second.mxController;
    else
        return NULL;
}

sal_uInt16 InsertPropertyPanel::GetItemIdForSubToolbarName (const OUString& rsSubToolbarName) const
{
    for (ControllerContainer::const_iterator iController(maControllers.begin()), iEnd(maControllers.end());
         iController!=iEnd;
         ++iController)
    {
        Reference<frame::XSubToolbarController> xSubToolbarController (iController->second.mxController, UNO_QUERY);
        if (xSubToolbarController.is())
            if (xSubToolbarController->getSubToolbarName().equals(rsSubToolbarName))
                return iController->first;
    }
    return 0;
}

void InsertPropertyPanel::UpdateIcons (void)
{
    const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge());

    for (ControllerContainer::iterator iController(maControllers.begin()), iEnd(maControllers.end());
         iController!=iEnd;
         ++iController)
    {
        const ::rtl::OUString sCommandURL (iController->second.msCurrentCommand);
        Image aImage (framework::GetImageFromURL(mxFrame, sCommandURL, bBigImages));
        ToolBox* pToolBox = GetToolBoxForItemId(iController->first);
        if (pToolBox != NULL)
            pToolBox->SetItemImage(iController->first, aImage);
    }
}

} } // end of namespace svx::sidebar
<commit_msg>getProcessServiceFactory->getProcessComponentContext<commit_after>/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */
#include "InsertPropertyPanel.hxx"
#include "InsertPropertyPanel.hrc"
#include "sfx2/sidebar/CommandInfoProvider.hxx"

#include <sfx2/sidebar/Theme.hxx>
#include <sfx2/sidebar/Tools.hxx>
#include <sfx2/sidebar/ControlFactory.hxx>

#include <svx/dialmgr.hxx>
#include <svtools/miscopt.hxx>
#include <svtools/generictoolboxcontroller.hxx>
#include <vcl/toolbox.hxx>
#include <sfx2/tbxctrl.hxx>
#include <framework/sfxhelperfunctions.hxx>
#include <framework/imageproducer.hxx>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/basemutex.hxx>

#include <com/sun/star/frame/XStatusListener.hpp>

using namespace css;
using namespace cssu;
using ::rtl::OUString;

namespace svx { namespace sidebar {

InsertPropertyPanel::InsertPropertyPanel (
    Window* pParent,
    const cssu::Reference<css::frame::XFrame>& rxFrame)
    :   Control(pParent, SVX_RES(RID_SIDEBAR_INSERT_PANEL)),
        mpStandardShapesBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)),
        mpStandardShapesToolBox(sfx2::sidebar::ControlFactory::CreateToolBox(
                mpStandardShapesBackground.get(),
                SVX_RES(TB_INSERT_STANDARD))),
        mpCustomShapesBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)),
        mpCustomShapesToolBox(sfx2::sidebar::ControlFactory::CreateToolBox(
                mpCustomShapesBackground.get(),
                SVX_RES(TB_INSERT_CUSTOM))),
        maControllers(),
        mxFrame(rxFrame)
{
    SetupToolBox(*mpStandardShapesToolBox);
    SetupToolBox(*mpCustomShapesToolBox);
    FreeResource();

    UpdateIcons();

    mpStandardShapesToolBox->Show();
    mpCustomShapesToolBox->Show();

    // Listen to all tool box selection events.
    Window* pTopWindow = pParent;
    while (pTopWindow->GetParent() != NULL)
        pTopWindow = pTopWindow->GetParent();
    pTopWindow->AddChildEventListener(LINK(this, InsertPropertyPanel, WindowEventListener));
}

InsertPropertyPanel::~InsertPropertyPanel (void)
{
    ControllerContainer aControllers;
    aControllers.swap(maControllers);
    for (ControllerContainer::iterator iController(aControllers.begin()), iEnd(aControllers.end());
         iController!=iEnd;
         ++iController)
    {
        Reference<lang::XComponent> xComponent (iController->second.mxController, UNO_QUERY);
        if (xComponent.is())
            xComponent->dispose();
    }

    // Remove window child listener.
    Window* pTopWindow = this;
    while (pTopWindow->GetParent() != NULL)
        pTopWindow = pTopWindow->GetParent();
    pTopWindow->RemoveChildEventListener(LINK(this, InsertPropertyPanel, WindowEventListener));

    mpStandardShapesToolBox.reset();
    mpCustomShapesToolBox.reset();
    mpStandardShapesBackground.reset();
    mpCustomShapesBackground.reset();
}

void InsertPropertyPanel::SetupToolBox (ToolBox& rToolBox)
{
    const sal_uInt16 nItemCount (rToolBox.GetItemCount());
    for (sal_uInt16 nItemIndex=0; nItemIndex<nItemCount; ++nItemIndex)
        CreateController(rToolBox.GetItemId(nItemIndex));

    rToolBox.SetDropdownClickHdl(LINK(this, InsertPropertyPanel, DropDownClickHandler));
    rToolBox.SetClickHdl(LINK(this, InsertPropertyPanel, ClickHandler));
    rToolBox.SetDoubleClickHdl(LINK(this, InsertPropertyPanel, DoubleClickHandler));
    rToolBox.SetSelectHdl(LINK(this, InsertPropertyPanel, SelectHandler));
    rToolBox.SetActivateHdl(LINK(this, InsertPropertyPanel, ActivateToolBox));
    rToolBox.SetDeactivateHdl(LINK(this, InsertPropertyPanel, DeactivateToolBox));

    rToolBox.SetSizePixel(rToolBox.CalcWindowSizePixel());
}

IMPL_LINK(InsertPropertyPanel, DropDownClickHandler, ToolBox*, pToolBox)
{
    if (pToolBox != NULL)
    {
        Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
        if (xController.is())
        {
            Reference<awt::XWindow> xWindow = xController->createPopupWindow();
            if (xWindow.is() )
                xWindow->setFocus();
        }
    }
    return 1;
}

IMPL_LINK(InsertPropertyPanel, ClickHandler, ToolBox*, pToolBox)
{
    if (pToolBox == NULL)
        return 0;

    Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
    if (xController.is())
        xController->click();

    return 1;
}

IMPL_LINK(InsertPropertyPanel, DoubleClickHandler, ToolBox*, pToolBox)
{
    if (pToolBox == NULL)
        return 0;

    Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
    if (xController.is())
        xController->doubleClick();

    return 1;
}

IMPL_LINK(InsertPropertyPanel, SelectHandler, ToolBox*, pToolBox)
{
    if (pToolBox == NULL)
        return 0;

    Reference<frame::XToolbarController> xController (GetControllerForItemId(pToolBox->GetCurItemId()));
    if (xController.is())
        xController->execute((sal_Int16)pToolBox->GetModifier());

    return 1;
}

IMPL_LINK(InsertPropertyPanel, WindowEventListener, VclSimpleEvent*, pEvent)
{
    // We will be getting a lot of window events (well, basically all
    // of them), so reject early everything that is not connected to
    // toolbox selection.
    if (pEvent == NULL)
        return 1;
    if ( ! pEvent->ISA(VclWindowEvent))
        return 1;
    if (pEvent->GetId() != VCLEVENT_TOOLBOX_SELECT)
        return 1;

    ToolBox* pToolBox = dynamic_cast<ToolBox*>(dynamic_cast<VclWindowEvent*>(pEvent)->GetWindow());
    if (pToolBox == NULL)
        return 1;

    // Extract name of (sub)toolbar from help id.
    OUString sToolbarName (rtl::OStringToOUString(pToolBox->GetHelpId(), RTL_TEXTENCODING_UTF8));
    if (sToolbarName.getLength() == 0)
        return 1;
    const util::URL aURL (sfx2::sidebar::Tools::GetURL(sToolbarName));
    if (aURL.Path.getLength() == 0)
        return 1;

    // Get item id.
    sal_uInt16 nId = pToolBox->GetCurItemId();
    if (nId == 0)
        return 1;

    // Get toolbar controller.
    const sal_uInt16 nItemId (GetItemIdForSubToolbarName(aURL.Path));
    Reference<frame::XSubToolbarController> xController (GetControllerForItemId(nItemId), UNO_QUERY);
    if ( ! xController.is())
        return 1;

    const OUString sCommand (pToolBox->GetItemCommand(nId));
    ControllerContainer::iterator iController (maControllers.find(nItemId));
    if (iController != maControllers.end())
        iController->second.msCurrentCommand = sCommand;
    xController->functionSelected(sCommand);

    const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge());
    Image aImage (framework::GetImageFromURL(mxFrame, sCommand, bBigImages));
    pToolBox->SetItemImage(iController->first, aImage);

    return 1;
}

IMPL_LINK(InsertPropertyPanel, ActivateToolBox, ToolBox*, EMPTYARG)
{
    return 1;
}

IMPL_LINK(InsertPropertyPanel, DeactivateToolBox, ToolBox*, EMPTYARG)
{
    return 1;
}

void InsertPropertyPanel::CreateController (
    const sal_uInt16 nItemId)
{
    ToolBox* pToolBox = GetToolBoxForItemId(nItemId);
    if (pToolBox != NULL)
    {
        ItemDescriptor aDescriptor;

        const OUString sCommandName (pToolBox->GetItemCommand(nItemId));

        // Create a controller for the new item.
        aDescriptor.mxController.set(
            static_cast<XWeak*>(::framework::CreateToolBoxController(
                    mxFrame,
                    pToolBox,
                    nItemId,
                    sCommandName)),
            UNO_QUERY);
        if ( ! aDescriptor.mxController.is())
            aDescriptor.mxController.set(
                static_cast<XWeak*>(new svt::GenericToolboxController(
                        ::comphelper::getProcessComponentContext(),
                        mxFrame,
                        pToolBox,
                        nItemId,
                        sCommandName)),
                UNO_QUERY);
        if ( ! aDescriptor.mxController.is())
            return;

        // Get dispatch object for the command.
        aDescriptor.maURL = sfx2::sidebar::Tools::GetURL(sCommandName);
        aDescriptor.msCurrentCommand = sCommandName;
        aDescriptor.mxDispatch = sfx2::sidebar::Tools::GetDispatch(mxFrame, aDescriptor.maURL);
        if ( ! aDescriptor.mxDispatch.is())
            return;

        // Initialize the controller with eg a service factory.
        Reference<lang::XInitialization> xInitialization (aDescriptor.mxController, UNO_QUERY);
        if (xInitialization.is())
        {
            beans::PropertyValue aPropValue;
            std::vector<Any> aPropertyVector;

            aPropValue.Name = A2S("Frame");
            aPropValue.Value <<= mxFrame;
            aPropertyVector.push_back(makeAny(aPropValue));

            aPropValue.Name = A2S("ServiceManager");
            aPropValue.Value <<= ::comphelper::getProcessServiceFactory();
            aPropertyVector.push_back(makeAny(aPropValue));

            aPropValue.Name = A2S("CommandURL");
            aPropValue.Value <<= sCommandName;
            aPropertyVector.push_back(makeAny(aPropValue));

            Sequence<Any> aArgs (comphelper::containerToSequence(aPropertyVector));
            xInitialization->initialize(aArgs);
        }

        Reference<util::XUpdatable> xUpdatable (aDescriptor.mxController, UNO_QUERY);
        if (xUpdatable.is())
            xUpdatable->update();

        // Add label.
        const OUString sLabel (sfx2::sidebar::CommandInfoProvider::Instance().GetLabelForCommand(
                sCommandName,
                mxFrame));
        pToolBox->SetQuickHelpText(nItemId, sLabel);

        // Add item to toolbox.
        pToolBox->EnableItem(nItemId);
        maControllers.insert(::std::make_pair(nItemId, aDescriptor));
    }
}

ToolBox* InsertPropertyPanel::GetToolBoxForItemId (const sal_uInt16 nItemId) const
{
    switch(nItemId)
    {
        case TBI_STANDARD_LINE:
        case TBI_STANDARD_ARROW:
        case TBI_STANDARD_RECTANGLE:
        case TBI_STANDARD_ELLIPSE:
        case TBI_STANDARD_TEXT:
        case TBI_STANDARD_LINES:
        case TBI_STANDARD_CONNECTORS:
        case TBI_STANDARD_ARROWS:
            return mpStandardShapesToolBox.get();

        case TBI_CUSTOM_BASICS:
        case TBI_CUSTOM_SYMBOLS:
        case TBI_CUSTOM_ARROWS:
        case TBI_CUSTOM_FLOWCHARTS:
        case TBI_CUSTOM_CALLOUTS:
        case TBI_CUSTOM_STARS:
            return mpCustomShapesToolBox.get();

        default:
            return NULL;
    }
}

Reference<frame::XToolbarController> InsertPropertyPanel::GetControllerForItemId (const sal_uInt16 nItemId) const
{
    ControllerContainer::const_iterator iController (maControllers.find(nItemId));
    if (iController != maControllers.end())
        return iController->second.mxController;
    else
        return NULL;
}

sal_uInt16 InsertPropertyPanel::GetItemIdForSubToolbarName (const OUString& rsSubToolbarName) const
{
    for (ControllerContainer::const_iterator iController(maControllers.begin()), iEnd(maControllers.end());
         iController!=iEnd;
         ++iController)
    {
        Reference<frame::XSubToolbarController> xSubToolbarController (iController->second.mxController, UNO_QUERY);
        if (xSubToolbarController.is())
            if (xSubToolbarController->getSubToolbarName().equals(rsSubToolbarName))
                return iController->first;
    }
    return 0;
}

void InsertPropertyPanel::UpdateIcons (void)
{
    const sal_Bool bBigImages (SvtMiscOptions().AreCurrentSymbolsLarge());

    for (ControllerContainer::iterator iController(maControllers.begin()), iEnd(maControllers.end());
         iController!=iEnd;
         ++iController)
    {
        const ::rtl::OUString sCommandURL (iController->second.msCurrentCommand);
        Image aImage (framework::GetImageFromURL(mxFrame, sCommandURL, bBigImages));
        ToolBox* pToolBox = GetToolBoxForItemId(iController->first);
        if (pToolBox != NULL)
            pToolBox->SetItemImage(iController->first, aImage);
    }
}

} } // end of namespace svx::sidebar
<|endoftext|>