<commit_before>// Use cases in C++
// See also file use-cases.md
//
// Notice: This is pseudo code. It will not compile, much less do anything useful.
//

using Storage::DeviceGraph;
using Storage::Disk;
using Storage::Partition;
typedef std::vector<Disk *> DiskVector;

#define EFI_BOOT_SIZE  64*MB
#define SWAP_SIZE       2*GB
#define ROOT_SIZE      20*GB
#define HOME_MIN_SIZE   5*GB

void bare_metal_pc() // this handles both modern and legacy bare metal PC
{
    const DeviceGraph *probed = Storage::get_probed();

    if ( probed->have_disks() )
    {
	DeviceGraph *staging = Storage::get_staging();
	Disk *disk = staging->get_disks().front();
	PartitionTable * partition_table = nullptr;

	if ( Storage::get_arch()->is_efi_boot() )
	{
	    // This implicitly deletes any existing partitions
	    partition_table = disk->create_partition_table( Disk::GPT );

	    Partition *efi_boot_part = partition_table->create_partition( EFI_BOOT_SIZE, ID_GPT_BOOT );
	    Filesystem *efi_boot_fs = efi_boot_part->create_filesystem( VFAT );
	    efi_boot_fs->set_mount_point( "/boot/efi" );
	}
	else
	{
	    partition_table = disk->create_partition_table( Disk::MSDOS );
	}

	Partition *swap_part = partition_table->create_partition( SWAP_SIZE, ID_SWAP );
	Filesystem *swap_fs = swap_part->create_filesystem( SWAP );
	swap_fs->set_mount_point( "swap" );

	DiskSize root_size = ROOT_SIZE;
	DiskSize home_size = disk->free_size() - root_size;

	if ( home_size < MIN_HOME_SIZE ) // No space for separate /home ?
	{
	    home_size = 0;
	    root_size = disk->free_size();
	}

	Partition *root_part = partition_table->create_partition( root_size, ID_LINUX );
	Filesystem *root_fs = root_part->create_filesystem( BTRFS );
	root_fs->set_mount_point( "/" );

	if ( home_size > 0 )
	{
	    Partition *home_part = partition_table->create_partition( home_size );
	    Filesystem *home_fs = home_part->create_filesystem( XFS );
	    home_fs->set_mount_point( "/home" );
	}

	try
	{
            // Apply all changes in staging: create and format partitions
	    //
	    // GUI applications will want to install error callbacks and use
	    // Storage::NoThrow
	    Storage::commit( Storage::DoThrow );
	}
	catch ( const Storage::Exception & exception )
	{
	    ST_CAUGHT( exception );

	    // Handle exception: Display errors to the user etc.
	    // ...
	    // ...
	}
    }

    // Intentionally NOT deleting staging or probed: They are owned by libstorage
}

void multi_boot_pc_with_windows()
// Pre-condition: We know that there is one disk, and that this one disk has an
// MS-DOS partition table and is completely occupied with one large Windows
// partition. These are just shortcuts to illustrate the relevant points here
// and to avoid getting bogged down in all kinds of fringe cases.
{
    const DeviceGraph *probed = Storage::get_probed();

    if ( ! probed->have_disks() )
	ST_THROW( StorageException( "Preconditions not met: No hard disk" ) );

    DeviceGraph *staging = Storage::get_staging();
    Disk *disk = staging->get_disks().front();
    MsDosPartitionTable * partition_table = disk->get_partition_table();

    if ( ! partition_table )
	ST_THROW( StorageException( "Preconditions not met: No MS-DOS partition table" ) );

    std::vector<const Partition *> partitions = disk->get_partitions();
    if ( partitions.size() != 1 )
	ST_THROW( StorageException( "Preconditions not met: One partition on disk expected" ) );

    // Find windows partition and resize it

    Partition *win_part = partitions.front();
    FsType win_fs_type = win_part->get_type();
    if ( win_part->get_type() != NTFS && win_part->get_type() != VFAT )
	ST_THROW( StorageException( "Preconditions not met: Expected NTFS or VFAT partition" ) );

    DiskSize win_size = win_part.get_size();
    DiskSize win_min_size = win_part.get_resize_info();
    DiskSize win_new_size = std::min( win_min_size * 1.2, win_size );

    win_part->resize( win_new_size );

    // Create Linux partitions

    Partition *swap_part = partition_table->create_partition( SWAP_SIZE, ID_SWAP ); // primary partition
    Filesystem *swap_fs = swap_part->create_filesystem( SWAP );
    swap_fs->set_mount_point( "swap" );

    Region free_space = partition_table->largest_free_region();
    Partition *extended_part = partition_table->create_partition( free_space, EXTENDED );
    DiskSize root_size = ROOT_SIZE;
    DiskSize home_size = extended_part->free_size() - root_size;

    if ( home_size < MIN_HOME_SIZE ) // No space for separate /home ?
    {
	home_size = 0;
	root_size = disk->free_size();
    }

    Partition *root_part = extended_part->create_partition( root_size, ID_LINUX ); // logical partition
    Filesystem *root_fs = root_part->create_filesystem( BTRFS );
    root_fs->set_mount_point( "/" );

    if ( home_size > 0 )
    {
	Partition *home_part = extended_part->create_partition( home_size ); // logical partition
	Filesystem *home_fs = home_part->create_filesystem( XFS );
	home_fs->set_mount_point( "/home" );
    }

    try
    {
	// Apply all changes in staging: create and format partitions
	//
	// GUI applications will want to install error callbacks and use
	// Storage::NoThrow
	Storage::commit( Storage::DoThrow );
    }
    catch ( const Storage::Exception & exception )
    {
	ST_CAUGHT( exception );

	// Handle exception: Display errors to the user etc.
	// ...
	// ...
    }

    // Intentionally NOT deleting staging or probed: They are owned by libstorage
}
<commit_msg>added comment<commit_after>// Use cases in C++
// See also file use-cases.md
//
// This is how I (shundhammer@suse.de) would like to use it from an application
// developer's point of view. Many aspects are already slightly changed to
// match some technical aspects of Arvin's prototype of the new libstorage.
//
// Notice: This is pseudo code. It will not compile, much less do anything useful.
//

using Storage::DeviceGraph;
using Storage::Disk;
using Storage::Partition;
typedef std::vector<Disk *> DiskVector;

#define EFI_BOOT_SIZE  64*MB
#define SWAP_SIZE       2*GB
#define ROOT_SIZE      20*GB
#define HOME_MIN_SIZE   5*GB

void bare_metal_pc() // this handles both modern and legacy bare metal PC
{
    const DeviceGraph *probed = Storage::get_probed();

    if ( probed->have_disks() )
    {
	DeviceGraph *staging = Storage::get_staging();
	Disk *disk = staging->get_disks().front();
	PartitionTable * partition_table = nullptr;

	if ( Storage::get_arch()->is_efi_boot() )
	{
	    // This implicitly deletes any existing partitions
	    partition_table = disk->create_partition_table( Disk::GPT );

	    Partition *efi_boot_part = partition_table->create_partition( EFI_BOOT_SIZE, ID_GPT_BOOT );
	    Filesystem *efi_boot_fs = efi_boot_part->create_filesystem( VFAT );
	    efi_boot_fs->set_mount_point( "/boot/efi" );
	}
	else
	{
	    partition_table = disk->create_partition_table( Disk::MSDOS );
	}

	Partition *swap_part = partition_table->create_partition( SWAP_SIZE, ID_SWAP );
	Filesystem *swap_fs = swap_part->create_filesystem( SWAP );
	swap_fs->set_mount_point( "swap" );

	DiskSize root_size = ROOT_SIZE;
	DiskSize home_size = disk->free_size() - root_size;

	if ( home_size < MIN_HOME_SIZE ) // No space for separate /home ?
	{
	    home_size = 0;
	    root_size = disk->free_size();
	}

	Partition *root_part = partition_table->create_partition( root_size, ID_LINUX );
	Filesystem *root_fs = root_part->create_filesystem( BTRFS );
	root_fs->set_mount_point( "/" );

	if ( home_size > 0 )
	{
	    Partition *home_part = partition_table->create_partition( home_size );
	    Filesystem *home_fs = home_part->create_filesystem( XFS );
	    home_fs->set_mount_point( "/home" );
	}

	try
	{
            // Apply all changes in staging: create and format partitions
	    //
	    // GUI applications will want to install error callbacks and use
	    // Storage::NoThrow
	    Storage::commit( Storage::DoThrow );
	}
	catch ( const Storage::Exception & exception )
	{
	    ST_CAUGHT( exception );

	    // Handle exception: Display errors to the user etc.
	    // ...
	    // ...
	}
    }

    // Intentionally NOT deleting staging or probed: They are owned by libstorage
}

void multi_boot_pc_with_windows()
// Pre-condition: We know that there is one disk, and that this one disk has an
// MS-DOS partition table and is completely occupied with one large Windows
// partition. These are just shortcuts to illustrate the relevant points here
// and to avoid getting bogged down in all kinds of fringe cases.
{
    const DeviceGraph *probed = Storage::get_probed();

    if ( ! probed->have_disks() )
	ST_THROW( StorageException( "Preconditions not met: No hard disk" ) );

    DeviceGraph *staging = Storage::get_staging();
    Disk *disk = staging->get_disks().front();
    MsDosPartitionTable * partition_table = disk->get_partition_table();

    if ( ! partition_table )
	ST_THROW( StorageException( "Preconditions not met: No MS-DOS partition table" ) );

    std::vector<const Partition *> partitions = disk->get_partitions();
    if ( partitions.size() != 1 )
	ST_THROW( StorageException( "Preconditions not met: One partition on disk expected" ) );

    // Find windows partition and resize it

    Partition *win_part = partitions.front();
    FsType win_fs_type = win_part->get_type();
    if ( win_part->get_type() != NTFS && win_part->get_type() != VFAT )
	ST_THROW( StorageException( "Preconditions not met: Expected NTFS or VFAT partition" ) );

    DiskSize win_size = win_part.get_size();
    DiskSize win_min_size = win_part.get_resize_info();
    DiskSize win_new_size = std::min( win_min_size * 1.2, win_size );

    win_part->resize( win_new_size );

    // Create Linux partitions

    Partition *swap_part = partition_table->create_partition( SWAP_SIZE, ID_SWAP ); // primary partition
    Filesystem *swap_fs = swap_part->create_filesystem( SWAP );
    swap_fs->set_mount_point( "swap" );

    Region free_space = partition_table->largest_free_region();
    Partition *extended_part = partition_table->create_partition( free_space, EXTENDED );
    DiskSize root_size = ROOT_SIZE;
    DiskSize home_size = extended_part->free_size() - root_size;

    if ( home_size < MIN_HOME_SIZE ) // No space for separate /home ?
    {
	home_size = 0;
	root_size = disk->free_size();
    }

    Partition *root_part = extended_part->create_partition( root_size, ID_LINUX ); // logical partition
    Filesystem *root_fs = root_part->create_filesystem( BTRFS );
    root_fs->set_mount_point( "/" );

    if ( home_size > 0 )
    {
	Partition *home_part = extended_part->create_partition( home_size ); // logical partition
	Filesystem *home_fs = home_part->create_filesystem( XFS );
	home_fs->set_mount_point( "/home" );
    }

    try
    {
	// Apply all changes in staging: create and format partitions
	//
	// GUI applications will want to install error callbacks and use
	// Storage::NoThrow
	Storage::commit( Storage::DoThrow );
    }
    catch ( const Storage::Exception & exception )
    {
	ST_CAUGHT( exception );

	// Handle exception: Display errors to the user etc.
	// ...
	// ...
    }

    // Intentionally NOT deleting staging or probed: They are owned by libstorage
}
<|endoftext|>


<commit_before>#include "drawable.h"

using namespace std;

Drawable::Drawable() : m_idVAO(0), m_idVBO(0), m_shader(nullptr), m_model(1.0)
{
}

Drawable::~Drawable()
{
    glDeleteBuffers(1, &m_idVBO);
    glDeleteVertexArrays(1, &m_idVAO);
}

void Drawable::setShader(Shader* shader)
{
    m_shader = shader;
}

void Drawable::setModel(glm::mat4 model)
{
    m_model = model;
}

const Shader* Drawable::getShader() const
{
    return m_shader;
}

const glm::mat4& Drawable::getModel() const
{
    return m_model;
}

GLuint Drawable::getIdVAO() const
{
    return m_idVAO;
}

GLuint Drawable::getIdVBO() const
{
    return m_idVBO;
}

GLuint Drawable::getIdIBO() const
{
    return m_idIBO;
}
int Drawable::getVerticesNumber() const
{
    return m_verticesNumber;
}

int Drawable::getIndicesNumber() const
{
    return m_indicesNumber;
}

void Drawable::rotate(glm::vec3 axis, float angle)
{
    m_model = glm::rotate(m_model, angle, axis);
}

void Drawable::translate(glm::vec3 translation)
{
    m_model = glm::translate(m_model, translation);
}

void Drawable::homothetie(glm::vec3 homoth)
{
    m_model = glm::scale(m_model, homoth);
}

void Drawable::load(std::vector<glm::vec3> const &vertices, std::vector<glm::uvec3> const &indices)
{
    int sizeVertices = sizeof(glm::vec3) * vertices.size();
    int sizeIBO = sizeof(glm::uvec3) * indices.size();

    if (glIsVertexArray(m_idVAO) == GL_TRUE)
        glDeleteVertexArrays(1, &m_idVAO);

    glGenVertexArrays(1, &m_idVAO);
    glBindVertexArray(m_idVAO);

    if (glIsBuffer(m_idVBO) == GL_TRUE)
        glDeleteBuffers(1, &m_idVBO);

    glGenBuffers(1, &m_idVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_idVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeVertices, &vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    if (glIsBuffer(m_idIBO) == GL_TRUE)
        glDeleteBuffers(1, &m_idIBO);

    glGenBuffers(1, &m_idIBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_idIBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeIBO, &indices[0], GL_STATIC_DRAW);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    m_indicesNumber = indices.size() * 3 ;
    m_verticesNumber = vertices.size() * 3 ;

}

void Drawable::update(const std::vector<float> &data, int offset)
{
    glBindBuffer(GL_ARRAY_BUFFER, m_idVBO);
        void* VBOAddress = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        if (VBOAddress == NULL)
        {
            std::cerr << "Erreur au niveau de la récupération du VBO" << std::endl;
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            return;
        }
        memcpy(GET_ADDRESS(VBOAddress, offset), &data[0], data.size() * sizeof(float));

        glUnmapBuffer(GL_ARRAY_BUFFER);
        VBOAddress = NULL;

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
<commit_msg>SEGFAULT FIXED \!\!\!<commit_after>#include "drawable.h"

using namespace std;

Drawable::Drawable() : m_idVAO(0), m_idVBO(0), m_idIBO(0), m_shader(nullptr), m_model(1.0)
{
}

Drawable::~Drawable()
{
    glDeleteBuffers(1, &m_idVBO);
    glDeleteVertexArrays(1, &m_idVAO);
}

void Drawable::setShader(Shader* shader)
{
    m_shader = shader;
}

void Drawable::setModel(glm::mat4 model)
{
    m_model = model;
}

const Shader* Drawable::getShader() const
{
    return m_shader;
}

const glm::mat4& Drawable::getModel() const
{
    return m_model;
}

GLuint Drawable::getIdVAO() const
{
    return m_idVAO;
}

GLuint Drawable::getIdVBO() const
{
    return m_idVBO;
}

GLuint Drawable::getIdIBO() const
{
    return m_idIBO;
}
int Drawable::getVerticesNumber() const
{
    return m_verticesNumber;
}

int Drawable::getIndicesNumber() const
{
    return m_indicesNumber;
}

void Drawable::rotate(glm::vec3 axis, float angle)
{
    m_model = glm::rotate(m_model, angle, axis);
}

void Drawable::translate(glm::vec3 translation)
{
    m_model = glm::translate(m_model, translation);
}

void Drawable::homothetie(glm::vec3 homoth)
{
    m_model = glm::scale(m_model, homoth);
}

void Drawable::load(std::vector<glm::vec3> const &vertices, std::vector<glm::uvec3> const &indices)
{
    int sizeVertices = sizeof(glm::vec3) * vertices.size();
    int sizeIBO = sizeof(glm::uvec3) * indices.size();

    if (glIsVertexArray(m_idVAO) == GL_TRUE)
        glDeleteVertexArrays(1, &m_idVAO);

    glGenVertexArrays(1, &m_idVAO);
    glBindVertexArray(m_idVAO);

    if (glIsBuffer(m_idVBO) == GL_TRUE)
        glDeleteBuffers(1, &m_idVBO);

    glGenBuffers(1, &m_idVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_idVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeVertices, &vertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    if (glIsBuffer(m_idIBO) == GL_TRUE)
        glDeleteBuffers(1, &m_idIBO);

    glGenBuffers(1, &m_idIBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_idIBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeIBO, &indices[0], GL_STATIC_DRAW);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    m_indicesNumber = indices.size() * 3 ;
    m_verticesNumber = vertices.size() * 3 ;

}

void Drawable::update(const std::vector<float> &data, int offset)
{
    glBindBuffer(GL_ARRAY_BUFFER, m_idVBO);
        void* VBOAddress = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        if (VBOAddress == NULL)
        {
            std::cerr << "Erreur au niveau de la récupération du VBO" << std::endl;
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            return;
        }
        memcpy(GET_ADDRESS(VBOAddress, offset), &data[0], data.size() * sizeof(float));

        glUnmapBuffer(GL_ARRAY_BUFFER);
        VBOAddress = NULL;

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
<|endoftext|>


<commit_before><commit_msg>Update CmdLineInterface.hpp<commit_after>#ifndef CmdLineInterface_hpp
#define CmdLineInterface_hpp

#include "AppConfig.hpp"

class CmdLineInterface
{
    private:
        //void printUsage(std::string name);
        AppConfig config;
    public:
        CmdLineInterface(int argc, char *argv[]);
        AppConfig getConfig();
};

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


<commit_before>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * DataConcentrator.cpp
 *
 *  Created on: 15/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

#ifdef WIN32

#else
#include <dlfcn.h>
#endif

#include <thread>
#include <asio.hpp>
#include <opendnp3/LogLevels.h>

#include "DataConcentrator.h"
#include "Console.h"

#include <asiodnp3/ConsoleLogger.h>
#include "logging_cmds.h"
#include "NullPort.h"

#include "../WebUI/WebUI.h"

DataConcentrator::DataConcentrator(std::string FileName):
	ConfigParser(FileName),
	DNP3Mgr(std::thread::hardware_concurrency()),
	LOG_LEVEL(opendnp3::levels::NORMAL),
	AdvConsoleLog(asiodnp3::ConsoleLogger::Instance(),LOG_LEVEL),
	FileLog("datacon_log"),
	AdvFileLog(FileLog,LOG_LEVEL),
	IOS(std::thread::hardware_concurrency()),
	ios_working(new asio::io_service::work(IOS)),
    UI(new WebUI(10443))
{
	//fire up some worker threads
	for(size_t i=0; i < std::thread::hardware_concurrency(); ++i)
		std::thread([&](){IOS.run();}).detach();

	AdvConsoleLog.AddIngoreAlways(".*"); //silence all console messages by default
	DNP3Mgr.AddLogSubscriber(&AdvConsoleLog);
	DNP3Mgr.AddLogSubscriber(&AdvFileLog);

	//Parse the configs and create all the ports and connections
	ProcessFile();

    UI->AddResponder("/DataPorts", DataPorts);
    UI->AddResponder("/DataConnectors", DataConnectors);

    //Initialise Data Ports
	for(auto& port : DataPorts)
	{
		port.second->AddLogSubscriber(&AdvConsoleLog);
		port.second->AddLogSubscriber(&AdvFileLog);
		port.second->SetIOS(&IOS);
		port.second->SetLogLevel(LOG_LEVEL);
    }

    //Initialise Data Connectors
	for(auto& conn : DataConnectors)
	{
		conn.second->AddLogSubscriber(&AdvConsoleLog);
		conn.second->AddLogSubscriber(&AdvFileLog);
		conn.second->SetIOS(&IOS);
		conn.second->SetLogLevel(LOG_LEVEL);
	}
}
DataConcentrator::~DataConcentrator()
{
	//turn everything off
	this->Shutdown();
	DNP3Mgr.Shutdown();
	//tell the io service to let it's run functions return once there's no handlers left (letting our threads end)
	ios_working.reset();
	//help finish any work
	IOS.run();
}

void DataConcentrator::ProcessElements(const Json::Value& JSONRoot)
{
	if(!JSONRoot["LogFileSizekB"].isNull())
		FileLog.SetLogFileSizekB(JSONRoot["LogFileSizekB"].asUInt());

	if(!JSONRoot["NumLogFiles"].isNull())
		FileLog.SetNumLogFiles(JSONRoot["NumLogFiles"].asUInt());

	if(!JSONRoot["LogName"].isNull())
		FileLog.SetLogName(JSONRoot["LogName"].asString());

	if(!JSONRoot["LOG_LEVEL"].isNull())
	{
		std::string value = JSONRoot["LOG_LEVEL"].asString();
		if(value == "ALL")
			LOG_LEVEL = opendnp3::levels::ALL;
		else if(value == "ALL_COMMS")
			LOG_LEVEL = opendnp3::levels::ALL_COMMS;
		else if(value == "NORMAL")
			LOG_LEVEL = opendnp3::levels::NORMAL;
		else if(value == "NOTHING")
			LOG_LEVEL = opendnp3::levels::NOTHING;
		else
			std::cout << "Warning: invalid LOG_LEVEL setting: '" << value << "' : ignoring and using 'NORMAL' log level." << std::endl;
		AdvFileLog.SetLogLevel(LOG_LEVEL);
		AdvConsoleLog.SetLogLevel(LOG_LEVEL);
	}

	if(!JSONRoot["Ports"].isNull())
	{
		const Json::Value Ports = JSONRoot["Ports"];

		for(Json::Value::ArrayIndex n = 0; n < Ports.size(); ++n)
		{
			if(Ports[n]["Type"].isNull() || Ports[n]["Name"].isNull() || Ports[n]["ConfFilename"].isNull())
			{
				std::cout<<"Warning: invalid port config: need at least Type, Name, ConfFilename: \n'"<<Ports[n].toStyledString()<<"\n' : ignoring"<<std::endl;
			}
			else if(Ports[n]["Type"].asString() == "Null")
			{
				DataPorts[Ports[n]["Name"].asString()] = std::unique_ptr<DataPort>(new NullPort(Ports[n]["Name"].asString(), Ports[n]["ConfFilename"].asString(), Ports[n]["ConfOverrides"]));
			}
			else
			{
				//Looks for a specific library (for libs that implement more than one class)
				std::string libname;
				if(!Ports[n]["Library"].isNull())
				{
					libname = GetLibFileName(Ports[n]["Library"].asString());
				}
				//Otherwise use the naming convention lib<Type>Port.so to find the default lib that implements a type of port
				else
				{
					libname = GetLibFileName(Ports[n]["Type"].asString());
				}

				//try to load the lib
				auto* portlib = DYNLIBLOAD(libname.c_str());

				if(portlib == nullptr)
				{
					std::cout << "Warning: failed to load library '"<<libname<<"' skipping port..."<<std::endl;
					continue;
				}

				//Our API says the library should export a creation function: DataPort* new_<Type>Port(Name, Filename, Overrides)
				//it should return a pointer to a heap allocated instance of a descendant of DataPort
				std::string new_funcname = "new_"+Ports[n]["Type"].asString()+"Port";
				auto new_port_func = (DataPort*(*)(std::string, std::string, const Json::Value))DYNLIBGETSYM(portlib, new_funcname.c_str());

				if(new_port_func == nullptr)
				{
					std::cout << "Warning: failed to load symbol '"<<new_funcname<<"' for port type '"<<Ports[n]["Type"].asString()<<"' skipping port..."<<std::endl;
					continue;
				}

				//call the creation function and wrap the returned pointer to a new port
				DataPorts[Ports[n]["Name"].asString()] = std::unique_ptr<DataPort>(new_port_func(Ports[n]["Name"].asString(), Ports[n]["ConfFilename"].asString(), Ports[n]["ConfOverrides"]));
			}
		}
	}

	if(!JSONRoot["Connectors"].isNull())
	{
		const Json::Value Connectors = JSONRoot["Connectors"];

		for(Json::Value::ArrayIndex n = 0; n < Connectors.size(); ++n)
		{
			if(Connectors[n]["Name"].isNull() || Connectors[n]["ConfFilename"].isNull())
			{
				std::cout<<"Warning: invalid Connector config: need at least Name, ConfFilename: \n'"<<Connectors[n].toStyledString()<<"\n' : ignoring"<<std::endl;
			}
			DataConnectors[Connectors[n]["Name"].asString()] = std::unique_ptr<DataConnector>(new DataConnector(Connectors[n]["Name"].asString(), Connectors[n]["ConfFilename"].asString(), Connectors[n]["ConfOverrides"]));
		}
	}
}
void DataConcentrator::BuildOrRebuild()
{
	for(auto& Name_n_Port : DataPorts)
	{
		Name_n_Port.second->BuildOrRebuild(DNP3Mgr,LOG_LEVEL);
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		Name_n_Conn.second->BuildOrRebuild(DNP3Mgr,LOG_LEVEL);
	}
}
void DataConcentrator::Run()
{
	for(auto& Name_n_Conn : DataConnectors)
	{
		IOS.post([=]()
		{
			Name_n_Conn.second->Enable();
		});
	}
	for(auto& Name_n_Port : DataPorts)
	{
		IOS.post([=]()
		{
			Name_n_Port.second->Enable();
		});
	}

	Console console("odc> ");

    UI->start();

	std::function<void (std::stringstream&)> bound_func;

	//Version
	bound_func = [](std::stringstream& ss){std::cout<<"Release 0.2"<<std::endl;};
	console.AddCmd("version",bound_func,"Print version information");

	//console logging control
	bound_func = std::bind(cmd_ignore_message,std::placeholders::_1,std::ref(AdvConsoleLog));
	console.AddCmd("ignore_message",bound_func,"Enter regex to silence matching messages from the console logger.");
	bound_func = std::bind(cmd_unignore_message,std::placeholders::_1,std::ref(AdvConsoleLog));
	console.AddCmd("unignore_message",bound_func,"Enter regex to remove from the console ignore list.");
	bound_func = std::bind(cmd_show_ignored,std::placeholders::_1,std::ref(AdvConsoleLog));
	console.AddCmd("show_ignored",bound_func,"Shows all console message ignore regexes and how many messages they've matched.");

	//file logging control
	bound_func = std::bind(cmd_ignore_message,std::placeholders::_1,std::ref(AdvFileLog));
	console.AddCmd("ignore_file_message",bound_func,"Enter regex to silence matching messages from the file logger.");
	bound_func = std::bind(cmd_unignore_message,std::placeholders::_1,std::ref(AdvFileLog));
	console.AddCmd("unignore_file_message",bound_func,"Enter regex to remove from the file ignore list.");
	bound_func = std::bind(cmd_show_ignored,std::placeholders::_1,std::ref(AdvFileLog));
	console.AddCmd("show_file_ignored",bound_func,"Shows all file message ignore regexes and how many messages they've matched.");

	//disable/enable/restart
	bound_func = std::bind(&DataConcentrator::EnablePortOrConn,this,std::placeholders::_1,true);
	console.AddCmd("enable",bound_func,"Enable ports and/or connectors matching a regex (by name)");
	bound_func = std::bind(&DataConcentrator::EnablePortOrConn,this,std::placeholders::_1,false);
	console.AddCmd("disable",bound_func,"Disable ports and/or connectors matching a regex (by name)");
	bound_func = std::bind(&DataConcentrator::RestartPortOrConn,this,std::placeholders::_1);
	console.AddCmd("restart",bound_func,"Restart ports and/or connectors matching a regex (by name)");

	//list ports/connectors
	bound_func = std::bind(&DataConcentrator::ListPorts,this,std::placeholders::_1);
	console.AddCmd("lsports",bound_func,"List ports matching a regex (by name)");
	bound_func = std::bind(&DataConcentrator::ListConns,this,std::placeholders::_1);
	console.AddCmd("lsconns",bound_func,"List connectors matching a regex (by name)");

	console.run();
	Shutdown();
}
void DataConcentrator::RestartPortOrConn(std::stringstream& args)
{
	EnablePortOrConn(args,false);
	EnablePortOrConn(args,true);
}
void DataConcentrator::EnablePortOrConn(std::stringstream& args, bool enable)
{
	std::string arg = "";
	std::string mregex;
	std::regex reg;
	if(!extract_delimited_string(args,mregex))
	{
		std::cout<<"Syntax error: Delimited regex expected, found \"..."<<mregex<<"\""<<std::endl;
		return;
	}
	try
	{
		reg = std::regex(mregex);
	}
	catch(std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
		return;
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		if(std::regex_match(Name_n_Conn.first, reg))
			enable ? Name_n_Conn.second->Enable() : Name_n_Conn.second->Disable();
	}
	for(auto& Name_n_Port : DataPorts)
	{
		if(std::regex_match(Name_n_Port.first, reg))
			enable ? Name_n_Port.second->Enable() : Name_n_Port.second->Disable();
	}
}
void DataConcentrator::ListPorts(std::stringstream& args)
{
	std::string arg = "";
	std::string mregex;
	std::regex reg;
	if(!extract_delimited_string(args,mregex))
	{
		std::cout<<"Syntax error: Delimited regex expected, found \"..."<<mregex<<"\""<<std::endl;
		return;
	}
	try
	{
		reg = std::regex(mregex);
	}
	catch(std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
		return;
	}
	for(auto& Name_n_Port : DataPorts)
	{
		if(std::regex_match(Name_n_Port.first, reg))
			std::cout<<Name_n_Port.first<<std::endl;
	}
}
void DataConcentrator::ListConns(std::stringstream& args)
{
	std::string arg = "";
	std::string mregex;
	std::regex reg;
	if(!extract_delimited_string(args,mregex))
	{
		std::cout<<"Syntax error: Delimited regex expected, found \"..."<<mregex<<"\""<<std::endl;
		return;
	}
	try
	{
		reg = std::regex(mregex);
	}
	catch(std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
		return;
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		if(std::regex_match(Name_n_Conn.first, reg))
			std::cout<<Name_n_Conn.first<<std::endl;
	}
}
void DataConcentrator::Shutdown()
{
    UI->stop();
	for(auto& Name_n_Port : DataPorts)
	{
		Name_n_Port.second->Disable();
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		Name_n_Conn.second->Disable();
	}
}
<commit_msg>Start WebUI as soon as DataConcentrator is created<commit_after>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * DataConcentrator.cpp
 *
 *  Created on: 15/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

#ifdef WIN32

#else
#include <dlfcn.h>
#endif

#include <thread>
#include <asio.hpp>
#include <opendnp3/LogLevels.h>

#include "DataConcentrator.h"
#include "Console.h"

#include <asiodnp3/ConsoleLogger.h>
#include "logging_cmds.h"
#include "NullPort.h"

#include "../WebUI/WebUI.h"

DataConcentrator::DataConcentrator(std::string FileName):
	ConfigParser(FileName),
	DNP3Mgr(std::thread::hardware_concurrency()),
	LOG_LEVEL(opendnp3::levels::NORMAL),
	AdvConsoleLog(asiodnp3::ConsoleLogger::Instance(),LOG_LEVEL),
	FileLog("datacon_log"),
	AdvFileLog(FileLog,LOG_LEVEL),
	IOS(std::thread::hardware_concurrency()),
	ios_working(new asio::io_service::work(IOS)),
    UI(new WebUI(10443))
{
    UI->start();

	//fire up some worker threads
	for(size_t i=0; i < std::thread::hardware_concurrency(); ++i)
		std::thread([&](){IOS.run();}).detach();

	AdvConsoleLog.AddIngoreAlways(".*"); //silence all console messages by default
	DNP3Mgr.AddLogSubscriber(&AdvConsoleLog);
	DNP3Mgr.AddLogSubscriber(&AdvFileLog);

	//Parse the configs and create all the ports and connections
	ProcessFile();

    UI->AddResponder("/DataPorts", DataPorts);
    UI->AddResponder("/DataConnectors", DataConnectors);

    //Initialise Data Ports
	for(auto& port : DataPorts)
	{
		port.second->AddLogSubscriber(&AdvConsoleLog);
		port.second->AddLogSubscriber(&AdvFileLog);
		port.second->SetIOS(&IOS);
		port.second->SetLogLevel(LOG_LEVEL);
    }

    //Initialise Data Connectors
	for(auto& conn : DataConnectors)
	{
		conn.second->AddLogSubscriber(&AdvConsoleLog);
		conn.second->AddLogSubscriber(&AdvFileLog);
		conn.second->SetIOS(&IOS);
		conn.second->SetLogLevel(LOG_LEVEL);
	}
}
DataConcentrator::~DataConcentrator()
{
	//turn everything off
	this->Shutdown();
	DNP3Mgr.Shutdown();
	//tell the io service to let it's run functions return once there's no handlers left (letting our threads end)
	ios_working.reset();
	//help finish any work
	IOS.run();

    UI->stop();
}

void DataConcentrator::ProcessElements(const Json::Value& JSONRoot)
{
	if(!JSONRoot["LogFileSizekB"].isNull())
		FileLog.SetLogFileSizekB(JSONRoot["LogFileSizekB"].asUInt());

	if(!JSONRoot["NumLogFiles"].isNull())
		FileLog.SetNumLogFiles(JSONRoot["NumLogFiles"].asUInt());

	if(!JSONRoot["LogName"].isNull())
		FileLog.SetLogName(JSONRoot["LogName"].asString());

	if(!JSONRoot["LOG_LEVEL"].isNull())
	{
		std::string value = JSONRoot["LOG_LEVEL"].asString();
		if(value == "ALL")
			LOG_LEVEL = opendnp3::levels::ALL;
		else if(value == "ALL_COMMS")
			LOG_LEVEL = opendnp3::levels::ALL_COMMS;
		else if(value == "NORMAL")
			LOG_LEVEL = opendnp3::levels::NORMAL;
		else if(value == "NOTHING")
			LOG_LEVEL = opendnp3::levels::NOTHING;
		else
			std::cout << "Warning: invalid LOG_LEVEL setting: '" << value << "' : ignoring and using 'NORMAL' log level." << std::endl;
		AdvFileLog.SetLogLevel(LOG_LEVEL);
		AdvConsoleLog.SetLogLevel(LOG_LEVEL);
	}

	if(!JSONRoot["Ports"].isNull())
	{
		const Json::Value Ports = JSONRoot["Ports"];

		for(Json::Value::ArrayIndex n = 0; n < Ports.size(); ++n)
		{
			if(Ports[n]["Type"].isNull() || Ports[n]["Name"].isNull() || Ports[n]["ConfFilename"].isNull())
			{
				std::cout<<"Warning: invalid port config: need at least Type, Name, ConfFilename: \n'"<<Ports[n].toStyledString()<<"\n' : ignoring"<<std::endl;
			}
			else if(Ports[n]["Type"].asString() == "Null")
			{
				DataPorts[Ports[n]["Name"].asString()] = std::unique_ptr<DataPort>(new NullPort(Ports[n]["Name"].asString(), Ports[n]["ConfFilename"].asString(), Ports[n]["ConfOverrides"]));
			}
			else
			{
				//Looks for a specific library (for libs that implement more than one class)
				std::string libname;
				if(!Ports[n]["Library"].isNull())
				{
					libname = GetLibFileName(Ports[n]["Library"].asString());
				}
				//Otherwise use the naming convention lib<Type>Port.so to find the default lib that implements a type of port
				else
				{
					libname = GetLibFileName(Ports[n]["Type"].asString());
				}

				//try to load the lib
				auto* portlib = DYNLIBLOAD(libname.c_str());

				if(portlib == nullptr)
				{
					std::cout << "Warning: failed to load library '"<<libname<<"' skipping port..."<<std::endl;
					continue;
				}

				//Our API says the library should export a creation function: DataPort* new_<Type>Port(Name, Filename, Overrides)
				//it should return a pointer to a heap allocated instance of a descendant of DataPort
				std::string new_funcname = "new_"+Ports[n]["Type"].asString()+"Port";
				auto new_port_func = (DataPort*(*)(std::string, std::string, const Json::Value))DYNLIBGETSYM(portlib, new_funcname.c_str());

				if(new_port_func == nullptr)
				{
					std::cout << "Warning: failed to load symbol '"<<new_funcname<<"' for port type '"<<Ports[n]["Type"].asString()<<"' skipping port..."<<std::endl;
					continue;
				}

				//call the creation function and wrap the returned pointer to a new port
				DataPorts[Ports[n]["Name"].asString()] = std::unique_ptr<DataPort>(new_port_func(Ports[n]["Name"].asString(), Ports[n]["ConfFilename"].asString(), Ports[n]["ConfOverrides"]));
			}
		}
	}

	if(!JSONRoot["Connectors"].isNull())
	{
		const Json::Value Connectors = JSONRoot["Connectors"];

		for(Json::Value::ArrayIndex n = 0; n < Connectors.size(); ++n)
		{
			if(Connectors[n]["Name"].isNull() || Connectors[n]["ConfFilename"].isNull())
			{
				std::cout<<"Warning: invalid Connector config: need at least Name, ConfFilename: \n'"<<Connectors[n].toStyledString()<<"\n' : ignoring"<<std::endl;
			}
			DataConnectors[Connectors[n]["Name"].asString()] = std::unique_ptr<DataConnector>(new DataConnector(Connectors[n]["Name"].asString(), Connectors[n]["ConfFilename"].asString(), Connectors[n]["ConfOverrides"]));
		}
	}
}
void DataConcentrator::BuildOrRebuild()
{
	for(auto& Name_n_Port : DataPorts)
	{
		Name_n_Port.second->BuildOrRebuild(DNP3Mgr,LOG_LEVEL);
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		Name_n_Conn.second->BuildOrRebuild(DNP3Mgr,LOG_LEVEL);
	}
}
void DataConcentrator::Run()
{
	for(auto& Name_n_Conn : DataConnectors)
	{
		IOS.post([=]()
		{
			Name_n_Conn.second->Enable();
		});
	}
	for(auto& Name_n_Port : DataPorts)
	{
		IOS.post([=]()
		{
			Name_n_Port.second->Enable();
		});
	}

	Console console("odc> ");

	std::function<void (std::stringstream&)> bound_func;

	//Version
	bound_func = [](std::stringstream& ss){std::cout<<"Release 0.2"<<std::endl;};
	console.AddCmd("version",bound_func,"Print version information");

	//console logging control
	bound_func = std::bind(cmd_ignore_message,std::placeholders::_1,std::ref(AdvConsoleLog));
	console.AddCmd("ignore_message",bound_func,"Enter regex to silence matching messages from the console logger.");
	bound_func = std::bind(cmd_unignore_message,std::placeholders::_1,std::ref(AdvConsoleLog));
	console.AddCmd("unignore_message",bound_func,"Enter regex to remove from the console ignore list.");
	bound_func = std::bind(cmd_show_ignored,std::placeholders::_1,std::ref(AdvConsoleLog));
	console.AddCmd("show_ignored",bound_func,"Shows all console message ignore regexes and how many messages they've matched.");

	//file logging control
	bound_func = std::bind(cmd_ignore_message,std::placeholders::_1,std::ref(AdvFileLog));
	console.AddCmd("ignore_file_message",bound_func,"Enter regex to silence matching messages from the file logger.");
	bound_func = std::bind(cmd_unignore_message,std::placeholders::_1,std::ref(AdvFileLog));
	console.AddCmd("unignore_file_message",bound_func,"Enter regex to remove from the file ignore list.");
	bound_func = std::bind(cmd_show_ignored,std::placeholders::_1,std::ref(AdvFileLog));
	console.AddCmd("show_file_ignored",bound_func,"Shows all file message ignore regexes and how many messages they've matched.");

	//disable/enable/restart
	bound_func = std::bind(&DataConcentrator::EnablePortOrConn,this,std::placeholders::_1,true);
	console.AddCmd("enable",bound_func,"Enable ports and/or connectors matching a regex (by name)");
	bound_func = std::bind(&DataConcentrator::EnablePortOrConn,this,std::placeholders::_1,false);
	console.AddCmd("disable",bound_func,"Disable ports and/or connectors matching a regex (by name)");
	bound_func = std::bind(&DataConcentrator::RestartPortOrConn,this,std::placeholders::_1);
	console.AddCmd("restart",bound_func,"Restart ports and/or connectors matching a regex (by name)");

	//list ports/connectors
	bound_func = std::bind(&DataConcentrator::ListPorts,this,std::placeholders::_1);
	console.AddCmd("lsports",bound_func,"List ports matching a regex (by name)");
	bound_func = std::bind(&DataConcentrator::ListConns,this,std::placeholders::_1);
	console.AddCmd("lsconns",bound_func,"List connectors matching a regex (by name)");

	console.run();
	Shutdown();
}
void DataConcentrator::RestartPortOrConn(std::stringstream& args)
{
	EnablePortOrConn(args,false);
	EnablePortOrConn(args,true);
}
void DataConcentrator::EnablePortOrConn(std::stringstream& args, bool enable)
{
	std::string arg = "";
	std::string mregex;
	std::regex reg;
	if(!extract_delimited_string(args,mregex))
	{
		std::cout<<"Syntax error: Delimited regex expected, found \"..."<<mregex<<"\""<<std::endl;
		return;
	}
	try
	{
		reg = std::regex(mregex);
	}
	catch(std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
		return;
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		if(std::regex_match(Name_n_Conn.first, reg))
			enable ? Name_n_Conn.second->Enable() : Name_n_Conn.second->Disable();
	}
	for(auto& Name_n_Port : DataPorts)
	{
		if(std::regex_match(Name_n_Port.first, reg))
			enable ? Name_n_Port.second->Enable() : Name_n_Port.second->Disable();
	}
}
void DataConcentrator::ListPorts(std::stringstream& args)
{
	std::string arg = "";
	std::string mregex;
	std::regex reg;
	if(!extract_delimited_string(args,mregex))
	{
		std::cout<<"Syntax error: Delimited regex expected, found \"..."<<mregex<<"\""<<std::endl;
		return;
	}
	try
	{
		reg = std::regex(mregex);
	}
	catch(std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
		return;
	}
	for(auto& Name_n_Port : DataPorts)
	{
		if(std::regex_match(Name_n_Port.first, reg))
			std::cout<<Name_n_Port.first<<std::endl;
	}
}
void DataConcentrator::ListConns(std::stringstream& args)
{
	std::string arg = "";
	std::string mregex;
	std::regex reg;
	if(!extract_delimited_string(args,mregex))
	{
		std::cout<<"Syntax error: Delimited regex expected, found \"..."<<mregex<<"\""<<std::endl;
		return;
	}
	try
	{
		reg = std::regex(mregex);
	}
	catch(std::exception& e)
	{
		std::cout<<e.what()<<std::endl;
		return;
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		if(std::regex_match(Name_n_Conn.first, reg))
			std::cout<<Name_n_Conn.first<<std::endl;
	}
}
void DataConcentrator::Shutdown()
{

	for(auto& Name_n_Port : DataPorts)
	{
		Name_n_Port.second->Disable();
	}
	for(auto& Name_n_Conn : DataConnectors)
	{
		Name_n_Conn.second->Disable();
	}
}
<|endoftext|>


<commit_before>

#include "DiscoveryVisitor.hpp"
#include "DataExtractor.hpp"

#include "util.hpp"
#include "Type.hpp"

namespace autobind {

std::string prototypeSpelling(clang::FunctionDecl *decl)
{
	std::string result;
	bool first = true;

	result += decl->getResultType().getAsString();
	result += " ";
	result += decl->getQualifiedNameAsString();

	result += "(";

	for(auto param : PROP_RANGE(decl->param))
	{
		if(first) first = false;
		else result += ", ";

		result += param->getType().getAsString();
		result += " ";
		result += param->getNameAsString();

	}
	result += ")";

	return result;
}

auto attributeStream(clang::Decl &x)
{
	return streams::stream(x.specific_attr_begin<clang::AnnotateAttr>(),
	                       x.specific_attr_end<clang::AnnotateAttr>());
}

bool isPyExport(clang::Decl *d)
{
	using namespace streams;

	auto pred = [](auto a) { return a->getAnnotation() == "pyexport"; };
	return any(attributeStream(*d) | transformed(pred));
}

class DiscoveryVisitor
: public clang::RecursiveASTVisitor<DiscoveryVisitor>
{
	DataExtractor _wrapperEmitter;
	bool _foundModule = false;
	std::vector<clang::FunctionDecl *> _matches;
	autobind::ModuleManager &_modmgr;
	std::vector<autobind::Module *> _modstack;
public:

	explicit DiscoveryVisitor(clang::ASTContext *context, autobind::ModuleManager &modmgr)
	: _wrapperEmitter(context)
	, _modmgr(modmgr)
	{

	}

	bool checkInModule(clang::Decl *d)
	{
		if(_modstack.empty())
		{
			auto &diags = d->getASTContext().getDiagnostics();
			unsigned id = diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
			                                    "python exports must be preceded by module declaration");
			diags.Report(d->getLocation(), id);
			return false;
		}

		return true;
	}

	bool VisitCXXRecordDecl(clang::CXXRecordDecl *decl)
	{

		if(isPyExport(decl))
		{
			if(!checkInModule(decl)) return false;

			auto name = decl->getQualifiedNameAsString();
			auto unqualName = rsplit(name, "::").second;

// 			assert(!_modstack.empty());
			auto ty = std::make_unique<Type>(unqualName, name, "");
			using namespace streams;

			bool foundConstructor = false;

			if(decl->hasTrivialCopyConstructor())
			{
				ty->setCopyAvailable();
			}

			for(auto field : stream(decl->decls_begin(), decl->decls_end()))
			{
// 				if(llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(field)
// 			   		|| llvm::dyn_cast_or_null<clang::CXXDestructorDecl>(field))
// 				{
// 					continue;
// 				}
				if(auto constructor = llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(field))
				{
					if(!foundConstructor && !constructor->isCopyOrMoveConstructor())
					{
						foundConstructor = true;
						auto cdata = _wrapperEmitter.function(constructor);
						cdata->setReturnType("void"); // prevents attempting to convert result type
						ty->setConstructor(std::move(cdata));
						std::cerr << "--> found constructor: "<< constructor->getQualifiedNameAsString() << "\n";
					}
					else if(constructor->isCopyConstructor())
					{
						ty->setCopyAvailable();
					}
				}
				else if(llvm::dyn_cast_or_null<clang::CXXDestructorDecl>(field))
				{
					// ignore
				}
				else if(auto method = llvm::dyn_cast_or_null<clang::CXXMethodDecl>(field))
				{
					if(!method->isOverloadedOperator() && method->getAccess() == clang::AS_public)
					{
// 						std::cerr << "--> found method: " << method->getQualifiedNameAsString() << "\n";
						auto mdata = _wrapperEmitter.method(method);
						ty->addMethod(std::move(mdata));
					}
// 					else
// 					{
// 						std::cerr << "--> ignored method: "<< method->getQualifiedNameAsString() << "\n";
// 					}
				}

			}

			_modstack.back()->addExport(std::move(ty));

		}

		return true;
	}

	bool VisitNamespaceDecl(clang::NamespaceDecl *decl)
	{
		using namespace streams;

		auto stream = attributeStream(*decl)
			| filtered([](auto a) { return a->getAnnotation().startswith("py:module:"); });

		if(!stream.empty())
		{
			if(_foundModule)
			{
				auto &diags = decl->getASTContext().getDiagnostics();
				unsigned id = diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
				                                    "redeclaration of module name");

				diags.Report(decl->getLocation(), id);

				return false;
			}

			auto parts = stream.front()->getAnnotation().rsplit(':');
			_modstack.insert(_modstack.begin(), &_modmgr.module(parts.second));
			_foundModule = true;

		}

		auto docstringStream = attributeStream(*decl)
			| filtered([](auto a) { return a->getAnnotation().startswith("pydocstring:"); });

		if(!docstringStream.empty())
		{
			auto ann = docstringStream.front()->getAnnotation();
			checkInModule(decl);

			_modstack.back()->setDocstring(ann.split(':').second);
		}

		return true;
	}

	bool TraverseNamespaceDecl(clang::NamespaceDecl *decl)
	{

		bool pushed = false;

		if(isPyExport(decl))
		{
			_modstack.push_back(&_modmgr.module(decl->getNameAsString()));

			if(auto comment = decl->getASTContext().getRawCommentForAnyRedecl(decl))
			{
				if(comment->isDocumentation())
				{
					_modstack.back()->setDocstring(comment->getRawText(decl->getASTContext().getSourceManager()));
				}
			}

			pushed = true;
		}

		bool result = clang::RecursiveASTVisitor<DiscoveryVisitor>::TraverseNamespaceDecl(decl);

		if(pushed)
		{
			assert(!_modstack.empty());
			_modstack.pop_back();
		}

		return result;
	}

//
// 	bool VisitMethodDecl(clang::CXXMethodDecl *decl)
// 	{
// 		if(isPyExport(decl->getParent()))
// 		{
// 			if(!checkInModule(decl)) return false;
//
// 			// check not a structor
// 			if(llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(decl)
// 			   || llvm::dyn_cast_or_null<clang::CXXDestructorDecl>(decl))
// 			{
// 				return true;
// 			}
//
//
// 		}
// 	}
//
	bool VisitFunctionDecl(clang::FunctionDecl *decl)
	{

		if(isPyExport(decl))
		{
			if(!checkInModule(decl)) return false;
			_modstack.back()->addExport(_wrapperEmitter.function(decl));
		}

		return true;
	}

	const std::vector<clang::FunctionDecl *> &matches() const
	{
		return _matches;
	}
};

void discoverTranslationUnit(autobind::ModuleManager &mgr,
                             clang::TranslationUnitDecl &tu)
{
	DiscoveryVisitor dv(&tu.getASTContext(), mgr);
	dv.TraverseDecl(&tu);

}
} // autobind<commit_msg>Fix copy constructor detection logic.<commit_after>

#include "DiscoveryVisitor.hpp"
#include "DataExtractor.hpp"

#include "util.hpp"
#include "Type.hpp"

namespace autobind {

std::string prototypeSpelling(clang::FunctionDecl *decl)
{
	std::string result;
	bool first = true;

	result += decl->getResultType().getAsString();
	result += " ";
	result += decl->getQualifiedNameAsString();

	result += "(";

	for(auto param : PROP_RANGE(decl->param))
	{
		if(first) first = false;
		else result += ", ";

		result += param->getType().getAsString();
		result += " ";
		result += param->getNameAsString();

	}
	result += ")";

	return result;
}

auto attributeStream(clang::Decl &x)
{
	return streams::stream(x.specific_attr_begin<clang::AnnotateAttr>(),
	                       x.specific_attr_end<clang::AnnotateAttr>());
}

bool isPyExport(clang::Decl *d)
{
	using namespace streams;

	auto pred = [](auto a) { return a->getAnnotation() == "pyexport"; };
	return any(attributeStream(*d) | transformed(pred));
}

class DiscoveryVisitor
: public clang::RecursiveASTVisitor<DiscoveryVisitor>
{
	DataExtractor _wrapperEmitter;
	bool _foundModule = false;
	std::vector<clang::FunctionDecl *> _matches;
	autobind::ModuleManager &_modmgr;
	std::vector<autobind::Module *> _modstack;
public:

	explicit DiscoveryVisitor(clang::ASTContext *context, autobind::ModuleManager &modmgr)
	: _wrapperEmitter(context)
	, _modmgr(modmgr)
	{

	}

	bool checkInModule(clang::Decl *d)
	{
		if(_modstack.empty())
		{
			auto &diags = d->getASTContext().getDiagnostics();
			unsigned id = diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
			                                    "python exports must be preceded by module declaration");
			diags.Report(d->getLocation(), id);
			return false;
		}

		return true;
	}

	bool VisitCXXRecordDecl(clang::CXXRecordDecl *decl)
	{

		if(isPyExport(decl))
		{
			if(!checkInModule(decl)) return false;

			auto name = decl->getQualifiedNameAsString();
			auto unqualName = rsplit(name, "::").second;

// 			assert(!_modstack.empty());
			auto ty = std::make_unique<Type>(unqualName, name, "");
			using namespace streams;

			bool foundConstructor = false;

			if(decl->hasTrivialCopyConstructor() || decl->hasNonTrivialCopyConstructor())
			{
				ty->setCopyAvailable();
			}

			for(auto field : stream(decl->decls_begin(), decl->decls_end()))
			{
// 				if(llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(field)
// 			   		|| llvm::dyn_cast_or_null<clang::CXXDestructorDecl>(field))
// 				{
// 					continue;
// 				}
				if(auto constructor = llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(field))
				{
					if(!foundConstructor && !constructor->isCopyOrMoveConstructor())
					{
						foundConstructor = true;
						auto cdata = _wrapperEmitter.function(constructor);
						cdata->setReturnType("void"); // prevents attempting to convert result type
						ty->setConstructor(std::move(cdata));
						std::cerr << "--> found constructor: "<< constructor->getQualifiedNameAsString() << "\n";
					}
					else if(constructor->isCopyConstructor())
					{
						ty->setCopyAvailable();
					}
				}
				else if(llvm::dyn_cast_or_null<clang::CXXDestructorDecl>(field))
				{
					// ignore
				}
				else if(auto method = llvm::dyn_cast_or_null<clang::CXXMethodDecl>(field))
				{
					if(!method->isOverloadedOperator() && method->getAccess() == clang::AS_public)
					{
// 						std::cerr << "--> found method: " << method->getQualifiedNameAsString() << "\n";
						auto mdata = _wrapperEmitter.method(method);
						ty->addMethod(std::move(mdata));
					}
// 					else
// 					{
// 						std::cerr << "--> ignored method: "<< method->getQualifiedNameAsString() << "\n";
// 					}
				}

			}

			_modstack.back()->addExport(std::move(ty));

		}

		return true;
	}

	bool VisitNamespaceDecl(clang::NamespaceDecl *decl)
	{
		using namespace streams;

		auto stream = attributeStream(*decl)
			| filtered([](auto a) { return a->getAnnotation().startswith("py:module:"); });

		if(!stream.empty())
		{
			if(_foundModule)
			{
				auto &diags = decl->getASTContext().getDiagnostics();
				unsigned id = diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
				                                    "redeclaration of module name");

				diags.Report(decl->getLocation(), id);

				return false;
			}

			auto parts = stream.front()->getAnnotation().rsplit(':');
			_modstack.insert(_modstack.begin(), &_modmgr.module(parts.second));
			_foundModule = true;

		}

		auto docstringStream = attributeStream(*decl)
			| filtered([](auto a) { return a->getAnnotation().startswith("pydocstring:"); });

		if(!docstringStream.empty())
		{
			auto ann = docstringStream.front()->getAnnotation();
			checkInModule(decl);

			_modstack.back()->setDocstring(ann.split(':').second);
		}

		return true;
	}

	bool TraverseNamespaceDecl(clang::NamespaceDecl *decl)
	{

		bool pushed = false;

		if(isPyExport(decl))
		{
			_modstack.push_back(&_modmgr.module(decl->getNameAsString()));

			if(auto comment = decl->getASTContext().getRawCommentForAnyRedecl(decl))
			{
				if(comment->isDocumentation())
				{
					_modstack.back()->setDocstring(comment->getRawText(decl->getASTContext().getSourceManager()));
				}
			}

			pushed = true;
		}

		bool result = clang::RecursiveASTVisitor<DiscoveryVisitor>::TraverseNamespaceDecl(decl);

		if(pushed)
		{
			assert(!_modstack.empty());
			_modstack.pop_back();
		}

		return result;
	}

//
// 	bool VisitMethodDecl(clang::CXXMethodDecl *decl)
// 	{
// 		if(isPyExport(decl->getParent()))
// 		{
// 			if(!checkInModule(decl)) return false;
//
// 			// check not a structor
// 			if(llvm::dyn_cast_or_null<clang::CXXConstructorDecl>(decl)
// 			   || llvm::dyn_cast_or_null<clang::CXXDestructorDecl>(decl))
// 			{
// 				return true;
// 			}
//
//
// 		}
// 	}
//
	bool VisitFunctionDecl(clang::FunctionDecl *decl)
	{

		if(isPyExport(decl))
		{
			if(!checkInModule(decl)) return false;
			_modstack.back()->addExport(_wrapperEmitter.function(decl));
		}

		return true;
	}

	const std::vector<clang::FunctionDecl *> &matches() const
	{
		return _matches;
	}
};

void discoverTranslationUnit(autobind::ModuleManager &mgr,
                             clang::TranslationUnitDecl &tu)
{
	DiscoveryVisitor dv(&tu.getASTContext(), mgr);
	dv.TraverseDecl(&tu);

}
} // autobind<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: querycontainerwindow.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2004-09-09 09:49:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source 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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef DBAUI_QUERYCONTAINERWINDOW_HXX
#include "querycontainerwindow.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef DBAUI_JOINCONTROLLER_HXX
#include "JoinController.hxx"
#endif
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _SFXSIDS_HRC
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
#include <com/sun/star/util/XCloseable.hpp>
#endif
//.........................................................................
namespace dbaui
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::frame;

    //=====================================================================
    //= OQueryContainerWindow
    //=====================================================================
    DBG_NAME(OQueryContainerWindow)
    OQueryContainerWindow::OQueryContainerWindow(Window* pParent, OQueryController* _pController,const Reference< XMultiServiceFactory >& _rFactory)
        :ODataView(pParent,_pController, _rFactory)
        ,m_pBeamer(NULL)
        ,m_pViewSwitch(NULL)
    {
        DBG_CTOR(OQueryContainerWindow,NULL);
        m_pViewSwitch = new OQueryViewSwitch(this,_pController,_rFactory);

        m_pSplitter = new Splitter(this,WB_VSCROLL);
        m_pSplitter->Hide();
        m_pSplitter->SetSplitHdl( LINK( this, OQueryContainerWindow, SplitHdl ) );
        m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
    }
    // -----------------------------------------------------------------------------
    OQueryContainerWindow::~OQueryContainerWindow()
    {
        DBG_DTOR(OQueryContainerWindow,NULL);
        {
            ::std::auto_ptr<OQueryViewSwitch> aTemp(m_pViewSwitch);
            m_pViewSwitch = NULL;
        }
        if ( m_pBeamer )
            ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
        m_pBeamer = NULL;
        if ( m_xBeamer.is() )
        {
            Reference< ::com::sun::star::util::XCloseable > xCloseable(m_xBeamer,UNO_QUERY);
            m_xBeamer = NULL;
            if(xCloseable.is())
                xCloseable->close(sal_False); // false - holds the owner ship of this frame
            //  m_xBeamer->setComponent(NULL,NULL);
        }
        {
            ::std::auto_ptr<Window> aTemp(m_pSplitter);
            m_pSplitter = NULL;
        }
    }
    // -----------------------------------------------------------------------------
    sal_Bool OQueryContainerWindow::switchView()
    {
        return m_pViewSwitch->switchView();
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::resizeAll( const Rectangle& _rPlayground )
    {
        Rectangle aPlayground( _rPlayground );

        if ( m_pBeamer && m_pBeamer->IsVisible() )
        {
            // calc pos and size of the splitter
            Point aSplitPos     = m_pSplitter->GetPosPixel();
            Size aSplitSize     = m_pSplitter->GetOutputSizePixel();
            aSplitSize.Width() = aPlayground.GetWidth();

            if ( aSplitPos.Y() <= aPlayground.Top() )
                aSplitPos.Y() = aPlayground.Top() + sal_Int32( aPlayground.GetHeight() * 0.2 );

            if ( aSplitPos.Y() + aSplitSize.Height() > aPlayground.GetHeight() )
                aSplitPos.Y() = aPlayground.GetHeight() - aSplitSize.Height();

            // set pos and size of the splitter
            m_pSplitter->SetPosSizePixel( aSplitPos, aSplitSize );
            m_pSplitter->SetDragRectPixel(  aPlayground );

            // set pos and size of the beamer
            Size aBeamerSize( aPlayground.GetWidth(), aSplitPos.Y() );
            m_pBeamer->SetPosSizePixel( aPlayground.TopLeft(), aBeamerSize );

            // shrink the playground by the size which is occupied by the beamer
            aPlayground.Top() = aSplitPos.Y() + aSplitSize.Height();
        }

        ODataView::resizeAll( aPlayground );
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::resizeDocumentView( Rectangle& _rPlayground )
    {
        m_pViewSwitch->SetPosSizePixel( _rPlayground.TopLeft(), Size( _rPlayground.GetWidth(), _rPlayground.GetHeight() ) );

        ODataView::resizeDocumentView( _rPlayground );
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::GetFocus()
    {
        ODataView::GetFocus();
        if(m_pViewSwitch)
            m_pViewSwitch->GrabFocus();
    }
    // -----------------------------------------------------------------------------
    IMPL_LINK( OQueryContainerWindow, SplitHdl, void*, p )
    {
        long nTest = m_pSplitter->GetPosPixel().Y();
        m_pSplitter->SetPosPixel( Point( m_pSplitter->GetPosPixel().X(),m_pSplitter->GetSplitPosPixel() ) );
        Resize();

        return 0L;
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::Construct()
    {
        m_pViewSwitch->Construct();
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::initialize(const Reference<XFrame>& _xFrame)
    {
        // append our frame
        Reference < XFramesSupplier > xSup(_xFrame,UNO_QUERY);
        Reference < XFrames > xFrames = xSup->getFrames();
        xFrames->append( m_xBeamer );
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::disposingPreview()
    {
        if ( m_pBeamer )
        {
            // here I know that we will be destroyed from the frame
            ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
            m_pBeamer = NULL;
            m_xBeamer = NULL;
            m_pSplitter->Hide();
            Resize();
        }
    }
    // -----------------------------------------------------------------------------
    long OQueryContainerWindow::PreNotify( NotifyEvent& rNEvt )
    {
        BOOL bHandled = FALSE;
        switch (rNEvt.GetType())
        {
            case  EVENT_GETFOCUS:
                if ( m_pViewSwitch )
                {
                    OJoinController* pController = m_pViewSwitch->getDesignView()->getController();
                    pController->InvalidateFeature(SID_CUT);
                    pController->InvalidateFeature(SID_COPY);
                    pController->InvalidateFeature(SID_PASTE);
                }
        }
        return bHandled ? 1L : ODataView::PreNotify(rNEvt);
    }
    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::showPreview(const Reference<XFrame>& _xFrame)
    {
        if(!m_pBeamer)
        {
            m_pBeamer = new OBeamer(this);

            ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::AddWindow));

            m_xBeamer.set(m_pViewSwitch->getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Frame")),UNO_QUERY);
            OSL_ENSURE(m_xBeamer.is(),"No frame created!");
            m_xBeamer->initialize( VCLUnoHelper::GetInterface ( m_pBeamer ) );
            m_xBeamer->setName(FRAME_NAME_QUERY_PREVIEW);

            // append our frame
            Reference < XFramesSupplier > xSup(_xFrame,UNO_QUERY);
            Reference < XFrames > xFrames = xSup->getFrames();
            xFrames->append( m_xBeamer );

            Size aSize = GetOutputSizePixel();
            Size aBeamer(aSize.Width(),sal_Int32(aSize.Height()*0.33));

            const long  nFrameHeight = LogicToPixel( Size( 0, 3 ), MAP_APPFONT ).Height();
            Point aPos(0,aBeamer.Height()+nFrameHeight);

            m_pBeamer->SetPosSizePixel(Point(0,0),aBeamer);
            m_pBeamer->Show();

            m_pSplitter->SetPosSizePixel( Point(0,aBeamer.Height()), Size(aSize.Width(),nFrameHeight) );
            // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
            m_pSplitter->SetSplitPosPixel( aBeamer.Height() );
            m_pViewSwitch->SetPosSizePixel(aPos,Size(aBeamer.Width(),aSize.Height() - aBeamer.Height()-nFrameHeight));

            m_pSplitter->Show();

            Resize();
        }
    }
    // -----------------------------------------------------------------------------

//.........................................................................
}   // namespace dbaui
//.........................................................................

<commit_msg>INTEGRATION: CWS ooo19126 (1.12.194); FILE MERGED 2005/09/05 17:35:39 rt 1.12.194.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: querycontainerwindow.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:33:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef DBAUI_QUERYCONTAINERWINDOW_HXX
#include "querycontainerwindow.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef DBAUI_JOINCONTROLLER_HXX
#include "JoinController.hxx"
#endif
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _SFXSIDS_HRC
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
#include <com/sun/star/util/XCloseable.hpp>
#endif
//.........................................................................
namespace dbaui
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::frame;

    //=====================================================================
    //= OQueryContainerWindow
    //=====================================================================
    DBG_NAME(OQueryContainerWindow)
    OQueryContainerWindow::OQueryContainerWindow(Window* pParent, OQueryController* _pController,const Reference< XMultiServiceFactory >& _rFactory)
        :ODataView(pParent,_pController, _rFactory)
        ,m_pBeamer(NULL)
        ,m_pViewSwitch(NULL)
    {
        DBG_CTOR(OQueryContainerWindow,NULL);
        m_pViewSwitch = new OQueryViewSwitch(this,_pController,_rFactory);

        m_pSplitter = new Splitter(this,WB_VSCROLL);
        m_pSplitter->Hide();
        m_pSplitter->SetSplitHdl( LINK( this, OQueryContainerWindow, SplitHdl ) );
        m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
    }
    // -----------------------------------------------------------------------------
    OQueryContainerWindow::~OQueryContainerWindow()
    {
        DBG_DTOR(OQueryContainerWindow,NULL);
        {
            ::std::auto_ptr<OQueryViewSwitch> aTemp(m_pViewSwitch);
            m_pViewSwitch = NULL;
        }
        if ( m_pBeamer )
            ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
        m_pBeamer = NULL;
        if ( m_xBeamer.is() )
        {
            Reference< ::com::sun::star::util::XCloseable > xCloseable(m_xBeamer,UNO_QUERY);
            m_xBeamer = NULL;
            if(xCloseable.is())
                xCloseable->close(sal_False); // false - holds the owner ship of this frame
            //  m_xBeamer->setComponent(NULL,NULL);
        }
        {
            ::std::auto_ptr<Window> aTemp(m_pSplitter);
            m_pSplitter = NULL;
        }
    }
    // -----------------------------------------------------------------------------
    sal_Bool OQueryContainerWindow::switchView()
    {
        return m_pViewSwitch->switchView();
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::resizeAll( const Rectangle& _rPlayground )
    {
        Rectangle aPlayground( _rPlayground );

        if ( m_pBeamer && m_pBeamer->IsVisible() )
        {
            // calc pos and size of the splitter
            Point aSplitPos     = m_pSplitter->GetPosPixel();
            Size aSplitSize     = m_pSplitter->GetOutputSizePixel();
            aSplitSize.Width() = aPlayground.GetWidth();

            if ( aSplitPos.Y() <= aPlayground.Top() )
                aSplitPos.Y() = aPlayground.Top() + sal_Int32( aPlayground.GetHeight() * 0.2 );

            if ( aSplitPos.Y() + aSplitSize.Height() > aPlayground.GetHeight() )
                aSplitPos.Y() = aPlayground.GetHeight() - aSplitSize.Height();

            // set pos and size of the splitter
            m_pSplitter->SetPosSizePixel( aSplitPos, aSplitSize );
            m_pSplitter->SetDragRectPixel(  aPlayground );

            // set pos and size of the beamer
            Size aBeamerSize( aPlayground.GetWidth(), aSplitPos.Y() );
            m_pBeamer->SetPosSizePixel( aPlayground.TopLeft(), aBeamerSize );

            // shrink the playground by the size which is occupied by the beamer
            aPlayground.Top() = aSplitPos.Y() + aSplitSize.Height();
        }

        ODataView::resizeAll( aPlayground );
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::resizeDocumentView( Rectangle& _rPlayground )
    {
        m_pViewSwitch->SetPosSizePixel( _rPlayground.TopLeft(), Size( _rPlayground.GetWidth(), _rPlayground.GetHeight() ) );

        ODataView::resizeDocumentView( _rPlayground );
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::GetFocus()
    {
        ODataView::GetFocus();
        if(m_pViewSwitch)
            m_pViewSwitch->GrabFocus();
    }
    // -----------------------------------------------------------------------------
    IMPL_LINK( OQueryContainerWindow, SplitHdl, void*, p )
    {
        long nTest = m_pSplitter->GetPosPixel().Y();
        m_pSplitter->SetPosPixel( Point( m_pSplitter->GetPosPixel().X(),m_pSplitter->GetSplitPosPixel() ) );
        Resize();

        return 0L;
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::Construct()
    {
        m_pViewSwitch->Construct();
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::initialize(const Reference<XFrame>& _xFrame)
    {
        // append our frame
        Reference < XFramesSupplier > xSup(_xFrame,UNO_QUERY);
        Reference < XFrames > xFrames = xSup->getFrames();
        xFrames->append( m_xBeamer );
    }

    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::disposingPreview()
    {
        if ( m_pBeamer )
        {
            // here I know that we will be destroyed from the frame
            ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
            m_pBeamer = NULL;
            m_xBeamer = NULL;
            m_pSplitter->Hide();
            Resize();
        }
    }
    // -----------------------------------------------------------------------------
    long OQueryContainerWindow::PreNotify( NotifyEvent& rNEvt )
    {
        BOOL bHandled = FALSE;
        switch (rNEvt.GetType())
        {
            case  EVENT_GETFOCUS:
                if ( m_pViewSwitch )
                {
                    OJoinController* pController = m_pViewSwitch->getDesignView()->getController();
                    pController->InvalidateFeature(SID_CUT);
                    pController->InvalidateFeature(SID_COPY);
                    pController->InvalidateFeature(SID_PASTE);
                }
        }
        return bHandled ? 1L : ODataView::PreNotify(rNEvt);
    }
    // -----------------------------------------------------------------------------
    void OQueryContainerWindow::showPreview(const Reference<XFrame>& _xFrame)
    {
        if(!m_pBeamer)
        {
            m_pBeamer = new OBeamer(this);

            ::dbaui::notifySystemWindow(this,m_pBeamer,::comphelper::mem_fun(&TaskPaneList::AddWindow));

            m_xBeamer.set(m_pViewSwitch->getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Frame")),UNO_QUERY);
            OSL_ENSURE(m_xBeamer.is(),"No frame created!");
            m_xBeamer->initialize( VCLUnoHelper::GetInterface ( m_pBeamer ) );
            m_xBeamer->setName(FRAME_NAME_QUERY_PREVIEW);

            // append our frame
            Reference < XFramesSupplier > xSup(_xFrame,UNO_QUERY);
            Reference < XFrames > xFrames = xSup->getFrames();
            xFrames->append( m_xBeamer );

            Size aSize = GetOutputSizePixel();
            Size aBeamer(aSize.Width(),sal_Int32(aSize.Height()*0.33));

            const long  nFrameHeight = LogicToPixel( Size( 0, 3 ), MAP_APPFONT ).Height();
            Point aPos(0,aBeamer.Height()+nFrameHeight);

            m_pBeamer->SetPosSizePixel(Point(0,0),aBeamer);
            m_pBeamer->Show();

            m_pSplitter->SetPosSizePixel( Point(0,aBeamer.Height()), Size(aSize.Width(),nFrameHeight) );
            // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
            m_pSplitter->SetSplitPosPixel( aBeamer.Height() );
            m_pViewSwitch->SetPosSizePixel(aPos,Size(aBeamer.Width(),aSize.Height() - aBeamer.Height()-nFrameHeight));

            m_pSplitter->Show();

            Resize();
        }
    }
    // -----------------------------------------------------------------------------

//.........................................................................
}   // namespace dbaui
//.........................................................................

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2015 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/Modules.h>

class CBlockMotd : public CModule {
public:
	MODCONSTRUCTOR(CBlockMotd) {
	}

	virtual ~CBlockMotd() {
	}

	EModRet OnRaw(CString &sLine) override {
		const CString sCmd = sLine.Token(1);

		if (sCmd == "375" /* begin of MOTD */
				|| sCmd == "372" /* MOTD */)
			return HALT;
		if (sCmd == "376" /* End of MOTD */) {
			sLine = sLine.Token(0) + " 422 " +
				sLine.Token(2) + " :MOTD blocked by ZNC";
		}
		return CONTINUE;
	}
};

template<> void TModInfo<CBlockMotd>(CModInfo& Info) {
	Info.AddType(CModInfo::NetworkModule);
	Info.AddType(CModInfo::GlobalModule);
	Info.SetWikiPage("block_motd");
}

USERMODULEDEFS(CBlockMotd, "Block the MOTD from IRC so it's not sent to your client(s).")
<commit_msg>blockmotd: Allow overriding via command<commit_after>/*
 * Copyright (C) 2004-2015 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/Modules.h>

class CBlockMotd : public CModule {
public:
	MODCONSTRUCTOR(CBlockMotd) {
		AddHelpCommand();
		AddCommand("GetMotd", static_cast<CModCommand::ModCmdFunc>(&CBlockMotd::OverrideCommand), "[<server>]", "Override the block with this command. Can optionally specify which server to query.");
	}

	virtual ~CBlockMotd() {
	}

	void OverrideCommand(const CString& sLine) {
		m_bTemporaryAcceptMotd = true;
		const CString sServer = sLine.Token(1);

		if (sServer.empty()) {
			PutIRC("motd");
		} else {
			PutIRC("motd " + sServer);
		}
	}

	EModRet OnRaw(CString &sLine) override {
		const CString sCmd = sLine.Token(1);

		if ((sCmd == "375" /* begin of MOTD */ || sCmd == "372" /* MOTD */)
			&& !m_bTemporaryAcceptMotd)
			return HALT;

		if (sCmd == "376" /* End of MOTD */) {
			if (!m_bTemporaryAcceptMotd) {
				sLine = sLine.Token(0) + " 422 " +
					sLine.Token(2) + " :MOTD blocked by ZNC";
			}
			m_bTemporaryAcceptMotd = false;
		}
		return CONTINUE;
	}

private:
	bool m_bTemporaryAcceptMotd = false;
};

template<> void TModInfo<CBlockMotd>(CModInfo& Info) {
	Info.AddType(CModInfo::NetworkModule);
	Info.AddType(CModInfo::GlobalModule);
	Info.SetWikiPage("block_motd");
}

USERMODULEDEFS(CBlockMotd, "Block the MOTD from IRC so it's not sent to your client(s).")
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "menufactory.h"
#include "messageview.h"
#include "userlistview.h"
#include "sessiontreeitem.h"
#include "sessiontabwidget.h"
#include "sessiontreewidget.h"
#include "session.h"
#include <IrcCommand>

MenuFactory::MenuFactory(QObject* parent) : QObject(parent)
{
}

MenuFactory::~MenuFactory()
{
}

class UserViewMenu : public QMenu
{
    Q_OBJECT

public:
    UserViewMenu(const QString& user, MessageView* view) :
        QMenu(view), user(user), view(view)
    {
    }

private slots:
    void onWhoisTriggered()
    {
        IrcCommand* command = IrcCommand::createWhois(user);
        view->session()->sendCommand(command);
    }

    void onQueryTriggered()
    {
        QMetaObject::invokeMethod(view, "queried", Q_ARG(QString, user));
    }

private:
    QString user;
    MessageView* view;
};

QMenu* MenuFactory::createUserViewMenu(const QString& user, MessageView* view)
{
    UserViewMenu* menu = new UserViewMenu(user, view);
    menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
    menu->addAction(tr("Query"), menu, SLOT(onQueryTriggered()));
    return menu;
}

class TabViewMenu : public QMenu
{
    Q_OBJECT

public:
    TabViewMenu(MessageView* view, SessionTabWidget* tab) :
        QMenu(tab), view(view), tab(tab)
    {
    }

private slots:
    void onEditSession()
    {
        QMetaObject::invokeMethod(tab, "editSession", Q_ARG(Session*, view->session()));
    }

    void onNamesTriggered()
    {
        IrcCommand* command = IrcCommand::createNames(view->receiver());
        view->session()->sendCommand(command);
    }

    void onWhoisTriggered()
    {
        IrcCommand* command = IrcCommand::createWhois(view->receiver());
        view->session()->sendCommand(command);
    }

    void onCloseView()
    {
        tab->removeView(view->receiver());
    }

private:
    MessageView* view;
    SessionTabWidget* tab;
};

QMenu* MenuFactory::createTabViewMenu(MessageView* view, SessionTabWidget* tab)
{
    TabViewMenu* menu = new TabViewMenu(view, tab);
    if (view->viewType() == MessageView::ServerView) {
        if (view->session()->isActive())
            menu->addAction(tr("Disconnect"), view->session(), SLOT(quit()));
        else
            menu->addAction(tr("Reconnect"), view->session(), SLOT(reconnect()));
        menu->addAction(tr("Edit"), menu, SLOT(onEditSession()))->setEnabled(!view->session()->isActive());
    }
    if (view->viewType() == MessageView::ChannelView) {
        menu->addAction(tr("Names"), menu, SLOT(onNamesTriggered()));
        menu->addAction(tr("Part"), menu, SLOT(onCloseView()));
    } else {
        menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
        menu->addAction(tr("Close"), menu, SLOT(onCloseView()));
    }
    return menu;
}

class UserListMenu : public QMenu
{
    Q_OBJECT

public:
    UserListMenu(UserListView* listView) : QMenu(listView), listView(listView)
    {
    }

private slots:
    void onWhoisTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            IrcCommand* command = IrcCommand::createWhois(action->data().toString());
            listView->session()->sendCommand(command);
        }
    }

    void onQueryTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action)
            QMetaObject::invokeMethod(listView, "queried", Q_ARG(QString, action->data().toString()));
    }

    void onModeTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            QStringList params = action->data().toStringList();
            IrcCommand* command = IrcCommand::createMode(listView->channel(), params.at(1), params.at(0));
            listView->session()->sendCommand(command);
        }
    }

    void onKickTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            IrcCommand* command = IrcCommand::createKick(listView->channel(), action->data().toString());
            listView->session()->sendCommand(command);
        }
    }

    void onBanTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            IrcCommand* command = IrcCommand::createMode(listView->channel(), "+b", action->data().toString() + "!*@*");
            listView->session()->sendCommand(command);
        }
    }

private:
    UserListView* listView;
};

QMenu* MenuFactory::createUserListMenu(const QString& user, UserListView* listView)
{
    UserListMenu* menu = new UserListMenu(listView);

    QString mode = listView->session()->userPrefix(user);
    QString name = listView->session()->unprefixedUser(user);

    QAction* action = 0;
    action = menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
    action->setData(name);

    action = menu->addAction(tr("Query"), menu, SLOT(onQueryTriggered()));
    action->setData(name);

    menu->addSeparator();

    if (mode.contains("@")) {
        action = menu->addAction(tr("Deop"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "-o");
    } else {
        action = menu->addAction(tr("Op"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "+o");
    }

    if (mode.contains("+")) {
        action = menu->addAction(tr("Devoice"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "-v");
    } else {
        action = menu->addAction(tr("Voice"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "+v");
    }

    menu->addSeparator();

    action = menu->addAction(tr("Kick"), menu, SLOT(onKickTriggered()));
    action->setData(name);

    action = menu->addAction(tr("Ban"), menu, SLOT(onBanTriggered()));
    action->setData(name);

    return menu;
}

class SessionTreeMenu : public QMenu
{
    Q_OBJECT

public:
    SessionTreeMenu(SessionTreeItem* item, SessionTreeWidget* tree) :
        QMenu(tree), item(item), tree(tree)
    {
    }

private slots:
    void onEditSession()
    {
        QMetaObject::invokeMethod(tree, "editSession", Q_ARG(Session*, item->session()));
    }

    void onNamesTriggered()
    {
        IrcCommand* command = IrcCommand::createNames(item->text(0));
        item->session()->sendCommand(command);
    }

    void onWhoisTriggered()
    {
        IrcCommand* command = IrcCommand::createWhois(item->text(0));
        item->session()->sendCommand(command);
    }

    void onCloseItem()
    {
        QMetaObject::invokeMethod(tree, "closeItem", Q_ARG(SessionTreeItem*, item));
    }

private:
    SessionTreeItem* item;
    SessionTreeWidget* tree;
};

QMenu* MenuFactory::createSessionTreeMenu(SessionTreeItem* item, SessionTreeWidget* tree)
{
    SessionTreeMenu* menu = new SessionTreeMenu(item, tree);
    if (!item->parent()) {
        if (item->session()->isActive())
            menu->addAction(tr("Disconnect"), item->session(), SLOT(quit()));
        else
            menu->addAction(tr("Reconnect"), item->session(), SLOT(reconnect()));
        menu->addAction(tr("Edit"), menu, SLOT(onEditSession()))->setEnabled(!item->session()->isActive());
    }
    if (item->session()->isChannel(item->text(0))) {
        menu->addAction(tr("Names"), menu, SLOT(onNamesTriggered()));
        menu->addAction(tr("Part"), menu, SLOT(onCloseItem()));
    } else {
        menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
        menu->addAction(tr("Close"), menu, SLOT(onCloseItem()));
    }
    return menu;
}

#include "menufactory.moc"
<commit_msg>desktop: fix the "Part" item in the session tree menu<commit_after>/*
* Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "menufactory.h"
#include "messageview.h"
#include "userlistview.h"
#include "sessiontreeitem.h"
#include "sessiontabwidget.h"
#include "sessiontreewidget.h"
#include "session.h"
#include <IrcCommand>

MenuFactory::MenuFactory(QObject* parent) : QObject(parent)
{
}

MenuFactory::~MenuFactory()
{
}

class UserViewMenu : public QMenu
{
    Q_OBJECT

public:
    UserViewMenu(const QString& user, MessageView* view) :
        QMenu(view), user(user), view(view)
    {
    }

private slots:
    void onWhoisTriggered()
    {
        IrcCommand* command = IrcCommand::createWhois(user);
        view->session()->sendCommand(command);
    }

    void onQueryTriggered()
    {
        QMetaObject::invokeMethod(view, "queried", Q_ARG(QString, user));
    }

private:
    QString user;
    MessageView* view;
};

QMenu* MenuFactory::createUserViewMenu(const QString& user, MessageView* view)
{
    UserViewMenu* menu = new UserViewMenu(user, view);
    menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
    menu->addAction(tr("Query"), menu, SLOT(onQueryTriggered()));
    return menu;
}

class TabViewMenu : public QMenu
{
    Q_OBJECT

public:
    TabViewMenu(MessageView* view, SessionTabWidget* tab) :
        QMenu(tab), view(view), tab(tab)
    {
    }

private slots:
    void onEditSession()
    {
        QMetaObject::invokeMethod(tab, "editSession", Q_ARG(Session*, view->session()));
    }

    void onNamesTriggered()
    {
        IrcCommand* command = IrcCommand::createNames(view->receiver());
        view->session()->sendCommand(command);
    }

    void onWhoisTriggered()
    {
        IrcCommand* command = IrcCommand::createWhois(view->receiver());
        view->session()->sendCommand(command);
    }

    void onCloseView()
    {
        tab->removeView(view->receiver());
    }

private:
    MessageView* view;
    SessionTabWidget* tab;
};

QMenu* MenuFactory::createTabViewMenu(MessageView* view, SessionTabWidget* tab)
{
    TabViewMenu* menu = new TabViewMenu(view, tab);
    if (view->viewType() == MessageView::ServerView) {
        if (view->session()->isActive())
            menu->addAction(tr("Disconnect"), view->session(), SLOT(quit()));
        else
            menu->addAction(tr("Reconnect"), view->session(), SLOT(reconnect()));
        menu->addAction(tr("Edit"), menu, SLOT(onEditSession()))->setEnabled(!view->session()->isActive());
    }
    if (view->viewType() == MessageView::ChannelView) {
        menu->addAction(tr("Names"), menu, SLOT(onNamesTriggered()));
        menu->addAction(tr("Part"), menu, SLOT(onCloseView()));
    } else {
        menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
        menu->addAction(tr("Close"), menu, SLOT(onCloseView()));
    }
    return menu;
}

class UserListMenu : public QMenu
{
    Q_OBJECT

public:
    UserListMenu(UserListView* listView) : QMenu(listView), listView(listView)
    {
    }

private slots:
    void onWhoisTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            IrcCommand* command = IrcCommand::createWhois(action->data().toString());
            listView->session()->sendCommand(command);
        }
    }

    void onQueryTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action)
            QMetaObject::invokeMethod(listView, "queried", Q_ARG(QString, action->data().toString()));
    }

    void onModeTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            QStringList params = action->data().toStringList();
            IrcCommand* command = IrcCommand::createMode(listView->channel(), params.at(1), params.at(0));
            listView->session()->sendCommand(command);
        }
    }

    void onKickTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            IrcCommand* command = IrcCommand::createKick(listView->channel(), action->data().toString());
            listView->session()->sendCommand(command);
        }
    }

    void onBanTriggered()
    {
        QAction* action = qobject_cast<QAction*>(sender());
        if (action) {
            IrcCommand* command = IrcCommand::createMode(listView->channel(), "+b", action->data().toString() + "!*@*");
            listView->session()->sendCommand(command);
        }
    }

private:
    UserListView* listView;
};

QMenu* MenuFactory::createUserListMenu(const QString& user, UserListView* listView)
{
    UserListMenu* menu = new UserListMenu(listView);

    QString mode = listView->session()->userPrefix(user);
    QString name = listView->session()->unprefixedUser(user);

    QAction* action = 0;
    action = menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
    action->setData(name);

    action = menu->addAction(tr("Query"), menu, SLOT(onQueryTriggered()));
    action->setData(name);

    menu->addSeparator();

    if (mode.contains("@")) {
        action = menu->addAction(tr("Deop"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "-o");
    } else {
        action = menu->addAction(tr("Op"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "+o");
    }

    if (mode.contains("+")) {
        action = menu->addAction(tr("Devoice"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "-v");
    } else {
        action = menu->addAction(tr("Voice"), menu, SLOT(onModeTriggered()));
        action->setData(QStringList() << name << "+v");
    }

    menu->addSeparator();

    action = menu->addAction(tr("Kick"), menu, SLOT(onKickTriggered()));
    action->setData(name);

    action = menu->addAction(tr("Ban"), menu, SLOT(onBanTriggered()));
    action->setData(name);

    return menu;
}

class SessionTreeMenu : public QMenu
{
    Q_OBJECT

public:
    SessionTreeMenu(SessionTreeItem* item, SessionTreeWidget* tree) :
        QMenu(tree), item(item), tree(tree)
    {
    }

private slots:
    void onEditSession()
    {
        QMetaObject::invokeMethod(tree, "editSession", Q_ARG(Session*, item->session()));
    }

    void onNamesTriggered()
    {
        IrcCommand* command = IrcCommand::createNames(item->text(0));
        item->session()->sendCommand(command);
    }

    void onWhoisTriggered()
    {
        IrcCommand* command = IrcCommand::createWhois(item->text(0));
        item->session()->sendCommand(command);
    }

    void onPartTriggered()
    {
        IrcCommand* command = IrcCommand::createPart(item->text(0));
        item->session()->sendCommand(command);
    }

    void onCloseTriggered()
    {
        QMetaObject::invokeMethod(tree, "closeItem", Q_ARG(SessionTreeItem*, item));
    }

private:
    SessionTreeItem* item;
    SessionTreeWidget* tree;
};

QMenu* MenuFactory::createSessionTreeMenu(SessionTreeItem* item, SessionTreeWidget* tree)
{
    SessionTreeMenu* menu = new SessionTreeMenu(item, tree);
    if (!item->parent()) {
        if (item->session()->isActive())
            menu->addAction(tr("Disconnect"), item->session(), SLOT(quit()));
        else
            menu->addAction(tr("Reconnect"), item->session(), SLOT(reconnect()));
        menu->addAction(tr("Edit"), menu, SLOT(onEditSession()))->setEnabled(!item->session()->isActive());
    }
    if (item->session()->isChannel(item->text(0))) {
        menu->addAction(tr("Names"), menu, SLOT(onNamesTriggered()));
        menu->addAction(tr("Part"), menu, SLOT(onPartTriggered()));
    } else {
        menu->addAction(tr("Whois"), menu, SLOT(onWhoisTriggered()));
        menu->addAction(tr("Close"), menu, SLOT(onCloseTriggered()));
    }
    return menu;
}

#include "menufactory.moc"
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string>
#include <time.h>

#include "Neural_Networks.h"

using namespace std;

void Read_MNIST(string training_set_images, string training_set_labels, string test_set_images, string test_set_labels, int number_training, int number_test, float **input, float **output) {
	ifstream file(training_set_images, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 4; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = 0; h < number_training; h++) {
			unsigned char pixel;

			for (int j = 0; j < 28 * 28; j++) {
				file.read((char*)(&pixel), 1);
				input[h][j] = pixel / 255.0;
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + training_set_images + " not found" << endl;
	}

	file.open(training_set_labels, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 2; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = 0; h < number_training; h++) {
			unsigned char label;

			file.read((char*)(&label), 1);

			for (int j = 0; j < 10; j++) {
				output[h][j] = (j == label);
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + training_set_labels + " not found" << endl;
	}

	file.open(test_set_images, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 4; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = number_training; h < number_training + number_test; h++) {
			unsigned char pixel;

			for (int j = 0; j < 28 * 28; j++) {
				file.read((char*)(&pixel), 1);
				input[h][j] = pixel / 255.0;
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + test_set_images + " not found" << endl;
	}

	file.open(test_set_labels, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 2; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = number_training; h < number_training + number_test; h++) {
			unsigned char label;

			file.read((char*)(&label), 1);

			for (int j = 0; j < 10; j++) {
				output[h][j] = (j == label);
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + test_set_labels + " not found" << endl;
	}
}

int main() {
	int epochs = 20;
	int number_training = 60000;
	int number_test = 10000;
	int number_nodes[] = { 784, 10 };

	float **x_data = new float*[number_training + number_test];
	float **y_data = new float*[number_training + number_test];
	float **x_train = x_data;
	float **y_train = y_data;
	float **x_test = &x_data[number_training];
	float **y_test = &y_data[number_training];

	double learning_rate = 0.1;

	string path;

	Neural_Networks NN = Neural_Networks();

	cout << "path where MNIST handwritten digits dataset is : ";
	getline(cin, path);

	for (int h = 0; h < number_training + number_test; h++) {
		x_data[h] = new float[number_nodes[0]];
		y_data[h] = new float[number_nodes[1]];
	}
	Read_MNIST(path + "train-images.idx3-ubyte", path + "train-labels.idx1-ubyte", path + "t10k-images.idx3-ubyte", path + "t10k-labels.idx1-ubyte", number_training, number_test, x_data, y_data);

	srand(0);
	NN.Add(number_nodes[0]);
	NN.Add(number_nodes[1]);
	NN.Connect(1, 0, 0.01);
	NN.Compile(learning_rate);

	for (int e = 0, time = clock(); e < epochs; e++) {
		int score[2] = { 0, };

		float *output = new float[number_nodes[1]];

		double loss[2] = { NN.Fit(x_train, y_train, number_training), NN.Evaluate(x_test, y_test, number_test) };

		for (int i = 0, argmax; i < number_training + number_test; i++) {
			double max = 0;

			NN.Predict(x_data[i], output);

			for (int j = 0; j < number_nodes[1]; j++) {
				if (j == 0 || max < output[j]) {
					max = output[argmax = j];
				}
			}
			score[(i < number_training) ? (0) : (1)] += (int)y_data[i][argmax];
		}
		printf("loss: %.4f / %.4f	accuracy: %.4f / %.4f	step %d  %.2f sec\n", loss[0], loss[1], 1.0 * score[0] / number_training, 1.0 * score[1] / number_test, e + 1, (double)(clock() - time) / CLOCKS_PER_SEC);

		delete[] output;
	}

	for (int i = 0; i < number_training + number_test; i++) {
		delete[] x_data[i];
		delete[] y_data[i];
	}
	delete[] x_data;
	delete[] y_data;
}<commit_msg>Delete main.cpp<commit_after><|endoftext|>