<commit_before>/**
 * @file llchannelmanager.cpp
 * @brief This class rules screen notification channels.
 *
 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "llchannelmanager.h"

#include "llappviewer.h"
#include "lldonotdisturbnotificationstorage.h"
#include "llpersistentnotificationstorage.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llrootview.h"
#include "llsyswellwindow.h"
#include "llfloaterreg.h"

#include <algorithm>

using namespace LLNotificationsUI;

//--------------------------------------------------------------------------
LLChannelManager::LLChannelManager()
{
	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
	mChannelList.clear();
	mStartUpChannel = NULL;

	if(!gViewerWindow)
	{
		llerrs << "LLChannelManager::LLChannelManager() - viwer window is not initialized yet" << llendl;
	}
}

//--------------------------------------------------------------------------
LLChannelManager::~LLChannelManager()
{
	// <FS:ND> HACK/Test FIRE-11884 / Crash on exit. After making sure no ScreenChannel gets destroyed in a LLView dtor, this can still
	// crash when the static singleton of LLChannelManager is destroyed.
	// Leak those few channels on shutdown here to test if that fixes the rest of the crash. As this is shutdown code, the OS will clean up after us.
	// Not nice or recommended, but not harmful either here.

	// for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it)
	// {
	// 	LLScreenChannelBase* channel = it->channel.get();
	// 	if (!channel) continue;
	//
	// 	delete channel;
	// }

	// </FS:ND>

	mChannelList.clear();
}

//--------------------------------------------------------------------------
LLScreenChannel* LLChannelManager::createNotificationChannel()
{
	//  creating params for a channel
	LLScreenChannelBase::Params p;
	p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
	p.channel_align = CA_RIGHT;
	// <FS:Ansariel> Group notices, IMs and chiclets position
	//p.toast_align = NA_TOP;
	if (gSavedSettings.getBOOL("InternalShowGroupNoticesTopRight"))
	{
		p.toast_align = NA_TOP;
	}
	else
	{
		p.toast_align = NA_BOTTOM;
	}
	// </FS:Ansariel> Group notices, IMs and chiclets position

	// Getting a Channel for our notifications
	return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
}

//--------------------------------------------------------------------------
void LLChannelManager::onLoginCompleted()
{
	S32 away_notifications = 0;

	// calc a number of all offline notifications
	for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it)
	{
		LLScreenChannelBase* channel = it->channel.get();
		if (!channel) continue;

		// don't calc notifications for Nearby Chat
		if(channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
		{
			continue;
		}

		// don't calc notifications for channels that always show their notifications
		if(!channel->getDisplayToastsAlways())
		{
			away_notifications +=channel->getNumberOfHiddenToasts();
		}
	}

	away_notifications += gIMMgr->getNumberOfUnreadIM();

	if(!away_notifications)
	{
		onStartUpToastClose();
	}
	else
	{
		// TODO: Seems this code leads to MAINT-3536 new crash in XML_ParserFree.
		// Need to investigate this and fix possible problems with notifications in startup time
		// Viewer can normally receive and show of postponed notifications about purchasing in marketplace on startup time.
		// Other types of postponed notifications did not tested.
		//// create a channel for the StartUp Toast
		//LLScreenChannelBase::Params p;
		//p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
		//p.channel_align = CA_RIGHT;
		//mStartUpChannel = createChannel(p);

		//if(!mStartUpChannel)
		//{
		//	onStartUpToastClose();
		//}
		//else
		//{
		//	gViewerWindow->getRootView()->addChild(mStartUpChannel);

		//	// init channel's position and size
		//	S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
		//	S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
		//	mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
		//	mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));

		//	mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
		//	mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
		//}
	}

	LLPersistentNotificationStorage::getInstance()->loadNotifications();
	LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
}

//--------------------------------------------------------------------------
void LLChannelManager::onStartUpToastClose()
{
	if(mStartUpChannel)
	{
		mStartUpChannel->setVisible(FALSE);
		mStartUpChannel->closeStartUpToast();
		removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID")));
		mStartUpChannel = NULL;
	}

	// set StartUp Toast Flag to allow all other channels to show incoming toasts
	LLScreenChannel::setStartUpToastShown();
}

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

LLScreenChannelBase*	LLChannelManager::addChannel(LLScreenChannelBase* channel)
{
	if(!channel)
		return 0;

	ChannelElem new_elem;
	new_elem.id = channel->getChannelID();
	new_elem.channel = channel->getHandle();

	mChannelList.push_back(new_elem);

	return channel;
}

LLScreenChannel* LLChannelManager::createChannel(LLScreenChannelBase::Params& p)
{
	LLScreenChannel* new_channel = new LLScreenChannel(p);

	addChannel(new_channel);
	return new_channel;
}

LLScreenChannelBase* LLChannelManager::getChannel(LLScreenChannelBase::Params& p)
{
	LLScreenChannelBase* new_channel = findChannelByID(p.id);

	if(new_channel)
		return new_channel;

	return createChannel(p);

}

//--------------------------------------------------------------------------
LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID& id)
{
	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
	if(it != mChannelList.end())
	{
		return (*it).channel.get();
	}

	return NULL;
}

//--------------------------------------------------------------------------
void LLChannelManager::removeChannelByID(const LLUUID& id)
{
	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
	if(it != mChannelList.end())
	{
		mChannelList.erase(it);
	}
}

//--------------------------------------------------------------------------
void LLChannelManager::muteAllChannels(bool mute)
{
	for (std::vector<ChannelElem>::iterator it = mChannelList.begin();
			it != mChannelList.end(); it++)
	{
		if (it->channel.get())
		{
			it->channel.get()->setShowToasts(!mute);
		}
	}
}

void LLChannelManager::killToastsFromChannel(const LLUUID& channel_id, const LLScreenChannel::Matcher& matcher)
{
	LLScreenChannel
			* screen_channel =
					dynamic_cast<LLScreenChannel*> (findChannelByID(channel_id));
	if (screen_channel != NULL)
	{
		screen_channel->killMatchedToasts(matcher);
	}
}

// static
LLNotificationsUI::LLScreenChannel* LLChannelManager::getNotificationScreenChannel()
{
	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
	(LLNotificationsUI::LLChannelManager::getInstance()->
										findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));

	if (channel == NULL)
	{
		llwarns << "Can't find screen channel by NotificationChannelUUID" << llendl;
		llassert(!"Can't find screen channel by NotificationChannelUUID");
	}

	return channel;
}

<commit_msg>Activate missed notifications at startup again; crash was caused by c-style cast in LLFloaterView and is fixed already<commit_after>/**
 * @file llchannelmanager.cpp
 * @brief This class rules screen notification channels.
 *
 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "llchannelmanager.h"

#include "llappviewer.h"
#include "lldonotdisturbnotificationstorage.h"
#include "llpersistentnotificationstorage.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llrootview.h"
#include "llsyswellwindow.h"
#include "llfloaterreg.h"

#include <algorithm>

using namespace LLNotificationsUI;

//--------------------------------------------------------------------------
LLChannelManager::LLChannelManager()
{
	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
	mChannelList.clear();
	mStartUpChannel = NULL;

	if(!gViewerWindow)
	{
		llerrs << "LLChannelManager::LLChannelManager() - viwer window is not initialized yet" << llendl;
	}
}

//--------------------------------------------------------------------------
LLChannelManager::~LLChannelManager()
{
	// <FS:ND> HACK/Test FIRE-11884 / Crash on exit. After making sure no ScreenChannel gets destroyed in a LLView dtor, this can still
	// crash when the static singleton of LLChannelManager is destroyed.
	// Leak those few channels on shutdown here to test if that fixes the rest of the crash. As this is shutdown code, the OS will clean up after us.
	// Not nice or recommended, but not harmful either here.

	// for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it)
	// {
	// 	LLScreenChannelBase* channel = it->channel.get();
	// 	if (!channel) continue;
	//
	// 	delete channel;
	// }

	// </FS:ND>

	mChannelList.clear();
}

//--------------------------------------------------------------------------
LLScreenChannel* LLChannelManager::createNotificationChannel()
{
	//  creating params for a channel
	LLScreenChannelBase::Params p;
	p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
	p.channel_align = CA_RIGHT;
	// <FS:Ansariel> Group notices, IMs and chiclets position
	//p.toast_align = NA_TOP;
	if (gSavedSettings.getBOOL("InternalShowGroupNoticesTopRight"))
	{
		p.toast_align = NA_TOP;
	}
	else
	{
		p.toast_align = NA_BOTTOM;
	}
	// </FS:Ansariel> Group notices, IMs and chiclets position

	// Getting a Channel for our notifications
	return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
}

//--------------------------------------------------------------------------
void LLChannelManager::onLoginCompleted()
{
	S32 away_notifications = 0;

	// calc a number of all offline notifications
	for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it)
	{
		LLScreenChannelBase* channel = it->channel.get();
		if (!channel) continue;

		// don't calc notifications for Nearby Chat
		if(channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
		{
			continue;
		}

		// don't calc notifications for channels that always show their notifications
		if(!channel->getDisplayToastsAlways())
		{
			away_notifications +=channel->getNumberOfHiddenToasts();
		}
	}

	away_notifications += gIMMgr->getNumberOfUnreadIM();

	if(!away_notifications)
	{
		onStartUpToastClose();
	}
	else
	{
		// TODO: Seems this code leads to MAINT-3536 new crash in XML_ParserFree.
		// Need to investigate this and fix possible problems with notifications in startup time
		// Viewer can normally receive and show of postponed notifications about purchasing in marketplace on startup time.
		// Other types of postponed notifications did not tested.
		// <FS:Ansariel> Uncomment this code again; crash was caused by c-style cast in LLFloaterView
		// create a channel for the StartUp Toast
		LLScreenChannelBase::Params p;
		p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
		p.channel_align = CA_RIGHT;
		mStartUpChannel = createChannel(p);

		if(!mStartUpChannel)
		{
			onStartUpToastClose();
		}
		else
		{
			gViewerWindow->getRootView()->addChild(mStartUpChannel);

			// init channel's position and size
			S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
			S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
			mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
			mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));

			mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
			mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
		}
	}
	// </FS:Ansariel>

	LLPersistentNotificationStorage::getInstance()->loadNotifications();
	LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
}

//--------------------------------------------------------------------------
void LLChannelManager::onStartUpToastClose()
{
	if(mStartUpChannel)
	{
		mStartUpChannel->setVisible(FALSE);
		mStartUpChannel->closeStartUpToast();
		removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID")));
		mStartUpChannel = NULL;
	}

	// set StartUp Toast Flag to allow all other channels to show incoming toasts
	LLScreenChannel::setStartUpToastShown();
}

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

LLScreenChannelBase*	LLChannelManager::addChannel(LLScreenChannelBase* channel)
{
	if(!channel)
		return 0;

	ChannelElem new_elem;
	new_elem.id = channel->getChannelID();
	new_elem.channel = channel->getHandle();

	mChannelList.push_back(new_elem);

	return channel;
}

LLScreenChannel* LLChannelManager::createChannel(LLScreenChannelBase::Params& p)
{
	LLScreenChannel* new_channel = new LLScreenChannel(p);

	addChannel(new_channel);
	return new_channel;
}

LLScreenChannelBase* LLChannelManager::getChannel(LLScreenChannelBase::Params& p)
{
	LLScreenChannelBase* new_channel = findChannelByID(p.id);

	if(new_channel)
		return new_channel;

	return createChannel(p);

}

//--------------------------------------------------------------------------
LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID& id)
{
	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
	if(it != mChannelList.end())
	{
		return (*it).channel.get();
	}

	return NULL;
}

//--------------------------------------------------------------------------
void LLChannelManager::removeChannelByID(const LLUUID& id)
{
	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
	if(it != mChannelList.end())
	{
		mChannelList.erase(it);
	}
}

//--------------------------------------------------------------------------
void LLChannelManager::muteAllChannels(bool mute)
{
	for (std::vector<ChannelElem>::iterator it = mChannelList.begin();
			it != mChannelList.end(); it++)
	{
		if (it->channel.get())
		{
			it->channel.get()->setShowToasts(!mute);
		}
	}
}

void LLChannelManager::killToastsFromChannel(const LLUUID& channel_id, const LLScreenChannel::Matcher& matcher)
{
	LLScreenChannel
			* screen_channel =
					dynamic_cast<LLScreenChannel*> (findChannelByID(channel_id));
	if (screen_channel != NULL)
	{
		screen_channel->killMatchedToasts(matcher);
	}
}

// static
LLNotificationsUI::LLScreenChannel* LLChannelManager::getNotificationScreenChannel()
{
	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
	(LLNotificationsUI::LLChannelManager::getInstance()->
										findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));

	if (channel == NULL)
	{
		llwarns << "Can't find screen channel by NotificationChannelUUID" << llendl;
		llassert(!"Can't find screen channel by NotificationChannelUUID");
	}

	return channel;
}

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "cpplocalsymbols.h"
#include "cppsemanticinfo.h"

#include <cplusplus/CppDocument.h>
#include <ASTVisitor.h>
#include <AST.h>
#include <Scope.h>
#include <Symbols.h>
#include <CoreTypes.h>
#include <Names.h>
#include <Literals.h>

using namespace CPlusPlus;
using namespace CppEditor::Internal;

namespace {

class FindLocalSymbols: protected ASTVisitor
{
    Scope *_functionScope;
    Document::Ptr _doc;

public:
    FindLocalSymbols(Document::Ptr doc)
        : ASTVisitor(doc->translationUnit()), _doc(doc), hasD(false), hasQ(false)
    { }

    // local and external uses.
    SemanticInfo::LocalUseMap localUses;
    bool hasD;
    bool hasQ;

    void operator()(DeclarationAST *ast)
    {
        localUses.clear();

        if (!ast)
            return;

        if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) {
            if (def->symbol) {
                _functionScope = def->symbol;
                accept(ast);
            }
        } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) {
            if (decl->method_prototype->symbol) {
                _functionScope = decl->method_prototype->symbol;
                accept(ast);
            }
        }
    }

protected:
    using ASTVisitor::visit;
    using ASTVisitor::endVisit;

    void enterScope(Scope *scope)
    {
        _scopeStack.append(scope);

        for (unsigned i = 0; i < scope->memberCount(); ++i) {
            if (Symbol *member = scope->memberAt(i)) {
                if (member->isTypedef())
                    continue;
                else if (! member->isGenerated() && (member->isDeclaration() || member->isArgument())) {
                    if (member->name() && member->name()->isNameId()) {
                        const Identifier *id = member->identifier();
                        unsigned line, column;
                        getTokenStartPosition(member->sourceLocation(), &line, &column);
                        localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::LocalUse));
                    }
                }
            }
        }
    }

    bool checkLocalUse(NameAST *nameAst, unsigned firstToken)
    {
        if (SimpleNameAST *simpleName = nameAst->asSimpleName()) {
            const Identifier *id = identifier(simpleName->identifier_token);
            for (int i = _scopeStack.size() - 1; i != -1; --i) {
                if (Symbol *member = _scopeStack.at(i)->find(id)) {
                    if (member->isTypedef() || !member->isDeclaration())
                        continue;
                    else if (!member->isGenerated() && (member->sourceLocation() < firstToken || member->enclosingScope()->isFunction())) {
                        unsigned line, column;
                        getTokenStartPosition(simpleName->identifier_token, &line, &column);
                        localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::LocalUse));
                        return false;
                    }
                }
            }
        }

        return true;
    }

    virtual bool visit(IdExpressionAST *ast)
    {
        return checkLocalUse(ast->name, ast->firstToken());
    }

    virtual bool visit(SizeofExpressionAST *ast)
    {
        if (ast->expression && ast->expression->asTypeId()) {
            TypeIdAST *typeId = ast->expression->asTypeId();
            if (!typeId->declarator && typeId->type_specifier_list && !typeId->type_specifier_list->next) {
                if (NamedTypeSpecifierAST *namedTypeSpec = typeId->type_specifier_list->value->asNamedTypeSpecifier()) {
                    if (checkLocalUse(namedTypeSpec->name, namedTypeSpec->firstToken()))
                        return false;
                }
            }
        }

        return true;
    }

    virtual bool visit(QtMemberDeclarationAST *ast)
    {
        if (tokenKind(ast->q_token) == T_Q_D)
            hasD = true;
        else
            hasQ = true;

        return true;
    }

    virtual bool visit(FunctionDefinitionAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(FunctionDefinitionAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(CompoundStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(CompoundStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(IfStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(IfStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(WhileStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(WhileStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(ForStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(ForStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(ForeachStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(ForeachStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(SwitchStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(SwitchStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(CatchClauseAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(CatchClauseAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
    {
        accept(ast->declaration);
        return false;
    }

private:
    QList<Scope *> _scopeStack;
};

} // end of anonymous namespace

LocalSymbols::LocalSymbols(CPlusPlus::Document::Ptr doc, CPlusPlus::DeclarationAST *ast)
{
    FindLocalSymbols findLocalSymbols(doc);
    findLocalSymbols(ast);
    hasD = findLocalSymbols.hasD;
    hasQ = findLocalSymbols.hasQ;
    uses = findLocalSymbols.localUses;
}
<commit_msg>C++: fix highlighting again, this time for arguments.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "cpplocalsymbols.h"
#include "cppsemanticinfo.h"

#include <cplusplus/CppDocument.h>
#include <ASTVisitor.h>
#include <AST.h>
#include <Scope.h>
#include <Symbols.h>
#include <CoreTypes.h>
#include <Names.h>
#include <Literals.h>

using namespace CPlusPlus;
using namespace CppEditor::Internal;

namespace {

class FindLocalSymbols: protected ASTVisitor
{
    Scope *_functionScope;
    Document::Ptr _doc;

public:
    FindLocalSymbols(Document::Ptr doc)
        : ASTVisitor(doc->translationUnit()), _doc(doc), hasD(false), hasQ(false)
    { }

    // local and external uses.
    SemanticInfo::LocalUseMap localUses;
    bool hasD;
    bool hasQ;

    void operator()(DeclarationAST *ast)
    {
        localUses.clear();

        if (!ast)
            return;

        if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) {
            if (def->symbol) {
                _functionScope = def->symbol;
                accept(ast);
            }
        } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) {
            if (decl->method_prototype->symbol) {
                _functionScope = decl->method_prototype->symbol;
                accept(ast);
            }
        }
    }

protected:
    using ASTVisitor::visit;
    using ASTVisitor::endVisit;

    void enterScope(Scope *scope)
    {
        _scopeStack.append(scope);

        for (unsigned i = 0; i < scope->memberCount(); ++i) {
            if (Symbol *member = scope->memberAt(i)) {
                if (member->isTypedef())
                    continue;
                else if (! member->isGenerated() && (member->isDeclaration() || member->isArgument())) {
                    if (member->name() && member->name()->isNameId()) {
                        const Identifier *id = member->identifier();
                        unsigned line, column;
                        getTokenStartPosition(member->sourceLocation(), &line, &column);
                        localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::LocalUse));
                    }
                }
            }
        }
    }

    bool checkLocalUse(NameAST *nameAst, unsigned firstToken)
    {
        if (SimpleNameAST *simpleName = nameAst->asSimpleName()) {
            const Identifier *id = identifier(simpleName->identifier_token);
            for (int i = _scopeStack.size() - 1; i != -1; --i) {
                if (Symbol *member = _scopeStack.at(i)->find(id)) {
                    if (member->isTypedef() ||
                            !(member->isDeclaration() || member->isArgument()))
                        continue;
                    else if (!member->isGenerated() && (member->sourceLocation() < firstToken || member->enclosingScope()->isFunction())) {
                        unsigned line, column;
                        getTokenStartPosition(simpleName->identifier_token, &line, &column);
                        localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::LocalUse));
                        return false;
                    }
                }
            }
        }

        return true;
    }

    virtual bool visit(IdExpressionAST *ast)
    {
        return checkLocalUse(ast->name, ast->firstToken());
    }

    virtual bool visit(SizeofExpressionAST *ast)
    {
        if (ast->expression && ast->expression->asTypeId()) {
            TypeIdAST *typeId = ast->expression->asTypeId();
            if (!typeId->declarator && typeId->type_specifier_list && !typeId->type_specifier_list->next) {
                if (NamedTypeSpecifierAST *namedTypeSpec = typeId->type_specifier_list->value->asNamedTypeSpecifier()) {
                    if (checkLocalUse(namedTypeSpec->name, namedTypeSpec->firstToken()))
                        return false;
                }
            }
        }

        return true;
    }

    virtual bool visit(QtMemberDeclarationAST *ast)
    {
        if (tokenKind(ast->q_token) == T_Q_D)
            hasD = true;
        else
            hasQ = true;

        return true;
    }

    virtual bool visit(FunctionDefinitionAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(FunctionDefinitionAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(CompoundStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(CompoundStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(IfStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(IfStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(WhileStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(WhileStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(ForStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(ForStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(ForeachStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(ForeachStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(SwitchStatementAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(SwitchStatementAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(CatchClauseAST *ast)
    {
        if (ast->symbol)
            enterScope(ast->symbol);
        return true;
    }

    virtual void endVisit(CatchClauseAST *ast)
    {
        if (ast->symbol)
            _scopeStack.removeLast();
    }

    virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
    {
        accept(ast->declaration);
        return false;
    }

private:
    QList<Scope *> _scopeStack;
};

} // end of anonymous namespace

LocalSymbols::LocalSymbols(CPlusPlus::Document::Ptr doc, CPlusPlus::DeclarationAST *ast)
{
    FindLocalSymbols findLocalSymbols(doc);
    findLocalSymbols(ast);
    hasD = findLocalSymbols.hasD;
    hasQ = findLocalSymbols.hasQ;
    uses = findLocalSymbols.localUses;
}
<|endoftext|>


<commit_before>#include "lightfield_pattern.h"

namespace possumwood { namespace opencv {

LightfieldPattern::LightfieldPattern() : m_lensPitch(0.0), m_pixelPitch(0.0), m_rotation(0.0) {
}

LightfieldPattern::LightfieldPattern(double lensPitch, double pixelPitch, double rotation,
	cv::Vec2d scaleFactor, cv::Vec3d sensorOffset, cv::Vec2i sensorResolution) :
	m_lensPitch(lensPitch), m_pixelPitch(pixelPitch), m_rotation(rotation),
	m_scaleFactor(scaleFactor), m_sensorOffset(sensorOffset), m_sensorResolution(sensorResolution)
{
}

bool LightfieldPattern::operator == (const LightfieldPattern& f) const {
	return m_lensPitch == f.m_lensPitch &&
		m_pixelPitch == f.m_pixelPitch &&
		m_rotation == f.m_rotation &&
		m_scaleFactor == f.m_scaleFactor &&
		m_sensorOffset == f.m_sensorOffset &&
		m_sensorResolution == f.m_sensorResolution;
}

bool LightfieldPattern::operator != (const LightfieldPattern& f) const {
	return m_lensPitch != f.m_lensPitch ||
		m_pixelPitch != f.m_pixelPitch ||
		m_rotation != f.m_rotation ||
		m_scaleFactor != f.m_scaleFactor ||
		m_sensorOffset != f.m_sensorOffset ||
		m_sensorResolution != f.m_sensorResolution;
}

cv::Vec4d LightfieldPattern::sample(const cv::Vec2i& pixelPos) const {
	cv::Vec4d result;

	result[0] = (double)pixelPos[0];
	result[1] = (double)pixelPos[1];

	const double xDiff = m_lensPitch / m_pixelPitch * m_scaleFactor[0];
	const double yDiff = m_lensPitch / m_pixelPitch * sqrt(3.0/4.0) * m_scaleFactor[1];

	cv::Vec2d vect(
		(double)pixelPos[0] / m_scaleFactor[0],
		(double)pixelPos[1] / m_scaleFactor[1]
	);

	const double cs = cos(m_rotation);
	const double sn = sin(m_rotation);

	vect = cv::Vec2d (
		(vect[0] * cs + vect[1] * sn),
		(-vect[0] * sn + vect[1] * cs)
	);

	vect[0] += m_sensorOffset[0] / m_pixelPitch;
	vect[1] += m_sensorOffset[1] / m_pixelPitch;

	result[3] = vect[1] / yDiff;

	if(((int)round(result[3])) % 2 == 0)
		result[2] = fmod(vect[0] / xDiff + 100.5, 1.0) - 0.5;
	else
		result[2] = fmod(vect[0] / xDiff + 100.0, 1.0) - 0.5;

	result[3] = fmod(result[3] + 100.5, 1.0) - 0.5;

	result[2] *= 2.0;
	result[3] *= 2.0;

	return result;
}

const cv::Vec2i& LightfieldPattern::sensorResolution() const {
	return m_sensorResolution;
}

std::ostream& operator << (std::ostream& out, const LightfieldPattern& f) {
	out << "(lightfields pattern)";
	return out;
}

} }
<commit_msg>LightfieldPattern no longer produces nans when uninitialised<commit_after>#include "lightfield_pattern.h"

namespace possumwood { namespace opencv {

LightfieldPattern::LightfieldPattern() : m_lensPitch(1.0), m_pixelPitch(1.0), m_rotation(0.0), m_scaleFactor(1.0, 1.0), m_sensorResolution(100, 100) {
}

LightfieldPattern::LightfieldPattern(double lensPitch, double pixelPitch, double rotation,
	cv::Vec2d scaleFactor, cv::Vec3d sensorOffset, cv::Vec2i sensorResolution) :
	m_lensPitch(lensPitch), m_pixelPitch(pixelPitch), m_rotation(rotation),
	m_scaleFactor(scaleFactor), m_sensorOffset(sensorOffset), m_sensorResolution(sensorResolution)
{
}

bool LightfieldPattern::operator == (const LightfieldPattern& f) const {
	return m_lensPitch == f.m_lensPitch &&
		m_pixelPitch == f.m_pixelPitch &&
		m_rotation == f.m_rotation &&
		m_scaleFactor == f.m_scaleFactor &&
		m_sensorOffset == f.m_sensorOffset &&
		m_sensorResolution == f.m_sensorResolution;
}

bool LightfieldPattern::operator != (const LightfieldPattern& f) const {
	return m_lensPitch != f.m_lensPitch ||
		m_pixelPitch != f.m_pixelPitch ||
		m_rotation != f.m_rotation ||
		m_scaleFactor != f.m_scaleFactor ||
		m_sensorOffset != f.m_sensorOffset ||
		m_sensorResolution != f.m_sensorResolution;
}

cv::Vec4d LightfieldPattern::sample(const cv::Vec2i& pixelPos) const {
	cv::Vec4d result;

	result[0] = (double)pixelPos[0];
	result[1] = (double)pixelPos[1];

	const double xDiff = m_lensPitch / m_pixelPitch * m_scaleFactor[0];
	const double yDiff = m_lensPitch / m_pixelPitch * sqrt(3.0/4.0) * m_scaleFactor[1];

	cv::Vec2d vect(
		(double)pixelPos[0] / m_scaleFactor[0],
		(double)pixelPos[1] / m_scaleFactor[1]
	);

	const double cs = cos(m_rotation);
	const double sn = sin(m_rotation);

	vect = cv::Vec2d (
		(vect[0] * cs + vect[1] * sn),
		(-vect[0] * sn + vect[1] * cs)
	);

	vect[0] += m_sensorOffset[0] / m_pixelPitch;
	vect[1] += m_sensorOffset[1] / m_pixelPitch;

	result[3] = vect[1] / yDiff;

	if(((int)round(result[3])) % 2 == 0)
		result[2] = fmod(vect[0] / xDiff + 100.5, 1.0) - 0.5;
	else
		result[2] = fmod(vect[0] / xDiff + 100.0, 1.0) - 0.5;

	result[3] = fmod(result[3] + 100.5, 1.0) - 0.5;

	result[2] *= 2.0;
	result[3] *= 2.0;

	return result;
}

const cv::Vec2i& LightfieldPattern::sensorResolution() const {
	return m_sensorResolution;
}

std::ostream& operator << (std::ostream& out, const LightfieldPattern& f) {
	out << "(lightfields pattern)";
	return out;
}

} }
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "qmlconsoleview.h"
#include "qmlconsoleitemdelegate.h"
#include "qmlconsoleitemmodel.h"

#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/manhattanstyle.h>
#include <utils/hostosinfo.h>

#include <QMouseEvent>
#include <QPainter>
#include <QApplication>
#include <QClipboard>
#include <QAbstractProxyModel>
#include <QFileInfo>
#include <QScrollBar>
#include <QStyleFactory>
#include <QString>
#include <QUrl>

using namespace QmlJS;

namespace QmlJSTools {
namespace Internal {

class QmlConsoleViewStyle : public ManhattanStyle
{
public:
    QmlConsoleViewStyle(const QString &baseStyleName) : ManhattanStyle(baseStyleName) {}

    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter,
                       const QWidget *widget = 0) const
    {
        if (element != QStyle::PE_PanelItemViewRow)
            ManhattanStyle::drawPrimitive(element, option, painter, widget);
    }

    int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
                  QStyleHintReturn *returnData = 0) const {
        if (hint == SH_ItemView_ShowDecorationSelected)
            return 0;
        else
            return ManhattanStyle::styleHint(hint, option, widget, returnData);
    }
};

///////////////////////////////////////////////////////////////////////
//
// QmlConsoleView
//
///////////////////////////////////////////////////////////////////////

QmlConsoleView::QmlConsoleView(QWidget *parent) :
    QTreeView(parent)
{
    setFrameStyle(QFrame::NoFrame);
    setHeaderHidden(true);
    setRootIsDecorated(false);
    setUniformRowHeights(true);
    setEditTriggers(QAbstractItemView::AllEditTriggers);
    setStyleSheet(QLatin1String("QTreeView::branch:has-siblings:!adjoins-item {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:has-siblings:adjoins-item {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:!has-children:!has-siblings:adjoins-item {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:has-children:!has-siblings:closed,"
                                "QTreeView::branch:closed:has-children:has-siblings {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:open:has-children:!has-siblings,"
                                "QTreeView::branch:open:has-children:has-siblings  {"
                                "border-image: none;"
                                "image: none; }"));

    QString baseName = QApplication::style()->objectName();
    if (Utils::HostOsInfo::isAnyUnixHost() && !Utils::HostOsInfo::isMacHost()
            && baseName == QLatin1String("windows")) {
        // Sometimes we get the standard windows 95 style as a fallback
        if (QStyleFactory::keys().contains(QLatin1String("Fusion"))) {
            baseName = QLatin1String("fusion"); // Qt5
        } else { // Qt4
            // e.g. if we are running on a KDE4 desktop
            QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
            if (desktopEnvironment == "kde")
                baseName = QLatin1String("plastique");
            else
                baseName = QLatin1String("cleanlooks");
        }
    }
    QmlConsoleViewStyle *style = new QmlConsoleViewStyle(baseName);
    setStyle(style);
    style->setParent(this);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    horizontalScrollBar()->setSingleStep(20);
    verticalScrollBar()->setSingleStep(20);

    connect(this, SIGNAL(activated(QModelIndex)), SLOT(onRowActivated(QModelIndex)));
}

void QmlConsoleView::onScrollToBottom()
{
    // Keep scrolling to bottom if scroll bar is at maximum()
    if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
        scrollToBottom();
}

void QmlConsoleView::mousePressEvent(QMouseEvent *event)
{
    QPoint pos = event->pos();
    QModelIndex index = indexAt(pos);
    if (index.isValid()) {
        ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data(
                    QmlConsoleItemModel::TypeRole).toInt();
        bool handled = false;
        if (type == ConsoleItem::UndefinedType) {
            bool showTypeIcon = index.parent() == QModelIndex();
            ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon,
                                           true);

            if (positions.expandCollapseIcon().contains(pos)) {
                if (isExpanded(index))
                    setExpanded(index, false);
                else
                    setExpanded(index, true);
                handled = true;
            }
        }
        if (!handled)
            QTreeView::mousePressEvent(event);
    } else {
        selectionModel()->setCurrentIndex(model()->index(model()->rowCount() - 1, 0),
                                          QItemSelectionModel::ClearAndSelect);
    }
}

void QmlConsoleView::keyPressEvent(QKeyEvent *e)
{
    if (!e->modifiers() && e->key() == Qt::Key_Return) {
        emit activated(currentIndex());
        e->accept();
        return;
    }
    QTreeView::keyPressEvent(e);
}

void QmlConsoleView::resizeEvent(QResizeEvent *e)
{
    static_cast<QmlConsoleItemDelegate *>(itemDelegate())->emitSizeHintChanged(
                selectionModel()->currentIndex());
    QTreeView::resizeEvent(e);
}

void QmlConsoleView::drawBranches(QPainter *painter, const QRect &rect,
                                  const QModelIndex &index) const
{
    static_cast<QmlConsoleItemDelegate *>(itemDelegate())->drawBackground(painter, rect, index,
                                                                            false);
    QTreeView::drawBranches(painter, rect, index);
}

void QmlConsoleView::contextMenuEvent(QContextMenuEvent *event)
{
    QModelIndex itemIndex = indexAt(event->pos());
    QMenu menu;

    QAction *copy = new QAction(tr("&Copy"), this);
    copy->setEnabled(itemIndex.isValid());
    menu.addAction(copy);
    QAction *show = new QAction(tr("&Show in Editor"), this);
    show->setEnabled(canShowItemInTextEditor(itemIndex));
    menu.addAction(show);
    menu.addSeparator();
    QAction *clear = new QAction(tr("C&lear"), this);
    menu.addAction(clear);

    QAction *a = menu.exec(event->globalPos());
    if (a == 0)
        return;

    if (a == copy) {
        copyToClipboard(itemIndex);
    } else if (a == show) {
        onRowActivated(itemIndex);
    } else if (a == clear) {
        QAbstractProxyModel *proxyModel = qobject_cast<QAbstractProxyModel *>(model());
        QmlConsoleItemModel *handler = qobject_cast<QmlConsoleItemModel *>(
                    proxyModel->sourceModel());
        handler->clear();
    }
}

void QmlConsoleView::onRowActivated(const QModelIndex &index)
{
    if (!index.isValid())
        return;

    // See if we have file and line Info
    QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
    const QUrl fileUrl = QUrl(filePath);
    if (fileUrl.isLocalFile())
        filePath = fileUrl.toLocalFile();
    if (!filePath.isEmpty()) {
        QFileInfo fi(filePath);
        if (fi.exists() && fi.isFile() && fi.isReadable()) {
            int line = model()->data(index, QmlConsoleItemModel::LineRole).toInt();
            Core::EditorManager::openEditorAt(fi.canonicalFilePath(), line);
        }
    }
}

void QmlConsoleView::copyToClipboard(const QModelIndex &index)
{
    if (!index.isValid())
        return;

    QString contents = model()->data(index, QmlConsoleItemModel::ExpressionRole).toString();
    // See if we have file and line Info
    QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
    const QUrl fileUrl = QUrl(filePath);
    if (fileUrl.isLocalFile())
        filePath = fileUrl.toLocalFile();
    if (!filePath.isEmpty()) {
        contents = QString(QLatin1String("%1 %2: %3")).arg(contents).arg(filePath).arg(
                    model()->data(index, QmlConsoleItemModel::LineRole).toString());
    }
    QClipboard *cb = QApplication::clipboard();
    cb->setText(contents);
}

bool QmlConsoleView::canShowItemInTextEditor(const QModelIndex &index)
{
    if (!index.isValid())
        return false;

    // See if we have file and line Info
    QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
    const QUrl fileUrl = QUrl(filePath);
    if (fileUrl.isLocalFile())
        filePath = fileUrl.toLocalFile();
    if (!filePath.isEmpty()) {
        QFileInfo fi(filePath);
        if (fi.exists() && fi.isFile() && fi.isReadable())
            return true;
    }
    return false;
}

} // Internal
} // QmlJSTools
<commit_msg>QmlJSConsole: Fix scrolling behavior<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "qmlconsoleview.h"
#include "qmlconsoleitemdelegate.h"
#include "qmlconsoleitemmodel.h"

#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/manhattanstyle.h>
#include <utils/hostosinfo.h>

#include <QMouseEvent>
#include <QPainter>
#include <QApplication>
#include <QClipboard>
#include <QAbstractProxyModel>
#include <QFileInfo>
#include <QScrollBar>
#include <QStyleFactory>
#include <QString>
#include <QUrl>

using namespace QmlJS;

namespace QmlJSTools {
namespace Internal {

class QmlConsoleViewStyle : public ManhattanStyle
{
public:
    QmlConsoleViewStyle(const QString &baseStyleName) : ManhattanStyle(baseStyleName) {}

    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter,
                       const QWidget *widget = 0) const
    {
        if (element != QStyle::PE_PanelItemViewRow)
            ManhattanStyle::drawPrimitive(element, option, painter, widget);
    }

    int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
                  QStyleHintReturn *returnData = 0) const {
        if (hint == SH_ItemView_ShowDecorationSelected)
            return 0;
        else
            return ManhattanStyle::styleHint(hint, option, widget, returnData);
    }
};

///////////////////////////////////////////////////////////////////////
//
// QmlConsoleView
//
///////////////////////////////////////////////////////////////////////

QmlConsoleView::QmlConsoleView(QWidget *parent) :
    QTreeView(parent)
{
    setFrameStyle(QFrame::NoFrame);
    setHeaderHidden(true);
    setRootIsDecorated(false);
    setUniformRowHeights(true);
    setEditTriggers(QAbstractItemView::AllEditTriggers);
    setStyleSheet(QLatin1String("QTreeView::branch:has-siblings:!adjoins-item {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:has-siblings:adjoins-item {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:!has-children:!has-siblings:adjoins-item {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:has-children:!has-siblings:closed,"
                                "QTreeView::branch:closed:has-children:has-siblings {"
                                "border-image: none;"
                                "image: none; }"
                                "QTreeView::branch:open:has-children:!has-siblings,"
                                "QTreeView::branch:open:has-children:has-siblings  {"
                                "border-image: none;"
                                "image: none; }"));

    QString baseName = QApplication::style()->objectName();
    if (Utils::HostOsInfo::isAnyUnixHost() && !Utils::HostOsInfo::isMacHost()
            && baseName == QLatin1String("windows")) {
        // Sometimes we get the standard windows 95 style as a fallback
        if (QStyleFactory::keys().contains(QLatin1String("Fusion"))) {
            baseName = QLatin1String("fusion"); // Qt5
        } else { // Qt4
            // e.g. if we are running on a KDE4 desktop
            QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
            if (desktopEnvironment == "kde")
                baseName = QLatin1String("plastique");
            else
                baseName = QLatin1String("cleanlooks");
        }
    }
    QmlConsoleViewStyle *style = new QmlConsoleViewStyle(baseName);
    setStyle(style);
    style->setParent(this);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    horizontalScrollBar()->setSingleStep(20);
    verticalScrollBar()->setSingleStep(20);

    connect(this, SIGNAL(activated(QModelIndex)), SLOT(onRowActivated(QModelIndex)));
}

void QmlConsoleView::onScrollToBottom()
{
    // Keep scrolling to bottom if scroll bar is not at maximum()
    if (verticalScrollBar()->value() != verticalScrollBar()->maximum())
        scrollToBottom();
}

void QmlConsoleView::mousePressEvent(QMouseEvent *event)
{
    QPoint pos = event->pos();
    QModelIndex index = indexAt(pos);
    if (index.isValid()) {
        ConsoleItem::ItemType type = (ConsoleItem::ItemType)index.data(
                    QmlConsoleItemModel::TypeRole).toInt();
        bool handled = false;
        if (type == ConsoleItem::UndefinedType) {
            bool showTypeIcon = index.parent() == QModelIndex();
            ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon,
                                           true);

            if (positions.expandCollapseIcon().contains(pos)) {
                if (isExpanded(index))
                    setExpanded(index, false);
                else
                    setExpanded(index, true);
                handled = true;
            }
        }
        if (!handled)
            QTreeView::mousePressEvent(event);
    } else {
        selectionModel()->setCurrentIndex(model()->index(model()->rowCount() - 1, 0),
                                          QItemSelectionModel::ClearAndSelect);
    }
}

void QmlConsoleView::keyPressEvent(QKeyEvent *e)
{
    if (!e->modifiers() && e->key() == Qt::Key_Return) {
        emit activated(currentIndex());
        e->accept();
        return;
    }
    QTreeView::keyPressEvent(e);
}

void QmlConsoleView::resizeEvent(QResizeEvent *e)
{
    static_cast<QmlConsoleItemDelegate *>(itemDelegate())->emitSizeHintChanged(
                selectionModel()->currentIndex());
    QTreeView::resizeEvent(e);
}

void QmlConsoleView::drawBranches(QPainter *painter, const QRect &rect,
                                  const QModelIndex &index) const
{
    static_cast<QmlConsoleItemDelegate *>(itemDelegate())->drawBackground(painter, rect, index,
                                                                            false);
    QTreeView::drawBranches(painter, rect, index);
}

void QmlConsoleView::contextMenuEvent(QContextMenuEvent *event)
{
    QModelIndex itemIndex = indexAt(event->pos());
    QMenu menu;

    QAction *copy = new QAction(tr("&Copy"), this);
    copy->setEnabled(itemIndex.isValid());
    menu.addAction(copy);
    QAction *show = new QAction(tr("&Show in Editor"), this);
    show->setEnabled(canShowItemInTextEditor(itemIndex));
    menu.addAction(show);
    menu.addSeparator();
    QAction *clear = new QAction(tr("C&lear"), this);
    menu.addAction(clear);

    QAction *a = menu.exec(event->globalPos());
    if (a == 0)
        return;

    if (a == copy) {
        copyToClipboard(itemIndex);
    } else if (a == show) {
        onRowActivated(itemIndex);
    } else if (a == clear) {
        QAbstractProxyModel *proxyModel = qobject_cast<QAbstractProxyModel *>(model());
        QmlConsoleItemModel *handler = qobject_cast<QmlConsoleItemModel *>(
                    proxyModel->sourceModel());
        handler->clear();
    }
}

void QmlConsoleView::onRowActivated(const QModelIndex &index)
{
    if (!index.isValid())
        return;

    // See if we have file and line Info
    QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
    const QUrl fileUrl = QUrl(filePath);
    if (fileUrl.isLocalFile())
        filePath = fileUrl.toLocalFile();
    if (!filePath.isEmpty()) {
        QFileInfo fi(filePath);
        if (fi.exists() && fi.isFile() && fi.isReadable()) {
            int line = model()->data(index, QmlConsoleItemModel::LineRole).toInt();
            Core::EditorManager::openEditorAt(fi.canonicalFilePath(), line);
        }
    }
}

void QmlConsoleView::copyToClipboard(const QModelIndex &index)
{
    if (!index.isValid())
        return;

    QString contents = model()->data(index, QmlConsoleItemModel::ExpressionRole).toString();
    // See if we have file and line Info
    QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
    const QUrl fileUrl = QUrl(filePath);
    if (fileUrl.isLocalFile())
        filePath = fileUrl.toLocalFile();
    if (!filePath.isEmpty()) {
        contents = QString(QLatin1String("%1 %2: %3")).arg(contents).arg(filePath).arg(
                    model()->data(index, QmlConsoleItemModel::LineRole).toString());
    }
    QClipboard *cb = QApplication::clipboard();
    cb->setText(contents);
}

bool QmlConsoleView::canShowItemInTextEditor(const QModelIndex &index)
{
    if (!index.isValid())
        return false;

    // See if we have file and line Info
    QString filePath = model()->data(index, QmlConsoleItemModel::FileRole).toString();
    const QUrl fileUrl = QUrl(filePath);
    if (fileUrl.isLocalFile())
        filePath = fileUrl.toLocalFile();
    if (!filePath.isEmpty()) {
        QFileInfo fi(filePath);
        if (fi.exists() && fi.isFile() && fi.isReadable())
            return true;
    }
    return false;
}

} // Internal
} // QmlJSTools
<|endoftext|>


<commit_before>
#include "../../Flare.h"
#include "FlareDashboard.h"
#include "../../Game/FlareGame.h"
#include "../../Player/FlareMenuManager.h"
#include "../../Player/FlareMenuPawn.h"
#include "../../Player/FlarePlayerController.h"
#include "../Components/FlareObjectiveInfo.h"

#define LOCTEXT_NAMESPACE "FlareDashboard"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareDashboard::Construct(const FArguments& InArgs)
{
	// Data
	MenuManager = InArgs._MenuManager;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	AFlarePlayerController* PC = MenuManager->GetPC();

	// Build structure
	ChildSlot
	.HAlign(HAlign_Fill)
	.VAlign(VAlign_Fill)
	[
		SNew(SVerticalBox)

		+ SVerticalBox::Slot()
		.AutoHeight()
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Center)
		.Padding(Theme.ContentPadding)
		[
			SNew(SHorizontalBox)

			// Icon
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SNew(SImage).Image(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Dashboard))
			]

			// Title
			+ SHorizontalBox::Slot()
			.VAlign(VAlign_Center)
			.Padding(Theme.ContentPadding)
			[
				SNew(STextBlock)
				.TextStyle(&Theme.TitleFont)
				.Text(LOCTEXT("Dashboard", "DASHBOARD"))
			]

			// Close
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("Close", "Close"))
				.HelpText(LOCTEXT("CloseInfo", "Close the menu and go back to flying the ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Exit, true))
				.OnClicked(this, &SFlareDashboard::OnExit)
			]
		]

		// Separator
		+ SVerticalBox::Slot()
		.AutoHeight()
		.Padding(FMargin(200, 20))
		[
			SNew(SImage).Image(&Theme.SeparatorBrush)
		]

		// Action list
		+ SVerticalBox::Slot()
		.AutoHeight()
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Center)
		.Padding(Theme.ContentPadding)
		[
			SNew(SHorizontalBox)

			// Objective
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.ContentPadding)
			[
				SNew(SFlareObjectiveInfo).PC(PC)
			]

			// Ship
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("InspectShip", "Ship"))
				.HelpText(LOCTEXT("InspectShipInfo", "Inspect your current ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Ship, true))
				.OnClicked(this, &SFlareDashboard::OnInspectShip)
			]

			// Ship upgrade
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("UpgradeShip", "Upgrade ship"))
				.HelpText(LOCTEXT("UpgradeShipInfo", "Upgrade your current ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_ShipConfig, true))
				.OnClicked(this, &SFlareDashboard::OnConfigureShip)
				.Visibility(this, &SFlareDashboard::GetDockedVisibility)
			]

			// Orbit
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("GoOrbit", "Orbital map"))
				.HelpText(LOCTEXT("GoOrbitInfo", "Exit the navigation mode and go back to the orbital map"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Orbit, true))
				.OnClicked(this, &SFlareDashboard::OnOrbit)
			]

			// Undock
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("Undock", "Undock"))
				.HelpText(LOCTEXT("UndockInfo", "Undock from this spacecraft and go back to flying the ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Undock, true))
				.OnClicked(this, &SFlareDashboard::OnUndock)
				.Visibility(this, &SFlareDashboard::GetDockedVisibility)
			]

			// Company
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("InspectCompany", "Company"))
				.HelpText(LOCTEXT("InspectCompanyInfo", "Inspect your company"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Company, true))
				.OnClicked(this, &SFlareDashboard::OnInspectCompany)
			]
		]

		// Content block
		+ SVerticalBox::Slot()
		[
			SNew(SScrollBox)
			.Style(&Theme.ScrollBoxStyle)
			.ScrollBarStyle(&Theme.ScrollBarStyle)

			+ SScrollBox::Slot()
			[
				SNew(SHorizontalBox)

				// Owned
				+ SHorizontalBox::Slot()
				.Padding(Theme.ContentPadding)
				[
					SAssignNew(OwnedShipList, SFlareShipList)
					.MenuManager(MenuManager)
					.Title(LOCTEXT("DashboardMyListTitle", "OWNED SPACECRAFTS IN SECTOR"))
				]

				// Others
				+ SHorizontalBox::Slot()
				.Padding(Theme.ContentPadding)
				[
					SAssignNew(OtherShipList, SFlareShipList)
					.MenuManager(MenuManager)
					.Title(LOCTEXT("DashboardOtherListTitle", "OTHER SPACECRAFTS IN SECTOR"))
				]
			]
		]
	];
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareDashboard::Setup()
{
	SetEnabled(false);
	SetVisibility(EVisibility::Hidden);
}

void SFlareDashboard::Enter()
{
	FLOG("SFlareDashboard::Enter");
	SetEnabled(true);
	SetVisibility(EVisibility::Visible);

	// Find all ships here
	AFlarePlayerController* PC = MenuManager->GetPC();
	if (PC)
	{
		AFlareSpacecraft* PlayerShip = PC->GetShipPawn();
		for (TActorIterator<AActor> ActorItr(PC->GetWorld()); ActorItr; ++ActorItr)
		{
			AFlareSpacecraft* ShipCandidate = Cast<AFlareSpacecraft>(*ActorItr);
			if (ShipCandidate && ShipCandidate->GetDamageSystem()->IsAlive())
			{
				// Owned ship
				if (PlayerShip && ShipCandidate->GetCompany() == PlayerShip->GetCompany())
				{
					OwnedShipList->AddShip(ShipCandidate);
				}

				// other
				else
				{
					OtherShipList->AddShip(ShipCandidate);
				}
			}
		}
	}

	OwnedShipList->RefreshList();
	OtherShipList->RefreshList();
}

void SFlareDashboard::Exit()
{
	OwnedShipList->Reset();
	OtherShipList->Reset();
	SetEnabled(false);
	SetVisibility(EVisibility::Hidden);
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

EVisibility SFlareDashboard::GetDockedVisibility() const
{
	AFlarePlayerController* PC = MenuManager->GetPC();
	if (PC)
	{
		AFlareSpacecraft* Ship = PC->GetShipPawn();
		if (Ship)
		{
			return (Ship->GetNavigationSystem()->IsDocked() ? EVisibility::Visible : EVisibility::Collapsed);
		}
	}

	return EVisibility::Collapsed;
}

void SFlareDashboard::OnInspectShip()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_Ship);
}

void SFlareDashboard::OnConfigureShip()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_ShipConfig);
}

void SFlareDashboard::OnOrbit()
{
	//MenuManager->Notify(LOCTEXT("Unavailable", "Unavailable feature !"), LOCTEXT("Info", "The full game will be released later :)"));
	MenuManager->OpenMenu(EFlareMenu::MENU_Orbit);
}

void SFlareDashboard::OnUndock()
{
	// Ask to undock, and close the menu
	AFlarePlayerController* PC = MenuManager->GetPC();
	if (PC)
	{
		AFlareSpacecraft* Ship = PC->GetShipPawn();
		if (Ship)
		{
			Ship->GetNavigationSystem()->Undock();
			MenuManager->CloseMenu();
		}
	}
}

void SFlareDashboard::OnInspectCompany()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_Company);
}

void SFlareDashboard::OnExit()
{
	MenuManager->CloseMenu();
}

#undef LOCTEXT_NAMESPACE

<commit_msg>Fixed RCS sound, removed comment<commit_after>
#include "../../Flare.h"
#include "FlareDashboard.h"
#include "../../Game/FlareGame.h"
#include "../../Player/FlareMenuManager.h"
#include "../../Player/FlareMenuPawn.h"
#include "../../Player/FlarePlayerController.h"
#include "../Components/FlareObjectiveInfo.h"

#define LOCTEXT_NAMESPACE "FlareDashboard"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareDashboard::Construct(const FArguments& InArgs)
{
	// Data
	MenuManager = InArgs._MenuManager;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	AFlarePlayerController* PC = MenuManager->GetPC();

	// Build structure
	ChildSlot
	.HAlign(HAlign_Fill)
	.VAlign(VAlign_Fill)
	[
		SNew(SVerticalBox)

		+ SVerticalBox::Slot()
		.AutoHeight()
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Center)
		.Padding(Theme.ContentPadding)
		[
			SNew(SHorizontalBox)

			// Icon
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SNew(SImage).Image(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Dashboard))
			]

			// Title
			+ SHorizontalBox::Slot()
			.VAlign(VAlign_Center)
			.Padding(Theme.ContentPadding)
			[
				SNew(STextBlock)
				.TextStyle(&Theme.TitleFont)
				.Text(LOCTEXT("Dashboard", "DASHBOARD"))
			]

			// Close
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("Close", "Close"))
				.HelpText(LOCTEXT("CloseInfo", "Close the menu and go back to flying the ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Exit, true))
				.OnClicked(this, &SFlareDashboard::OnExit)
			]
		]

		// Separator
		+ SVerticalBox::Slot()
		.AutoHeight()
		.Padding(FMargin(200, 20))
		[
			SNew(SImage).Image(&Theme.SeparatorBrush)
		]

		// Action list
		+ SVerticalBox::Slot()
		.AutoHeight()
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Center)
		.Padding(Theme.ContentPadding)
		[
			SNew(SHorizontalBox)

			// Objective
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.ContentPadding)
			[
				SNew(SFlareObjectiveInfo).PC(PC)
			]

			// Ship
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("InspectShip", "Ship"))
				.HelpText(LOCTEXT("InspectShipInfo", "Inspect your current ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Ship, true))
				.OnClicked(this, &SFlareDashboard::OnInspectShip)
			]

			// Ship upgrade
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("UpgradeShip", "Upgrade ship"))
				.HelpText(LOCTEXT("UpgradeShipInfo", "Upgrade your current ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_ShipConfig, true))
				.OnClicked(this, &SFlareDashboard::OnConfigureShip)
				.Visibility(this, &SFlareDashboard::GetDockedVisibility)
			]

			// Orbit
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("GoOrbit", "Orbital map"))
				.HelpText(LOCTEXT("GoOrbitInfo", "Exit the navigation mode and go back to the orbital map"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Orbit, true))
				.OnClicked(this, &SFlareDashboard::OnOrbit)
			]

			// Undock
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			.AutoWidth()
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("Undock", "Undock"))
				.HelpText(LOCTEXT("UndockInfo", "Undock from this spacecraft and go back to flying the ship"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Undock, true))
				.OnClicked(this, &SFlareDashboard::OnUndock)
				.Visibility(this, &SFlareDashboard::GetDockedVisibility)
			]

			// Company
			+ SHorizontalBox::Slot()
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Bottom)
			.Padding(Theme.TitleButtonPadding)
			[
				SNew(SFlareRoundButton)
				.Text(LOCTEXT("InspectCompany", "Company"))
				.HelpText(LOCTEXT("InspectCompanyInfo", "Inspect your company"))
				.Icon(AFlareMenuManager::GetMenuIcon(EFlareMenu::MENU_Company, true))
				.OnClicked(this, &SFlareDashboard::OnInspectCompany)
			]
		]

		// Content block
		+ SVerticalBox::Slot()
		[
			SNew(SScrollBox)
			.Style(&Theme.ScrollBoxStyle)
			.ScrollBarStyle(&Theme.ScrollBarStyle)

			+ SScrollBox::Slot()
			[
				SNew(SHorizontalBox)

				// Owned
				+ SHorizontalBox::Slot()
				.Padding(Theme.ContentPadding)
				[
					SAssignNew(OwnedShipList, SFlareShipList)
					.MenuManager(MenuManager)
					.Title(LOCTEXT("DashboardMyListTitle", "OWNED SPACECRAFTS IN SECTOR"))
				]

				// Others
				+ SHorizontalBox::Slot()
				.Padding(Theme.ContentPadding)
				[
					SAssignNew(OtherShipList, SFlareShipList)
					.MenuManager(MenuManager)
					.Title(LOCTEXT("DashboardOtherListTitle", "OTHER SPACECRAFTS IN SECTOR"))
				]
			]
		]
	];
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareDashboard::Setup()
{
	SetEnabled(false);
	SetVisibility(EVisibility::Hidden);
}

void SFlareDashboard::Enter()
{
	FLOG("SFlareDashboard::Enter");
	SetEnabled(true);
	SetVisibility(EVisibility::Visible);

	// Find all ships here
	AFlarePlayerController* PC = MenuManager->GetPC();
	if (PC)
	{
		AFlareSpacecraft* PlayerShip = PC->GetShipPawn();
		for (TActorIterator<AActor> ActorItr(PC->GetWorld()); ActorItr; ++ActorItr)
		{
			AFlareSpacecraft* ShipCandidate = Cast<AFlareSpacecraft>(*ActorItr);
			if (ShipCandidate && ShipCandidate->GetDamageSystem()->IsAlive())
			{
				// Owned ship
				if (PlayerShip && ShipCandidate->GetCompany() == PlayerShip->GetCompany())
				{
					OwnedShipList->AddShip(ShipCandidate);
				}

				// other
				else
				{
					OtherShipList->AddShip(ShipCandidate);
				}
			}
		}
	}

	OwnedShipList->RefreshList();
	OtherShipList->RefreshList();
}

void SFlareDashboard::Exit()
{
	OwnedShipList->Reset();
	OtherShipList->Reset();
	SetEnabled(false);
	SetVisibility(EVisibility::Hidden);
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

EVisibility SFlareDashboard::GetDockedVisibility() const
{
	AFlarePlayerController* PC = MenuManager->GetPC();
	if (PC)
	{
		AFlareSpacecraft* Ship = PC->GetShipPawn();
		if (Ship)
		{
			return (Ship->GetNavigationSystem()->IsDocked() ? EVisibility::Visible : EVisibility::Collapsed);
		}
	}

	return EVisibility::Collapsed;
}

void SFlareDashboard::OnInspectShip()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_Ship);
}

void SFlareDashboard::OnConfigureShip()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_ShipConfig);
}

void SFlareDashboard::OnOrbit()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_Orbit);
}

void SFlareDashboard::OnUndock()
{
	// Ask to undock, and close the menu
	AFlarePlayerController* PC = MenuManager->GetPC();
	if (PC)
	{
		AFlareSpacecraft* Ship = PC->GetShipPawn();
		if (Ship)
		{
			Ship->GetNavigationSystem()->Undock();
			MenuManager->CloseMenu();
		}
	}
}

void SFlareDashboard::OnInspectCompany()
{
	MenuManager->OpenMenu(EFlareMenu::MENU_Company);
}

void SFlareDashboard::OnExit()
{
	MenuManager->CloseMenu();
}

#undef LOCTEXT_NAMESPACE

<|endoftext|>


<commit_before>/**
 * Unit Tests for Piezas
**/

#include <gtest/gtest.h>
#include "Piezas.h"

class PiezasTest : public ::testing::Test
{
    protected:
        PiezasTest(){} //constructor runs before each test
        virtual ~PiezasTest(){} //destructor cleans up after tests
        virtual void SetUp(){} //sets up before each test (after constructor)
        virtual void TearDown(){} //clean up after each test, (before destructor)
};

TEST(PiezasTest, sanityCheck)
{
    ASSERT_TRUE(true);
}

TEST(PiezasTest, blankBoard)
{
    Piezas game;
    Piece board[3][4];
    int count = 0;

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            if(board[i][j] == Blank)
            {
                count++;
            }
        }
    }
    ASSERT_EQ(count, 12);
}

TEST(PiezasTest, placeFirstX)
{
    Piezas game;
    Piece board[3][4];
    Piece confirm;

    confirm = game.dropPiece(2);

    ASSERT_EQ(confirm, board[2][2]);
}<commit_msg>Add files via upload<commit_after>/**
 * Unit Tests for Piezas
**/

#include <gtest/gtest.h>
#include "Piezas.h"

class PiezasTest : public ::testing::Test
{
    protected:
        PiezasTest(){} //constructor runs before each test
        virtual ~PiezasTest(){} //destructor cleans up after tests
        virtual void SetUp(){} //sets up before each test (after constructor)
        virtual void TearDown(){} //clean up after each test, (before destructor)
};

TEST(PiezasTest, sanityCheck)
{
    ASSERT_TRUE(true);
}

TEST(PiezasTest, blankBoard)
{
    Piezas game;
    Piece board[3][4];
    int count = 0;

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            if(board[i][j] == Blank)
            {
                count++;
                std::cout<<count<<endl;
            }
        }
    }
    ASSERT_EQ(count, 12);
}

TEST(PiezasTest, placeFirstX)
{
    Piezas game;
    Piece board[3][4];
    Piece confirm;

    confirm = game.dropPiece(2);

    ASSERT_EQ(confirm, board[2][2]);
}<|endoftext|>


<commit_before>/// Copyright 2015 Google Inc. All rights reserved.
///
/// 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 "SantaDriverClient.h"

#define super IOUserClient
#define SantaDriverClient com_google_SantaDriverClient

// The defines above can'be used in this function, must use the full names.
OSDefineMetaClassAndStructors(com_google_SantaDriverClient, IOUserClient);

#pragma mark Driver Management

bool SantaDriverClient::initWithTask(
    task_t owningTask, void *securityID, UInt32 type) {
  if (clientHasPrivilege(
      owningTask, kIOClientPrivilegeAdministrator) != KERN_SUCCESS) {
    LOGW("Unprivileged client attempted to connect.");
    return false;
  }

  if (!super::initWithTask(owningTask, securityID, type)) return false;

  return true;
}

bool SantaDriverClient::start(IOService *provider) {
  fProvider = OSDynamicCast(com_google_SantaDriver, provider);

  if (!fProvider) return false;
  if (!super::start(provider)) return false;

  fSDM = fProvider->GetDecisionManager();

  return true;
}

void SantaDriverClient::stop(IOService *provider) {
  super::stop(provider);
  fProvider = NULL;
}

IOReturn SantaDriverClient::clientClose() {
  terminate(kIOServiceSynchronous);
  return kIOReturnSuccess;
}

bool SantaDriverClient::terminate(IOOptionBits options) {
  fSDM->DisconnectClient();
  LOGI("Client disconnected.");

  fSharedMemory->release();
  fDataQueue->release();

  fSharedMemory = NULL;
  fDataQueue = NULL;

  if (fProvider && fProvider->isOpen(this)) fProvider->close(this);

  return super::terminate(options);
}

#pragma mark Fetching memory and data queue notifications

IOReturn SantaDriverClient::registerNotificationPort(mach_port_t port,
                                                     UInt32 type,
                                                     UInt32 ref) {
  if ((!fDataQueue) || (port == MACH_PORT_NULL)) return kIOReturnError;

  fDataQueue->setNotificationPort(port);

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::clientMemoryForType(UInt32 type,
                                                IOOptionBits *options,
                                                IOMemoryDescriptor **memory) {
  *memory = NULL;
  *options = 0;

  if (type == kIODefaultMemoryType) {
    if (!fSharedMemory) return kIOReturnNoMemory;
    fSharedMemory->retain();  // client will decrement this ref
    *memory = fSharedMemory;

    fSDM->ConnectClient(fDataQueue, proc_selfpid());
    LOGI("Client connected, PID: %d.", proc_selfpid());

    return kIOReturnSuccess;
  }

  return kIOReturnNoMemory;
}

#pragma mark Callable Methods

IOReturn SantaDriverClient::open() {
  if (isInactive()) return kIOReturnNotAttached;

  if (!fProvider->open(this)) {
    LOGW("A second client tried to connect.");
    return kIOReturnExclusiveAccess;
  }

  fDataQueue = IOSharedDataQueue::withCapacity((sizeof(santa_message_t) +
                                                DATA_QUEUE_ENTRY_HEADER_SIZE)
                                                * kMaxQueueEvents);
  if (!fDataQueue) return kIOReturnNoMemory;

  fSharedMemory = fDataQueue->getMemoryDescriptor();
  if (!fSharedMemory) {
    fDataQueue->release();
    fDataQueue = NULL;
    return kIOReturnVMError;
  }

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_open(
    SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->open();
}

IOReturn SantaDriverClient::allow_binary(const uint64_t vnode_id) {
  char vnode_id_str[21];
  snprintf(vnode_id_str, sizeof(vnode_id_str), "%llu", vnode_id);
  fSDM->AddToCache(vnode_id_str,
                   ACTION_RESPOND_CHECKBW_ALLOW,
                   fSDM->GetCurrentUptime());

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_allow_binary(
    SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->allow_binary(
      *(static_cast<const uint64_t *>(arguments->scalarInput)));
}

IOReturn SantaDriverClient::deny_binary(const uint64_t vnode_id) {
  char vnode_id_str[21];
  snprintf(vnode_id_str, sizeof(vnode_id_str), "%llu", vnode_id);
  fSDM->AddToCache(vnode_id_str,
                   ACTION_RESPOND_CHECKBW_DENY,
                   fSDM->GetCurrentUptime());

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_deny_binary(
    com_google_SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->deny_binary(
      *(static_cast<const uint64_t *>(arguments->scalarInput)));
}

IOReturn SantaDriverClient::clear_cache() {
  fSDM->ClearCache();
  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_clear_cache(
    com_google_SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->clear_cache();
}

IOReturn SantaDriverClient::cache_count(uint64_t *output) {
  *output = fSDM->CacheCount();
  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_cache_count(
    com_google_SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->cache_count(&(arguments->scalarOutput[0]));
}

#pragma mark Method Resolution

IOReturn SantaDriverClient::externalMethod(
    UInt32 selector,
    IOExternalMethodArguments *arguments,
    IOExternalMethodDispatch *dispatch,
    OSObject *target,
    void *reference) {
  ///  Array of methods callable by clients. The order of these must match the
  ///  order of the items in SantaDriverMethods in SNTKernelCommon.h
  IOExternalMethodDispatch sMethods[kSantaUserClientNMethods] = {
    {
      reinterpret_cast<IOExternalMethodAction>(&SantaDriverClient::static_open),
      0,  // input scalar
      0,  // input struct
      0,  // output scalar
      0   // output struct
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_allow_binary),
      1,
      0,
      0,
      0
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_deny_binary),
      1,
      0,
      0,
      0
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_clear_cache),
      0,
      0,
      0,
      0
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_cache_count),
      0,
      0,
      1,
      0
    }
  };

  if (selector < static_cast<UInt32>(kSantaUserClientNMethods)) {
    dispatch = &(sMethods[selector]);
    if (!target) target = this;
  } else {
    return kIOReturnBadArgument;
  }

  return super::externalMethod(selector,
                               arguments,
                               dispatch,
                               target,
                               reference);
}

#undef super
<commit_msg>santa-driver: Ensure fSDM and fDataQueue are NULL'd ASAP.<commit_after>/// Copyright 2015 Google Inc. All rights reserved.
///
/// 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 "SantaDriverClient.h"

#define super IOUserClient
#define SantaDriverClient com_google_SantaDriverClient

// The defines above can'be used in this function, must use the full names.
OSDefineMetaClassAndStructors(com_google_SantaDriverClient, IOUserClient);

#pragma mark Driver Management

bool SantaDriverClient::initWithTask(
    task_t owningTask, void *securityID, UInt32 type) {
  if (clientHasPrivilege(
      owningTask, kIOClientPrivilegeAdministrator) != KERN_SUCCESS) {
    LOGW("Unprivileged client attempted to connect.");
    return false;
  }

  if (!super::initWithTask(owningTask, securityID, type)) return false;

  return true;
}

bool SantaDriverClient::start(IOService *provider) {
  fProvider = OSDynamicCast(com_google_SantaDriver, provider);

  if (!fProvider) return false;
  if (!super::start(provider)) return false;

  fSDM = fProvider->GetDecisionManager();

  return true;
}

void SantaDriverClient::stop(IOService *provider) {
  super::stop(provider);

  fSDM = NULL;
  fProvider = NULL;
}

IOReturn SantaDriverClient::clientClose() {
  terminate(kIOServiceSynchronous);
  return kIOReturnSuccess;
}

bool SantaDriverClient::terminate(IOOptionBits options) {
  fSDM->DisconnectClient();
  LOGI("Client disconnected.");

  fSharedMemory->release();
  fSharedMemory = NULL;

  fDataQueue->release();
  fDataQueue = NULL;

  if (fProvider && fProvider->isOpen(this)) fProvider->close(this);

  return super::terminate(options);
}

#pragma mark Fetching memory and data queue notifications

IOReturn SantaDriverClient::registerNotificationPort(mach_port_t port,
                                                     UInt32 type,
                                                     UInt32 ref) {
  if ((!fDataQueue) || (port == MACH_PORT_NULL)) return kIOReturnError;

  fDataQueue->setNotificationPort(port);

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::clientMemoryForType(UInt32 type,
                                                IOOptionBits *options,
                                                IOMemoryDescriptor **memory) {
  *memory = NULL;
  *options = 0;

  if (type == kIODefaultMemoryType) {
    if (!fSharedMemory) return kIOReturnNoMemory;
    fSharedMemory->retain();  // client will decrement this ref
    *memory = fSharedMemory;

    fSDM->ConnectClient(fDataQueue, proc_selfpid());
    LOGI("Client connected, PID: %d.", proc_selfpid());

    return kIOReturnSuccess;
  }

  return kIOReturnNoMemory;
}

#pragma mark Callable Methods

IOReturn SantaDriverClient::open() {
  if (isInactive()) return kIOReturnNotAttached;

  if (!fProvider->open(this)) {
    LOGW("A second client tried to connect.");
    return kIOReturnExclusiveAccess;
  }

  fDataQueue = IOSharedDataQueue::withCapacity((sizeof(santa_message_t) +
                                                DATA_QUEUE_ENTRY_HEADER_SIZE)
                                                * kMaxQueueEvents);
  if (!fDataQueue) return kIOReturnNoMemory;

  fSharedMemory = fDataQueue->getMemoryDescriptor();
  if (!fSharedMemory) {
    fDataQueue->release();
    fDataQueue = NULL;
    return kIOReturnVMError;
  }

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_open(
    SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->open();
}

IOReturn SantaDriverClient::allow_binary(const uint64_t vnode_id) {
  char vnode_id_str[21];
  snprintf(vnode_id_str, sizeof(vnode_id_str), "%llu", vnode_id);
  fSDM->AddToCache(vnode_id_str,
                   ACTION_RESPOND_CHECKBW_ALLOW,
                   fSDM->GetCurrentUptime());

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_allow_binary(
    SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->allow_binary(
      *(static_cast<const uint64_t *>(arguments->scalarInput)));
}

IOReturn SantaDriverClient::deny_binary(const uint64_t vnode_id) {
  char vnode_id_str[21];
  snprintf(vnode_id_str, sizeof(vnode_id_str), "%llu", vnode_id);
  fSDM->AddToCache(vnode_id_str,
                   ACTION_RESPOND_CHECKBW_DENY,
                   fSDM->GetCurrentUptime());

  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_deny_binary(
    com_google_SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->deny_binary(
      *(static_cast<const uint64_t *>(arguments->scalarInput)));
}

IOReturn SantaDriverClient::clear_cache() {
  fSDM->ClearCache();
  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_clear_cache(
    com_google_SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->clear_cache();
}

IOReturn SantaDriverClient::cache_count(uint64_t *output) {
  *output = fSDM->CacheCount();
  return kIOReturnSuccess;
}

IOReturn SantaDriverClient::static_cache_count(
    com_google_SantaDriverClient *target,
    void *reference,
    IOExternalMethodArguments *arguments) {
  if (!target) return kIOReturnBadArgument;
  return target->cache_count(&(arguments->scalarOutput[0]));
}

#pragma mark Method Resolution

IOReturn SantaDriverClient::externalMethod(
    UInt32 selector,
    IOExternalMethodArguments *arguments,
    IOExternalMethodDispatch *dispatch,
    OSObject *target,
    void *reference) {
  ///  Array of methods callable by clients. The order of these must match the
  ///  order of the items in SantaDriverMethods in SNTKernelCommon.h
  IOExternalMethodDispatch sMethods[kSantaUserClientNMethods] = {
    {
      reinterpret_cast<IOExternalMethodAction>(&SantaDriverClient::static_open),
      0,  // input scalar
      0,  // input struct
      0,  // output scalar
      0   // output struct
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_allow_binary),
      1,
      0,
      0,
      0
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_deny_binary),
      1,
      0,
      0,
      0
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_clear_cache),
      0,
      0,
      0,
      0
    },
    {
      reinterpret_cast<IOExternalMethodAction>(
          &SantaDriverClient::static_cache_count),
      0,
      0,
      1,
      0
    }
  };

  if (selector < static_cast<UInt32>(kSantaUserClientNMethods)) {
    dispatch = &(sMethods[selector]);
    if (!target) target = this;
  } else {
    return kIOReturnBadArgument;
  }

  return super::externalMethod(selector,
                               arguments,
                               dispatch,
                               target,
                               reference);
}

#undef super
<|endoftext|>