<commit_before>#include "ros/ros.h"
#include "std_msgs/Time.h"
#include "std_msgs/Float32.h"
#include "std_msgs/UInt32.h"
#include "geometry_msgs/Quaternion.h"
#include "geometry_msgs/Point.h"
#include "geometry_msgs/Pose.h"
#include "sensor_msgs/LaserScan.h"
#include "nav_msgs/MapMetaData.h"
#include "nav_msgs/OccupancyGrid.h"
#include <sstream>
#include "math.h"
#include "stdio.h"

class oGridMaker {
	private:
		ros::NodeHandle n;
		ros::Publisher mapper_pub;
		ros::Subscriber sub;
		nav_msgs::MapMetaData mmd;
		nav_msgs::OccupancyGrid mapGrid;
	public:
		oGridMaker(ros::NodeHandle &nh)
		{
			n = nh;
            mapper_pub = n.advertise<nav_msgs::OccupancyGrid>("map_eric", 10, true);

			// or this->scannerCallBack
            sub = n.subscribe("scan", 10, &oGridMaker::scannerCallBack, this);

            //make map meta data
            mmd.map_load_time = ros::Time::now();
            mmd.resolution = 1.0;
            mmd.width = 10;
            mmd.height = 5;
            mmd.origin = createPose();

            mapGrid.info = mmd;
            for (int i=0;i++;i<50)
            {
                mapGrid.data[i] = -1;
            }

		}

        geometry_msgs::Pose createPose()
        {
            geometry_msgs::Point thisp;
            thisp.x = -1.0;
            thisp.y = -5.0;
            thisp.z = 0.0;

            geometry_msgs::Quaternion thisq;
            thisq.x = 0.0;
            thisq.y = 0.0;
            thisq.z = 0.0;
            thisq.w = 0.0;

            geometry_msgs::Pose thispose;
            thispose.position = thisp;
            thispose.orientation = thisq;

            return thispose;
        }

		//this is where the work gets done
        void OGridFromLScan(const sensor_msgs::LaserScan::ConstPtr& msg)
		{
            //update time
            this->mmd.map_load_time = msg->header.stamp;

            //angle to this scan, with distance, should determine which tiles it hit on as filled
              //number of
            for (int i=0;i++;i < msg->ranges.size())
            {
                float thisangle = msg->angle_min + i*msg->angle_increment;
                float thisrange = msg->ranges[i];
                float x = sin(thisangle)*thisrange;
                float y = cos(thisangle)*thisrange;

                x = x + 1.0;
                y = y + 5.0;
                int ix = int(x);
                int iy = int(y);

                //find the position on the occupancy grid
                updatePosOccGrid(ix,iy);

                //downgrade grids between that range and my position
                updateNegOccGrid(thisrange,thisangle);
            }
            this->mapGrid.info = this->mmd;

		}

        void updatePosOccGrid(int x, int y)
        {
          updateOccGrid(x,y,1);
        }

        void updateNegOccGrid(float range, float angle)
        {
           //subtract confidence from grids between that grid and my position

            //get the new range (subtract one grid length from my range based on the angle)
            float subd = 1.0 / sin(angle);
            range -= subd;

            float x = sin(angle)*range;
            float y = cos(angle)*range;

            x = x + 1.0;
            y = y + 5.0;
            int ix = int(x);
            int iy = int(y);

            //this grid is between the hit range and my position, so I think it is empty
            updateOccGrid(ix,iy,-1);

            //recursively call until I get to my position
            if (ix > 1 && iy > 5)
            {
                updateNegOccGrid(range,angle);
            }

        }

        void updateOccGrid(int x, int y, int change)
        {
           //add confidence to grid that range hit in
           int grid = x*10 + y;
           this->mapGrid.data[grid] += change;
           if (this->mapGrid.data[grid] > 100)
           {
               this->mapGrid.data[grid] = 100;
           }
           else if (this->mapGrid.data[grid] < 0)
           {
               this->mapGrid.data[grid] = 0;
           }
        }

        void scannerCallBack(const sensor_msgs::LaserScan::ConstPtr& msg)
		{
	  		//Figure out if I need to use another pointer for this msg

            OGridFromLScan(msg);

	  		mapper_pub.publish(mapGrid);

		}

};

int main(int argc, char **argv)
{

  	ros::init(argc, argv, "scantomap");

  	ros::NodeHandle nh;

	oGridMaker ogm(nh);

  	//ogmaker.initialize(nh);

  	//ros::Publisher chatter_pub = n.advertise<nav_msgs::OccupancyGrid>("map_data", 1, true);

  	//ros::Subscriber sub = n.subscribe("scan_data", 10, chatterCallback);

  	ros::spin();

  return 0;
}
<commit_msg>still not working, going to start echoing debug messages<commit_after>#include "ros/ros.h"
#include "std_msgs/Time.h"
#include "std_msgs/Float32.h"
#include "std_msgs/UInt32.h"
#include "geometry_msgs/Quaternion.h"
#include "geometry_msgs/Point.h"
#include "geometry_msgs/Pose.h"
#include "sensor_msgs/LaserScan.h"
#include "nav_msgs/MapMetaData.h"
#include "nav_msgs/OccupancyGrid.h"
#include <sstream>
#include "math.h"
#include "stdio.h"

class oGridMaker {
	private:
		ros::NodeHandle n;
		ros::Publisher mapper_pub;
		ros::Subscriber sub;
		nav_msgs::MapMetaData mmd;
		nav_msgs::OccupancyGrid mapGrid;
	public:
		oGridMaker(ros::NodeHandle &nh)
		{
			n = nh;
            mapper_pub = n.advertise<nav_msgs::OccupancyGrid>("map_eric", 10, true);

			// or this->scannerCallBack
            sub = n.subscribe("scan", 10, &oGridMaker::scannerCallBack, this);

            //make map meta data
            mmd.map_load_time = ros::Time::now();
            mmd.resolution = 1.0;
            mmd.width = 10;
            mmd.height = 5;
            mmd.origin = createPose();

            mapGrid.info = mmd;
            for (int i=0;i++;i < (this->mmd.width * this->mmd.height))
            {
                mapGrid.data[i] = -1;
            }

		}

        geometry_msgs::Pose createPose()
        {
            geometry_msgs::Point thisp;
            thisp.x = -1.0;
            thisp.y = -5.0;
            thisp.z = 0.0;

            geometry_msgs::Quaternion thisq;
            thisq.x = 0.0;
            thisq.y = 0.0;
            thisq.z = 0.0;
            thisq.w = 0.0;

            geometry_msgs::Pose thispose;
            thispose.position = thisp;
            thispose.orientation = thisq;

            return thispose;
        }

		//this is where the work gets done
        void OGridFromLScan(const sensor_msgs::LaserScan::ConstPtr& msg)
		{
            //update time
            this->mmd.map_load_time = msg->header.stamp;

            //angle to this scan, with distance, should determine which tiles it hit on as filled
              //number of
            for (int i=0;i++;i < msg->ranges.size())
            {
                float thisangle = msg->angle_min + i*msg->angle_increment;
                float thisrange = msg->ranges[i];
                float x = sin(thisangle)*thisrange;
                float y = cos(thisangle)*thisrange;

                x = x + 1.0;
                y = y + 5.0;
                int ix = int(x);
                int iy = int(y);

                //find the position on the occupancy grid
                updatePosOccGrid(ix,iy);

                //downgrade grids between that range and my position
                updateNegOccGrid(thisrange,thisangle);
            }
            this->mapGrid.info = this->mmd;

		}

        void updatePosOccGrid(int x, int y)
        {
          updateOccGrid(x,y,1);
        }

        void updateNegOccGrid(float range, float angle)
        {
           //subtract confidence from grids between that grid and my position

            //get the new range (subtract one grid length from my range based on the angle)
            float subd = 1.0 / sin(angle);
            range -= subd;

            float x = sin(angle)*range;
            float y = cos(angle)*range;

            x = x + 1.0;
            y = y + 5.0;
            int ix = int(x);
            int iy = int(y);

            //this grid is between the hit range and my position, so I think it is empty
            updateOccGrid(ix,iy,-1);

            //recursively call until I get to my position
            if (ix > 1 && iy > 5)
            {
                updateNegOccGrid(range,angle);
            }

        }

        void updateOccGrid(int x, int y, int change)
        {
           //add confidence to grid that range hit in
           int grid = x*10 + y;
           this->mapGrid.data[grid] += change;
           if (this->mapGrid.data[grid] > 100)
           {
               this->mapGrid.data[grid] = 100;
           }
           else if (this->mapGrid.data[grid] < 0)
           {
               this->mapGrid.data[grid] = 0;
           }
        }

        void scannerCallBack(const sensor_msgs::LaserScan::ConstPtr& msg)
		{
	  		//Figure out if I need to use another pointer for this msg

            OGridFromLScan(msg);

	  		mapper_pub.publish(mapGrid);

		}

};

int main(int argc, char **argv)
{

  	ros::init(argc, argv, "scantomap");

  	ros::NodeHandle nh;

	oGridMaker ogm(nh);

  	//ogmaker.initialize(nh);

  	//ros::Publisher chatter_pub = n.advertise<nav_msgs::OccupancyGrid>("map_data", 1, true);

  	//ros::Subscriber sub = n.subscribe("scan_data", 10, chatterCallback);

  	ros::spin();

  return 0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *       Miklos Vajna <vmiklos@frugalware.org>
 * Portions created by the Initial Developer are Copyright (C) 2011 the
 * Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

#include <sal/cppunit.h>

#include <cppuhelper/bootstrap.hxx>
#include <comphelper/processfactory.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/document/XFilter.hpp>

#include <osl/file.hxx>
#include <osl/process.h>

#include <vcl/svapp.hxx>
#include <ucbhelper/contentbroker.hxx>

using namespace ::com::sun::star;

class RtfTest : public CppUnit::TestFixture
{
public:
    RtfTest();
    ~RtfTest();

    virtual void setUp();
    virtual void tearDown();

    void recursiveScan(const rtl::OUString &rURL, bool bExpected);
    bool load(const rtl::OUString &rURL);
    void test();

    CPPUNIT_TEST_SUITE(RtfTest);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();
private:
    uno::Reference<uno::XComponentContext> m_xContext;
    uno::Reference<lang::XMultiComponentFactory> m_xFactory;
    uno::Reference<lang::XMultiServiceFactory> m_xMSF;
    uno::Reference<document::XFilter> m_xFilter;

    ::rtl::OUString m_aSrcRoot;
    int m_nLoadedDocs;
};

RtfTest::RtfTest()
    : m_aSrcRoot(RTL_CONSTASCII_USTRINGPARAM("file://")),
    m_nLoadedDocs(0)
{
    m_xContext = cppu::defaultBootstrap_InitialComponentContext();
    m_xFactory = m_xContext->getServiceManager();
    m_xMSF = uno::Reference<lang::XMultiServiceFactory>(m_xFactory, uno::UNO_QUERY_THROW);
    m_xFilter = uno::Reference< document::XFilter >(m_xMSF->createInstance(
        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Writer.RtfFilter"))),
        uno::UNO_QUERY_THROW);

    const char* pSrcRoot = getenv( "SRC_ROOT" );
    CPPUNIT_ASSERT_MESSAGE("SRC_ROOT env variable not set", pSrcRoot != NULL && pSrcRoot[0] != 0);

#ifdef WNT
    if (pSrcRoot[1] == ':')
        m_aSrcRoot += rtl::OUString::createFromAscii( "/" );
#endif
    m_aSrcRoot += rtl::OUString::createFromAscii( pSrcRoot );

    // Without these we're crashing
    comphelper::setProcessServiceFactory(m_xMSF);
    InitVCL(m_xMSF);

    // initialise UCB-Broker
    uno::Sequence<uno::Any> aUcbInitSequence(2);
    aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
    aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
    bool bInitUcb = ucbhelper::ContentBroker::initialize(m_xMSF, aUcbInitSequence);
    CPPUNIT_ASSERT_MESSAGE("Should be able to initialize UCB", bInitUcb);

    uno::Reference<ucb::XContentProviderManager> xUcb =
        ucbhelper::ContentBroker::get()->getContentProviderManagerInterface();
    uno::Reference<ucb::XContentProvider> xFileProvider(m_xMSF->createInstance(
                rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.FileContentProvider"))), uno::UNO_QUERY);
    xUcb->registerContentProvider(xFileProvider, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file")), sal_True);
}

RtfTest::~RtfTest()
{
    DeInitVCL();
}

void RtfTest::setUp()
{
}

void RtfTest::tearDown()
{
}

bool RtfTest::load(const rtl::OUString &rURL)
{
    ++m_nLoadedDocs;
    uno::Sequence< beans::PropertyValue > aDescriptor(1);
    aDescriptor[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
    aDescriptor[0].Value <<= rURL;
    return m_xFilter->filter(aDescriptor);
}

void RtfTest::recursiveScan(const rtl::OUString &rURL, bool bExpected)
{
    osl::Directory aDir(rURL);

    CPPUNIT_ASSERT_MESSAGE("failed to open directory", osl::FileBase::E_None == aDir.open());
    osl::DirectoryItem aItem;
    osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileURL|osl_FileStatus_Mask_Type);
    while (aDir.getNextItem(aItem) == osl::FileBase::E_None)
    {
        aItem.getFileStatus(aFileStatus);
        rtl::OUString sURL = aFileStatus.getFileURL();
        if (aFileStatus.getFileType() == osl::FileStatus::Directory)
            recursiveScan(sURL, bExpected);
        else
        {
            bool bRes = load(sURL);
            rtl::OString aRes(rtl::OUStringToOString(sURL, osl_getThreadTextEncoding()));
            CPPUNIT_ASSERT_MESSAGE(aRes.getStr(), bRes == bExpected);
        }
    }
    CPPUNIT_ASSERT_MESSAGE("failed to close directory", osl::FileBase::E_None == aDir.close());
}

void RtfTest::test()
{
    recursiveScan(m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/writerfilter/qa/cppunittests/rtftok/data/pass")), true);

    printf("Rtf: tested %d files\n", m_nLoadedDocs);
}

CPPUNIT_TEST_SUITE_REGISTRATION(RtfTest);

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>testrtftok: fix path on windows<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *       Miklos Vajna <vmiklos@frugalware.org>
 * Portions created by the Initial Developer are Copyright (C) 2011 the
 * Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

#include <sal/cppunit.h>

#include <cppuhelper/bootstrap.hxx>
#include <comphelper/processfactory.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/document/XFilter.hpp>

#include <osl/file.hxx>
#include <osl/process.h>

#include <vcl/svapp.hxx>
#include <ucbhelper/contentbroker.hxx>

using namespace ::com::sun::star;

class RtfTest : public CppUnit::TestFixture
{
public:
    RtfTest();
    ~RtfTest();

    virtual void setUp();
    virtual void tearDown();

    void recursiveScan(const rtl::OUString &rURL, bool bExpected);
    bool load(const rtl::OUString &rURL);
    void test();

    CPPUNIT_TEST_SUITE(RtfTest);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();
private:
    uno::Reference<uno::XComponentContext> m_xContext;
    uno::Reference<lang::XMultiComponentFactory> m_xFactory;
    uno::Reference<lang::XMultiServiceFactory> m_xMSF;
    uno::Reference<document::XFilter> m_xFilter;

    ::rtl::OUString m_aSrcRoot;
    int m_nLoadedDocs;
};

RtfTest::RtfTest()
    : m_aSrcRoot(RTL_CONSTASCII_USTRINGPARAM("file://")),
    m_nLoadedDocs(0)
{
    m_xContext = cppu::defaultBootstrap_InitialComponentContext();
    m_xFactory = m_xContext->getServiceManager();
    m_xMSF = uno::Reference<lang::XMultiServiceFactory>(m_xFactory, uno::UNO_QUERY_THROW);
    m_xFilter = uno::Reference< document::XFilter >(m_xMSF->createInstance(
        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Writer.RtfFilter"))),
        uno::UNO_QUERY_THROW);

    const char* pSrcRoot = getenv( "SRC_ROOT" );
    CPPUNIT_ASSERT_MESSAGE("SRC_ROOT env variable not set", pSrcRoot != NULL && pSrcRoot[0] != 0);

#ifdef WNT
    if (pSrcRoot[1] == ':')
        m_aSrcRoot += rtl::OUString::createFromAscii( "/" );
#endif
    m_aSrcRoot += rtl::OUString::createFromAscii( pSrcRoot );

    // Without these we're crashing
    comphelper::setProcessServiceFactory(m_xMSF);
    InitVCL(m_xMSF);

    // initialise UCB-Broker
    uno::Sequence<uno::Any> aUcbInitSequence(2);
    aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
    aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
    bool bInitUcb = ucbhelper::ContentBroker::initialize(m_xMSF, aUcbInitSequence);
    CPPUNIT_ASSERT_MESSAGE("Should be able to initialize UCB", bInitUcb);

    uno::Reference<ucb::XContentProviderManager> xUcb =
        ucbhelper::ContentBroker::get()->getContentProviderManagerInterface();
    uno::Reference<ucb::XContentProvider> xFileProvider(m_xMSF->createInstance(
                rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.FileContentProvider"))), uno::UNO_QUERY);
    xUcb->registerContentProvider(xFileProvider, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file")), sal_True);
}

RtfTest::~RtfTest()
{
    DeInitVCL();
}

void RtfTest::setUp()
{
}

void RtfTest::tearDown()
{
}

bool RtfTest::load(const rtl::OUString &rURL)
{
    ++m_nLoadedDocs;
    uno::Sequence< beans::PropertyValue > aDescriptor(1);
    aDescriptor[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
    aDescriptor[0].Value <<= rURL;
    return m_xFilter->filter(aDescriptor);
}

void RtfTest::recursiveScan(const rtl::OUString &rURL, bool bExpected)
{
    osl::Directory aDir(rURL);

    CPPUNIT_ASSERT_MESSAGE("failed to open directory", osl::FileBase::E_None == aDir.open());
    osl::DirectoryItem aItem;
    osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileURL|osl_FileStatus_Mask_Type);
    while (aDir.getNextItem(aItem) == osl::FileBase::E_None)
    {
        aItem.getFileStatus(aFileStatus);
        rtl::OUString sURL = aFileStatus.getFileURL();
        if (aFileStatus.getFileType() == osl::FileStatus::Directory)
            recursiveScan(sURL, bExpected);
        else
        {
            bool bRes = load(sURL);
            rtl::OString aRes(rtl::OUStringToOString(sURL, osl_getThreadTextEncoding()));
            CPPUNIT_ASSERT_MESSAGE(aRes.getStr(), bRes == bExpected);
        }
    }
    CPPUNIT_ASSERT_MESSAGE("failed to close directory", osl::FileBase::E_None == aDir.close());
}

void RtfTest::test()
{
    recursiveScan(m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/clone/filters/writerfilter/qa/cppunittests/rtftok/data/pass")), true);
    recursiveScan(m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/clone/filters/writerfilter/qa/cppunittests/rtftok/data/fail")), false);

    printf("Rtf: tested %d files\n", m_nLoadedDocs);
}

CPPUNIT_TEST_SUITE_REGISTRATION(RtfTest);

CPPUNIT_PLUGIN_IMPLEMENT();

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


<commit_before>#include "Model.h"

using namespace qReal;

using namespace model;

Model::Model()
{
	mClient = new client::Client();
	rootItem = new ModelTreeItem(ROOT_ID,NULL);
	treeItems.insert(ROOT_ID,rootItem);
}

Model::~Model()
{
	delete mClient;
}

Qt::ItemFlags Model::flags( const QModelIndex &index ) const
{
	if (index.isValid()) {
		return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled
			| Qt::ItemIsDropEnabled | Qt::ItemIsEnabled;
	} else {
		return Qt::NoItemFlags;
	}
}

QVariant Model::data( const QModelIndex &index, int role) const
{
	if (index.isValid()) {
		ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
		switch (role) {
			case Qt::DisplayRole:
			case Qt::EditRole:
				return mClient->property(item->id(),"Name");
		}
		return QVariant();
	} else {
		return QVariant();
	}
}

QVariant Model::headerData( int section, Qt::Orientation orientation, int role ) const
{
	if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0 ) {
		return QVariant("Name");
	} else {
		return QVariant();
	}
}

int Model::rowCount( const QModelIndex &parent ) const
{
	ModelTreeItem *parentItem;
	if (parent.isValid()) {
		parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
	} else {
		parentItem = rootItem;
	}
	return parentItem->children().size();
}

int Model::columnCount( const QModelIndex &parent ) const
{
	return 1;
}
bool Model::setData( const QModelIndex &index, const QVariant &value, int role )
{
	if (index.isValid()) {
		ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
		switch (role) {
			case Qt::DisplayRole:
			case Qt::EditRole:
				mClient->setProperty(item->id(),"Name",value);
				return true;
		}
		return false;
	} else {
		return false;
	}
}

bool Model::removeRows( int row, int count, const QModelIndex &parent )
{
	if (parent.isValid()) {
		ModelTreeItem *parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
		if (parentItem->children().size() < row + count) {
			return false;
		} else {
			for (int i = row; i < row + count; i++) {
				removeModelItems(parentItem->children().at(i));
			}
			return true;
		}
	} else {
		return false;
	}
}

PropertyName Model::pathToItem( ModelTreeItem *item ) const
{
	PropertyName path;
	do {
		item = item->parent();
		path = item->id() + PATH_DIVIDER + path;
	} while (item!=rootItem);
	return path;
}

void Model::removeConfigurationInClient( ModelTreeItem *item )
{
	mClient->removeProperty(item->id(),"position + " + pathToItem(item));
	mClient->removeProperty(item->id(),"configuration + " + pathToItem(item));
}

QModelIndex Model::index( ModelTreeItem *item )
{
	if (item!=rootItem) {
		return createIndex(item->row(),0,item);
	} else {
		return QModelIndex();
	}
}

void Model::removeModelItems( ModelTreeItem *root )
{
	foreach (ModelTreeItem *child, root->children()) {
		removeModelItems(child);
		int childRow = child->row();
		beginRemoveRows(index(root),childRow,childRow);
		removeConfigurationInClient(child);
		child->parent()->removeChild(child);
		treeItems.remove(child->id(),child);
		if (treeItems.count(child->id())==0) {
			mClient->removeChild(root->id(),child->id());
		}
		delete child;
		endRemoveRows();
	}
}

QModelIndex Model::index( int row, int column, const QModelIndex &parent ) const
{
	if (parent.isValid()) {
		ModelTreeItem *parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
		ModelTreeItem *item = parentItem->children().at(row);
		return createIndex(row,column,item);
	} else {
		return QModelIndex();
	}
}

QModelIndex Model::parent( const QModelIndex &index ) const
{
	if (index.isValid()) {
		ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
		ModelTreeItem *parentItem = item->parent();
		if (parentItem==rootItem) {
			return QModelIndex();
		} else{
			return createIndex(parentItem->row(),0,parentItem);
		}
	} else {
		return QModelIndex();
	}
}

Qt::DropActions Model::supportedDropActions() const
{
	return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
}

QStringList Model::mimeTypes() const
{
	QStringList types;
	types.append(DEFAULT_MIME_TYPE);
	return types;
}

QMimeData* Model::mimeData( const QModelIndexList &indexes ) const
{
	QByteArray data;
	QDataStream stream(&data, QIODevice::WriteOnly);
	foreach (QModelIndex index, indexes) {
		if (index.isValid()) {
			ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
			stream << item->id();
			stream << pathToItem(item);
			stream << mClient->property(item->id(),"position + " + pathToItem(item)).toPointF();
		}
	}
	QMimeData *mimeData = new QMimeData();
	mimeData->setData(DEFAULT_MIME_TYPE, data);
	return mimeData;
}

bool Model::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
{
	Q_UNUSED(row)
	Q_UNUSED(column)
	if (parent.isValid()) {
		if (action == Qt::IgnoreAction) {
			return true;
		} else {
			ModelTreeItem *parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
			QByteArray dragData = data->data(DEFAULT_MIME_TYPE);
			QDataStream stream(&dragData, QIODevice::ReadOnly);
			IdType id;
			PropertyName pathToItem;
			QPointF position;
			stream >> id;
			stream >> pathToItem;
			stream >> position;
			return addElementToModel(parentItem,id,pathToItem,position,action);
		}
	} else {
		return false;
	}
}

bool Model::addElementToModel( ModelTreeItem *parentItem, const IdType &id,
		const PropertyName &pathToItem, const QPointF &position, Qt::DropAction action )
{
	ModelTreeItem *item = new ModelTreeItem(id,parentItem);
	parentItem->addChild(item);
	return true;
}

void Model::test()
{
	beginInsertRows(index(rootItem),0,0);
	ModelTreeItem *item1 = new ModelTreeItem("item1",rootItem);
	rootItem->addChild(item1);
	treeItems.insert("item1",item1);
	mClient->addChild(ROOT_ID,"item1");
	mClient->setProperty("item1","Name","anon");
	endInsertRows();
}
<commit_msg>Уже что-то отображает<commit_after>#include "Model.h"

#include <qDebug>

using namespace qReal;

using namespace model;

Model::Model()
{
	mClient = new client::Client();
	rootItem = new ModelTreeItem(ROOT_ID,NULL);
	treeItems.insert(ROOT_ID,rootItem);
}

Model::~Model()
{
	delete mClient;
}

Qt::ItemFlags Model::flags( const QModelIndex &index ) const
{
	if (index.isValid()) {
		return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled
			| Qt::ItemIsDropEnabled | Qt::ItemIsEnabled;
	} else {
		return Qt::NoItemFlags;
	}
}

QVariant Model::data( const QModelIndex &index, int role) const
{
	if (index.isValid()) {
		ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
		switch (role) {
			case Qt::DisplayRole:
			case Qt::EditRole:
				return mClient->property(item->id(),"Name");
		}
		return QVariant();
	} else {
		return QVariant();
	}
}

QVariant Model::headerData( int section, Qt::Orientation orientation, int role ) const
{
	if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0 ) {
		return QVariant("Name");
	} else {
		return QVariant();
	}
}

int Model::rowCount( const QModelIndex &parent ) const
{
	ModelTreeItem *parentItem;
	if (parent.isValid()) {
		parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
	} else {
		parentItem = rootItem;
	}
	return parentItem->children().size();
}

int Model::columnCount( const QModelIndex &parent ) const
{
	return 1;
}

bool Model::setData( const QModelIndex &index, const QVariant &value, int role )
{
	if (index.isValid()) {
		ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
		switch (role) {
			case Qt::DisplayRole:
			case Qt::EditRole:
				mClient->setProperty(item->id(),"Name",value);
				return true;
		}
		return false;
	} else {
		return false;
	}
}

bool Model::removeRows( int row, int count, const QModelIndex &parent )
{
	if (parent.isValid()) {
		ModelTreeItem *parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
		if (parentItem->children().size() < row + count) {
			return false;
		} else {
			for (int i = row; i < row + count; i++) {
				removeModelItems(parentItem->children().at(i));
			}
			return true;
		}
	} else {
		return false;
	}
}

PropertyName Model::pathToItem( ModelTreeItem *item ) const
{
	PropertyName path;
	do {
		item = item->parent();
		path = item->id() + PATH_DIVIDER + path;
	} while (item!=rootItem);
	return path;
}

void Model::removeConfigurationInClient( ModelTreeItem *item )
{
	mClient->removeProperty(item->id(),"position + " + pathToItem(item));
	mClient->removeProperty(item->id(),"configuration + " + pathToItem(item));
}

QModelIndex Model::index( ModelTreeItem *item )
{
	if (item!=rootItem) {
		return createIndex(item->row(),0,item);
	} else {
		return QModelIndex();
	}
}

void Model::removeModelItems( ModelTreeItem *root )
{
	foreach (ModelTreeItem *child, root->children()) {
		removeModelItems(child);
		int childRow = child->row();
		beginRemoveRows(index(root),childRow,childRow);
		removeConfigurationInClient(child);
		child->parent()->removeChild(child);
		treeItems.remove(child->id(),child);
		if (treeItems.count(child->id())==0) {
			mClient->removeChild(root->id(),child->id());
		}
		delete child;
		endRemoveRows();
	}
}

QModelIndex Model::index( int row, int column, const QModelIndex &parent ) const
{
	ModelTreeItem *parentItem;
	if (parent.isValid()) {
		parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
	} else {
		parentItem = rootItem;
	}
	ModelTreeItem *item = parentItem->children().at(row);
	return createIndex(row,column,item);
}

QModelIndex Model::parent( const QModelIndex &index ) const
{
	if (index.isValid()) {
		ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
		ModelTreeItem *parentItem = item->parent();
		if (parentItem==rootItem) {
			return QModelIndex();
		} else{
			return createIndex(parentItem->row(),0,parentItem);
		}
	} else {
		return QModelIndex();
	}
}

Qt::DropActions Model::supportedDropActions() const
{
	return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
}

QStringList Model::mimeTypes() const
{
	QStringList types;
	types.append(DEFAULT_MIME_TYPE);
	return types;
}

QMimeData* Model::mimeData( const QModelIndexList &indexes ) const
{
	QByteArray data;
	QDataStream stream(&data, QIODevice::WriteOnly);
	foreach (QModelIndex index, indexes) {
		if (index.isValid()) {
			ModelTreeItem *item = static_cast<ModelTreeItem*>(index.internalPointer());
			stream << item->id();
			stream << pathToItem(item);
			stream << mClient->property(item->id(),"position + " + pathToItem(item)).toPointF();
		}
	}
	QMimeData *mimeData = new QMimeData();
	mimeData->setData(DEFAULT_MIME_TYPE, data);
	return mimeData;
}

bool Model::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
{
	Q_UNUSED(row)
	Q_UNUSED(column)
	if (parent.isValid()) {
		if (action == Qt::IgnoreAction) {
			return true;
		} else {
			ModelTreeItem *parentItem = static_cast<ModelTreeItem*>(parent.internalPointer());
			QByteArray dragData = data->data(DEFAULT_MIME_TYPE);
			QDataStream stream(&dragData, QIODevice::ReadOnly);
			IdType id;
			PropertyName pathToItem;
			QPointF position;
			stream >> id;
			stream >> pathToItem;
			stream >> position;
			return addElementToModel(parentItem,id,pathToItem,position,action);
		}
	} else {
		return false;
	}
}

bool Model::addElementToModel( ModelTreeItem *parentItem, const IdType &id,
		const PropertyName &pathToItem, const QPointF &position, Qt::DropAction action )
{
	ModelTreeItem *item = new ModelTreeItem(id,parentItem);
	parentItem->addChild(item);
	return true;
}

void Model::test()
{
	beginInsertRows(index(rootItem),0,0);
	ModelTreeItem *item1 = new ModelTreeItem("item1",rootItem);
	rootItem->addChild(item1);
	treeItems.insert("item1",item1);
	mClient->addChild(ROOT_ID,"item1");
	mClient->setProperty("item1","Name","anon");
	endInsertRows();

	beginInsertRows(index(item1),0,0);
	ModelTreeItem *item2 = new ModelTreeItem("item2",item1);
	item1->addChild(item2);
	treeItems.insert("item2",item2);
	mClient->addChild(item1->id(),"item2");
	mClient->setProperty("item2","Name","anon2");
	endInsertRows();

	beginInsertRows(index(rootItem),1,1);
	ModelTreeItem *item3 = new ModelTreeItem("item3",rootItem);
	rootItem->addChild(item3);
	treeItems.insert("item3",item3);
	mClient->addChild(ROOT_ID,"item3");
	mClient->setProperty("item3","Name","anon3");
	endInsertRows();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016-2017 dresden elektronik ingenieurtechnik gmbh.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 *
 */

#include <QApplication>
#include <QTimer>
#include <QNetworkAccessManager>
#include <QNetworkInterface>
#include <QNetworkReply>
#include <vector>
#include "gateway_scanner.h"
#include "deconz.h"
#include "json.h"

enum ScanState
{
    StateInit,
    StateIdle,
    StateRunning,
};

enum ScanEvent
{
    ActionProcess,
    EventTimeout,
    EventGotReply
};

class GatewayScannerPrivate
{
public:
    void initScanner();
    void handleEvent(ScanEvent event);
    void startScanTimer(int msec, ScanEvent action);
    void stopTimer();
    void queryNextIp();
    void processReply();

    GatewayScanner *q;
    ScanState state;
    QNetworkAccessManager *manager;
    QNetworkReply *reply;
    QTimer *timer;
    ScanEvent timerAction;
    std::vector<quint32> interfaces;
    quint32 scanIp;
    quint16 scanPort;
    int scanIteration;
    quint32 host;
    size_t interfaceIter;
};

GatewayScanner::GatewayScanner(QObject *parent) :
    QObject(parent),
    d_ptr(new GatewayScannerPrivate)
{
    Q_D(GatewayScanner);
    d->q = this;
    d->scanIteration = 0;
    d->state = StateInit;
    d->manager = new QNetworkAccessManager(this);
    connect(d->manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
    d->timer = new QTimer(this);
    d->timer->setSingleShot(true);
    connect(d->timer, SIGNAL(timeout()), this, SLOT(scanTimerFired()));
}

GatewayScanner::~GatewayScanner()
{
    Q_ASSERT(d_ptr != nullptr);
    if (d_ptr)
    {
        delete d_ptr;
        d_ptr = nullptr;
    }
}

bool GatewayScanner::isRunning() const
{
    Q_D(const GatewayScanner);

    return (d->state != StateInit);
}

void GatewayScanner::queryGateway(const QString &url)
{
    Q_D(GatewayScanner);

    if (!isRunning() && d->reply == nullptr)
    {
        d->reply = d->manager->get(QNetworkRequest(url));
        QObject::connect(d->reply, SIGNAL(error(QNetworkReply::NetworkError)),
                d->manager->parent(), SLOT(onError(QNetworkReply::NetworkError)));
    }
}

void GatewayScanner::startScan()
{
    Q_D(GatewayScanner);

    if (d->state == StateInit)
    {
        d->startScanTimer(1, ActionProcess);
    }
}

void GatewayScanner::scanTimerFired()
{
    Q_D(GatewayScanner);
    d->handleEvent(d->timerAction);
}

void GatewayScanner::requestFinished(QNetworkReply *reply)
{
    Q_D(GatewayScanner);

    if (reply == d->reply)
    {
        d->processReply();
    }

    if (isRunning())
    {
        d->handleEvent(EventGotReply);
    }
}

void GatewayScannerPrivate::processReply()
{
    if (!reply)
    {
        return;
    }

    QNetworkReply *r = reply;
    reply = 0;
    r->deleteLater();

    int code = r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if (code != 200) // not authorized or ok
    {
        return;
    }

    bool ok;
    QVariant var = Json::parse(r->readAll(), ok);
    if (!ok)
    {
        return;
    }

    QVariantMap map = var.toMap();
    if (map.isEmpty())
    {
        return;
    }

    if (!map.contains(QLatin1String("bridgeid")) ||
        !map.contains(QLatin1String("modelid")) ||
        !map.contains(QLatin1String("name")))
    {
        return;
    }

    QString name = map["name"].toString();
    //QString modelid = map["modelid"].toString();
    QString bridgeid = map["bridgeid"].toString();

    QUrl url = r->url();

    QHostAddress host(url.host());
    if (host.isNull() || name.isEmpty() || bridgeid.isEmpty())
    {
        return;
    }

    //DBG_Printf(DBG_INFO, "GW: %s %s, %s, %s\n", qPrintable(url.host()), qPrintable(name), qPrintable(modelid), qPrintable(bridgeid));
    q->foundGateway(host, static_cast<quint16>(url.port(80)), bridgeid, name);
}

void GatewayScanner::onError(QNetworkReply::NetworkError code)
{
    Q_D(GatewayScanner);
    Q_UNUSED(code)

    if (!d->timer->isActive())
    {
        // must be in timeout window
        return;
    }

    if (d->reply && sender() == d->reply)
    {
        //DBG_Printf(DBG_INFO, "reply err: %d\n", code);
        d->timer->stop();
        d->handleEvent(EventGotReply);
    }
}

void GatewayScannerPrivate::initScanner()
{
    QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();

    QList<QNetworkInterface>::Iterator ifi = ifaces.begin();
    QList<QNetworkInterface>::Iterator ifend = ifaces.end();

    for (; ifi != ifend; ++ifi)
    {
        QString name = ifi->humanReadableName();

        // filter
        if (name.contains("vm", Qt::CaseInsensitive) ||
            name.contains("virtual", Qt::CaseInsensitive) ||
            name.contains("loop", Qt::CaseInsensitive))
        {
            continue;
        }

        QList<QNetworkAddressEntry> addr = ifi->addressEntries();

        QList<QNetworkAddressEntry>::Iterator i = addr.begin();
        QList<QNetworkAddressEntry>::Iterator end = addr.end();

        for (; i != end; ++i)
        {
            QHostAddress a = i->ip();

            if (a.protocol() == QAbstractSocket::IPv4Protocol)
            {
                quint32 ipv4 = a.toIPv4Address();
                if ((ipv4 & 0xff000000UL) == 0x7f000000UL)
                {
                    // 127.x.x.x
                    continue;
                }

                if (std::find(interfaces.begin(), interfaces.end(), ipv4) == interfaces.end())
                {
                    interfaces.push_back(ipv4);
                }
            }
        }
    }

    scanIteration++;
    interfaceIter = 0;
    host = 0;
}

void GatewayScannerPrivate::handleEvent(ScanEvent event)
{
    if (state == StateInit)
    {
        if (event == ActionProcess)
        {
            initScanner();
            state = StateIdle;
            startScanTimer(10, ActionProcess);
        }
        else
        {
            Q_ASSERT(0);
        }
    }
    else if (state == StateIdle)
    {
        if (event == ActionProcess)
        {
            queryNextIp();
        }
        else if (event == EventTimeout)
        {
            QNetworkReply *r = reply;
            if (reply)
            {
                reply = nullptr;
                if (r->isRunning())
                {
                    r->abort();
                }
                r->deleteLater();
            }
            host++;
            startScanTimer(1, ActionProcess);
        }
        else if (event == EventGotReply)
        {
            host++;
            startScanTimer(1, ActionProcess);
        }
        else
        {
            Q_ASSERT(0);
        }
    }
    else
    {
        Q_ASSERT(0);
    }
}

void GatewayScannerPrivate::startScanTimer(int msec, ScanEvent action)
{
    timerAction = action;
    timer->stop();
    timer->start(msec);
}

void GatewayScannerPrivate::stopTimer()
{
    timer->stop();
}

void GatewayScannerPrivate::queryNextIp()
{
    if (!interfaces.empty() && host > 255)
    {
        interfaces.pop_back();
        host = 0;
    }

    if (interfaces.empty())
    {
        state = StateInit;
        DBG_Printf(DBG_INFO, "scan finished\n");
        return;
    }

    scanIp = interfaces.back();
    scanPort = 80;

    if (host == (scanIp & 0x000000fful))
    {
        DBG_Printf(DBG_INFO, "scan skip host .%u\n", host);
        host++; // don't scan own ip
    }

    QString url;
    url.sprintf("http://%u.%u.%u.%u:%u/api/config",
                ((scanIp >> 24) & 0xff),
                ((scanIp >> 16) & 0xff),
                ((scanIp >> 8) & 0xff),
                host & 0xff, scanPort);

    scanIp &= 0xffffff00ull;
    scanIp |= host & 0xff;

    //DBG_Printf(DBG_INFO, "scan %s\n", qPrintable(url));
    reply = manager->get(QNetworkRequest(url));
    QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            manager->parent(), SLOT(onError(QNetworkReply::NetworkError)));

    startScanTimer(100, EventTimeout);
}
<commit_msg>Gateway scanner: cleanup reply only after finish or error<commit_after>/*
 * Copyright (c) 2016-2017 dresden elektronik ingenieurtechnik gmbh.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 *
 */

#include <QApplication>
#include <QTimer>
#include <QNetworkAccessManager>
#include <QNetworkInterface>
#include <QNetworkReply>
#include <vector>
#include "gateway_scanner.h"
#include "deconz.h"
#include "json.h"

enum ScanState
{
    StateInit,
    StateIdle,
    StateRunning,
};

enum ScanEvent
{
    ActionProcess,
    EventTimeout,
    EventGotReply
};

class GatewayScannerPrivate
{
public:
    void initScanner();
    void handleEvent(ScanEvent event);
    void startScanTimer(int msec, ScanEvent action);
    void stopTimer();
    void queryNextIp();
    void processReply();

    GatewayScanner *q;
    ScanState state;
    QNetworkAccessManager *manager;
    QNetworkReply *reply;
    QTimer *timer;
    ScanEvent timerAction;
    std::vector<quint32> interfaces;
    quint32 scanIp;
    quint16 scanPort;
    int scanIteration;
    quint32 host;
    size_t interfaceIter;
};

GatewayScanner::GatewayScanner(QObject *parent) :
    QObject(parent),
    d_ptr(new GatewayScannerPrivate)
{
    Q_D(GatewayScanner);
    d->q = this;
    d->scanIteration = 0;
    d->state = StateInit;
    d->manager = new QNetworkAccessManager(this);
    connect(d->manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
    d->timer = new QTimer(this);
    d->timer->setSingleShot(true);
    connect(d->timer, SIGNAL(timeout()), this, SLOT(scanTimerFired()));
}

GatewayScanner::~GatewayScanner()
{
    Q_ASSERT(d_ptr != nullptr);
    if (d_ptr)
    {
        delete d_ptr;
        d_ptr = nullptr;
    }
}

bool GatewayScanner::isRunning() const
{
    Q_D(const GatewayScanner);

    return (d->state != StateInit);
}

void GatewayScanner::queryGateway(const QString &url)
{
    Q_D(GatewayScanner);

    if (!isRunning() && d->reply == nullptr)
    {
        d->reply = d->manager->get(QNetworkRequest(url));
        QObject::connect(d->reply, SIGNAL(error(QNetworkReply::NetworkError)),
                d->manager->parent(), SLOT(onError(QNetworkReply::NetworkError)));
    }
}

void GatewayScanner::startScan()
{
    Q_D(GatewayScanner);

    if (d->state == StateInit)
    {
        d->startScanTimer(1, ActionProcess);
    }
}

void GatewayScanner::scanTimerFired()
{
    Q_D(GatewayScanner);
    d->handleEvent(d->timerAction);
}

void GatewayScanner::requestFinished(QNetworkReply *reply)
{
    Q_D(GatewayScanner);

    if (reply == d->reply)
    {
        d->processReply();
    }

    if (isRunning())
    {
        d->handleEvent(EventGotReply);
    }
    reply->deleteLater();
}

void GatewayScannerPrivate::processReply()
{
    if (!reply)
    {
        return;
    }

    QNetworkReply *r = reply;
    reply = nullptr;

    int code = r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if (code != 200) // not authorized or ok
    {
        return;
    }

    bool ok;
    QVariant var = Json::parse(r->readAll(), ok);
    if (!ok)
    {
        return;
    }

    QVariantMap map = var.toMap();
    if (map.isEmpty())
    {
        return;
    }

    if (!map.contains(QLatin1String("bridgeid")) ||
        !map.contains(QLatin1String("modelid")) ||
        !map.contains(QLatin1String("name")))
    {
        return;
    }

    QString name = map["name"].toString();
    //QString modelid = map["modelid"].toString();
    QString bridgeid = map["bridgeid"].toString();

    QUrl url = r->url();

    QHostAddress host(url.host());
    if (host.isNull() || name.isEmpty() || bridgeid.isEmpty())
    {
        return;
    }

    //DBG_Printf(DBG_INFO, "GW: %s %s, %s, %s\n", qPrintable(url.host()), qPrintable(name), qPrintable(modelid), qPrintable(bridgeid));
    q->foundGateway(host, static_cast<quint16>(url.port(80)), bridgeid, name);
}

void GatewayScanner::onError(QNetworkReply::NetworkError code)
{
    Q_D(GatewayScanner);
    Q_UNUSED(code)

    sender()->deleteLater();

    if (!d->timer->isActive())
    {
        // must be in timeout window
        return;
    }

    if (d->reply && sender() == d->reply)
    {
        //DBG_Printf(DBG_INFO, "reply err: %d\n", code);
        d->timer->stop();
        d->handleEvent(EventGotReply);
    }
}

void GatewayScannerPrivate::initScanner()
{
    QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();

    QList<QNetworkInterface>::Iterator ifi = ifaces.begin();
    QList<QNetworkInterface>::Iterator ifend = ifaces.end();

    for (; ifi != ifend; ++ifi)
    {
        QString name = ifi->humanReadableName();

        // filter
        if (name.contains("vm", Qt::CaseInsensitive) ||
            name.contains("virtual", Qt::CaseInsensitive) ||
            name.contains("loop", Qt::CaseInsensitive))
        {
            continue;
        }

        QList<QNetworkAddressEntry> addr = ifi->addressEntries();

        QList<QNetworkAddressEntry>::Iterator i = addr.begin();
        QList<QNetworkAddressEntry>::Iterator end = addr.end();

        for (; i != end; ++i)
        {
            QHostAddress a = i->ip();

            if (a.protocol() == QAbstractSocket::IPv4Protocol)
            {
                quint32 ipv4 = a.toIPv4Address();
                if ((ipv4 & 0xff000000UL) == 0x7f000000UL)
                {
                    // 127.x.x.x
                    continue;
                }

                if (std::find(interfaces.begin(), interfaces.end(), ipv4) == interfaces.end())
                {
                    interfaces.push_back(ipv4);
                }
            }
        }
    }

    scanIteration++;
    interfaceIter = 0;
    host = 0;
}

void GatewayScannerPrivate::handleEvent(ScanEvent event)
{
    if (state == StateInit)
    {
        if (event == ActionProcess)
        {
            initScanner();
            state = StateIdle;
            startScanTimer(10, ActionProcess);
        }
        else
        {
            Q_ASSERT(0);
        }
    }
    else if (state == StateIdle)
    {
        if (event == ActionProcess)
        {
            queryNextIp();
        }
        else if (event == EventTimeout)
        {
            QNetworkReply *r = reply;
            if (reply)
            {
                reply = nullptr;
                if (r->isRunning())
                {
                    r->abort();
                }
                r->deleteLater();
            }
            host++;
            startScanTimer(1, ActionProcess);
        }
        else if (event == EventGotReply)
        {
            host++;
            startScanTimer(1, ActionProcess);
        }
        else
        {
            Q_ASSERT(0);
        }
    }
    else
    {
        Q_ASSERT(0);
    }
}

void GatewayScannerPrivate::startScanTimer(int msec, ScanEvent action)
{
    timerAction = action;
    timer->stop();
    timer->start(msec);
}

void GatewayScannerPrivate::stopTimer()
{
    timer->stop();
}

void GatewayScannerPrivate::queryNextIp()
{
    if (!interfaces.empty() && host > 255)
    {
        interfaces.pop_back();
        host = 0;
    }

    if (interfaces.empty())
    {
        state = StateInit;
        DBG_Printf(DBG_INFO, "scan finished\n");
        return;
    }

    scanIp = interfaces.back();
    scanPort = 80;

    if (host == (scanIp & 0x000000fful))
    {
        DBG_Printf(DBG_INFO, "scan skip host .%u\n", host);
        host++; // don't scan own ip
    }

    QString url;
    url.sprintf("http://%u.%u.%u.%u:%u/api/config",
                ((scanIp >> 24) & 0xff),
                ((scanIp >> 16) & 0xff),
                ((scanIp >> 8) & 0xff),
                host & 0xff, scanPort);

    scanIp &= 0xffffff00ull;
    scanIp |= host & 0xff;

    //DBG_Printf(DBG_INFO, "scan %s\n", qPrintable(url));
    reply = manager->get(QNetworkRequest(url));
    QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            manager->parent(), SLOT(onError(QNetworkReply::NetworkError)));

    startScanTimer(100, EventTimeout);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/status/status_area_view.h"

#include <algorithm>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "chrome/browser/chromeos/view_ids.h"
#include "ui/gfx/canvas.h"
#include "ui/views/border.h"

#if defined(USE_ASH)
#include "ash/focus_cycler.h"
#include "ash/shell.h"
#endif

// Number of pixels to separate each icon.
const int kSeparation = 0;

StatusAreaView::StatusAreaView()
    : need_return_focus_(false),
      skip_next_focus_return_(true) {
  set_id(VIEW_ID_STATUS_AREA);
}

StatusAreaView::~StatusAreaView() {
}

void StatusAreaView::AddButton(StatusAreaButton* button, ButtonBorder border) {
  buttons_.push_back(button);
  if (border == HAS_BORDER)
    button->set_border(views::Border::CreateEmptyBorder(0, 1, 0, 0));
  AddChildView(button);
  UpdateButtonVisibility();
}

void StatusAreaView::RemoveButton(StatusAreaButton* button) {
  std::list<StatusAreaButton*>::iterator iter =
      std::find(buttons_.begin(), buttons_.end(), button);
  if (iter != buttons_.end()) {
    RemoveChildView(*iter);
    buttons_.erase(iter);
  }
  UpdateButtonVisibility();
}

// views::View* overrides.

gfx::Size StatusAreaView::GetPreferredSize() {
  int result_w = 0;
  int result_h = 0;

  for (int i = 0; i < child_count(); i++) {
    views::View* cur = child_at(i);
    gfx::Size cur_size = cur->GetPreferredSize();
    if (cur->visible() && !cur_size.IsEmpty()) {
      if (result_w == 0)
        result_w = kSeparation;

      // Add each width.
      result_w += cur_size.width() + kSeparation;
      // Use max height.
      result_h = std::max(result_h, cur_size.height());
    }
  }
  return gfx::Size(result_w, result_h);
}

void StatusAreaView::Layout() {
  int cur_x = kSeparation;
  for (int i = 0; i < child_count(); i++) {
    views::View* cur = child_at(i);
    gfx::Size cur_size = cur->GetPreferredSize();
    if (cur->visible() && !cur_size.IsEmpty()) {
      int cur_y = (height() - cur_size.height()) / 2;

      // Handle odd number of pixels.
      cur_y += (height() - cur_size.height()) % 2;

      // Put next in row horizontally, and center vertically.
      cur->SetBounds(cur_x, cur_y, cur_size.width(), cur_size.height());
      cur_x += cur_size.width() + kSeparation;
    }
  }
}

void StatusAreaView::PreferredSizeChanged() {
#if defined(USE_AURA)
  if (GetWidget())
    GetWidget()->SetSize(GetPreferredSize());
#endif
  views::AccessiblePaneView::PreferredSizeChanged();
}

void StatusAreaView::ChildPreferredSizeChanged(View* child) {
  // When something like the clock menu button's size changes, we need to
  // relayout. Also mark that this view's size has changed. This will let
  // BrowserView know to relayout, which will reset the bounds of this view.
  Layout();
  PreferredSizeChanged();
}

bool StatusAreaView::CanActivate() const {
#if defined(USE_ASH)
  // We don't want mouse clicks to activate us, but we need to allow
  // activation when the user is using the keyboard (FocusCycler).
  ash::internal::FocusCycler* focus_cycler =
      ash::Shell::GetInstance()->focus_cycler();
  return focus_cycler->widget_activating() == GetWidget();
#else
  return false;
#endif
}

views::Widget* StatusAreaView::GetWidget() {
  return View::GetWidget();
}

const views::Widget* StatusAreaView::GetWidget() const {
  return View::GetWidget();
}

void StatusAreaView::MakeButtonsActive(bool active) {
  for (std::list<StatusAreaButton*>::iterator iter = buttons_.begin();
       iter != buttons_.end(); ++iter) {
    (*iter)->SetMenuActive(active);
  }
}

void StatusAreaView::UpdateButtonVisibility() {
  Layout();
  PreferredSizeChanged();
}

void StatusAreaView::UpdateButtonTextStyle() {
  for (std::list<StatusAreaButton*>::const_iterator it = buttons_.begin();
       it != buttons_.end(); ++it) {
    StatusAreaButton* button = *it;
    button->UpdateTextStyle();
  }
}

void StatusAreaView::TakeFocus(
    bool reverse,
    const ReturnFocusCallback& return_focus_cb) {
  SetPaneFocus(reverse ? GetLastFocusableChild() : GetFirstFocusableChild());
  need_return_focus_ = true;
  return_focus_cb_ = return_focus_cb;
  GetWidget()->AddObserver(this);
}

void StatusAreaView::ReturnFocus(bool reverse) {
  ClearFocus();
  return_focus_cb_.Run(reverse);
}

void StatusAreaView::ClearFocus() {
  GetWidget()->RemoveObserver(this);
  RemovePaneFocus();
  focus_manager_->ClearFocus();
  need_return_focus_ = false;
}

void StatusAreaView::OnDidChangeFocus(views::View* focused_before,
                                      views::View* focused_now) {
  views::AccessiblePaneView::OnDidChangeFocus(focused_before, focused_now);
  if (need_return_focus_ && !skip_next_focus_return_) {
    const views::View* first = GetFirstFocusableChild();
    const views::View* last = GetLastFocusableChild();
    const bool first_to_last = (focused_before == first && focused_now == last);
    const bool last_to_first = (focused_now == first && focused_before == last);

    if (first_to_last || last_to_first)
      ReturnFocus(first_to_last);
  }
  skip_next_focus_return_ = false;
}

void StatusAreaView::OnWidgetActivationChanged(views::Widget* widget,
                                               bool active) {
  if (!active)
    ClearFocus();
}

bool StatusAreaView::AcceleratorPressed(const ui::Accelerator& accelerator) {
  if (need_return_focus_ && accelerator.key_code() == ui::VKEY_ESCAPE) {
    // Override Escape handling to return focus back.
    ReturnFocus(false);
    return true;
  } else if (accelerator.key_code() == ui::VKEY_HOME ||
             accelerator.key_code() == ui::VKEY_END) {
    // Do not return focus if it wraps right after pressing Home/End.
    skip_next_focus_return_ = true;
  }
  return AccessiblePaneView::AcceleratorPressed(accelerator);
}
<commit_msg>Allow the status area to be accessed via tab on the login screen<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/status/status_area_view.h"

#include <algorithm>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "chrome/browser/chromeos/view_ids.h"
#include "ui/gfx/canvas.h"
#include "ui/views/border.h"

#if defined(USE_ASH)
#include "ash/focus_cycler.h"
#include "ash/shell.h"
#endif

// Number of pixels to separate each icon.
const int kSeparation = 0;

StatusAreaView::StatusAreaView()
    : need_return_focus_(false),
      skip_next_focus_return_(true) {
  set_id(VIEW_ID_STATUS_AREA);
}

StatusAreaView::~StatusAreaView() {
}

void StatusAreaView::AddButton(StatusAreaButton* button, ButtonBorder border) {
  buttons_.push_back(button);
  if (border == HAS_BORDER)
    button->set_border(views::Border::CreateEmptyBorder(0, 1, 0, 0));
  AddChildView(button);
  UpdateButtonVisibility();
}

void StatusAreaView::RemoveButton(StatusAreaButton* button) {
  std::list<StatusAreaButton*>::iterator iter =
      std::find(buttons_.begin(), buttons_.end(), button);
  if (iter != buttons_.end()) {
    RemoveChildView(*iter);
    buttons_.erase(iter);
  }
  UpdateButtonVisibility();
}

// views::View* overrides.

gfx::Size StatusAreaView::GetPreferredSize() {
  int result_w = 0;
  int result_h = 0;

  for (int i = 0; i < child_count(); i++) {
    views::View* cur = child_at(i);
    gfx::Size cur_size = cur->GetPreferredSize();
    if (cur->visible() && !cur_size.IsEmpty()) {
      if (result_w == 0)
        result_w = kSeparation;

      // Add each width.
      result_w += cur_size.width() + kSeparation;
      // Use max height.
      result_h = std::max(result_h, cur_size.height());
    }
  }
  return gfx::Size(result_w, result_h);
}

void StatusAreaView::Layout() {
  int cur_x = kSeparation;
  for (int i = 0; i < child_count(); i++) {
    views::View* cur = child_at(i);
    gfx::Size cur_size = cur->GetPreferredSize();
    if (cur->visible() && !cur_size.IsEmpty()) {
      int cur_y = (height() - cur_size.height()) / 2;

      // Handle odd number of pixels.
      cur_y += (height() - cur_size.height()) % 2;

      // Put next in row horizontally, and center vertically.
      cur->SetBounds(cur_x, cur_y, cur_size.width(), cur_size.height());
      cur_x += cur_size.width() + kSeparation;
    }
  }
}

void StatusAreaView::PreferredSizeChanged() {
#if defined(USE_AURA)
  if (GetWidget())
    GetWidget()->SetSize(GetPreferredSize());
#endif
  views::AccessiblePaneView::PreferredSizeChanged();
}

void StatusAreaView::ChildPreferredSizeChanged(View* child) {
  // When something like the clock menu button's size changes, we need to
  // relayout. Also mark that this view's size has changed. This will let
  // BrowserView know to relayout, which will reset the bounds of this view.
  Layout();
  PreferredSizeChanged();
}

bool StatusAreaView::CanActivate() const {
#if defined(USE_ASH)
  // We don't want mouse clicks to activate us, but we need to allow
  // activation when the user is using the keyboard, such as by the FocusCycler
  // or on the Login screen.
  ash::internal::FocusCycler* focus_cycler =
      ash::Shell::GetInstance()->focus_cycler();
  return focus_cycler->widget_activating() == GetWidget() ||
      need_return_focus_;
#else
  return false;
#endif
}

views::Widget* StatusAreaView::GetWidget() {
  return View::GetWidget();
}

const views::Widget* StatusAreaView::GetWidget() const {
  return View::GetWidget();
}

void StatusAreaView::MakeButtonsActive(bool active) {
  for (std::list<StatusAreaButton*>::iterator iter = buttons_.begin();
       iter != buttons_.end(); ++iter) {
    (*iter)->SetMenuActive(active);
  }
}

void StatusAreaView::UpdateButtonVisibility() {
  Layout();
  PreferredSizeChanged();
}

void StatusAreaView::UpdateButtonTextStyle() {
  for (std::list<StatusAreaButton*>::const_iterator it = buttons_.begin();
       it != buttons_.end(); ++it) {
    StatusAreaButton* button = *it;
    button->UpdateTextStyle();
  }
}

void StatusAreaView::TakeFocus(
    bool reverse,
    const ReturnFocusCallback& return_focus_cb) {
  SetPaneFocus(reverse ? GetLastFocusableChild() : GetFirstFocusableChild());
  need_return_focus_ = true;
  return_focus_cb_ = return_focus_cb;
  GetWidget()->AddObserver(this);
}

void StatusAreaView::ReturnFocus(bool reverse) {
  ClearFocus();
  return_focus_cb_.Run(reverse);
}

void StatusAreaView::ClearFocus() {
  GetWidget()->RemoveObserver(this);
  RemovePaneFocus();
  focus_manager_->ClearFocus();
  need_return_focus_ = false;
}

void StatusAreaView::OnDidChangeFocus(views::View* focused_before,
                                      views::View* focused_now) {
  views::AccessiblePaneView::OnDidChangeFocus(focused_before, focused_now);
  if (need_return_focus_ && !skip_next_focus_return_) {
    const views::View* first = GetFirstFocusableChild();
    const views::View* last = GetLastFocusableChild();
    const bool first_to_last = (focused_before == first && focused_now == last);
    const bool last_to_first = (focused_now == first && focused_before == last);

    if (first_to_last || last_to_first)
      ReturnFocus(first_to_last);
  }
  skip_next_focus_return_ = false;
}

void StatusAreaView::OnWidgetActivationChanged(views::Widget* widget,
                                               bool active) {
  if (!active)
    ClearFocus();
}

bool StatusAreaView::AcceleratorPressed(const ui::Accelerator& accelerator) {
  if (need_return_focus_ && accelerator.key_code() == ui::VKEY_ESCAPE) {
    // Override Escape handling to return focus back.
    ReturnFocus(false);
    return true;
  } else if (accelerator.key_code() == ui::VKEY_HOME ||
             accelerator.key_code() == ui::VKEY_END) {
    // Do not return focus if it wraps right after pressing Home/End.
    skip_next_focus_return_ = true;
  }
  return AccessiblePaneView::AcceleratorPressed(accelerator);
}
<|endoftext|>


<commit_before>#include <Python.h>

#define BOOST_TEST_MODULE Error
#define BOOST_TEST_DYN_LINK

#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>
#include <boost/python.hpp>
#include "../Error.hpp"

BOOST_AUTO_TEST_SUITE(test_Error)

BOOST_AUTO_TEST_CASE(test_raise_with_value)
{
    using namespace pccl::python;
    using namespace boost::python;
    Py_InitializeEx(false);
    try
    {
        object main_module(handle<>(borrowed(PyImport_AddModule("__main__"))));
        object main_namespace = main_module.attr("__dict__");
        exec_statement("raise NameError", main_namespace, main_namespace);
        BOOST_FAIL("Expected a Python exception to be thrown");
    }
    catch (error_already_set& error)
    {
        Error description;
        description << boost::throw_function(BOOST_CURRENT_FUNCTION);
        description << boost::throw_line(__LINE__);
        BOOST_CHECK_EQUAL("NameError", description.what());
        BOOST_CHECK_EQUAL(
                "Throw in function void test_Error::test_raise_with_value::test_method()\n"
                "Dynamic exception type: pccl::python::Error\n"
                "std::exception::what: NameError\n"
                "[pccl::python::traceback_list_t*] = \n"
                "Traceback (most recent call last):\n"
                "  File \"<string>\", line 1, in <module>\n"
                "NameError\n",
                boost::diagnostic_information(description));
    }
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Error test now compatible with Boost 1.42 and earlier.<commit_after>#include <Python.h>

#define BOOST_TEST_MODULE Error
#define BOOST_TEST_DYN_LINK

#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>
#include <boost/python.hpp>
#include <boost/version.hpp>
#include "../Error.hpp"

BOOST_AUTO_TEST_SUITE(test_Error)

BOOST_AUTO_TEST_CASE(test_raise_with_value)
{
    using namespace pccl::python;
    using namespace boost::python;
    Py_InitializeEx(false);
    try
    {
        object main_module(handle<>(borrowed(PyImport_AddModule("__main__"))));
        object main_namespace = main_module.attr("__dict__");
        exec_statement("raise NameError", main_namespace, main_namespace);
        BOOST_FAIL("Expected a Python exception to be thrown");
    }
    catch (error_already_set& error)
    {
        Error description;
        description << boost::throw_function(BOOST_CURRENT_FUNCTION);
        description << boost::throw_line(__LINE__);
        BOOST_CHECK_EQUAL("NameError", description.what());
        BOOST_CHECK_EQUAL(
                "Throw in function void test_Error::test_raise_with_value::test_method()\n"
#if BOOST_VERSION < 104300 // older Boost versions don't demangle C++ type names
                "Dynamic exception type: N4pccl6python5ErrorE\n"
                "std::exception::what: NameError\n"
                "[PN4pccl6python16traceback_list_tE] = \n"
#else
                "Dynamic exception type: pccl::python::Error\n"
                "std::exception::what: NameError\n"
                "[pccl::python::traceback_list_t*] = \n"
#endif
                "Traceback (most recent call last):\n"
                "  File \"<string>\", line 1, in <module>\n"
                "NameError\n",
                boost::diagnostic_information(description));
    }
}

BOOST_AUTO_TEST_SUITE_END()
<|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 .
 */

#ifndef _CONNECTIVITY_MAB_QUERYHELPER_HXX_
#define _CONNECTIVITY_MAB_QUERYHELPER_HXX_

#include <MNSInclude.hxx>
#include "MErrorResource.hxx"
#include <sal/types.h>
#include <rtl/ustring.hxx>
#include <osl/mutex.hxx>
#include <osl/conditn.hxx>
#include <comphelper/stl_types.hxx>
#include <osl/thread.hxx>

#include <boost/unordered_map.hpp>

namespace connectivity
{
    namespace mozab
    {
        class MQueryHelperResultEntry
        {
        private:
            typedef ::boost::unordered_map< OString, OUString, OStringHash >  FieldMap;

            mutable ::osl::Mutex    m_aMutex;
            FieldMap                m_Fields;
            nsCOMPtr<nsIAbCard>     m_Card;
            sal_Int32               m_RowStates;

        public:
            MQueryHelperResultEntry();
            ~MQueryHelperResultEntry();

            void            insert( const OString &key, OUString &value );
            OUString   getValue( const OString &key ) const;
            void            setValue( const OString &key, const OUString & rValue);

            void setCard(nsIAbCard *card);
            nsIAbCard *getCard();
            sal_Bool setRowStates(sal_Int32 state){m_RowStates = state; return sal_True;};
            sal_Int32 getRowStates() const { return m_RowStates;};
        };

        class MQueryHelper : public nsIAbDirectoryQueryResultListener
        {
        private:
            typedef std::vector< MQueryHelperResultEntry* > resultsArray;

            mutable ::osl::Mutex        m_aMutex;
            ::osl::Condition    m_aCondition;
            resultsArray        m_aResults;
            sal_uInt32          m_nIndex;
            sal_Bool            m_bHasMore;
            sal_Bool            m_bAtEnd;
            sal_Bool            m_bErrorCondition;
            sal_Bool            m_bQueryComplete;
            ErrorDescriptor     m_aError;

            void            append(MQueryHelperResultEntry* resEnt );

            void            clear_results();

            void            clearResultOrComplete();
            void            notifyResultOrComplete();
            sal_Bool        waitForResultOrComplete( );
            void            getCardValues(nsIAbCard  *card,sal_uInt32 rowIndex=0);
#if OSL_DEBUG_LEVEL > 0
            oslThreadIdentifier m_oThreadID;
#endif

        public:
            NS_DECL_ISUPPORTS
            NS_DECL_NSIABDIRECTORYQUERYRESULTLISTENER

                                            MQueryHelper();
            virtual                         ~MQueryHelper();

            void                            reset();

            MQueryHelperResultEntry*   next( );

            MQueryHelperResultEntry*   getByIndex( sal_uInt32 nRow );

            const ErrorDescriptor&     getError() const { return m_aError; }

            sal_Bool                   isError() const;

            sal_Bool                   queryComplete() const;

            sal_Bool                   waitForQueryComplete(  );
            sal_Bool                   waitForRow( sal_Int32 rowNum );

            sal_Int32                  getResultCount() const;
            sal_uInt32                 getRealCount() const;
            sal_Int32                  createNewCard(); //return Row count number
            sal_Bool                   resyncRow(sal_uInt32 rowIndex);

            void                       notifyQueryError() ;
            sal_Bool                   setCardValues(const sal_uInt32 rowIndex);
            sal_Int32                  commitCard(const sal_uInt32 rowIndex, nsIAbDirectory * directory);
            sal_Int32                  deleteCard(const sal_uInt32 rowIndex, nsIAbDirectory * directory);
        };
    }
}
#endif // _CONNECTIVITY_MAB_QUERYHELPER_HXX_

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Missing include<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 .
 */

#ifndef _CONNECTIVITY_MAB_QUERYHELPER_HXX_
#define _CONNECTIVITY_MAB_QUERYHELPER_HXX_

#include <sal/config.h>

#include <vector>

#include <MNSInclude.hxx>
#include "MErrorResource.hxx"
#include <sal/types.h>
#include <rtl/ustring.hxx>
#include <osl/mutex.hxx>
#include <osl/conditn.hxx>
#include <comphelper/stl_types.hxx>
#include <osl/thread.hxx>

#include <boost/unordered_map.hpp>

namespace connectivity
{
    namespace mozab
    {
        class MQueryHelperResultEntry
        {
        private:
            typedef ::boost::unordered_map< OString, OUString, OStringHash >  FieldMap;

            mutable ::osl::Mutex    m_aMutex;
            FieldMap                m_Fields;
            nsCOMPtr<nsIAbCard>     m_Card;
            sal_Int32               m_RowStates;

        public:
            MQueryHelperResultEntry();
            ~MQueryHelperResultEntry();

            void            insert( const OString &key, OUString &value );
            OUString   getValue( const OString &key ) const;
            void            setValue( const OString &key, const OUString & rValue);

            void setCard(nsIAbCard *card);
            nsIAbCard *getCard();
            sal_Bool setRowStates(sal_Int32 state){m_RowStates = state; return sal_True;};
            sal_Int32 getRowStates() const { return m_RowStates;};
        };

        class MQueryHelper : public nsIAbDirectoryQueryResultListener
        {
        private:
            typedef std::vector< MQueryHelperResultEntry* > resultsArray;

            mutable ::osl::Mutex        m_aMutex;
            ::osl::Condition    m_aCondition;
            resultsArray        m_aResults;
            sal_uInt32          m_nIndex;
            sal_Bool            m_bHasMore;
            sal_Bool            m_bAtEnd;
            sal_Bool            m_bErrorCondition;
            sal_Bool            m_bQueryComplete;
            ErrorDescriptor     m_aError;

            void            append(MQueryHelperResultEntry* resEnt );

            void            clear_results();

            void            clearResultOrComplete();
            void            notifyResultOrComplete();
            sal_Bool        waitForResultOrComplete( );
            void            getCardValues(nsIAbCard  *card,sal_uInt32 rowIndex=0);
#if OSL_DEBUG_LEVEL > 0
            oslThreadIdentifier m_oThreadID;
#endif

        public:
            NS_DECL_ISUPPORTS
            NS_DECL_NSIABDIRECTORYQUERYRESULTLISTENER

                                            MQueryHelper();
            virtual                         ~MQueryHelper();

            void                            reset();

            MQueryHelperResultEntry*   next( );

            MQueryHelperResultEntry*   getByIndex( sal_uInt32 nRow );

            const ErrorDescriptor&     getError() const { return m_aError; }

            sal_Bool                   isError() const;

            sal_Bool                   queryComplete() const;

            sal_Bool                   waitForQueryComplete(  );
            sal_Bool                   waitForRow( sal_Int32 rowNum );

            sal_Int32                  getResultCount() const;
            sal_uInt32                 getRealCount() const;
            sal_Int32                  createNewCard(); //return Row count number
            sal_Bool                   resyncRow(sal_uInt32 rowIndex);

            void                       notifyQueryError() ;
            sal_Bool                   setCardValues(const sal_uInt32 rowIndex);
            sal_Int32                  commitCard(const sal_uInt32 rowIndex, nsIAbDirectory * directory);
            sal_Int32                  deleteCard(const sal_uInt32 rowIndex, nsIAbDirectory * directory);
        };
    }
}
#endif // _CONNECTIVITY_MAB_QUERYHELPER_HXX_

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


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_GLOBALS_HPP
#define MFEM_GLOBALS_HPP

#include "../config/config.hpp"
#include <iostream>

#ifdef MFEM_USE_MPI
#include <mpi.h>
#endif

namespace mfem
{

/// Simple extension of std::ostream.
/** This class adds the ability to enable and disable the stream. The associated
    std::streambuf and tied std::ostream can be replaced with that of any
    std::ostream. */
class OutStream : public std::ostream
{
protected:
   // Pointer that stores the associated streambuf when output is disabled.
   std::streambuf *m_rdbuf;
   // Pointer that stores the tied ostream when output is disabled.
   std::ostream *m_tie;

   void Init();

public:
   /** @brief Construct an OutStream from the given stream @a out, by using its
       `rdbuf()`. */
   OutStream(std::ostream &out) : std::ostream(NULL) { SetStream(out); }

   /** @brief Replace the `rdbuf()` and `tie()` of the OutStream with that of
       @a out, enabling output. */
   void SetStream(std::ostream &out)
   {
      rdbuf(m_rdbuf = out.rdbuf()); tie(m_tie = out.tie()); Init();
   }

   /// Enable output.
   void Enable() { if (!IsEnabled()) { rdbuf(m_rdbuf); tie(m_tie); } }
   /// Disable output.
   void Disable()
   {
      if (IsEnabled()) { m_rdbuf = rdbuf(NULL); m_tie = tie(NULL); }
   }
   /// Check if output is enabled.
   bool IsEnabled() const { return (rdbuf() != NULL); }
};

/** @brief Global stream used by the library for standard output. Initially it
    uses the same std::streambuf as std::cout, however that can be changed.
    @sa OutStream. */
extern OutStream out;
/** @brief Global stream used by the library for standard error output.
    Initially it uses the same std::streambuf as std::cerr, however that can be
    changed.
    @sa OutStream. */
extern OutStream err;

/** @brief Construct a string of the form "<prefix><myid><suffix>" where the
    integer @a myid is padded with leading zeros to be at least @a width digits
    long. */
/** This is a convenience function, e.g. to redirect mfem::out to individual
    files for each rank, one can use:
    \code
       std::ofstream out_file(MakeParFilename("app_out.", myid).c_str());
       mfem::out.SetStream(out_file);
    \endcode
*/
std::string MakeParFilename(const std::string &prefix, const int myid,
                            const std::string suffix = "", const int width = 6);

#ifdef MFEM_USE_MPI

/** @name MFEM "global" communicator functions.

    Functions for getting and setting the MPI communicator used by the library
    as the "global" communicator.

    This "global" communicator is used for example in the function mfem_error(),
    which is invoked when an error is detected - the "global" communicator is
    used as a parameter to MPI_Abort() to terminate all "global" tasks. */
///@{

/// Get MFEM's "global" MPI communicator.
MPI_Comm GetGlobalMPI_Comm();

/// Set MFEM's "global" MPI communicator.
void SetGlobalMPI_Comm(MPI_Comm comm);

///@}

#endif

} // namespace mfem

// Request a global object to be instantiated for each thread in its TLS.
#define MFEM_THREAD_LOCAL thread_local

// MFEM_DEPRECATED macro to mark obsolete functions and methods
// see https://stackoverflow.com/questions/295120/c-mark-as-deprecated
#if defined(__GNUC__) || defined(__clang__)
#define MFEM_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define MFEM_DEPRECATED __declspec(deprecated)
#else
#pragma message("WARNING: You need to implement MFEM_DEPRECATED for this compiler")
#define MFEM_DEPRECATED
#endif

// Sometimes we have to ignore deprecation warnings internally to guarantee
// backwards compatibility.
// Code derived from https://www.fluentcpp.com/2019/08/30/how-to-disable-a-warning-in-cpp/
#if defined(_MSC_VER)
#define MFEM_DISABLE_WARNING_PUSH           __pragma(warning( push ))
#define MFEM_DISABLE_WARNING_POP            __pragma(warning( pop ))
#define MFEM_DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber ))
#define MFEM_DISABLE_WARNING_DEPRECATED     DISABLE_WARNING(4996)
#elif defined(__GNUC__) || defined(__clang__)
#define MFEM_DO_PRAGMA(X) _Pragma(#X)
#define MFEM_DISABLE_WARNING_PUSH           MFEM_DO_PRAGMA(GCC diagnostic push)
#define MFEM_DISABLE_WARNING_POP            MFEM_DO_PRAGMA(GCC diagnostic pop)
#define MFEM_DISABLE_WARNING(warningName)   MFEM_DO_PRAGMA(GCC diagnostic ignored #warningName)
#define MFEM_DISABLE_WARNING_DEPRECATED     MFEM_DISABLE_WARNING(-Wdeprecated-declarations)
#else
#pragma message("WARNING: You need to implement DISABLE_WARNING_* for this compiler")
#define MFEM_DISABLE_WARNING_PUSH
#define MFEM_DISABLE_WARNING_POP
#define MFEM_DISABLE_WARNING_DEPRECATED
#endif

#endif
<commit_msg>Fix new macros in MSVC.<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_GLOBALS_HPP
#define MFEM_GLOBALS_HPP

#include "../config/config.hpp"
#include <iostream>

#ifdef MFEM_USE_MPI
#include <mpi.h>
#endif

namespace mfem
{

/// Simple extension of std::ostream.
/** This class adds the ability to enable and disable the stream. The associated
    std::streambuf and tied std::ostream can be replaced with that of any
    std::ostream. */
class OutStream : public std::ostream
{
protected:
   // Pointer that stores the associated streambuf when output is disabled.
   std::streambuf *m_rdbuf;
   // Pointer that stores the tied ostream when output is disabled.
   std::ostream *m_tie;

   void Init();

public:
   /** @brief Construct an OutStream from the given stream @a out, by using its
       `rdbuf()`. */
   OutStream(std::ostream &out) : std::ostream(NULL) { SetStream(out); }

   /** @brief Replace the `rdbuf()` and `tie()` of the OutStream with that of
       @a out, enabling output. */
   void SetStream(std::ostream &out)
   {
      rdbuf(m_rdbuf = out.rdbuf()); tie(m_tie = out.tie()); Init();
   }

   /// Enable output.
   void Enable() { if (!IsEnabled()) { rdbuf(m_rdbuf); tie(m_tie); } }
   /// Disable output.
   void Disable()
   {
      if (IsEnabled()) { m_rdbuf = rdbuf(NULL); m_tie = tie(NULL); }
   }
   /// Check if output is enabled.
   bool IsEnabled() const { return (rdbuf() != NULL); }
};

/** @brief Global stream used by the library for standard output. Initially it
    uses the same std::streambuf as std::cout, however that can be changed.
    @sa OutStream. */
extern OutStream out;
/** @brief Global stream used by the library for standard error output.
    Initially it uses the same std::streambuf as std::cerr, however that can be
    changed.
    @sa OutStream. */
extern OutStream err;

/** @brief Construct a string of the form "<prefix><myid><suffix>" where the
    integer @a myid is padded with leading zeros to be at least @a width digits
    long. */
/** This is a convenience function, e.g. to redirect mfem::out to individual
    files for each rank, one can use:
    \code
       std::ofstream out_file(MakeParFilename("app_out.", myid).c_str());
       mfem::out.SetStream(out_file);
    \endcode
*/
std::string MakeParFilename(const std::string &prefix, const int myid,
                            const std::string suffix = "", const int width = 6);

#ifdef MFEM_USE_MPI

/** @name MFEM "global" communicator functions.

    Functions for getting and setting the MPI communicator used by the library
    as the "global" communicator.

    This "global" communicator is used for example in the function mfem_error(),
    which is invoked when an error is detected - the "global" communicator is
    used as a parameter to MPI_Abort() to terminate all "global" tasks. */
///@{

/// Get MFEM's "global" MPI communicator.
MPI_Comm GetGlobalMPI_Comm();

/// Set MFEM's "global" MPI communicator.
void SetGlobalMPI_Comm(MPI_Comm comm);

///@}

#endif

} // namespace mfem

// Request a global object to be instantiated for each thread in its TLS.
#define MFEM_THREAD_LOCAL thread_local

// MFEM_DEPRECATED macro to mark obsolete functions and methods
// see https://stackoverflow.com/questions/295120/c-mark-as-deprecated
#if defined(__GNUC__) || defined(__clang__)
#define MFEM_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define MFEM_DEPRECATED __declspec(deprecated)
#else
#pragma message("WARNING: You need to implement MFEM_DEPRECATED for this compiler")
#define MFEM_DEPRECATED
#endif

// Sometimes we have to ignore deprecation warnings internally to guarantee
// backwards compatibility.
// Code derived from https://www.fluentcpp.com/2019/08/30/how-to-disable-a-warning-in-cpp/
#if defined(_MSC_VER)
#define MFEM_DISABLE_WARNING_PUSH           __pragma(warning( push ))
#define MFEM_DISABLE_WARNING_POP            __pragma(warning( pop ))
#define MFEM_DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber ))
#define MFEM_DISABLE_WARNING_DEPRECATED     MFEM_DISABLE_WARNING(4996)
#elif defined(__GNUC__) || defined(__clang__)
#define MFEM_DO_PRAGMA(X) _Pragma(#X)
#define MFEM_DISABLE_WARNING_PUSH           MFEM_DO_PRAGMA(GCC diagnostic push)
#define MFEM_DISABLE_WARNING_POP            MFEM_DO_PRAGMA(GCC diagnostic pop)
#define MFEM_DISABLE_WARNING(warningName)   MFEM_DO_PRAGMA(GCC diagnostic ignored #warningName)
#define MFEM_DISABLE_WARNING_DEPRECATED     MFEM_DISABLE_WARNING(-Wdeprecated-declarations)
#else
#pragma message("WARNING: You need to implement DISABLE_WARNING_* for this compiler")
#define MFEM_DISABLE_WARNING_PUSH
#define MFEM_DISABLE_WARNING_POP
#define MFEM_DISABLE_WARNING_DEPRECATED
#endif

#endif
<|endoftext|>