<commit_before>#include <stdio.h>
#include <osg/Notify>
#include <osg/Statistics>

#include <osgUtil/RenderStage>

using namespace osg;
using namespace osgUtil;

// register a RenderStage prototype with the RenderBin prototype list.
//RegisterRenderBinProxy<RenderStage> s_registerRenderStageProxy;

RenderStage::RenderStage(SortMode mode):
    RenderBin(mode)
{
    // point RenderBin's _stage to this to ensure that references to
    // stage don't go tempted away to any other stage.
    _stage = this;
    _stageDrawnThisFrame = false;

    _clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
    _clearColor.set(0.0f,0.0f,0.0f,0.0f);
    _clearAccum.set(0.0f,0.0f,0.0f,0.0f);
    _clearDepth = 1.0;
    _clearStencil = 0;

}

RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop):
        RenderBin(rhs,copyop),
        _stageDrawnThisFrame(false),
        _dependencyList(rhs._dependencyList),
        _viewport(rhs._viewport),
        _clearMask(rhs._clearMask),
        _colorMask(rhs._colorMask),
        _clearColor(rhs._clearColor),
        _clearAccum(rhs._clearAccum),
        _clearDepth(rhs._clearDepth),
        _clearStencil(rhs._clearStencil),
        _renderStageLighting(rhs._renderStageLighting)

{
}

RenderStage::~RenderStage()
{
}

void RenderStage::reset()
{
    _dependencyList.clear();
    _stageDrawnThisFrame = false;

    if (_renderStageLighting.valid()) _renderStageLighting->reset();

    RenderBin::reset();
}

void RenderStage::addToDependencyList(RenderStage* rs)
{
    if (rs) _dependencyList.push_back(rs);
}

void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
{
    if (_stageDrawnThisFrame) return;

    if (!_viewport)
    {
        notify(FATAL) << "Error: cannot draw stage due to undefined viewport."<< std::endl;
        return;
    }

    _stageDrawnThisFrame = true;

    for(DependencyList::iterator itr=_dependencyList.begin();
        itr!=_dependencyList.end();
        ++itr)
    {
        (*itr)->draw(state,previous);
    }

    // set up the back buffer.
    state.applyAttribute(_viewport.get());

#define USE_SISSOR_TEST
#ifdef USE_SISSOR_TEST
    glScissor( _viewport->x(), _viewport->y(), _viewport->width(), _viewport->height() );
    glEnable( GL_SCISSOR_TEST );
#endif

    // glEnable( GL_DEPTH_TEST );

    // set which color planes to operate on.
    if (_colorMask.valid()) _colorMask->apply(state);
    else glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

    if (_clearMask & GL_COLOR_BUFFER_BIT)
        glClearColor( _clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]);

    if (_clearMask & GL_DEPTH_BUFFER_BIT)
        glClearDepth( _clearDepth);

    if (_clearMask & GL_STENCIL_BUFFER_BIT)
        glClearStencil( _clearStencil);

    if (_clearMask & GL_ACCUM_BUFFER_BIT)
        glClearAccum( _clearAccum[0], _clearAccum[1], _clearAccum[2], _clearAccum[3]);

    glClear( _clearMask );

#ifdef USE_SISSOR_TEST
    glDisable( GL_SCISSOR_TEST );
#endif

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // apply the lights.
    if (_renderStageLighting.valid()) _renderStageLighting->draw(state,previous);

    // draw the children and local.
    RenderBin::draw(state,previous);

    // now reset the state so its back in its default state.
    if (previous)
    {
        RenderGraph::moveToRootRenderGraph(state,previous->_parent);
        state.apply();
        previous = NULL;
    }

}
// Statistics features
bool RenderStage::getStats(Statistics* primStats)
{
    if (_renderStageLighting.valid())
    {
        // need to re-implement by checking for lights in the scene
        // by downcasting the positioned attribute list. RO. May 2002.
        //primStats->addLight(_renderStageLighting->_lightList.size());
    }
    return RenderBin::getStats(primStats);
}
<commit_msg>Fixed copy constructor so that the _stage member variable was set to this correctly.<commit_after>#include <stdio.h>
#include <osg/Notify>
#include <osg/Statistics>

#include <osgUtil/RenderStage>

using namespace osg;
using namespace osgUtil;

// register a RenderStage prototype with the RenderBin prototype list.
//RegisterRenderBinProxy<RenderStage> s_registerRenderStageProxy;

RenderStage::RenderStage(SortMode mode):
    RenderBin(mode)
{
    // point RenderBin's _stage to this to ensure that references to
    // stage don't go tempted away to any other stage.
    _stage = this;
    _stageDrawnThisFrame = false;

    _clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
    _clearColor.set(0.0f,0.0f,0.0f,0.0f);
    _clearAccum.set(0.0f,0.0f,0.0f,0.0f);
    _clearDepth = 1.0;
    _clearStencil = 0;

}

RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop):
        RenderBin(rhs,copyop),
        _stageDrawnThisFrame(false),
        _dependencyList(rhs._dependencyList),
        _viewport(rhs._viewport),
        _clearMask(rhs._clearMask),
        _colorMask(rhs._colorMask),
        _clearColor(rhs._clearColor),
        _clearAccum(rhs._clearAccum),
        _clearDepth(rhs._clearDepth),
        _clearStencil(rhs._clearStencil),
        _renderStageLighting(rhs._renderStageLighting)

{
    _stage = this;
}

RenderStage::~RenderStage()
{
}

void RenderStage::reset()
{
    _dependencyList.clear();
    _stageDrawnThisFrame = false;

    if (_renderStageLighting.valid()) _renderStageLighting->reset();

    RenderBin::reset();
}

void RenderStage::addToDependencyList(RenderStage* rs)
{
    if (rs) _dependencyList.push_back(rs);
}

void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
{
    if (_stageDrawnThisFrame) return;

    if (!_viewport)
    {
        notify(FATAL) << "Error: cannot draw stage due to undefined viewport."<< std::endl;
        return;
    }

    _stageDrawnThisFrame = true;

    for(DependencyList::iterator itr=_dependencyList.begin();
        itr!=_dependencyList.end();
        ++itr)
    {
        (*itr)->draw(state,previous);
    }

    // set up the back buffer.
    state.applyAttribute(_viewport.get());

#define USE_SISSOR_TEST
#ifdef USE_SISSOR_TEST
    glScissor( _viewport->x(), _viewport->y(), _viewport->width(), _viewport->height() );
    glEnable( GL_SCISSOR_TEST );
#endif

    // glEnable( GL_DEPTH_TEST );

    // set which color planes to operate on.
    if (_colorMask.valid()) _colorMask->apply(state);
    else glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

    if (_clearMask & GL_COLOR_BUFFER_BIT)
        glClearColor( _clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]);

    if (_clearMask & GL_DEPTH_BUFFER_BIT)
        glClearDepth( _clearDepth);

    if (_clearMask & GL_STENCIL_BUFFER_BIT)
        glClearStencil( _clearStencil);

    if (_clearMask & GL_ACCUM_BUFFER_BIT)
        glClearAccum( _clearAccum[0], _clearAccum[1], _clearAccum[2], _clearAccum[3]);

    glClear( _clearMask );

#ifdef USE_SISSOR_TEST
    glDisable( GL_SCISSOR_TEST );
#endif

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // apply the lights.
    if (_renderStageLighting.valid()) _renderStageLighting->draw(state,previous);

    // draw the children and local.
    RenderBin::draw(state,previous);

    // now reset the state so its back in its default state.
    if (previous)
    {
        RenderGraph::moveToRootRenderGraph(state,previous->_parent);
        state.apply();
        previous = NULL;
    }

}
// Statistics features
bool RenderStage::getStats(Statistics* primStats)
{
    if (_renderStageLighting.valid())
    {
        // need to re-implement by checking for lights in the scene
        // by downcasting the positioned attribute list. RO. May 2002.
        //primStats->addLight(_renderStageLighting->_lightList.size());
    }
    return RenderBin::getStats(primStats);
}
<|endoftext|>


<commit_before>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
#include "player_sys.sqf"

class playerSettings {

	idd = playersys_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[] execVM 'client\systems\playerMenu\item_list.sqf'";

	class controlsBackground {

		class MainBG : w_RscPicture {
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {0,0,0,0};
			text = "#(argb,8,8,3)color(0,0,0,0.6)";
			moving = true;
			x = 0.0; y = 0.1;
			w = .745; h = 0.65;
		};

		class TopBar: w_RscPicture
		{
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {0,0,0,0};
			text = "#(argb,8,8,3)color(0.25,0.51,0.96,0.8)";

			x = 0;
			y = 0.1;
			w = 0.745;
			h = 0.05;
		};

		class MainTitle : w_RscText {
			idc = -1;
			text = "Player Inventory";
			sizeEx = 0.04;
			shadow = 2;
			x = 0.260; y = 0.1;
			w = 0.3; h = 0.05;
		};

		class waterIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\water.paa";
			x = 0.022; y = 0.2;
			w = 0.04 / (4/3); h = 0.04;
		};

		class foodIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\food.paa";
			x = 0.022; y = 0.26;
			w = 0.04 / (4/3); h = 0.04;
		};

		class moneyIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\money.paa";
			x = 0.022; y = 0.32;
			w = 0.04 / (4/3); h = 0.04;
		};

		class waterText : w_RscText {
			idc = water_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.193;
			w = 0.3; h = 0.05;
		};

		class foodText : w_RscText {
			idc = food_text;
			sizeEx = 0.03;
			text = "";
			x = 0.06; y = 0.254;
			w = 0.3; h = 0.05;
		};

		class moneyText : w_RscText {
			idc = money_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.313;
			w = 0.3; h = 0.05;
		};

		class distanceText : w_RscText {
			idc = view_range_text;
			text = "View range:";
			sizeEx = 0.025;
			x = 0.03; y = 0.40;
			w = 0.3; h = 0.02;
		};

		class uptimeText : w_RscText {
			idc = uptime_text;
			text = "";
			sizeEx = 0.030;
			x = 0.52; y = 0.69;
			w = 0.225; h = 0.03;
		};
	};

	class controls {

		class itemList : w_Rsclist {
			idc = item_list;
			x = 0.49; y = 0.185;
			w = 0.235; h = 0.325;
		};

		class DropButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[1] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.610; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class UseButton : w_RscButton {
			idc = -1;
			text = "Use";
			onButtonClick = "[0] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.489; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class moneyInput: w_RscCombo {
			idc = money_value;
			x = 0.610; y = 0.618;
			w = .116; h = .030;
		};

		class DropcButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[] execVM 'client\systems\playerMenu\dropMoney.sqf'";
			x = 0.489; y = 0.60;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class CloseButton : w_RscButton {
			idc = close_button;
			text = "Close";
			onButtonClick = "[] execVM 'client\systems\playerMenu\closePlayerMenu.sqf'";
			x = 0.02; y = 0.66;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class GroupsButton : w_RscButton {
			idc = groupButton;
			text = "Group Management";
			onButtonClick = "[] execVM 'client\systems\groups\loadGroupManagement.sqf'";
			x = 0.158; y = 0.66;
			w = 0.225; h = 0.033 * safezoneH;
		};

		class btnDistanceNear : w_RscButton {
			idc = -1;
			text = "Near";
			onButtonClick = "setViewDistance 1100;";
			x = 0.02; y = 0.43;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceMedium : w_RscButton {
			idc = -1;
			text = "Medium";
			onButtonClick = "setViewDistance 2200;";
			x = 0.02; y = 0.5;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceFar : w_RscButton {
			idc = -1;
			text = "Far";
			onButtonClick = "setViewDistance 3300;";
			x = 0.02; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceInsane : w_RscButton {
			text = "Insane";
			onButtonClick = "setViewDistance 5000;";
			x = 0.02; y = 0.60;
			w = 0.125; h = 0.033 * safezoneH;
		};
	};
};
<commit_msg>Adjust position to reveal Insane View Distance Button<commit_after>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
#include "player_sys.sqf"

class playerSettings {

	idd = playersys_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[] execVM 'client\systems\playerMenu\item_list.sqf'";

	class controlsBackground {

		class MainBG : w_RscPicture {
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {0,0,0,0};
			text = "#(argb,8,8,3)color(0,0,0,0.6)";
			moving = true;
			x = 0.0; y = 0.1;
			w = .745; h = 0.65;
		};

		class TopBar: w_RscPicture
		{
			idc = -1;
			colorText[] = {1, 1, 1, 1};
			colorBackground[] = {0,0,0,0};
			text = "#(argb,8,8,3)color(0.25,0.51,0.96,0.8)";

			x = 0;
			y = 0.1;
			w = 0.745;
			h = 0.05;
		};

		class MainTitle : w_RscText {
			idc = -1;
			text = "Player Inventory";
			sizeEx = 0.04;
			shadow = 2;
			x = 0.260; y = 0.1;
			w = 0.3; h = 0.05;
		};

		class waterIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\water.paa";
			x = 0.022; y = 0.2;
			w = 0.04 / (4/3); h = 0.04;
		};

		class foodIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\food.paa";
			x = 0.022; y = 0.26;
			w = 0.04 / (4/3); h = 0.04;
		};

		class moneyIcon : w_RscPicture {
			idc = -1;
			text = "client\icons\money.paa";
			x = 0.022; y = 0.32;
			w = 0.04 / (4/3); h = 0.04;
		};

		class waterText : w_RscText {
			idc = water_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.193;
			w = 0.3; h = 0.05;
		};

		class foodText : w_RscText {
			idc = food_text;
			sizeEx = 0.03;
			text = "";
			x = 0.06; y = 0.254;
			w = 0.3; h = 0.05;
		};

		class moneyText : w_RscText {
			idc = money_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.313;
			w = 0.3; h = 0.05;
		};

		class distanceText : w_RscText {
			idc = view_range_text;
			text = "View range:";
			sizeEx = 0.025;
			x = 0.03; y = 0.40;
			w = 0.3; h = 0.02;
		};

		class uptimeText : w_RscText {
			idc = uptime_text;
			text = "";
			sizeEx = 0.030;
			x = 0.52; y = 0.69;
			w = 0.225; h = 0.03;
		};
	};

	class controls {

		class itemList : w_Rsclist {
			idc = item_list;
			x = 0.49; y = 0.185;
			w = 0.235; h = 0.325;
		};

		class DropButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[1] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.610; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class UseButton : w_RscButton {
			idc = -1;
			text = "Use";
			onButtonClick = "[0] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.489; y = 0.525;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class moneyInput: w_RscCombo {
			idc = money_value;
			x = 0.610; y = 0.618;
			w = .116; h = .030;
		};

		class DropcButton : w_RscButton {
			idc = -1;
			text = "Drop";
			onButtonClick = "[] execVM 'client\systems\playerMenu\dropMoney.sqf'";
			x = 0.489; y = 0.60;
			w = 0.116; h = 0.033 * safezoneH;
		};

		class CloseButton : w_RscButton {
			idc = close_button;
			text = "Close";
			onButtonClick = "[] execVM 'client\systems\playerMenu\closePlayerMenu.sqf'";
			x = 0.02; y = 0.66;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class GroupsButton : w_RscButton {
			idc = groupButton;
			text = "Group Management";
			onButtonClick = "[] execVM 'client\systems\groups\loadGroupManagement.sqf'";
			x = 0.158; y = 0.66;
			w = 0.225; h = 0.033 * safezoneH;
		};

		class btnDistanceNear : w_RscButton {
			idc = -1;
			text = "Near";
			onButtonClick = "setViewDistance 1100;";
			x = 0.02; y = 0.43;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceMedium : w_RscButton {
			idc = -1;
			text = "Medium";
			onButtonClick = "setViewDistance 2200;";
			x = 0.02; y = 0.5;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceFar : w_RscButton {
			idc = -1;
			text = "Far";
			onButtonClick = "setViewDistance 3300;";
			x = 0.02; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceInsane : w_RscButton {
			text = "Insane";
			onButtonClick = "setViewDistance 5000;";
			x = 0.158; y = 0.57;
			w = 0.125; h = 0.033 * safezoneH;
		};
	};
};
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "TableFieldDescription.hxx"
#include <tools/debug.hxx>
#include <com/sun/star/sdbc/DataType.hpp>
#include <comphelper/namedvaluecollection.hxx>

#include <functional>

using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace comphelper;
using namespace dbaui;

OTableFieldDesc::OTableFieldDesc()
    :m_pTabWindow(0)
    ,m_eDataType(1000)
    ,m_eFunctionType( FKT_NONE )
    ,m_eFieldType(TAB_NORMAL_FIELD)
    ,m_eOrderDir( ORDER_NONE )
    ,m_nIndex(0)
    ,m_nColWidth(0)
    ,m_nColumnId((sal_uInt16)-1)
    ,m_bGroupBy(false)
    ,m_bVisible(false)
{
}

OTableFieldDesc::OTableFieldDesc(const OTableFieldDesc& rRS)
    : ::salhelper::SimpleReferenceObject()

{
    *this = rRS;
}

OTableFieldDesc::OTableFieldDesc(const OUString& rT, const OUString& rF )
    :m_pTabWindow(0)
    ,m_eDataType(1000)
    ,m_eFunctionType( FKT_NONE )
    ,m_eFieldType(TAB_NORMAL_FIELD)
    ,m_eOrderDir( ORDER_NONE )
    ,m_nIndex(0)
    ,m_nColWidth(0)
    ,m_nColumnId((sal_uInt16)-1)
    ,m_bGroupBy(false)
    ,m_bVisible(false)
{
    SetField( rF ); SetTable( rT );
}

OTableFieldDesc::~OTableFieldDesc()
{
}

OTableFieldDesc& OTableFieldDesc::operator=( const OTableFieldDesc& rRS )
{
    if (&rRS == this)
        return *this;

    m_aCriteria = rRS.GetCriteria();
    m_aTableName = rRS.GetTable();
    m_aAliasName = rRS.GetAlias();      // table range
    m_aFieldName = rRS.GetField();      // column
    m_aFieldAlias = rRS.GetFieldAlias();    // column alias
    m_aFunctionName = rRS.GetFunction();    // Funktionsname
    m_pTabWindow = rRS.GetTabWindow();
    m_eDataType = rRS.GetDataType();
    m_eFunctionType = rRS.GetFunctionType();
    m_eFieldType = rRS.GetFieldType();
    m_eOrderDir = rRS.GetOrderDir();
    m_nIndex = rRS.GetFieldIndex();
    m_nColWidth = rRS.GetColWidth();
    m_nColumnId = rRS.m_nColumnId;
    m_bGroupBy = rRS.IsGroupBy();
    m_bVisible = rRS.IsVisible();

    return *this;
}

bool OTableFieldDesc::operator==( const OTableFieldDesc& rDesc )
{

    return (    m_eOrderDir != rDesc.GetOrderDir()      ||
                m_eDataType != rDesc.GetDataType()      ||
                m_aAliasName != rDesc.GetAlias()        ||
                m_aFunctionName != rDesc.GetFunction()  ||
                m_aFieldName != rDesc.GetField()        ||
                m_aTableName != rDesc.GetTable()        ||
                m_bGroupBy != rDesc.IsGroupBy()         ||
                m_aCriteria != rDesc.GetCriteria()  ||
                m_bVisible != rDesc.IsVisible() );

}

void OTableFieldDesc::SetCriteria( sal_uInt16 nIdx, const OUString& rCrit)
{
    if (nIdx < m_aCriteria.size())
        m_aCriteria[nIdx] = rCrit;
    else
    {
        for(sal_Int32 i=m_aCriteria.size();i<nIdx;++i)
            m_aCriteria.push_back( OUString());
        m_aCriteria.push_back(rCrit);
    }
}

OUString OTableFieldDesc::GetCriteria( sal_uInt16 nIdx ) const
{
    OUString aRetStr;
    if( nIdx < m_aCriteria.size())
        aRetStr = m_aCriteria[nIdx];

    return aRetStr;
}

namespace
{
    struct SelectPropertyValueAsString : public ::std::unary_function< PropertyValue, OUString >
    {
        OUString operator()( const PropertyValue& i_rPropValue ) const
        {
            OUString sValue;
            OSL_VERIFY( i_rPropValue.Value >>= sValue );
            return sValue;
        }
    };
}

void OTableFieldDesc::Load( const ::com::sun::star::beans::PropertyValue& i_rSettings, const bool i_bIncludingCriteria )
{

    ::comphelper::NamedValueCollection aFieldDesc( i_rSettings.Value );
    m_aAliasName = aFieldDesc.getOrDefault( "AliasName", m_aAliasName );
    m_aTableName = aFieldDesc.getOrDefault( "TableName", m_aTableName );
    m_aFieldName = aFieldDesc.getOrDefault( "FieldName", m_aFieldName );
    m_aFieldAlias = aFieldDesc.getOrDefault( "FieldAlias", m_aFieldAlias );
    m_aFunctionName = aFieldDesc.getOrDefault( "FunctionName", m_aFunctionName );
    m_eDataType = aFieldDesc.getOrDefault( "DataType", m_eDataType );
    m_eFunctionType = aFieldDesc.getOrDefault( "FunctionType", m_eFunctionType );
    m_nColWidth = aFieldDesc.getOrDefault( "ColWidth", m_nColWidth );
    m_bGroupBy = aFieldDesc.getOrDefault( "GroupBy", m_bGroupBy );
    m_bVisible = aFieldDesc.getOrDefault( "Visible", m_bVisible );

    m_eFieldType = static_cast< ETableFieldType >( aFieldDesc.getOrDefault( "FieldType", static_cast< sal_Int32 >( m_eFieldType ) ) );
    m_eOrderDir = static_cast< EOrderDir >( aFieldDesc.getOrDefault( "OrderDir", static_cast< sal_Int32 >( m_eOrderDir ) ) );

    if ( i_bIncludingCriteria )
    {
        const Sequence< PropertyValue > aCriteria( aFieldDesc.getOrDefault( "Criteria", Sequence< PropertyValue >() ) );
        m_aCriteria.resize( aCriteria.getLength() );
        ::std::transform(
            aCriteria.getConstArray(),
            aCriteria.getConstArray() + aCriteria.getLength(),
            m_aCriteria.begin(),
            SelectPropertyValueAsString()
        );
    }
}

void OTableFieldDesc::Save( ::comphelper::NamedValueCollection& o_rSettings, const bool i_bIncludingCriteria )
{

    o_rSettings.put( "AliasName", m_aAliasName );
    o_rSettings.put( "TableName", m_aTableName );
    o_rSettings.put( "FieldName", m_aFieldName );
    o_rSettings.put( "FieldAlias", m_aFieldAlias );
    o_rSettings.put( "FunctionName", m_aFunctionName );
    o_rSettings.put( "DataType", m_eDataType );
    o_rSettings.put( "FunctionType", (sal_Int32)m_eFunctionType );
    o_rSettings.put( "FieldType", (sal_Int32)m_eFieldType );
    o_rSettings.put( "OrderDir", (sal_Int32)m_eOrderDir );
    o_rSettings.put( "ColWidth", m_nColWidth );
    o_rSettings.put( "GroupBy", m_bGroupBy );
    o_rSettings.put( "Visible", m_bVisible );

    if ( i_bIncludingCriteria )
    {
        if ( !m_aCriteria.empty() )
        {
            sal_Int32 c = 0;
            Sequence< PropertyValue > aCriteria( m_aCriteria.size() );
            for (   ::std::vector< OUString >::const_iterator crit = m_aCriteria.begin();
                    crit != m_aCriteria.end();
                    ++crit, ++c
                )
            {
                aCriteria[c].Name = "Criterion_" + OUString::number( c );
                aCriteria[c].Value <<= *crit;
            }

            o_rSettings.put( "Criteria", aCriteria );
        }
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#707746 Uninitialized pointer field<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "TableFieldDescription.hxx"
#include <tools/debug.hxx>
#include <com/sun/star/sdbc/DataType.hpp>
#include <comphelper/namedvaluecollection.hxx>

#include <functional>

using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace comphelper;
using namespace dbaui;

OTableFieldDesc::OTableFieldDesc()
    :m_pTabWindow(0)
    ,m_eDataType(1000)
    ,m_eFunctionType( FKT_NONE )
    ,m_eFieldType(TAB_NORMAL_FIELD)
    ,m_eOrderDir( ORDER_NONE )
    ,m_nIndex(0)
    ,m_nColWidth(0)
    ,m_nColumnId((sal_uInt16)-1)
    ,m_bGroupBy(false)
    ,m_bVisible(false)
{
}

OTableFieldDesc::OTableFieldDesc(const OTableFieldDesc& rRS)
    : ::salhelper::SimpleReferenceObject()
    , m_pTabWindow(NULL)
{
    *this = rRS;
}

OTableFieldDesc::OTableFieldDesc(const OUString& rT, const OUString& rF )
    :m_pTabWindow(0)
    ,m_eDataType(1000)
    ,m_eFunctionType( FKT_NONE )
    ,m_eFieldType(TAB_NORMAL_FIELD)
    ,m_eOrderDir( ORDER_NONE )
    ,m_nIndex(0)
    ,m_nColWidth(0)
    ,m_nColumnId((sal_uInt16)-1)
    ,m_bGroupBy(false)
    ,m_bVisible(false)
{
    SetField( rF ); SetTable( rT );
}

OTableFieldDesc::~OTableFieldDesc()
{
}

OTableFieldDesc& OTableFieldDesc::operator=( const OTableFieldDesc& rRS )
{
    if (&rRS == this)
        return *this;

    m_aCriteria = rRS.GetCriteria();
    m_aTableName = rRS.GetTable();
    m_aAliasName = rRS.GetAlias();      // table range
    m_aFieldName = rRS.GetField();      // column
    m_aFieldAlias = rRS.GetFieldAlias();    // column alias
    m_aFunctionName = rRS.GetFunction();    // Funktionsname
    m_pTabWindow = rRS.GetTabWindow();
    m_eDataType = rRS.GetDataType();
    m_eFunctionType = rRS.GetFunctionType();
    m_eFieldType = rRS.GetFieldType();
    m_eOrderDir = rRS.GetOrderDir();
    m_nIndex = rRS.GetFieldIndex();
    m_nColWidth = rRS.GetColWidth();
    m_nColumnId = rRS.m_nColumnId;
    m_bGroupBy = rRS.IsGroupBy();
    m_bVisible = rRS.IsVisible();

    return *this;
}

bool OTableFieldDesc::operator==( const OTableFieldDesc& rDesc )
{

    return (    m_eOrderDir != rDesc.GetOrderDir()      ||
                m_eDataType != rDesc.GetDataType()      ||
                m_aAliasName != rDesc.GetAlias()        ||
                m_aFunctionName != rDesc.GetFunction()  ||
                m_aFieldName != rDesc.GetField()        ||
                m_aTableName != rDesc.GetTable()        ||
                m_bGroupBy != rDesc.IsGroupBy()         ||
                m_aCriteria != rDesc.GetCriteria()  ||
                m_bVisible != rDesc.IsVisible() );

}

void OTableFieldDesc::SetCriteria( sal_uInt16 nIdx, const OUString& rCrit)
{
    if (nIdx < m_aCriteria.size())
        m_aCriteria[nIdx] = rCrit;
    else
    {
        for(sal_Int32 i=m_aCriteria.size();i<nIdx;++i)
            m_aCriteria.push_back( OUString());
        m_aCriteria.push_back(rCrit);
    }
}

OUString OTableFieldDesc::GetCriteria( sal_uInt16 nIdx ) const
{
    OUString aRetStr;
    if( nIdx < m_aCriteria.size())
        aRetStr = m_aCriteria[nIdx];

    return aRetStr;
}

namespace
{
    struct SelectPropertyValueAsString : public ::std::unary_function< PropertyValue, OUString >
    {
        OUString operator()( const PropertyValue& i_rPropValue ) const
        {
            OUString sValue;
            OSL_VERIFY( i_rPropValue.Value >>= sValue );
            return sValue;
        }
    };
}

void OTableFieldDesc::Load( const ::com::sun::star::beans::PropertyValue& i_rSettings, const bool i_bIncludingCriteria )
{

    ::comphelper::NamedValueCollection aFieldDesc( i_rSettings.Value );
    m_aAliasName = aFieldDesc.getOrDefault( "AliasName", m_aAliasName );
    m_aTableName = aFieldDesc.getOrDefault( "TableName", m_aTableName );
    m_aFieldName = aFieldDesc.getOrDefault( "FieldName", m_aFieldName );
    m_aFieldAlias = aFieldDesc.getOrDefault( "FieldAlias", m_aFieldAlias );
    m_aFunctionName = aFieldDesc.getOrDefault( "FunctionName", m_aFunctionName );
    m_eDataType = aFieldDesc.getOrDefault( "DataType", m_eDataType );
    m_eFunctionType = aFieldDesc.getOrDefault( "FunctionType", m_eFunctionType );
    m_nColWidth = aFieldDesc.getOrDefault( "ColWidth", m_nColWidth );
    m_bGroupBy = aFieldDesc.getOrDefault( "GroupBy", m_bGroupBy );
    m_bVisible = aFieldDesc.getOrDefault( "Visible", m_bVisible );

    m_eFieldType = static_cast< ETableFieldType >( aFieldDesc.getOrDefault( "FieldType", static_cast< sal_Int32 >( m_eFieldType ) ) );
    m_eOrderDir = static_cast< EOrderDir >( aFieldDesc.getOrDefault( "OrderDir", static_cast< sal_Int32 >( m_eOrderDir ) ) );

    if ( i_bIncludingCriteria )
    {
        const Sequence< PropertyValue > aCriteria( aFieldDesc.getOrDefault( "Criteria", Sequence< PropertyValue >() ) );
        m_aCriteria.resize( aCriteria.getLength() );
        ::std::transform(
            aCriteria.getConstArray(),
            aCriteria.getConstArray() + aCriteria.getLength(),
            m_aCriteria.begin(),
            SelectPropertyValueAsString()
        );
    }
}

void OTableFieldDesc::Save( ::comphelper::NamedValueCollection& o_rSettings, const bool i_bIncludingCriteria )
{

    o_rSettings.put( "AliasName", m_aAliasName );
    o_rSettings.put( "TableName", m_aTableName );
    o_rSettings.put( "FieldName", m_aFieldName );
    o_rSettings.put( "FieldAlias", m_aFieldAlias );
    o_rSettings.put( "FunctionName", m_aFunctionName );
    o_rSettings.put( "DataType", m_eDataType );
    o_rSettings.put( "FunctionType", (sal_Int32)m_eFunctionType );
    o_rSettings.put( "FieldType", (sal_Int32)m_eFieldType );
    o_rSettings.put( "OrderDir", (sal_Int32)m_eOrderDir );
    o_rSettings.put( "ColWidth", m_nColWidth );
    o_rSettings.put( "GroupBy", m_bGroupBy );
    o_rSettings.put( "Visible", m_bVisible );

    if ( i_bIncludingCriteria )
    {
        if ( !m_aCriteria.empty() )
        {
            sal_Int32 c = 0;
            Sequence< PropertyValue > aCriteria( m_aCriteria.size() );
            for (   ::std::vector< OUString >::const_iterator crit = m_aCriteria.begin();
                    crit != m_aCriteria.end();
                    ++crit, ++c
                )
            {
                aCriteria[c].Name = "Criterion_" + OUString::number( c );
                aCriteria[c].Value <<= *crit;
            }

            o_rSettings.put( "Criteria", aCriteria );
        }
    }
}

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


<commit_before>/*
  Copyright (C) 2005-2018 Steven L. Scott

  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; either version 2.1 of the License, or (at your option)
  any later version.

  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
*/

#include "test_utils/check_derivatives.hpp"
#include "test_utils/test_utils.hpp"
#include "numopt/NumericalDerivatives.hpp"
#include <sstream>

namespace BOOM {

  namespace {

    // If everything in g and h is within epsilon of 0 return true.  Otherwise
    // return false.
    bool all_zeros(const Vector &g, const Matrix &h, double epsilon) {
      for (int i = 0; i < g.size(); ++i) {
        if (fabs(g[i]) > epsilon) return false;
      }

      for (int i = 0; i < h.nrow(); ++i) {
        for (int j = 0; j < h.ncol(); ++j) {
          if (fabs(h(i, j)) > epsilon) {
            return false;
          }
        }
      }
      return true;
    }
  }

  std::string CheckDerivatives(DerivativeTestTarget target,
                               const Vector &evaluation_point,
                               double epsilon) {
    using std::endl;
    NumericalDerivatives derivs( [&target](const Vector &x) {
        Vector g;
        Matrix h;
        return target(x, g, h, 0);
      });

    int dim = evaluation_point.size();
    Vector analytic_gradient(dim);
    Matrix analytic_hessian(dim, dim);
    target(evaluation_point, analytic_gradient, analytic_hessian, 2);
    std::ostringstream err;
    if (all_zeros(analytic_gradient, analytic_hessian, epsilon)) {
      return "Test function was constant at evaluation point.";
    }

    Vector numeric_gradient = derivs.gradient(evaluation_point);
    if (!VectorEquals(analytic_gradient, numeric_gradient, epsilon)) {
      err << "gradient does not match." << endl
          << "analytic    numeric" << endl
          << cbind(analytic_gradient, numeric_gradient)
          << "maximum absolute deviation: "
          << (numeric_gradient - analytic_gradient).max_abs();
      return err.str();
    }

    Matrix numeric_hessian = derivs.Hessian(evaluation_point);
    if (!MatrixEquals(analytic_hessian, numeric_hessian, epsilon)) {
      err << "Hessian does not match." << endl
          << "Analytic Hessian: " << endl
          << analytic_hessian
          << "Numeric Hessian: " << endl
          << numeric_hessian
          << "maximum absolute deviation: "
          << (numeric_hessian - analytic_hessian).max_abs();

      return err.str();
    }
    return "";
  }

  //===========================================================================
  std::string CheckDerivatives(PointerDerivativeTestTarget &target,
                               const Vector &evaluation_point,
                               double epsilon) {
    using std::endl;
    DerivativeTestTarget real_target =
        [&target](const Vector &v, Vector &gradient, Matrix &hessian, int nd) {
      return target(v, nd > 0 ? &gradient : nullptr, nd > 1 ? &hessian : nullptr);
    };
    return CheckDerivatives(real_target, evaluation_point, epsilon);
  }

  //===========================================================================
  std::string CheckDerivatives(ScalarDerivativeTestTarget target,
                               double evaluation_point,
                               double epsilon) {

    // Compute analytic derivatives.
    double g = 0, h = 0;
    target(evaluation_point, g, h, 2);

    if (fabs(g) < epsilon && fabs(h) < epsilon) {
      return "Test function was constant at the evaluation point.";
    }

    ScalarNumericalDerivatives derivs([target](double x) {
        double g, h;
        return target(x, g, h, 0);
      });

    // Check first derivative.
    double d1_numeric = derivs.first_derivative(evaluation_point);
    std::ostringstream err;
    if (fabs(g - d1_numeric) > epsilon) {
      err << "first derivative does not match." << std::endl
          << "analytic:    " << g << std::endl
          << "numeric:     " << d1_numeric << std::endl;
      return err.str();
    }

    // Check second derivative.
    double d2_numeric = derivs.second_derivative(evaluation_point);
    if (fabs(h - d2_numeric) > epsilon) {
      err << "second derivative does not match." << std::endl
          << "analytic:   " << h << std::endl
          << "numeric:    " << d2_numeric << std::endl;
      return err.str();
    }

    return "";
  }

}  // namespace BOOM
<commit_msg>trival comment update<commit_after>/*
  Copyright (C) 2005-2018 Steven L. Scott

  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; either version 2.1 of the License, or (at your option)
  any later version.

  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
*/

#include "test_utils/check_derivatives.hpp"
#include "test_utils/test_utils.hpp"
#include "numopt/NumericalDerivatives.hpp"
#include <sstream>

namespace BOOM {

  namespace {

    // If everything in g and h is within epsilon of 0 return true.  Otherwise
    // return false.
    bool all_zeros(const Vector &g, const Matrix &h, double epsilon) {
      for (int i = 0; i < g.size(); ++i) {
        if (fabs(g[i]) > epsilon) return false;
      }

      for (int i = 0; i < h.nrow(); ++i) {
        for (int j = 0; j < h.ncol(); ++j) {
          if (fabs(h(i, j)) > epsilon) {
            return false;
          }
        }
      }
      return true;
    }
  }  // namespace

  std::string CheckDerivatives(DerivativeTestTarget target,
                               const Vector &evaluation_point,
                               double epsilon) {
    using std::endl;
    NumericalDerivatives derivs( [&target](const Vector &x) {
        Vector g;
        Matrix h;
        return target(x, g, h, 0);
      });

    int dim = evaluation_point.size();
    Vector analytic_gradient(dim);
    Matrix analytic_hessian(dim, dim);
    target(evaluation_point, analytic_gradient, analytic_hessian, 2);
    std::ostringstream err;
    if (all_zeros(analytic_gradient, analytic_hessian, epsilon)) {
      return "Test function was constant at evaluation point.";
    }

    Vector numeric_gradient = derivs.gradient(evaluation_point);
    if (!VectorEquals(analytic_gradient, numeric_gradient, epsilon)) {
      err << "gradient does not match." << endl
          << "analytic    numeric" << endl
          << cbind(analytic_gradient, numeric_gradient)
          << "maximum absolute deviation: "
          << (numeric_gradient - analytic_gradient).max_abs();
      return err.str();
    }

    Matrix numeric_hessian = derivs.Hessian(evaluation_point);
    if (!MatrixEquals(analytic_hessian, numeric_hessian, epsilon)) {
      err << "Hessian does not match." << endl
          << "Analytic Hessian: " << endl
          << analytic_hessian
          << "Numeric Hessian: " << endl
          << numeric_hessian
          << "maximum absolute deviation: "
          << (numeric_hessian - analytic_hessian).max_abs();

      return err.str();
    }
    return "";
  }

  //===========================================================================
  std::string CheckDerivatives(PointerDerivativeTestTarget &target,
                               const Vector &evaluation_point,
                               double epsilon) {
    using std::endl;
    DerivativeTestTarget real_target =
        [&target](const Vector &v, Vector &gradient, Matrix &hessian, int nd) {
      return target(v, nd > 0 ? &gradient : nullptr, nd > 1 ? &hessian : nullptr);
    };
    return CheckDerivatives(real_target, evaluation_point, epsilon);
  }

  //===========================================================================
  std::string CheckDerivatives(ScalarDerivativeTestTarget target,
                               double evaluation_point,
                               double epsilon) {

    // Compute analytic derivatives.
    double g = 0, h = 0;
    target(evaluation_point, g, h, 2);

    if (fabs(g) < epsilon && fabs(h) < epsilon) {
      return "Test function was constant at the evaluation point.";
    }

    ScalarNumericalDerivatives derivs([target](double x) {
        double g, h;
        return target(x, g, h, 0);
      });

    // Check first derivative.
    double d1_numeric = derivs.first_derivative(evaluation_point);
    std::ostringstream err;
    if (fabs(g - d1_numeric) > epsilon) {
      err << "first derivative does not match." << std::endl
          << "analytic:    " << g << std::endl
          << "numeric:     " << d1_numeric << std::endl;
      return err.str();
    }

    // Check second derivative.
    double d2_numeric = derivs.second_derivative(evaluation_point);
    if (fabs(h - d2_numeric) > epsilon) {
      err << "second derivative does not match." << std::endl
          << "analytic:   " << h << std::endl
          << "numeric:    " << d2_numeric << std::endl;
      return err.str();
    }

    return "";
  }

}  // namespace BOOM
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QGraphicsWidget>
#include <QTest>
#include <QString>
#include <QPixmap>
#include <QSignalSpy>
#include <QGraphicsSceneMouseEvent>

#include <mimagewidget.h>
#include "mcomponentdata.h"

#include "ut_mimagewidget.h"

Ut_MImageWidget::Ut_MImageWidget() :
        m_subject(0)
{
}

void Ut_MImageWidget::initTestCase()
{
    QImage img(qApp->applicationDirPath() + "/ut_mimagewidget-test.png");

    if (! MComponentData::instance()) {
        static char *argv = 0;
        static int argc = 0;
        new MComponentData(argc, &argv, QString("ut_mimagewidget"), NULL);
    }

    m_subject = new MImageWidget(&img);
    QVERIFY(m_subject != 0);
}

void Ut_MImageWidget::cleanupTestCase()
{
    delete m_subject;
    m_subject = 0;

    delete MComponentData::instance();
}

void Ut_MImageWidget::testConstructor_data()
{
    QTest::addColumn<QString>("fname");

    QTest::newRow("png") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png";
}

void Ut_MImageWidget::testConstructor()
{
    QFETCH(QString, fname);

    QSize s;

    QPixmap pixmap(fname);
    s = pixmap.size();

    // test load image files
    QImage img(fname);
    MImageWidget *myImage = new MImageWidget(&img);
    QCOMPARE(myImage->imageSize(), s);

    // test constructor from pixmap
    QPixmap *source = new QPixmap(s);
    source->fill(QColor(0, 0, 0, 0));
    MImageWidget *myImage3 = new MImageWidget(source);
    QCOMPARE(myImage3->imageSize(), s);
    delete myImage3;

    // test copy constructor
    MImageWidget *myImage4 = new MImageWidget(*myImage);
    QCOMPARE(myImage4->imageSize(), myImage->imageSize());
    delete myImage4;

    MImageWidget myImage5 = *myImage;
    QCOMPARE(myImage5.imageSize(), myImage->imageSize());

    delete source;
    delete myImage;
}

void Ut_MImageWidget::testImageDataSize_data()
{
    QTest::addColumn<QString>("fname");

    QTest::newRow("png") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png";
}

void Ut_MImageWidget::testImageDataSize()
{
    QFETCH(QString, fname);

    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QSize imgSize;
    QPixmap pixmap(fname);
    imgSize = pixmap.size();

    const QPixmap *p = m_subject->pixmap();
    QCOMPARE(imgSize, p->size());
    QCOMPARE(imgSize, m_subject->imageSize());

    // test setPixmap
    m_subject->setPixmap(pixmap);
    p = m_subject->pixmap();
    QCOMPARE(pixmap.toImage(), p->toImage());

    // test setImage
    QImage image = pixmap.toImage();
    m_subject->setImage(image);
    p = m_subject->pixmap();
    QCOMPARE(image, p->toImage());

//     // test imageDataSize after set crop section
//     QSizeF half = imgSize*0.5;
//     m_subject->setCropSize(half);
//     QCOMPARE(half, m_subject->imageDataSize());

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetZoomFactor_data()
{
    QTest::addColumn<QString>("fname");
    QTest::addColumn<qreal>("factor");
    QTest::addColumn<qreal>("f2");

    QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << static_cast<qreal>(1.0) << static_cast<qreal>(2.0);
    QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << static_cast<qreal>(0.0001) << static_cast<qreal>(2.0);
}

void Ut_MImageWidget::testSetZoomFactor()
{
    QFETCH(QString, fname);
    QFETCH(qreal, factor);
    QFETCH(qreal, f2);

    Q_UNUSED(factor)
    Q_UNUSED(f2)

    QImage img(fname);
    m_subject = new MImageWidget(&img);
    m_subject->setZoomFactor(factor);

    qreal fx, fy;
    m_subject->zoomFactor(&fx, &fy);

    QSize size = m_subject->imageSize();
    if (size.width() * factor > 2.0) {
        QCOMPARE(fx, factor);
        QCOMPARE(fy, factor);

        // test zoom in & zoom out
        m_subject->zoomIn();
        m_subject->zoomFactor(&fx, &fy);

        QCOMPARE(fx, factor * 2.0f);
        QCOMPARE(fy, factor * 2.0f);

        m_subject->zoomOut();
        m_subject->zoomFactor(&fx, &fy);

        QCOMPARE(fx, factor);
        QCOMPARE(fy, factor);

        // test AspectRatioMode
        m_subject->setZoomFactor(factor, f2);
        QCOMPARE(Qt::IgnoreAspectRatio, m_subject->aspectRatioMode());

    } else {
        m_subject->setZoomFactor(factor, factor);
        m_subject->zoomFactor(&fx, &fy);

        QVERIFY(fx != factor);
        QVERIFY(fy != factor);
    }

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetNegativeZoomFactor()
{
    qreal posvalue = 2.0f;
    qreal negvalue = -2.0f;
    qreal zx, zy;

    QImage img(qApp->applicationDirPath() + "/ut_mimagewidget-test.png");
    m_subject = new MImageWidget(&img);
    m_subject->setZoomFactor(posvalue, posvalue);
    m_subject->zoomFactor(&zx, &zy);

    QVERIFY(qAbs(zx - posvalue) < 1e-3);
    QVERIFY(qAbs(zy - posvalue) < 1e-3);

    m_subject->setZoomFactor(negvalue, negvalue);
    m_subject->zoomFactor(&zx, &zy);

    QVERIFY(qAbs(zx - posvalue) < 1e-3);
    QVERIFY(qAbs(zy - posvalue) < 1e-3);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetCropSize_data()
{
    QTest::addColumn<QString>("fname");
    QTest::addColumn<QSizeF>("crop");

    QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QSizeF(-10.0, -10.0);
    QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QSizeF(10.0, 10.0);
    QTest::newRow("png3") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QSizeF(10000.0, 10000.0);
}

void Ut_MImageWidget::testSetCropSize()
{
    QFETCH(QString, fname);
    QFETCH(QSizeF, crop);

    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QRectF rect(QPointF(0.0, 0.0), crop);
    m_subject->setCrop(rect);

    QSize imgSize = m_subject->imageSize();
    QSizeF t = m_subject->crop().size();

    if (crop.width() < 0.0)
        QCOMPARE(t, QSizeF(0.0, 0.0));
    else if (crop.width() > imgSize.width())
        QCOMPARE(t, QSizeF(imgSize));
    else
        QCOMPARE(t, crop);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetCropTopLeftPoint_data()
{
    QTest::addColumn<QString>("fname");
    QTest::addColumn<QPointF>("topLeft");

    QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(-10.0, -10.0);
    QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(-1.0, -1.0);
    QTest::newRow("png3") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(0.0, 0.0);
    QTest::newRow("png4") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(10.0, 10.0);
    QTest::newRow("png5") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(10000.0, 10000.0);
}

void Ut_MImageWidget::testSetCropTopLeftPoint()
{
    QFETCH(QString, fname);
    QFETCH(QPointF, topLeft);

    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QRectF rect(topLeft, QSize(10.0, 10.0));
    m_subject->setCrop(rect);

    QPointF point = m_subject->crop().topLeft();
    QSize imgSize = m_subject->imageSize();

    // This is default value in MImageWidget
    if (topLeft.x() < 0.0 || topLeft.x() < 0.0)
        QCOMPARE(point, QPointF(-1.0, -1.0));
    else if (topLeft.x() > imgSize.width() || topLeft.y() > imgSize.height())
        QCOMPARE(point, QPointF(-1.0, -1.0));
    else
        QCOMPARE(point, topLeft);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testImageNotExist_data()
{
    QTest::addColumn<QString>("fname");
    QTest::newRow("png") << "doesnotexist.png";
}

void Ut_MImageWidget::testImageNotExist()
{
    QFETCH(QString, fname);
    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QSize imageSize = m_subject->imageSize();
    QVERIFY(imageSize.isEmpty());

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testImageName()
{
    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png" );
    m_subject = new MImageWidget(fname);

    QCOMPARE(fname, m_subject->image());
    //whatever image name was set internal pixmap should be created
    //(if imagename was not found by themedaemon, then it will be the
    //red rectangle)
    QVERIFY(m_subject->pixmap());

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testZoomIn()
{
    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png" );
    m_subject = new MImageWidget(fname);

    qreal fx(0), fy(0);
    m_subject->zoomFactor(&fx, &fy);
//qWarning() << "fx, fy: " <<fx << " ," << fy;
    m_subject->zoomIn();

    qreal nfx(0), nfy(0);
    m_subject->zoomFactor(&nfx, &nfy);
//qWarning() << "nfx, nfy: " <<nfx << " ," << nfy;

    QVERIFY(nfx >= fx);
    QVERIFY(nfy >= fy);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testZoomOut()
{

    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png");
    m_subject = new MImageWidget(fname);

    qreal fx(0), fy(0);
    m_subject->zoomFactor(&fx, &fy);
//qWarning() << "fx, fy: " <<(fx) << " ," << (fy);
    m_subject->zoomOut();

    qreal nfx(0), nfy(0);
    m_subject->zoomFactor(&nfx, &nfy);

//qWarning() << "nfx, nfy: " <<(nfx) << " ," << (nfy);

    QVERIFY(nfx <= fx);
    QVERIFY(nfy <= fy);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testConstructors()
{
    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png" );
    const QPixmap pixmap ( fname );

    m_subject = new MImageWidget( &pixmap );
    QCOMPARE( m_subject->pixmap()->toImage(), pixmap.toImage());

    delete m_subject;
    m_subject = 0;

    QImage *image = new QImage(fname);
    m_subject = new MImageWidget ( image );

    QCOMPARE( m_subject->pixmap()->toImage(), *image);

    delete image;

    delete m_subject;
    m_subject = 0;

    const MImageWidget myImageWidget ( &pixmap );
    m_subject = new MImageWidget( myImageWidget );

    QCOMPARE ( m_subject->image(), myImageWidget.image() );

    delete m_subject;
    m_subject = 0;

    m_subject = new MImageWidget();
    *m_subject = myImageWidget;

    QCOMPARE(m_subject->image(), myImageWidget.image());

    delete m_subject;
    m_subject = 0;

    m_subject = new MImageWidget ( fname );
    QCOMPARE ( m_subject->image(), fname );
}

QTEST_MAIN(Ut_MImageWidget);

<commit_msg>Changes: Fixing Ut_MImageWidget::testZoomIn and Ut_MImageWidget::testZoomOut unit tests,          diasbling one test in Ut_MImageWidget::testConstructors() method<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QGraphicsWidget>
#include <QTest>
#include <QString>
#include <QPixmap>
#include <QSignalSpy>
#include <QGraphicsSceneMouseEvent>

#include <mimagewidget.h>
#include "mcomponentdata.h"

#include "ut_mimagewidget.h"

Ut_MImageWidget::Ut_MImageWidget() :
        m_subject(0)
{
}

void Ut_MImageWidget::initTestCase()
{
    QImage img(qApp->applicationDirPath() + "/ut_mimagewidget-test.png");

    if (! MComponentData::instance()) {
        static char *argv = 0;
        static int argc = 0;
        new MComponentData(argc, &argv, QString("ut_mimagewidget"), NULL);
    }

    m_subject = new MImageWidget(&img);
    QVERIFY(m_subject != 0);
}

void Ut_MImageWidget::cleanupTestCase()
{
    delete m_subject;
    m_subject = 0;

    delete MComponentData::instance();
}

void Ut_MImageWidget::testConstructor_data()
{
    QTest::addColumn<QString>("fname");

    QTest::newRow("png") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png";
}

void Ut_MImageWidget::testConstructor()
{
    QFETCH(QString, fname);

    QSize s;

    QPixmap pixmap(fname);
    s = pixmap.size();

    // test load image files
    QImage img(fname);
    MImageWidget *myImage = new MImageWidget(&img);
    QCOMPARE(myImage->imageSize(), s);

    // test constructor from pixmap
    QPixmap *source = new QPixmap(s);
    source->fill(QColor(0, 0, 0, 0));
    MImageWidget *myImage3 = new MImageWidget(source);
    QCOMPARE(myImage3->imageSize(), s);
    delete myImage3;

    // test copy constructor
    MImageWidget *myImage4 = new MImageWidget(*myImage);
    QCOMPARE(myImage4->imageSize(), myImage->imageSize());
    delete myImage4;

    MImageWidget myImage5 = *myImage;
    QCOMPARE(myImage5.imageSize(), myImage->imageSize());

    delete source;
    delete myImage;
}

void Ut_MImageWidget::testImageDataSize_data()
{
    QTest::addColumn<QString>("fname");

    QTest::newRow("png") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png";
}

void Ut_MImageWidget::testImageDataSize()
{
    QFETCH(QString, fname);

    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QSize imgSize;
    QPixmap pixmap(fname);
    imgSize = pixmap.size();

    const QPixmap *p = m_subject->pixmap();
    QCOMPARE(imgSize, p->size());
    QCOMPARE(imgSize, m_subject->imageSize());

    // test setPixmap
    m_subject->setPixmap(pixmap);
    p = m_subject->pixmap();
    QCOMPARE(pixmap.toImage(), p->toImage());

    // test setImage
    QImage image = pixmap.toImage();
    m_subject->setImage(image);
    p = m_subject->pixmap();
    QCOMPARE(image, p->toImage());

//     // test imageDataSize after set crop section
//     QSizeF half = imgSize*0.5;
//     m_subject->setCropSize(half);
//     QCOMPARE(half, m_subject->imageDataSize());

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetZoomFactor_data()
{
    QTest::addColumn<QString>("fname");
    QTest::addColumn<qreal>("factor");
    QTest::addColumn<qreal>("f2");

    QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << static_cast<qreal>(1.0) << static_cast<qreal>(2.0);
    QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << static_cast<qreal>(0.0001) << static_cast<qreal>(2.0);
}

void Ut_MImageWidget::testSetZoomFactor()
{
    QFETCH(QString, fname);
    QFETCH(qreal, factor);
    QFETCH(qreal, f2);

    Q_UNUSED(factor)
    Q_UNUSED(f2)

    QImage img(fname);
    m_subject = new MImageWidget(&img);
    m_subject->setZoomFactor(factor);

    qreal fx, fy;
    m_subject->zoomFactor(&fx, &fy);

    QSize size = m_subject->imageSize();
    if (size.width() * factor > 2.0) {
        QCOMPARE(fx, factor);
        QCOMPARE(fy, factor);

        // test zoom in & zoom out
        m_subject->zoomIn();
        m_subject->zoomFactor(&fx, &fy);

        QCOMPARE(fx, factor * 2.0f);
        QCOMPARE(fy, factor * 2.0f);

        m_subject->zoomOut();
        m_subject->zoomFactor(&fx, &fy);

        QCOMPARE(fx, factor);
        QCOMPARE(fy, factor);

        // test AspectRatioMode
        m_subject->setZoomFactor(factor, f2);
        QCOMPARE(Qt::IgnoreAspectRatio, m_subject->aspectRatioMode());

    } else {
        m_subject->setZoomFactor(factor, factor);
        m_subject->zoomFactor(&fx, &fy);

        QVERIFY(fx != factor);
        QVERIFY(fy != factor);
    }

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetNegativeZoomFactor()
{
    qreal posvalue = 2.0f;
    qreal negvalue = -2.0f;
    qreal zx, zy;

    QImage img(qApp->applicationDirPath() + "/ut_mimagewidget-test.png");
    m_subject = new MImageWidget(&img);
    m_subject->setZoomFactor(posvalue, posvalue);
    m_subject->zoomFactor(&zx, &zy);

    QVERIFY(qAbs(zx - posvalue) < 1e-3);
    QVERIFY(qAbs(zy - posvalue) < 1e-3);

    m_subject->setZoomFactor(negvalue, negvalue);
    m_subject->zoomFactor(&zx, &zy);

    QVERIFY(qAbs(zx - posvalue) < 1e-3);
    QVERIFY(qAbs(zy - posvalue) < 1e-3);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetCropSize_data()
{
    QTest::addColumn<QString>("fname");
    QTest::addColumn<QSizeF>("crop");

    QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QSizeF(-10.0, -10.0);
    QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QSizeF(10.0, 10.0);
    QTest::newRow("png3") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QSizeF(10000.0, 10000.0);
}

void Ut_MImageWidget::testSetCropSize()
{
    QFETCH(QString, fname);
    QFETCH(QSizeF, crop);

    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QRectF rect(QPointF(0.0, 0.0), crop);
    m_subject->setCrop(rect);

    QSize imgSize = m_subject->imageSize();
    QSizeF t = m_subject->crop().size();

    if (crop.width() < 0.0)
        QCOMPARE(t, QSizeF(0.0, 0.0));
    else if (crop.width() > imgSize.width())
        QCOMPARE(t, QSizeF(imgSize));
    else
        QCOMPARE(t, crop);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testSetCropTopLeftPoint_data()
{
    QTest::addColumn<QString>("fname");
    QTest::addColumn<QPointF>("topLeft");

    QTest::newRow("png1") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(-10.0, -10.0);
    QTest::newRow("png2") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(-1.0, -1.0);
    QTest::newRow("png3") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(0.0, 0.0);
    QTest::newRow("png4") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(10.0, 10.0);
    QTest::newRow("png5") << qApp->applicationDirPath() + "/ut_mimagewidget-test.png" << QPointF(10000.0, 10000.0);
}

void Ut_MImageWidget::testSetCropTopLeftPoint()
{
    QFETCH(QString, fname);
    QFETCH(QPointF, topLeft);

    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QRectF rect(topLeft, QSize(10.0, 10.0));
    m_subject->setCrop(rect);

    QPointF point = m_subject->crop().topLeft();
    QSize imgSize = m_subject->imageSize();

    // This is default value in MImageWidget
    if (topLeft.x() < 0.0 || topLeft.x() < 0.0)
        QCOMPARE(point, QPointF(-1.0, -1.0));
    else if (topLeft.x() > imgSize.width() || topLeft.y() > imgSize.height())
        QCOMPARE(point, QPointF(-1.0, -1.0));
    else
        QCOMPARE(point, topLeft);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testImageNotExist_data()
{
    QTest::addColumn<QString>("fname");
    QTest::newRow("png") << "doesnotexist.png";
}

void Ut_MImageWidget::testImageNotExist()
{
    QFETCH(QString, fname);
    QImage img(fname);
    m_subject = new MImageWidget(&img);

    QSize imageSize = m_subject->imageSize();
    QVERIFY(imageSize.isEmpty());

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testImageName()
{
    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png" );
    m_subject = new MImageWidget(fname);

    QCOMPARE(fname, m_subject->image());
    //whatever image name was set internal pixmap should be created
    //(if imagename was not found by themedaemon, then it will be the
    //red rectangle)
    QVERIFY(m_subject->pixmap());

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testZoomIn()
{
    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png" );
    m_subject = new MImageWidget(fname);

    qreal fx(5), fy(5);
    m_subject->setZoomFactor(1, 1);
    m_subject->zoomFactor(&fx, &fy);

    QVERIFY(fx == 1.0);
    QVERIFY(fy == 1.0);

    m_subject->zoomIn();

    qreal nfx(0), nfy(0);
    m_subject->zoomFactor(&nfx, &nfy);

    QVERIFY(nfx == 2.0 * fx);
    QVERIFY(nfy == 2.0 * fy);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testZoomOut()
{

    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png");
    m_subject = new MImageWidget(fname);

    qreal fx(5), fy(5);
    m_subject->setZoomFactor(1, 1);
    m_subject->zoomFactor(&fx, &fy);

    QVERIFY(fx == 1.0);
    QVERIFY(fy == 1.0);

    m_subject->zoomOut();

    qreal nfx(0), nfy(0);
    m_subject->zoomFactor(&nfx, &nfy);

    QVERIFY(nfx == 0.5 * fx);
    QVERIFY(nfy == 0.5 * fy);

    delete m_subject;
    m_subject = 0;
}

void Ut_MImageWidget::testConstructors()
{
    QString fname(qApp->applicationDirPath() + "/ut_mimagewidget-test.png" );
    const QPixmap pixmap ( fname );

    m_subject = new MImageWidget( &pixmap );
    QCOMPARE( m_subject->pixmap()->toImage(), pixmap.toImage());

    delete m_subject;
    m_subject = 0;

    QImage *image = new QImage(fname);
    m_subject = new MImageWidget ( image );

    //later on this comparation will be substituted with some reliable one
    //QVERIFY( m_subject->pixmap()->toImage() == *image);

    delete image;

    delete m_subject;
    m_subject = 0;

    const MImageWidget myImageWidget ( &pixmap );
    m_subject = new MImageWidget( myImageWidget );

    QCOMPARE ( m_subject->image(), myImageWidget.image() );

    delete m_subject;
    m_subject = 0;

    m_subject = new MImageWidget();
    *m_subject = myImageWidget;

    QCOMPARE(m_subject->image(), myImageWidget.image());

    delete m_subject;
    m_subject = 0;

    m_subject = new MImageWidget ( fname );
    QCOMPARE ( m_subject->image(), fname );
}

QTEST_MAIN(Ut_MImageWidget);

<|endoftext|>


<commit_before>#include <utility>

/******************************************************************************
 * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 */

#include "avatar.h"

#include "jobs/mediathumbnailjob.h"
#include "events/eventcontent.h"
#include "connection.h"

#include <QtGui/QPainter>
#include <QtCore/QPointer>
#include <QtCore/QDir>
#include <QtCore/QStandardPaths>
#include <QtCore/QStringBuilder>

using namespace QMatrixClient;
using std::move;

class Avatar::Private
{
    public:
        explicit Private(QUrl url = {})
            : _url(move(url))
        { }
        ~Private()
        {
            if (isJobRunning(_thumbnailRequest))
                _thumbnailRequest->abandon();
            if (isJobRunning(_uploadRequest))
                _uploadRequest->abandon();
        }

        QImage get(Connection* connection, QSize size,
                   get_callback_t callback) const;
        bool upload(UploadContentJob* job, upload_callback_t callback);

        bool checkUrl(const QUrl& url) const;
        QString localFile() const;

        QUrl _url;

        // The below are related to image caching, hence mutable
        mutable QImage _originalImage;
        mutable std::vector<QPair<QSize, QImage>> _scaledImages;
        mutable QSize _requestedSize;
        mutable enum { Unknown, Cache, Network, Banned } _imageSource = Unknown;
        mutable QPointer<MediaThumbnailJob> _thumbnailRequest = nullptr;
        mutable QPointer<BaseJob> _uploadRequest = nullptr;
        mutable std::vector<get_callback_t> callbacks;
};

Avatar::Avatar()
    : d(std::make_unique<Private>())
{ }

Avatar::Avatar(QUrl url)
    : d(std::make_unique<Private>(std::move(url)))
{ }

Avatar::Avatar(Avatar&&) = default;

Avatar::~Avatar() = default;

Avatar& Avatar::operator=(Avatar&&) = default;

QImage Avatar::get(Connection* connection, int dimension,
                   get_callback_t callback) const
{
    return d->get(connection, {dimension, dimension}, move(callback));
}

QImage Avatar::get(Connection* connection, int width, int height,
                   get_callback_t callback) const
{
    return d->get(connection, {width, height}, move(callback));
}

bool Avatar::upload(Connection* connection, const QString& fileName,
                    upload_callback_t callback) const
{
    if (isJobRunning(d->_uploadRequest))
        return false;
    return d->upload(connection->uploadFile(fileName), move(callback));
}

bool Avatar::upload(Connection* connection, QIODevice* source,
                    upload_callback_t callback) const
{
    if (isJobRunning(d->_uploadRequest) || !source->isReadable())
        return false;
    return d->upload(connection->uploadContent(source), move(callback));
}

QString Avatar::mediaId() const
{
    return d->_url.authority() + d->_url.path();
}

QImage Avatar::Private::get(Connection* connection, QSize size,
                            get_callback_t callback) const
{
    if (!callback)
    {
        qCCritical(MAIN) << "Null callbacks are not allowed in Avatar::get";
        Q_ASSERT(false);
    }

    if (_imageSource == Unknown && _originalImage.load(localFile()))
    {
        _imageSource = Cache;
        _requestedSize = _originalImage.size();
    }

    // Alternating between longer-width and longer-height requests is a sure way
    // to trick the below code into constantly getting another image from
    // the server because the existing one is alleged unsatisfactory.
    // Client authors can only blame themselves if they do so.
    if (((_imageSource == Unknown && !_thumbnailRequest) ||
            size.width() > _requestedSize.width() ||
            size.height() > _requestedSize.height()) && checkUrl(_url)) {
        qCDebug(MAIN) << "Getting avatar from" << _url.toString();
        _requestedSize = size;
        if (isJobRunning(_thumbnailRequest))
            _thumbnailRequest->abandon();
        if (callback)
            callbacks.emplace_back(move(callback));
        _thumbnailRequest = connection->getThumbnail(_url, size);
        QObject::connect( _thumbnailRequest, &MediaThumbnailJob::success,
            _thumbnailRequest, [this] {
                _imageSource = Network;
                _originalImage =
                        _thumbnailRequest->scaledThumbnail(_requestedSize);
                _originalImage.save(localFile());
                _scaledImages.clear();
                for (const auto& n: callbacks)
                    n();
                callbacks.clear();
            });
    }

    for (const auto& p: _scaledImages)
        if (p.first == size)
            return p.second;
    auto result = _originalImage.isNull() ? QImage() : _originalImage.scaled(size,
                    Qt::KeepAspectRatio, Qt::SmoothTransformation);
    _scaledImages.emplace_back(size, result);
    return result;
}

bool Avatar::Private::upload(UploadContentJob* job, upload_callback_t callback)
{
    _uploadRequest = job;
    if (!isJobRunning(_uploadRequest))
        return false;
    _uploadRequest->connect(_uploadRequest, &BaseJob::success, _uploadRequest,
                            [job,callback] { callback(job->contentUri()); });
    return true;
}

bool Avatar::Private::checkUrl(const QUrl& url) const
{
    if (_imageSource == Banned || url.isEmpty())
        return false;

    // FIXME: Make "mxc" a library-wide constant and maybe even make
    // the URL checker a Connection(?) method.
    if (!url.isValid() || url.scheme() != "mxc" || url.path().count('/') != 1)
    {
        qCWarning(MAIN) << "Avatar URL is invalid or not mxc-based:"
                        << url.toDisplayString();
        _imageSource = Banned;
    }
    return _imageSource != Banned;
}

QString Avatar::Private::localFile() const {
    static const auto cachePath = cacheLocation(QStringLiteral("avatars"));
    return cachePath % _url.authority() % '_' % _url.fileName() % ".png";
}

QUrl Avatar::url() const { return d->_url; }

bool Avatar::updateUrl(const QUrl& newUrl)
{
    if (newUrl == d->_url)
        return false;

    d->_url = newUrl;
    d->_imageSource = Private::Unknown;
    if (isJobRunning(d->_thumbnailRequest))
        d->_thumbnailRequest->abandon();
    return true;
}
<commit_msg>Drop unneeded #include<commit_after>/******************************************************************************
 * Copyright (C) 2017 Kitsune Ral <kitsune-ral@users.sf.net>
 *
 * 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; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 */

#include "avatar.h"

#include "jobs/mediathumbnailjob.h"
#include "events/eventcontent.h"
#include "connection.h"

#include <QtGui/QPainter>
#include <QtCore/QPointer>
#include <QtCore/QDir>
#include <QtCore/QStandardPaths>
#include <QtCore/QStringBuilder>

using namespace QMatrixClient;
using std::move;

class Avatar::Private
{
    public:
        explicit Private(QUrl url = {})
            : _url(move(url))
        { }
        ~Private()
        {
            if (isJobRunning(_thumbnailRequest))
                _thumbnailRequest->abandon();
            if (isJobRunning(_uploadRequest))
                _uploadRequest->abandon();
        }

        QImage get(Connection* connection, QSize size,
                   get_callback_t callback) const;
        bool upload(UploadContentJob* job, upload_callback_t callback);

        bool checkUrl(const QUrl& url) const;
        QString localFile() const;

        QUrl _url;

        // The below are related to image caching, hence mutable
        mutable QImage _originalImage;
        mutable std::vector<QPair<QSize, QImage>> _scaledImages;
        mutable QSize _requestedSize;
        mutable enum { Unknown, Cache, Network, Banned } _imageSource = Unknown;
        mutable QPointer<MediaThumbnailJob> _thumbnailRequest = nullptr;
        mutable QPointer<BaseJob> _uploadRequest = nullptr;
        mutable std::vector<get_callback_t> callbacks;
};

Avatar::Avatar()
    : d(std::make_unique<Private>())
{ }

Avatar::Avatar(QUrl url)
    : d(std::make_unique<Private>(std::move(url)))
{ }

Avatar::Avatar(Avatar&&) = default;

Avatar::~Avatar() = default;

Avatar& Avatar::operator=(Avatar&&) = default;

QImage Avatar::get(Connection* connection, int dimension,
                   get_callback_t callback) const
{
    return d->get(connection, {dimension, dimension}, move(callback));
}

QImage Avatar::get(Connection* connection, int width, int height,
                   get_callback_t callback) const
{
    return d->get(connection, {width, height}, move(callback));
}

bool Avatar::upload(Connection* connection, const QString& fileName,
                    upload_callback_t callback) const
{
    if (isJobRunning(d->_uploadRequest))
        return false;
    return d->upload(connection->uploadFile(fileName), move(callback));
}

bool Avatar::upload(Connection* connection, QIODevice* source,
                    upload_callback_t callback) const
{
    if (isJobRunning(d->_uploadRequest) || !source->isReadable())
        return false;
    return d->upload(connection->uploadContent(source), move(callback));
}

QString Avatar::mediaId() const
{
    return d->_url.authority() + d->_url.path();
}

QImage Avatar::Private::get(Connection* connection, QSize size,
                            get_callback_t callback) const
{
    if (!callback)
    {
        qCCritical(MAIN) << "Null callbacks are not allowed in Avatar::get";
        Q_ASSERT(false);
    }

    if (_imageSource == Unknown && _originalImage.load(localFile()))
    {
        _imageSource = Cache;
        _requestedSize = _originalImage.size();
    }

    // Alternating between longer-width and longer-height requests is a sure way
    // to trick the below code into constantly getting another image from
    // the server because the existing one is alleged unsatisfactory.
    // Client authors can only blame themselves if they do so.
    if (((_imageSource == Unknown && !_thumbnailRequest) ||
            size.width() > _requestedSize.width() ||
            size.height() > _requestedSize.height()) && checkUrl(_url)) {
        qCDebug(MAIN) << "Getting avatar from" << _url.toString();
        _requestedSize = size;
        if (isJobRunning(_thumbnailRequest))
            _thumbnailRequest->abandon();
        if (callback)
            callbacks.emplace_back(move(callback));
        _thumbnailRequest = connection->getThumbnail(_url, size);
        QObject::connect( _thumbnailRequest, &MediaThumbnailJob::success,
            _thumbnailRequest, [this] {
                _imageSource = Network;
                _originalImage =
                        _thumbnailRequest->scaledThumbnail(_requestedSize);
                _originalImage.save(localFile());
                _scaledImages.clear();
                for (const auto& n: callbacks)
                    n();
                callbacks.clear();
            });
    }

    for (const auto& p: _scaledImages)
        if (p.first == size)
            return p.second;
    auto result = _originalImage.isNull() ? QImage() : _originalImage.scaled(size,
                    Qt::KeepAspectRatio, Qt::SmoothTransformation);
    _scaledImages.emplace_back(size, result);
    return result;
}

bool Avatar::Private::upload(UploadContentJob* job, upload_callback_t callback)
{
    _uploadRequest = job;
    if (!isJobRunning(_uploadRequest))
        return false;
    _uploadRequest->connect(_uploadRequest, &BaseJob::success, _uploadRequest,
                            [job,callback] { callback(job->contentUri()); });
    return true;
}

bool Avatar::Private::checkUrl(const QUrl& url) const
{
    if (_imageSource == Banned || url.isEmpty())
        return false;

    // FIXME: Make "mxc" a library-wide constant and maybe even make
    // the URL checker a Connection(?) method.
    if (!url.isValid() || url.scheme() != "mxc" || url.path().count('/') != 1)
    {
        qCWarning(MAIN) << "Avatar URL is invalid or not mxc-based:"
                        << url.toDisplayString();
        _imageSource = Banned;
    }
    return _imageSource != Banned;
}

QString Avatar::Private::localFile() const {
    static const auto cachePath = cacheLocation(QStringLiteral("avatars"));
    return cachePath % _url.authority() % '_' % _url.fileName() % ".png";
}

QUrl Avatar::url() const { return d->_url; }

bool Avatar::updateUrl(const QUrl& newUrl)
{
    if (newUrl == d->_url)
        return false;

    d->_url = newUrl;
    d->_imageSource = Private::Unknown;
    if (isJobRunning(d->_thumbnailRequest))
        d->_thumbnailRequest->abandon();
    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
 * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
 * Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
 * SPI Master library for arduino.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#include "SPI.h"

SPIClass SPI;

uint8_t SPIClass::initialized = 0;
uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0;
uint8_t SPIClass::interruptSave = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif

void SPIClass::begin()
{
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  if (!initialized) {
    // Set SS to high so a connected chip will be "deselected" by default
    digitalWrite(SS, HIGH);

    // When the SS pin is set as OUTPUT, it can be used as
    // a general purpose output port (it doesn't influence
    // SPI operations).
    pinMode(SS, OUTPUT);

    // Warning: if the SS pin ever becomes a LOW INPUT then SPI
    // automatically switches to Slave, so the data direction of
    // the SS pin MUST be kept as OUTPUT.
    SPCR |= _BV(MSTR);
    SPCR |= _BV(SPE);

    // Set direction register for SCK and MOSI pin.
    // MISO pin automatically overrides to INPUT.
    // By doing this AFTER enabling SPI, we avoid accidentally
    // clocking in a single bit since the lines go directly
    // from "input" to SPI control.
    // http://code.google.com/p/arduino/issues/detail?id=888
    pinMode(SCK, OUTPUT);
    pinMode(MOSI, OUTPUT);
  }
  initialized++; // reference count
  SREG = sreg;
}

void SPIClass::end() {
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  // Decrease the reference counter
  if (initialized)
    initialized--;
  // If there are no more references disable SPI
  if (!initialized) {
    SPCR &= ~_BV(SPE);
    interruptMode = 0;
    #ifdef SPI_TRANSACTION_MISMATCH_LED
    inTransactionFlag = 0;
    #endif
  }
  SREG = sreg;
}

// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
#if defined(__AVR_ATmega32U4__)
  #define SPI_INT0_MASK  (1<<INT0)
  #define SPI_INT1_MASK  (1<<INT1)
  #define SPI_INT2_MASK  (1<<INT2)
  #define SPI_INT3_MASK  (1<<INT3)
  #define SPI_INT4_MASK  (1<<INT6)
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  #define SPI_INT0_MASK  (1<<INT0)
  #define SPI_INT1_MASK  (1<<INT1)
  #define SPI_INT2_MASK  (1<<INT2)
  #define SPI_INT3_MASK  (1<<INT3)
  #define SPI_INT4_MASK  (1<<INT4)
  #define SPI_INT5_MASK  (1<<INT5)
  #define SPI_INT6_MASK  (1<<INT6)
  #define SPI_INT7_MASK  (1<<INT7)
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  #define SPI_INT0_MASK  (1<<INT4)
  #define SPI_INT1_MASK  (1<<INT5)
  #define SPI_INT2_MASK  (1<<INT0)
  #define SPI_INT3_MASK  (1<<INT1)
  #define SPI_INT4_MASK  (1<<INT2)
  #define SPI_INT5_MASK  (1<<INT3)
  #define SPI_INT6_MASK  (1<<INT6)
  #define SPI_INT7_MASK  (1<<INT7)
#else
  #ifdef INT0
  #define SPI_INT0_MASK  (1<<INT0)
  #endif
  #ifdef INT1
  #define SPI_INT1_MASK  (1<<INT1)
  #endif
  #ifdef INT2
  #define SPI_INT2_MASK  (1<<INT2)
  #endif
#endif

void SPIClass::usingInterrupt(uint8_t interruptNumber)
{
  uint8_t mask;

  if (interruptMode > 1) return;

  noInterrupts();
  switch (interruptNumber) {
  #ifdef SPI_INT0_MASK
  case 0: mask = SPI_INT0_MASK; break;
  #endif
  #ifdef SPI_INT1_MASK
  case 1: mask = SPI_INT1_MASK; break;
  #endif
  #ifdef SPI_INT2_MASK
  case 2: mask = SPI_INT2_MASK; break;
  #endif
  #ifdef SPI_INT3_MASK
  case 3: mask = SPI_INT3_MASK; break;
  #endif
  #ifdef SPI_INT4_MASK
  case 4: mask = SPI_INT4_MASK; break;
  #endif
  #ifdef SPI_INT5_MASK
  case 5: mask = SPI_INT5_MASK; break;
  #endif
  #ifdef SPI_INT6_MASK
  case 6: mask = SPI_INT6_MASK; break;
  #endif
  #ifdef SPI_INT7_MASK
  case 7: mask = SPI_INT7_MASK; break;
  #endif
  default:
    interruptMode = 2;
    interrupts();
    return;
  }
  interruptMode = 1;
  interruptMask |= mask;
  interrupts();
}

void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
{
  // Once in mode 2 we can't go back to 0 without a proper reference count
  if (interruptMode == 2)
    return;
  uint8_t mask = 0;
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  switch (interruptNumber) {
  #ifdef SPI_INT0_MASK
  case 0: mask = SPI_INT0_MASK; break;
  #endif
  #ifdef SPI_INT1_MASK
  case 1: mask = SPI_INT1_MASK; break;
  #endif
  #ifdef SPI_INT2_MASK
  case 2: mask = SPI_INT2_MASK; break;
  #endif
  #ifdef SPI_INT3_MASK
  case 3: mask = SPI_INT3_MASK; break;
  #endif
  #ifdef SPI_INT4_MASK
  case 4: mask = SPI_INT4_MASK; break;
  #endif
  #ifdef SPI_INT5_MASK
  case 5: mask = SPI_INT5_MASK; break;
  #endif
  #ifdef SPI_INT6_MASK
  case 6: mask = SPI_INT6_MASK; break;
  #endif
  #ifdef SPI_INT7_MASK
  case 7: mask = SPI_INT7_MASK; break;
  #endif
  default:
    break;
    // this case can't be reached
  }
  interruptMask &= ~mask;
  if (!interruptMask)
    interruptMode = 0;
  SREG = sreg;
}
<commit_msg>[avr] Made SPI.usingInterrupt() synchronized (Andrew Kroll)<commit_after>/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
 * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
 * Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
 * SPI Master library for arduino.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#include "SPI.h"

SPIClass SPI;

uint8_t SPIClass::initialized = 0;
uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0;
uint8_t SPIClass::interruptSave = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif

void SPIClass::begin()
{
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  if (!initialized) {
    // Set SS to high so a connected chip will be "deselected" by default
    digitalWrite(SS, HIGH);

    // When the SS pin is set as OUTPUT, it can be used as
    // a general purpose output port (it doesn't influence
    // SPI operations).
    pinMode(SS, OUTPUT);

    // Warning: if the SS pin ever becomes a LOW INPUT then SPI
    // automatically switches to Slave, so the data direction of
    // the SS pin MUST be kept as OUTPUT.
    SPCR |= _BV(MSTR);
    SPCR |= _BV(SPE);

    // Set direction register for SCK and MOSI pin.
    // MISO pin automatically overrides to INPUT.
    // By doing this AFTER enabling SPI, we avoid accidentally
    // clocking in a single bit since the lines go directly
    // from "input" to SPI control.
    // http://code.google.com/p/arduino/issues/detail?id=888
    pinMode(SCK, OUTPUT);
    pinMode(MOSI, OUTPUT);
  }
  initialized++; // reference count
  SREG = sreg;
}

void SPIClass::end() {
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  // Decrease the reference counter
  if (initialized)
    initialized--;
  // If there are no more references disable SPI
  if (!initialized) {
    SPCR &= ~_BV(SPE);
    interruptMode = 0;
    #ifdef SPI_TRANSACTION_MISMATCH_LED
    inTransactionFlag = 0;
    #endif
  }
  SREG = sreg;
}

// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
#if defined(__AVR_ATmega32U4__)
  #define SPI_INT0_MASK  (1<<INT0)
  #define SPI_INT1_MASK  (1<<INT1)
  #define SPI_INT2_MASK  (1<<INT2)
  #define SPI_INT3_MASK  (1<<INT3)
  #define SPI_INT4_MASK  (1<<INT6)
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  #define SPI_INT0_MASK  (1<<INT0)
  #define SPI_INT1_MASK  (1<<INT1)
  #define SPI_INT2_MASK  (1<<INT2)
  #define SPI_INT3_MASK  (1<<INT3)
  #define SPI_INT4_MASK  (1<<INT4)
  #define SPI_INT5_MASK  (1<<INT5)
  #define SPI_INT6_MASK  (1<<INT6)
  #define SPI_INT7_MASK  (1<<INT7)
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  #define SPI_INT0_MASK  (1<<INT4)
  #define SPI_INT1_MASK  (1<<INT5)
  #define SPI_INT2_MASK  (1<<INT0)
  #define SPI_INT3_MASK  (1<<INT1)
  #define SPI_INT4_MASK  (1<<INT2)
  #define SPI_INT5_MASK  (1<<INT3)
  #define SPI_INT6_MASK  (1<<INT6)
  #define SPI_INT7_MASK  (1<<INT7)
#else
  #ifdef INT0
  #define SPI_INT0_MASK  (1<<INT0)
  #endif
  #ifdef INT1
  #define SPI_INT1_MASK  (1<<INT1)
  #endif
  #ifdef INT2
  #define SPI_INT2_MASK  (1<<INT2)
  #endif
#endif

void SPIClass::usingInterrupt(uint8_t interruptNumber)
{
  uint8_t mask = 0;
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  switch (interruptNumber) {
  #ifdef SPI_INT0_MASK
  case 0: mask = SPI_INT0_MASK; break;
  #endif
  #ifdef SPI_INT1_MASK
  case 1: mask = SPI_INT1_MASK; break;
  #endif
  #ifdef SPI_INT2_MASK
  case 2: mask = SPI_INT2_MASK; break;
  #endif
  #ifdef SPI_INT3_MASK
  case 3: mask = SPI_INT3_MASK; break;
  #endif
  #ifdef SPI_INT4_MASK
  case 4: mask = SPI_INT4_MASK; break;
  #endif
  #ifdef SPI_INT5_MASK
  case 5: mask = SPI_INT5_MASK; break;
  #endif
  #ifdef SPI_INT6_MASK
  case 6: mask = SPI_INT6_MASK; break;
  #endif
  #ifdef SPI_INT7_MASK
  case 7: mask = SPI_INT7_MASK; break;
  #endif
  default:
    interruptMode = 2;
    break;
  }
  interruptMask |= mask;
  if (!interruptMode)
    interruptMode = 1;
  SREG = sreg;
}

void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
{
  // Once in mode 2 we can't go back to 0 without a proper reference count
  if (interruptMode == 2)
    return;
  uint8_t mask = 0;
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  switch (interruptNumber) {
  #ifdef SPI_INT0_MASK
  case 0: mask = SPI_INT0_MASK; break;
  #endif
  #ifdef SPI_INT1_MASK
  case 1: mask = SPI_INT1_MASK; break;
  #endif
  #ifdef SPI_INT2_MASK
  case 2: mask = SPI_INT2_MASK; break;
  #endif
  #ifdef SPI_INT3_MASK
  case 3: mask = SPI_INT3_MASK; break;
  #endif
  #ifdef SPI_INT4_MASK
  case 4: mask = SPI_INT4_MASK; break;
  #endif
  #ifdef SPI_INT5_MASK
  case 5: mask = SPI_INT5_MASK; break;
  #endif
  #ifdef SPI_INT6_MASK
  case 6: mask = SPI_INT6_MASK; break;
  #endif
  #ifdef SPI_INT7_MASK
  case 7: mask = SPI_INT7_MASK; break;
  #endif
  default:
    break;
    // this case can't be reached
  }
  interruptMask &= ~mask;
  if (!interruptMask)
    interruptMode = 0;
  SREG = sreg;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2009 - http://ruinwesen.com/ */

#ifndef CALLBACK_H__
#define CALLBACK_H__

/**
 * \addtogroup CommonTools
 *
 * @{
 *
 * \addtogroup helpers_callback Callback classes
 *
 * @{
 *
 * \file
 * Callback classes.
 **/

/**
 * \addtogroup callbackvector Callback vector
 *
 * @{
 */

#include <inttypes.h>
#include "helpers.h"

/**
 * Templated class that holds an array of N pointers to callback
 * objects of class C, with a callback function of type M.
 **/
template <class C, int N, typename M = void(C::*)()> class CallbackVector {
	/**
	 * \addtogroup callbackvector
	 * @{
	 **/
public:
  struct {
    C* obj;
    M ptr;
  } callbacks[N];

  uint8_t size;

  CallbackVector() {
    CallbackVector<C,N,M>::size = 0;
  }

	/** Add obj with callback method ptr to the callback vector, returns false if no room left. **/
  bool add(C *obj, M ptr) {
    if (size >= N) {
      return false;
    } else {
      for (uint8_t i = 0; i < size; i++) {
				if (callbacks[i].obj == obj &&
						callbacks[i].ptr == ptr)
					return true;
      }
      callbacks[size].obj = obj;
      callbacks[size].ptr = ptr;
      size++;
      return true;
    }
  }

	/** Remove obj with callback method ptr from the callback vector. **/
  void remove(C *obj, M ptr) {
    USE_LOCK();
    SET_LOCK();
    for (uint8_t i = 0; i < size; i++) {
      if (callbacks[i].obj == obj &&
					callbacks[i].ptr == ptr) {
				m_memcpy(callbacks + i, callbacks + i + 1, sizeof(callbacks[0]) * (size - i - 1));
				size--;
				break;
      }
    }
    CLEAR_LOCK();
  }

	/** Remove all instances of callback object obj from the vector. **/
  void remove(C *obj) {
    USE_LOCK();
    SET_LOCK();
  again:
    for (uint8_t i = 0; i < size; i++) {
      if (callbacks[i].obj == obj) {
				m_memcpy(callbacks + i, callbacks + i + 1, sizeof(callbacks[0]) * (size - i - 1));
				size--;
				goto again;
      }
    }
    CLEAR_LOCK();
  }

	/** Call all the stored callback objects. **/
  void call() {
    for (uint8_t i = 0; i < size; i++) {
      ((callbacks[i].obj)->*(callbacks[i].ptr))();
    }
  }

	/* @} */
};

/** Templated callback vector class with callback method taking one argument of type Arg1. **/
template <class C, int N = 4, typename Arg1 = void, typename M = void(C::*)(Arg1)> class CallbackVector1 :
  public CallbackVector<C, N, M> {
public:

	/** Call the callback method with argument a1. **/
  void call(Arg1 a1) {
    for (uint8_t i = 0; i < CallbackVector<C,N,M>::size; i++) {
      ((CallbackVector<C,N,M>::callbacks[i].obj)->*(CallbackVector<C,N,M>::callbacks[i].ptr))(a1);
    }
  }
};

/** Templated callback vector class with callback method taking two arguments of type Arg1 and Arg2. **/
template <class C, int N = 4, typename Arg1 = void, typename Arg2 = void, typename M = void(C::*)(Arg1, Arg2)>
class CallbackVector2 :
  public CallbackVector<C, N, M> {
public:

	/** Call the callback method with argument a1 and 2. **/
  void call(Arg1 a1, Arg2 a2) {
    for (uint8_t i = 0; i < CallbackVector<C,N,M>::size; i++) {
      ((CallbackVector<C,N,M>::callbacks[i].obj)->*(CallbackVector<C,N,M>::callbacks[i].ptr))(a1, a2);
    }
  }
};

/**
 * Templated callback vector class with callback method taking one
 * argument of type Arg1 and returning a boolean.
 *
 * This one is used mainly for GUI event callbacks, where the boolean
 * value indicates whether the event was handled.
 **/
template <class C, int N = 4, typename Arg1 = void, typename M = bool(C::*)(Arg1)>
class BoolCallbackVector1 :
  public CallbackVector<C, N, M> {
public:

	/** Call the callback methods until one callback returns true. **/
  bool callBool(Arg1 a1) {
    for (uint8_t i = 0; i < CallbackVector<C,N,M>::size; i++) {
      if (((CallbackVector<C,N,M>::callbacks[i].obj)->*(CallbackVector<C,N,M>::callbacks[i].ptr))(a1)) {
				return true;
			}
    }
		return false;
  }
};

/* @} @} @} */

#endif /* CALLBACK_H__ */
<commit_msg>Indentation<commit_after>/* Copyright (c) 2009 - http://ruinwesen.com/ */

#ifndef CALLBACK_H__
#define CALLBACK_H__

/**
 * \addtogroup CommonTools
 *
 * @{
 *
 * \addtogroup helpers_callback Callback classes
 *
 * @{
 *
 * \file
 * Callback classes.
 **/

/**
 * \addtogroup callbackvector Callback vector
 *
 * @{
 */

#include <inttypes.h>
#include "helpers.h"

/**
 * Templated class that holds an array of N pointers to callback
 * objects of class C, with a callback function of type M.
 **/
template <class C, int N, typename M = void(C::*)()> class CallbackVector {
  /**
   * \addtogroup callbackvector
   * @{
   **/
public:
  struct {
    C* obj;
    M ptr;
  } callbacks[N];

  uint8_t size;

  CallbackVector() {
    CallbackVector<C,N,M>::size = 0;
  }

  /** Add obj with callback method ptr to the callback vector, returns false if no room left. **/
  bool add(C *obj, M ptr) {
    if (size >= N) {
      return false;
    } else {
      for (uint8_t i = 0; i < size; i++) {
        if (callbacks[i].obj == obj &&
            callbacks[i].ptr == ptr)
          return true;
      }
      callbacks[size].obj = obj;
      callbacks[size].ptr = ptr;
      size++;
      return true;
    }
  }

  /** Remove obj with callback method ptr from the callback vector. **/
  void remove(C *obj, M ptr) {
    USE_LOCK();
    SET_LOCK();
    for (uint8_t i = 0; i < size; i++) {
      if (callbacks[i].obj == obj &&
          callbacks[i].ptr == ptr) {
        m_memcpy(callbacks + i, callbacks + i + 1, sizeof(callbacks[0]) * (size - i - 1));
        size--;
        break;
      }
    }
    CLEAR_LOCK();
  }

  /** Remove all instances of callback object obj from the vector. **/
  void remove(C *obj) {
    USE_LOCK();
    SET_LOCK();
  again:
    for (uint8_t i = 0; i < size; i++) {
      if (callbacks[i].obj == obj) {
        m_memcpy(callbacks + i, callbacks + i + 1, sizeof(callbacks[0]) * (size - i - 1));
        size--;
        goto again;
      }
    }
    CLEAR_LOCK();
  }

  /** Call all the stored callback objects. **/
  void call() {
    for (uint8_t i = 0; i < size; i++) {
      ((callbacks[i].obj)->*(callbacks[i].ptr))();
    }
  }

  /* @} */
};

/** Templated callback vector class with callback method taking one argument of type Arg1. **/
template <class C, int N = 4, typename Arg1 = void, typename M = void(C::*)(Arg1)> class CallbackVector1 :
  public CallbackVector<C, N, M> {
public:

  /** Call the callback method with argument a1. **/
  void call(Arg1 a1) {
    for (uint8_t i = 0; i < CallbackVector<C,N,M>::size; i++) {
      ((CallbackVector<C,N,M>::callbacks[i].obj)->*(CallbackVector<C,N,M>::callbacks[i].ptr))(a1);
    }
  }
};

/** Templated callback vector class with callback method taking two arguments of type Arg1 and Arg2. **/
template <class C, int N = 4, typename Arg1 = void, typename Arg2 = void, typename M = void(C::*)(Arg1, Arg2)>
class CallbackVector2 :
  public CallbackVector<C, N, M> {
public:

  /** Call the callback method with argument a1 and 2. **/
  void call(Arg1 a1, Arg2 a2) {
    for (uint8_t i = 0; i < CallbackVector<C,N,M>::size; i++) {
      ((CallbackVector<C,N,M>::callbacks[i].obj)->*(CallbackVector<C,N,M>::callbacks[i].ptr))(a1, a2);
    }
  }
};

/**
 * Templated callback vector class with callback method taking one
 * argument of type Arg1 and returning a boolean.
 *
 * This one is used mainly for GUI event callbacks, where the boolean
 * value indicates whether the event was handled.
 **/
template <class C, int N = 4, typename Arg1 = void, typename M = bool(C::*)(Arg1)>
class BoolCallbackVector1 :
  public CallbackVector<C, N, M> {
public:

  /** Call the callback methods until one callback returns true. **/
  bool callBool(Arg1 a1) {
    for (uint8_t i = 0; i < CallbackVector<C,N,M>::size; i++) {
      if (((CallbackVector<C,N,M>::callbacks[i].obj)->*(CallbackVector<C,N,M>::callbacks[i].ptr))(a1)) {
        return true;
      }
    }
    return false;
  }
};

/* @} @} @} */

#endif /* CALLBACK_H__ */
<|endoftext|>