<commit_before>
/*
* Top Level window for KArm -- Sirtaj Singh Kang <taj@kde.org>
* Distributed under the GPL.
*
* $Id$
*/

#include <qpopupmenu.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qkeycode.h>

#include <kiconloader.h>
#include <kapp.h>
#include <klocale.h>
#include <kglobal.h>
#include <ktmainwindow.h>
#include <kmenubar.h>
#include <ktoolbar.h>
#include <kstatusbar.h>
#include <kaccel.h>
#include <kkeydialog.h>

#include "karm.h"
#include "toolicons.h"
#include "top.h"
#include "version.h"

#include"kaccelmenuwatch.h"

KarmWindow::KarmWindow()
	:	KTMainWindow(),

		_mainMenu( menuBar() ),
		_toolBar( toolBar() ),
		_statusBar( statusBar() ),
		_accel( new KAccel( this ) ),
		_watcher( new KAccelMenuWatch( _accel, this ) ),

		_karm( new Karm( this ) ),

		_totalTime( 0 ),
		_sessionTimeBuffer( new char[100] )

{
	setMenu( _mainMenu );

	setView( _karm, FALSE );
	_karm->show();

	// accelerators
	initAccelItems();

	// status bar

	_statusBar->insertItem( i18n( "clock inactive" ), 0 );
	_statusBar->insertItem( i18n( "This session:" ), 1 );
	_statusBar->insertItem( "0:00", 2 );

	// popup menus
	makeMenus();
	connectAccels();
	_watcher->updateMenus();

	// toolbar

	KIconLoader *loader = KGlobal::iconLoader();
	QPixmap icon;

	icon.loadFromData(clock_xpm_data, clock_xpm_len );
	_toolBar->insertButton( icon, 0, SIGNAL(clicked()),
			_karm, SLOT(startClock()),
                       TRUE, i18n( "Start Clock" ) );

	_toolBar->insertButton( loader->loadIcon("stop.xpm"), 1,
			SIGNAL(clicked()),
			_karm, SLOT(stopClock()),
			FALSE, i18n( "Stop Clock" ) );

	_toolBar->insertSeparator();

	_toolBar->insertButton( loader->loadIcon("filenew.xpm") , 2,
				SIGNAL(clicked()),_karm, SLOT(newTask()),
				TRUE, i18n( "New Task" ) );

	_toolBar->insertButton( loader->loadIcon("filedel.xpm") , 3,
				SIGNAL(clicked()),_karm, SLOT(deleteTask()),
				TRUE, i18n( "Delete Task" ) );

	icon.loadFromData( clockedit_xpm_data, clockedit_xpm_len );
	_toolBar->insertButton( icon, 4, SIGNAL(clicked()),
			_karm, SLOT(editTask()),
                       TRUE, i18n( "Edit Task" ) );

	// FIXME: this shouldnt stay. We need to check whether the
	// file exists and if not, create a blank one and ask whether
	// we want to add a task.
	_karm->load();

	// connections
	connect( _karm, SIGNAL(timerStarted()), this, SLOT(clockStartMsg()));
	connect( _karm, SIGNAL(timerStopped()), this, SLOT(clockStopMsg()));
	connect( _karm, SIGNAL(timerTick()), this, SLOT(updateTime()));

	// caption
	setCaption( _karm->KarmName );
}

KarmWindow::~KarmWindow()
{
	delete _fileMenu;
	delete _clockMenu;
	delete _taskMenu;
	delete _helpMenu;
	delete[] _sessionTimeBuffer;
}

void KarmWindow::updateTime()
{
	_totalTime++;

	Karm::formatTime( _sessionTimeBuffer, _totalTime );

	_statusBar->changeItem( _sessionTimeBuffer, 2);
}

void KarmWindow::clockStartMsg()
{
	_toolBar->setItemEnabled( 0, FALSE);
	_toolBar->setItemEnabled( 1, TRUE );
       _statusBar->changeItem( i18n( "clock active" ), 0);
}

void KarmWindow::clockStopMsg()
{
	_toolBar->setItemEnabled( 1, FALSE);
	_toolBar->setItemEnabled( 0, TRUE );
	_statusBar->changeItem( i18n( "clock inactive" ), 0);
}

void KarmWindow::saveProperties( KConfig* )
{
	_karm->save();
}

void KarmWindow::initAccelItems()
{
	_accel->insertItem( i18n( "Preferences" ), "Prefs",
		CTRL + Key_P );
	_accel->insertItem( i18n( "Start Clock" ), "StartClock",
		CTRL + Key_S );
	_accel->insertItem( i18n( "Stop Clock" ), "StopClock",
		CTRL + Key_T );
	_accel->insertItem( i18n( "New Task" ), "NewTask",
		CTRL + Key_N );
	_accel->insertItem( i18n( "Delete Task" ), "DeleteTask",
		CTRL + Key_D );
	_accel->insertItem( i18n( "Edit Task" ), "EditTask",
		CTRL + Key_E );

	_accel->insertStdItem( KAccel::Quit );

	_accel->readSettings();
}

void KarmWindow::connectAccels()
{
	_accel->connectItem( "Prefs",		this,	SLOT(prefs()) );
	_accel->connectItem( KAccel::Quit,	kapp,	SLOT(quit()) );
	_accel->connectItem( "StartClock",	_karm,	SLOT(startClock()) );
	_accel->connectItem( "StopClock",	_karm,	SLOT(stopClock()) );
	_accel->connectItem( "NewTask",		_karm,	SLOT(newTask()) );
	_accel->connectItem( "DeleteTask",	_karm,	SLOT(deleteTask()) );
	_accel->connectItem( "EditTask",	_karm,	SLOT(editTask()) );
}

void KarmWindow::prefs()
{
	if( KKeyDialog::configureKeys ( _accel ) ) {
		_watcher->updateMenus();
	}
}

void KarmWindow::makeMenus()
{
	_fileMenu = new QPopupMenu;
	_clockMenu= new QPopupMenu;
	_taskMenu = new QPopupMenu;
	_helpMenu = new QPopupMenu;

	QString about;
	about = i18n("%1 %2 -- Sirtaj Singh Kang\n"
			"taj@kde.org, Oct 1997\n\n"
			"The K Desktop Environment")
			.arg(_karm->KarmName).arg(KARM_VERSION);

	_mainMenu->insertItem( i18n( "&File" ), _fileMenu);
	_mainMenu->insertItem( i18n( "&Clock" ), _clockMenu );
	_mainMenu->insertItem( i18n( "&Task" ), _taskMenu);

	_mainMenu->insertSeparator();

	_mainMenu->insertItem( i18n( "&Help" ),
		kapp->helpMenu(TRUE, about ) );

	_watcher->setMenu( _fileMenu );
	int id = _fileMenu->insertItem( i18n( "&Preferences..." ),
			this, SLOT( prefs() ) );
	_watcher->connectAccel( id, "Prefs" );

	id = _fileMenu->insertItem( i18n( "E&xit" ),
			kapp, SLOT( quit() ) );
	_watcher->connectAccel( id, KAccel::Quit );

	_watcher->setMenu( _clockMenu );
	id = _clockMenu->insertItem( i18n( "&Start" ), _karm,
			SLOT(startClock()) );
	_watcher->connectAccel( id, "StartClock" );

	id = _clockMenu->insertItem( i18n( "S&top" ), _karm,
			SLOT(stopClock()) );
	_watcher->connectAccel( id, "StopClock" );

	_watcher->setMenu( _taskMenu );
	id = _taskMenu->insertItem( i18n( "&New" ), _karm, SLOT(newTask()) );
	_watcher->connectAccel( id, "NewTask" );

	id = _taskMenu->insertItem( i18n( "&Delete" ), _karm,
			SLOT(deleteTask()) );
	_watcher->connectAccel( id, "DeleteTask" );

	id = _taskMenu->insertItem( i18n( "&Edit" ), _karm, SLOT(editTask()));
	_watcher->connectAccel( id, "EditTask" );
}
<commit_msg>Added a seperator before E&xit in the file menu.<commit_after>
/*
* Top Level window for KArm -- Sirtaj Singh Kang <taj@kde.org>
* Distributed under the GPL.
*
* $Id$
*/

#include <qpopupmenu.h>
#include <qlayout.h>
#include <qpixmap.h>
#include <qkeycode.h>

#include <kiconloader.h>
#include <kapp.h>
#include <klocale.h>
#include <kglobal.h>
#include <ktmainwindow.h>
#include <kmenubar.h>
#include <ktoolbar.h>
#include <kstatusbar.h>
#include <kaccel.h>
#include <kkeydialog.h>

#include "karm.h"
#include "toolicons.h"
#include "top.h"
#include "version.h"

#include"kaccelmenuwatch.h"

KarmWindow::KarmWindow()
	:	KTMainWindow(),

		_mainMenu( menuBar() ),
		_toolBar( toolBar() ),
		_statusBar( statusBar() ),
		_accel( new KAccel( this ) ),
		_watcher( new KAccelMenuWatch( _accel, this ) ),

		_karm( new Karm( this ) ),

		_totalTime( 0 ),
		_sessionTimeBuffer( new char[100] )

{
	setMenu( _mainMenu );

	setView( _karm, FALSE );
	_karm->show();

	// accelerators
	initAccelItems();

	// status bar

	_statusBar->insertItem( i18n( "clock inactive" ), 0 );
	_statusBar->insertItem( i18n( "This session:" ), 1 );
	_statusBar->insertItem( "0:00", 2 );

	// popup menus
	makeMenus();
	connectAccels();
	_watcher->updateMenus();

	// toolbar

	KIconLoader *loader = KGlobal::iconLoader();
	QPixmap icon;

	icon.loadFromData(clock_xpm_data, clock_xpm_len );
	_toolBar->insertButton( icon, 0, SIGNAL(clicked()),
			_karm, SLOT(startClock()),
                       TRUE, i18n( "Start Clock" ) );

	_toolBar->insertButton( loader->loadIcon("stop.xpm"), 1,
			SIGNAL(clicked()),
			_karm, SLOT(stopClock()),
			FALSE, i18n( "Stop Clock" ) );

	_toolBar->insertSeparator();

	_toolBar->insertButton( loader->loadIcon("filenew.xpm") , 2,
				SIGNAL(clicked()),_karm, SLOT(newTask()),
				TRUE, i18n( "New Task" ) );

	_toolBar->insertButton( loader->loadIcon("filedel.xpm") , 3,
				SIGNAL(clicked()),_karm, SLOT(deleteTask()),
				TRUE, i18n( "Delete Task" ) );

	icon.loadFromData( clockedit_xpm_data, clockedit_xpm_len );
	_toolBar->insertButton( icon, 4, SIGNAL(clicked()),
			_karm, SLOT(editTask()),
                       TRUE, i18n( "Edit Task" ) );

	// FIXME: this shouldnt stay. We need to check whether the
	// file exists and if not, create a blank one and ask whether
	// we want to add a task.
	_karm->load();

	// connections
	connect( _karm, SIGNAL(timerStarted()), this, SLOT(clockStartMsg()));
	connect( _karm, SIGNAL(timerStopped()), this, SLOT(clockStopMsg()));
	connect( _karm, SIGNAL(timerTick()), this, SLOT(updateTime()));

	// caption
	setCaption( _karm->KarmName );
}

KarmWindow::~KarmWindow()
{
	delete _fileMenu;
	delete _clockMenu;
	delete _taskMenu;
	delete _helpMenu;
	delete[] _sessionTimeBuffer;
}

void KarmWindow::updateTime()
{
	_totalTime++;

	Karm::formatTime( _sessionTimeBuffer, _totalTime );

	_statusBar->changeItem( _sessionTimeBuffer, 2);
}

void KarmWindow::clockStartMsg()
{
	_toolBar->setItemEnabled( 0, FALSE);
	_toolBar->setItemEnabled( 1, TRUE );
       _statusBar->changeItem( i18n( "clock active" ), 0);
}

void KarmWindow::clockStopMsg()
{
	_toolBar->setItemEnabled( 1, FALSE);
	_toolBar->setItemEnabled( 0, TRUE );
	_statusBar->changeItem( i18n( "clock inactive" ), 0);
}

void KarmWindow::saveProperties( KConfig* )
{
	_karm->save();
}

void KarmWindow::initAccelItems()
{
	_accel->insertItem( i18n( "Preferences" ), "Prefs",
		CTRL + Key_P );
	_accel->insertItem( i18n( "Start Clock" ), "StartClock",
		CTRL + Key_S );
	_accel->insertItem( i18n( "Stop Clock" ), "StopClock",
		CTRL + Key_T );
	_accel->insertItem( i18n( "New Task" ), "NewTask",
		CTRL + Key_N );
	_accel->insertItem( i18n( "Delete Task" ), "DeleteTask",
		CTRL + Key_D );
	_accel->insertItem( i18n( "Edit Task" ), "EditTask",
		CTRL + Key_E );

	_accel->insertStdItem( KAccel::Quit );

	_accel->readSettings();
}

void KarmWindow::connectAccels()
{
	_accel->connectItem( "Prefs",		this,	SLOT(prefs()) );
	_accel->connectItem( KAccel::Quit,	kapp,	SLOT(quit()) );
	_accel->connectItem( "StartClock",	_karm,	SLOT(startClock()) );
	_accel->connectItem( "StopClock",	_karm,	SLOT(stopClock()) );
	_accel->connectItem( "NewTask",		_karm,	SLOT(newTask()) );
	_accel->connectItem( "DeleteTask",	_karm,	SLOT(deleteTask()) );
	_accel->connectItem( "EditTask",	_karm,	SLOT(editTask()) );
}

void KarmWindow::prefs()
{
	if( KKeyDialog::configureKeys ( _accel ) ) {
		_watcher->updateMenus();
	}
}

void KarmWindow::makeMenus()
{
	_fileMenu = new QPopupMenu;
	_clockMenu= new QPopupMenu;
	_taskMenu = new QPopupMenu;
	_helpMenu = new QPopupMenu;

	QString about;
	about = i18n("%1 %2 -- Sirtaj Singh Kang\n"
			"taj@kde.org, Oct 1997\n\n"
			"The K Desktop Environment")
			.arg(_karm->KarmName).arg(KARM_VERSION);

	_mainMenu->insertItem( i18n( "&File" ), _fileMenu);
	_mainMenu->insertItem( i18n( "&Clock" ), _clockMenu );
	_mainMenu->insertItem( i18n( "&Task" ), _taskMenu);

	_mainMenu->insertSeparator();

	_mainMenu->insertItem( i18n( "&Help" ),
		kapp->helpMenu(TRUE, about ) );

	_watcher->setMenu( _fileMenu );
	int id = _fileMenu->insertItem( i18n( "&Preferences..." ),
			this, SLOT( prefs() ) );
	_watcher->connectAccel( id, "Prefs" );

        _fileMenu->insertSeparator( - 1 );
	id = _fileMenu->insertItem( i18n( "E&xit" ),
			kapp, SLOT( quit() ) );
	_watcher->connectAccel( id, KAccel::Quit );

	_watcher->setMenu( _clockMenu );
	id = _clockMenu->insertItem( i18n( "&Start" ), _karm,
			SLOT(startClock()) );
	_watcher->connectAccel( id, "StartClock" );

	id = _clockMenu->insertItem( i18n( "S&top" ), _karm,
			SLOT(stopClock()) );
	_watcher->connectAccel( id, "StopClock" );

	_watcher->setMenu( _taskMenu );
	id = _taskMenu->insertItem( i18n( "&New" ), _karm, SLOT(newTask()) );
	_watcher->connectAccel( id, "NewTask" );

	id = _taskMenu->insertItem( i18n( "&Delete" ), _karm,
			SLOT(deleteTask()) );
	_watcher->connectAccel( id, "DeleteTask" );

	id = _taskMenu->insertItem( i18n( "&Edit" ), _karm, SLOT(editTask()));
	_watcher->connectAccel( id, "EditTask" );
}
<|endoftext|>


<commit_before><commit_msg>Now is possible to access array offsets in instruction fields<commit_after><|endoftext|>


<commit_before>#pragma once

#include <d3d11.h>
#include <DirectXMath.h>

namespace dx
{
    struct MappedGpuResource : Noncopyable
    {
        MappedGpuResource(ID3D11DeviceContext& context, ID3D11Resource* resource,
            void* memory, std::size_t size)
            : m_bytes{static_cast<std::byte*>(memory), static_cast<std::ptrdiff_t>(size)},
            m_context{&context},
            m_resource{resource}
        {}

        //defend against usage like `buffer.Map().Bytes()`.
        gsl::span<std::byte> Bytes() const &
        {
            return m_bytes;
        }

        ~MappedGpuResource();

    private:
        ID3D11DeviceContext * m_context;
        ID3D11Resource* m_resource;
        gsl::span<std::byte> m_bytes;

    };

    struct GpuBufferView
    {
        ID3D11Buffer* Buffer;
        std::uint32_t Offset;
        std::uint32_t Count;
        std::uint32_t Stride;

        void Update(ID3D11DeviceContext& context, gsl::span<const std::byte> bytes);
    };

    namespace Internal
    {
        wrl::ComPtr<ID3D11Buffer> RawMakeD3DBuffer(
            ::ID3D11Device& device,
            const void* buffer,
            std::uint32_t bufferSize,
            BindFlag bindFlags,
            ResourceUsage usage);
    }

    D3D11_BUFFER_DESC GetDesc(ID3D11Buffer& buffer);

    template<typename>
    using TypedGpuBuffer = wrl::ComPtr<ID3D11Buffer>;

    using GpuBuffer = TypedGpuBuffer<std::byte>;

    template<typename T>
    TypedGpuBuffer<T> MakeImmutableGpuBuffer(ID3D11Device& device, gsl::span<T> vertices, BindFlag bindFlags)
    {
        return Internal::RawMakeD3DBuffer(device, vertices.data(), gsl::narrow<std::uint32_t>(vertices.size_bytes()), bindFlags, ResourceUsage::Immutable);
    }

    template<typename T = std::byte>
    TypedGpuBuffer<T> MakeDynamicGpuBuffer(ID3D11Device& device, std::uint32_t size, BindFlag bindFlags)
    {
        return Internal::RawMakeD3DBuffer(device, nullptr, size, bindFlags, ResourceUsage::Dynamic);
    }

    template<typename T>
    TypedGpuBuffer<T> MakeImmutableVertexBuffer(ID3D11Device& device, gsl::span<T> vertices)
    {
        return MakeImmutableGpuBuffer(device, vertices, BindFlag::VertexBuffer);
    }

    template<typename T = std::byte>
    TypedGpuBuffer<T> MakeDynamicVertexBuffer(ID3D11Device& device, std::uint32_t size)
    {
        return MakeDynamicGpuBuffer(device, size, BindFlag::VertexBuffer);
    }

    using ShortIndex = std::uint16_t;
    using LongIndex = std::uint32_t;

    template<typename T>
    using is_index = is_one_of<std::decay_t<T>, ShortIndex, LongIndex>;

    template<typename T, typename = std::enable_if_t<is_index<T>::value>>
    TypedGpuBuffer<T> MakeImmutableIndexBuffer(ID3D11Device& device, gsl::span<T> vertices)
    {
        return MakeImmutableGpuBuffer(device, vertices, BindFlag::IndexBuffer);
    }

    template<typename T, typename = std::enable_if_t<is_index<T>::value>>
    TypedGpuBuffer<T> MakeDynamicIndexBuffer(ID3D11Device& device, gsl::span<T> vertices)
    {
        return MakeDynamicGpuBuffer(device, vertices, BindFlag::IndexBuffer);
    }

    MappedGpuResource Map(ID3D11DeviceContext& context, ID3D11Buffer& gpuBuffer, ResourceMapType mapType = ResourceMapType::WriteDiscard);

    template<typename T>
    void UpdateWithDiscard(ID3D11DeviceContext& context, ID3D11Buffer& gpuBuffer, gsl::span<T> vertices)
    {
        const auto desc = GetDesc(gpuBuffer);
        //Ensures(sizeof(T) == desc.StructureByteStride);
        Ensures(vertices.size() <= desc.ByteWidth);
        auto resource = Map(context, gpuBuffer, ResourceMapType::WriteDiscard);
        gsl::copy(vertices, resource.Bytes());
    }

    template<typename T>
    wrl::ComPtr<ID3D11Buffer> MakeConstantBuffer(
        ID3D11Device& device,
        T* cb = nullptr,
        ResourceUsage usage = ResourceUsage::Dynamic)
    {
        return { Internal::RawMakeD3DBuffer(device, cb, gsl::narrow<std::uint32_t>(sizeof(*cb)), BindFlag::ConstantBuffer, usage) };
    }

    inline wrl::ComPtr<ID3D11Buffer> MakeConstantBuffer(ID3D11Device& device, std::uint32_t size)
    {
        return {Internal::RawMakeD3DBuffer(device, nullptr, size, BindFlag::ConstantBuffer,
                                           ResourceUsage::Dynamic)};
    }

    void SetupIndexBuffer(ID3D11DeviceContext& context3D, ID3D11Buffer& indexBuffer, std::uint32_t offset = 0);
}<commit_msg>补充创建 Dynamic Buffer 的接口。<commit_after>#pragma once

#include <d3d11.h>
#include <DirectXMath.h>

namespace dx
{
    struct MappedGpuResource : Noncopyable
    {
        MappedGpuResource(ID3D11DeviceContext& context, ID3D11Resource* resource,
            void* memory, std::size_t size)
            : m_bytes{static_cast<std::byte*>(memory), static_cast<std::ptrdiff_t>(size)},
            m_context{&context},
            m_resource{resource}
        {}

        //defend against usage like `buffer.Map().Bytes()`.
        gsl::span<std::byte> Bytes() const &
        {
            return m_bytes;
        }

        ~MappedGpuResource();

    private:
        ID3D11DeviceContext * m_context;
        ID3D11Resource* m_resource;
        gsl::span<std::byte> m_bytes;

    };

    struct GpuBufferView
    {
        ID3D11Buffer* Buffer;
        std::uint32_t Offset;
        std::uint32_t Count;
        std::uint32_t Stride;

        void Update(ID3D11DeviceContext& context, gsl::span<const std::byte> bytes);
    };

    namespace Internal
    {
        wrl::ComPtr<ID3D11Buffer> RawMakeD3DBuffer(
            ::ID3D11Device& device,
            const void* buffer,
            std::uint32_t bufferSize,
            BindFlag bindFlags,
            ResourceUsage usage);
    }

    D3D11_BUFFER_DESC GetDesc(ID3D11Buffer& buffer);

    template<typename>
    using TypedGpuBuffer = wrl::ComPtr<ID3D11Buffer>;

    using GpuBuffer = TypedGpuBuffer<std::byte>;

    template<typename T>
    TypedGpuBuffer<T> MakeImmutableGpuBuffer(ID3D11Device& device, gsl::span<T> vertices, BindFlag bindFlags)
    {
        return Internal::RawMakeD3DBuffer(device, vertices.data(), gsl::narrow<std::uint32_t>(vertices.size_bytes()), bindFlags, ResourceUsage::Immutable);
    }

    template<typename T = std::byte>
    TypedGpuBuffer<T> MakeDynamicGpuBuffer(ID3D11Device& device, std::uint32_t size, BindFlag bindFlags, T* data = nullptr)
    {
        return Internal::RawMakeD3DBuffer(device, data, size, bindFlags, ResourceUsage::Dynamic);
    }

    template<typename T>
    TypedGpuBuffer<T> MakeImmutableVertexBuffer(ID3D11Device& device, gsl::span<T> vertices)
    {
        return MakeImmutableGpuBuffer(device, vertices, BindFlag::VertexBuffer);
    }

    template<typename T = std::byte>
    TypedGpuBuffer<T> MakeDynamicVertexBuffer(ID3D11Device& device, std::uint32_t size)
    {
        return MakeDynamicGpuBuffer(device, size, BindFlag::VertexBuffer);
    }

    template<typename T = std::byte>
    TypedGpuBuffer<T> MakeDynamicVertexBuffer(ID3D11Device& device, gsl::span<T> data)
    {
        return MakeDynamicGpuBuffer(device, data.size_bytes(), BindFlag::VertexBuffer, data.data());
    }

    using ShortIndex = std::uint16_t;
    using LongIndex = std::uint32_t;

    template<typename T>
    using is_index = is_one_of<std::decay_t<T>, ShortIndex, LongIndex>;

    template<typename T, typename = std::enable_if_t<is_index<T>::value>>
    TypedGpuBuffer<T> MakeImmutableIndexBuffer(ID3D11Device& device, gsl::span<T> vertices)
    {
        return MakeImmutableGpuBuffer(device, vertices, BindFlag::IndexBuffer);
    }

    template<typename T, typename = std::enable_if_t<is_index<T>::value>>
    TypedGpuBuffer<T> MakeDynamicIndexBuffer(ID3D11Device& device, gsl::span<T> vertices)
    {
        return MakeDynamicGpuBuffer(device, vertices, BindFlag::IndexBuffer);
    }

    MappedGpuResource Map(ID3D11DeviceContext& context, ID3D11Buffer& gpuBuffer, ResourceMapType mapType = ResourceMapType::WriteDiscard);

    template<typename T>
    void UpdateWithDiscard(ID3D11DeviceContext& context, ID3D11Buffer& gpuBuffer, gsl::span<T> vertices)
    {
        const auto desc = GetDesc(gpuBuffer);
        //Ensures(sizeof(T) == desc.StructureByteStride);
        Ensures(vertices.size() <= desc.ByteWidth);
        auto resource = Map(context, gpuBuffer, ResourceMapType::WriteDiscard);
        gsl::copy(vertices, resource.Bytes());
    }

    template<typename T>
    wrl::ComPtr<ID3D11Buffer> MakeConstantBuffer(
        ID3D11Device& device,
        T* cb = nullptr,
        ResourceUsage usage = ResourceUsage::Dynamic)
    {
        return { Internal::RawMakeD3DBuffer(device, cb, gsl::narrow<std::uint32_t>(sizeof(*cb)), BindFlag::ConstantBuffer, usage) };
    }

    inline wrl::ComPtr<ID3D11Buffer> MakeConstantBuffer(ID3D11Device& device, std::uint32_t size)
    {
        return {Internal::RawMakeD3DBuffer(device, nullptr, size, BindFlag::ConstantBuffer,
                                           ResourceUsage::Dynamic)};
    }

    void SetupIndexBuffer(ID3D11DeviceContext& context3D, ID3D11Buffer& indexBuffer, std::uint32_t offset = 0);
}<|endoftext|>


<commit_before>#include "Stop.h"
#include <Engine/Utils/Collections/Algorithms.h>
#include <assert.h>
#include "ScheduleActualizer.h"

namespace Scheduler
{

	Stop::Stop(Run* run):
	run(run),
	schedule_actualizer(nullptr),
	nextStop(nullptr),
	prevStop(nullptr),
	has_actual_route(false)
	{
	}

	const TimeWindow &Stop::getAllocationTime() const {
		schedule_actualizer->actualize();

		return allocation_time;
	}

	void Stop::setAllocationTime(const TimeWindow &time) {
		this->allocation_time = time;
	}

	const Duration &Stop::getDuration() const {
		schedule_actualizer->actualize();

		return duration;
	}

	void Stop::setDuration(const Duration &duration) {
		this->duration = duration;
	}

	void Stop::setNextRoute(const Route &route) {
		this->next_route = route;

		schedule_actualizer->onStopNextRouteChanged(this);
	}

	const Run *Stop::getRun() const {
		return run;
	}

	Run *Stop::getRun() {
		return run;
	}

	Stop* Stop::getNextStop() const
	{
		return nextStop;
	}

	Stop* Stop::getPrevStop() const
	{
		return prevStop;
	}

	const Route &Stop::getNextRoute() const
	{
		schedule_actualizer->actualize();

		return next_route;
	}

	void Stop::setScheduleActualizer(ScheduleActualizer *actualizer) {
		assert(actualizer);

		this->schedule_actualizer = actualizer;
	}

	void Stop::invalidateRoute()
	{
		has_actual_route = false;
	}

	bool Stop::hasActualRoute() const
	{
		return has_actual_route;
	}

	void Stop::setNextStop(Stop* stop)
	{
		this->nextStop = stop;
	}

	void Stop::setPrevStop(Stop* stop)
	{
		this->prevStop = stop;
	}

	void Stop::setStartTime(const TimePoint &time)
	{
		this->setAllocationTime(TimeWindow(time, time + duration));
	}

	void Stop::setEndTime(const TimePoint &time)
	{
		this->setAllocationTime(TimeWindow(time - duration, time));
	}
}<commit_msg>[#20] fix stop actualization<commit_after>#include "Stop.h"
#include <Engine/Utils/Collections/Algorithms.h>
#include <assert.h>
#include "ScheduleActualizer.h"

namespace Scheduler
{

	Stop::Stop(Run* run):
	run(run),
	schedule_actualizer(nullptr),
	nextStop(nullptr),
	prevStop(nullptr),
	has_actual_route(false)
	{
	}

	const TimeWindow &Stop::getAllocationTime() const {
		schedule_actualizer->actualize();

		return allocation_time;
	}

	void Stop::setAllocationTime(const TimeWindow &time) {
		this->allocation_time = time;
	}

	const Duration &Stop::getDuration() const {
		schedule_actualizer->actualize();

		return duration;
	}

	void Stop::setDuration(const Duration &duration) {
		this->duration = duration;
	}

	void Stop::setNextRoute(const Route &route) {
		this->next_route = route;

		schedule_actualizer->onStopNextRouteChanged(this);

        has_actual_route = true;
	}

	const Run *Stop::getRun() const {
		return run;
	}

	Run *Stop::getRun() {
		return run;
	}

	Stop* Stop::getNextStop() const
	{
		return nextStop;
	}

	Stop* Stop::getPrevStop() const
	{
		return prevStop;
	}

	const Route &Stop::getNextRoute() const
	{
		schedule_actualizer->actualize();

		return next_route;
	}

	void Stop::setScheduleActualizer(ScheduleActualizer *actualizer) {
		assert(actualizer);

		this->schedule_actualizer = actualizer;
	}

	void Stop::invalidateRoute()
	{
		has_actual_route = false;
	}

	bool Stop::hasActualRoute() const
	{
		return has_actual_route;
	}

	void Stop::setNextStop(Stop* stop)
	{
		this->nextStop = stop;
	}

	void Stop::setPrevStop(Stop* stop)
	{
		this->prevStop = stop;
	}

	void Stop::setStartTime(const TimePoint &time)
	{
		this->setAllocationTime(TimeWindow(time, time + duration));
	}

	void Stop::setEndTime(const TimePoint &time)
	{
		this->setAllocationTime(TimeWindow(time - duration, time));
	}
}
<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNodeObject.cpp,v $
//   $Revision: 1.39 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2009/06/04 19:33:18 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"
#include "CEvaluationNode.h"
#include "CEvaluationTree.h"
#include "CExpression.h"
#include "report/CCopasiObjectName.h"
#include "report/CCopasiObject.h"
#include "report/CCopasiContainer.h"
#include "model/CModel.h"
#include "CopasiDataModel/CCopasiDataModel.h"

#include "sbml/math/ASTNode.h"
#include "sbml/SBase.h"
#include "sbml/SBMLTypeCodes.h"
#include "sbml/Compartment.h"
#include "sbml/Species.h"
#include "sbml/Parameter.h"
#include "sbml/Reaction.h"

CEvaluationNodeObject::CEvaluationNodeObject():
    CEvaluationNode(CEvaluationNode::INVALID, ""),
    mpValue(NULL),
    mpObject(NULL),
    mRegisteredObjectCN("")
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const SubType & subType,
    const Data & data):
    CEvaluationNode((Type)(CEvaluationNode::OBJECT | subType), data),
    mpValue(NULL),
    mpObject(NULL),
    mRegisteredObjectCN(data.substr(1, data.length() - 2))
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const C_FLOAT64 * pValue):
    CEvaluationNode((Type)(CEvaluationNode::OBJECT | POINTER), "pointer"),
    mpValue(pValue),
    mpObject(NULL),
    mRegisteredObjectCN("")
{
  mPrecedence = PRECEDENCE_NUMBER;

  std::ostringstream Pointer;
  Pointer << pValue;
  mData = Pointer.str();
}

CEvaluationNodeObject::CEvaluationNodeObject(const CEvaluationNodeObject & src):
    CEvaluationNode(src),
    mpValue(src.mpValue),
    mpObject(src.mpObject),
    mRegisteredObjectCN(src.mRegisteredObjectCN)
{}

CEvaluationNodeObject::~CEvaluationNodeObject() {}

bool CEvaluationNodeObject::compile(const CEvaluationTree * pTree)
{
  mpObject = NULL;

  switch ((int) subType(mType))
    {
      case CN:
      {
        const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);

        if (!pExpression) return false;

        mpObject =
          pExpression->getNodeObject(mRegisteredObjectCN);

        if (mpObject)
          mpValue = (C_FLOAT64 *) mpObject->getValuePointer();
        else
          mpValue = NULL;

        if (mpValue == NULL)
          {
            mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();
            mpValue = &mValue;
            return false;
          }

        if (!mpObject->isValueDbl()) return false;

        mData = "<" + mRegisteredObjectCN + ">";
      }
      break;

      case POINTER:
        break;

      case INVALID:
        break;
    }

  return (getChild() == NULL); // We must not have any children.
}

CEvaluationNode::Data CEvaluationNodeObject::getData() const
{return "<" + mRegisteredObjectCN + ">";}

bool CEvaluationNodeObject::setData(const Data & data)
{
  mData = data;

  if ((int) subType(mType) == (int) CN)
    mRegisteredObjectCN = data.substr(1, data.length() - 2);

  return true;
}

std::string CEvaluationNodeObject::getInfix() const
{return "<" + mRegisteredObjectCN + ">";}

#if 0
std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * pTree) const
{
  const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);

  if (!pExpression) return false;

  const CCopasiObject * pObject =
    CCopasiContainer::ObjectFromName(mRegisteredObjectCN);

  if (pObject == NULL) return "<" + mRegisteredObjectCN + ">";

  return "<" + pObject->getObjectDisplayName() + ">";
}
#endif

std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * /* pTree */) const
{
  return "<" + mRegisteredObjectCN + ">";
}

std::string CEvaluationNodeObject::getDisplay_C_String(const CEvaluationTree * /* pTree */) const
{
  return mData;
}

std::string CEvaluationNodeObject::getDisplay_MMD_String(const CEvaluationTree * /* pTree */) const
{
  return mData;
}

std::string CEvaluationNodeObject::getDisplay_XPP_String(const CEvaluationTree * /* pTree */) const
{
  return mData;
}

CEvaluationNode* CEvaluationNodeObject::createNodeFromASTTree(const ASTNode& node)
{
  CEvaluationNodeObject* pNode = NULL;
  ASTNodeType_t type = node.getType();

  switch (type)
    {
      case AST_NAME_TIME:
      case AST_NAME:
        pNode = new CEvaluationNodeObject(CN, CCopasiObjectName(std::string("<") + node.getName() + std::string(">")));
        break;
      default:
        break;
    }

  return pNode;
}

ASTNode* CEvaluationNodeObject::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* node = new ASTNode();
  node->setType(AST_NAME);
  // since I can not get the model in which this node is located, I just
  // assume that it will always be the current global model.
  const CCopasiObject* object = pDataModel->getObject(mRegisteredObjectCN);
  assert(object);

  // if it is a reference, we get the parent of the reference
  if (object->isReference())
    {
      object = object->getObjectParent();
    }

  const CModelEntity* pME = dynamic_cast<const CModelEntity*>(object);

  if (pME != NULL)
    {
      const CModel* pModel = dynamic_cast<const CModel*>(pME);

      if (pModel != NULL)
        {
          node->setType(AST_NAME_TIME);
          node->setName("time");

          if (pModel->getInitialTime() != 0.0)
            {
              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 1);
            }
        }
      else
        {
          node->setName(pME->getSBMLId().c_str());
        }
    }
  else
    {
      const CCopasiParameter* pPara = dynamic_cast<const CCopasiParameter*>(object);

      if (pPara != NULL)
        {
          // now we have to use the common name as the name for the
          // node since we need to be able to identify local parameters
          // in arbitrary expressions for the export
          node->setName(pPara->getCN().c_str());
        }
      else
        {
          fatalError();
        }
    }

  return node;
}

const CRegisteredObjectName & CEvaluationNodeObject::getObjectCN() const
{return mRegisteredObjectCN;}

#include "utilities/copasimathml.h"

void CEvaluationNodeObject::writeMathML(std::ostream & out,
                                        const std::vector<std::vector<std::string> > & /* env */,
                                        bool /* expand */,
                                        unsigned C_INT32 l) const
{
  out << SPC(l) << CMathMl::getMMLName(mpObject) << std::endl;
}
<commit_msg>Fix for handling references to reaction when converting to and from AST nodes.<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNodeObject.cpp,v $
//   $Revision: 1.40 $
//   $Name:  $
//   $Author: gauges $
//   $Date: 2009/06/26 13:08:45 $
// End CVS Header

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"
#include "CEvaluationNode.h"
#include "CEvaluationTree.h"
#include "CExpression.h"
#include "report/CCopasiObjectName.h"
#include "report/CCopasiObject.h"
#include "report/CCopasiContainer.h"
#include "model/CModel.h"
#include "CopasiDataModel/CCopasiDataModel.h"

#include "sbml/math/ASTNode.h"
#include "sbml/SBase.h"
#include "sbml/SBMLTypeCodes.h"
#include "sbml/Compartment.h"
#include "sbml/Species.h"
#include "sbml/Parameter.h"
#include "sbml/Reaction.h"

CEvaluationNodeObject::CEvaluationNodeObject():
    CEvaluationNode(CEvaluationNode::INVALID, ""),
    mpValue(NULL),
    mpObject(NULL),
    mRegisteredObjectCN("")
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const SubType & subType,
    const Data & data):
    CEvaluationNode((Type)(CEvaluationNode::OBJECT | subType), data),
    mpValue(NULL),
    mpObject(NULL),
    mRegisteredObjectCN(data.substr(1, data.length() - 2))
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeObject::CEvaluationNodeObject(const C_FLOAT64 * pValue):
    CEvaluationNode((Type)(CEvaluationNode::OBJECT | POINTER), "pointer"),
    mpValue(pValue),
    mpObject(NULL),
    mRegisteredObjectCN("")
{
  mPrecedence = PRECEDENCE_NUMBER;

  std::ostringstream Pointer;
  Pointer << pValue;
  mData = Pointer.str();
}

CEvaluationNodeObject::CEvaluationNodeObject(const CEvaluationNodeObject & src):
    CEvaluationNode(src),
    mpValue(src.mpValue),
    mpObject(src.mpObject),
    mRegisteredObjectCN(src.mRegisteredObjectCN)
{}

CEvaluationNodeObject::~CEvaluationNodeObject() {}

bool CEvaluationNodeObject::compile(const CEvaluationTree * pTree)
{
  mpObject = NULL;

  switch ((int) subType(mType))
    {
      case CN:
      {
        const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);

        if (!pExpression) return false;

        mpObject =
          pExpression->getNodeObject(mRegisteredObjectCN);

        if (mpObject)
          mpValue = (C_FLOAT64 *) mpObject->getValuePointer();
        else
          mpValue = NULL;

        if (mpValue == NULL)
          {
            mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();
            mpValue = &mValue;
            return false;
          }

        if (!mpObject->isValueDbl()) return false;

        mData = "<" + mRegisteredObjectCN + ">";
      }
      break;

      case POINTER:
        break;

      case INVALID:
        break;
    }

  return (getChild() == NULL); // We must not have any children.
}

CEvaluationNode::Data CEvaluationNodeObject::getData() const
{return "<" + mRegisteredObjectCN + ">";}

bool CEvaluationNodeObject::setData(const Data & data)
{
  mData = data;

  if ((int) subType(mType) == (int) CN)
    mRegisteredObjectCN = data.substr(1, data.length() - 2);

  return true;
}

std::string CEvaluationNodeObject::getInfix() const
{return "<" + mRegisteredObjectCN + ">";}

#if 0
std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * pTree) const
{
  const CExpression * pExpression = dynamic_cast< const CExpression * >(pTree);

  if (!pExpression) return false;

  const CCopasiObject * pObject =
    CCopasiContainer::ObjectFromName(mRegisteredObjectCN);

  if (pObject == NULL) return "<" + mRegisteredObjectCN + ">";

  return "<" + pObject->getObjectDisplayName() + ">";
}
#endif

std::string CEvaluationNodeObject::getDisplayString(const CEvaluationTree * /* pTree */) const
{
  return "<" + mRegisteredObjectCN + ">";
}

std::string CEvaluationNodeObject::getDisplay_C_String(const CEvaluationTree * /* pTree */) const
{
  return mData;
}

std::string CEvaluationNodeObject::getDisplay_MMD_String(const CEvaluationTree * /* pTree */) const
{
  return mData;
}

std::string CEvaluationNodeObject::getDisplay_XPP_String(const CEvaluationTree * /* pTree */) const
{
  return mData;
}

CEvaluationNode* CEvaluationNodeObject::createNodeFromASTTree(const ASTNode& node)
{
  CEvaluationNodeObject* pNode = NULL;
  ASTNodeType_t type = node.getType();

  switch (type)
    {
      case AST_NAME_TIME:
      case AST_NAME:
        pNode = new CEvaluationNodeObject(CN, CCopasiObjectName(std::string("<") + node.getName() + std::string(">")));
        break;
      default:
        break;
    }

  return pNode;
}

ASTNode* CEvaluationNodeObject::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* node = new ASTNode();
  node->setType(AST_NAME);
  // since I can not get the model in which this node is located, I just
  // assume that it will always be the current global model.
  const CCopasiObject* object = pDataModel->getObject(mRegisteredObjectCN);
  assert(object);

  // if it is a reference, we get the parent of the reference
  if (object->isReference())
    {
      object = object->getObjectParent();
    }

  const CModelEntity* pME = dynamic_cast<const CModelEntity*>(object);

  if (pME != NULL)
    {
      const CModel* pModel = dynamic_cast<const CModel*>(pME);

      if (pModel != NULL)
        {
          node->setType(AST_NAME_TIME);
          node->setName("time");

          if (pModel->getInitialTime() != 0.0)
            {
              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 1);
            }
        }
      else
        {
          node->setName(pME->getSBMLId().c_str());
        }
    }
  else
    {
      const CCopasiParameter* pPara = dynamic_cast<const CCopasiParameter*>(object);

      if (pPara != NULL)
        {
          // now we have to use the common name as the name for the
          // node since we need to be able to identify local parameters
          // in arbitrary expressions for the export
          node->setName(pPara->getCN().c_str());
        }
      else
        {
          const CReaction* pReaction = dynamic_cast<const CReaction*>(object);

          if (pReaction)
            {
              node->setName(pReaction->getSBMLId().c_str());
            }
          else
            {
              fatalError();
            }
        }
    }

  return node;
}

const CRegisteredObjectName & CEvaluationNodeObject::getObjectCN() const
{return mRegisteredObjectCN;}

#include "utilities/copasimathml.h"

void CEvaluationNodeObject::writeMathML(std::ostream & out,
                                        const std::vector<std::vector<std::string> > & /* env */,
                                        bool /* expand */,
                                        unsigned C_INT32 l) const
{
  out << SPC(l) << CMathMl::getMMLName(mpObject) << std::endl;
}
<|endoftext|>


<commit_before>#include "persistence/net/netclientbackend.h"

#include "persistence/json/jsonserializer.h"
#include "persistence/net/jsonserializer.h"

#include "persistence/changequeue.h"

#include <boost/asio/connect.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/read.hpp>

namespace persistence
{
  namespace net
  {

    NetClientBackend::NetClientBackend(const std::string& host, int port)
        : _host(host), _port(port), _status(NotConnected), _ioService(), _socket(_ioService), _nextOperationId(1),
          _nextStreamId(1)
    {
      start();
    }

    NetClientBackend::~NetClientBackend()
    {
      stopAndJoin();
    }

    void NetClientBackend::start()
    {
      // Try to connect to the server
      {
        std::lock_guard<std::mutex> lock(_communicationMutex);
        assert(_status == NotConnected);
        _status = Connecting;
        boost::asio::ip::tcp::resolver resolver(_ioService);
        auto endpointIterator = resolver.resolve({_host, std::to_string(_port)});
        boost::asio::async_connect(_socket, endpointIterator, [this](boost::system::error_code ec, boost::asio::ip::tcp::endpoint) { this->socketConnected(ec); });
      }

      // Start processing the communication on a separate thread
      _communicationThread = std::thread([this]() {
        _ioService.run();
        std::cout << "IO service has terminated!" << std::endl;
      });
    }

    void NetClientBackend::stopAndJoin()
    {
      _ioService.post([this](){ _socket.close(); });
      _communicationThread.join();
    }

    ChangeQueue &NetClientBackend::changeQueue()
    {
      return _changeQueue;
    }

    UniqueTaskHandle NetClientBackend::queueOperations(op::Operations operations, TaskObserver *observer)
    {
      // Create a task
      _nextOperationId++;
      auto sharedState = std::make_shared<Task>(_nextOperationId);
      sharedState->connect(observer);
      _tasks[_nextOperationId] = sharedState;
      _changeQueue.addTask(sharedState);

      nlohmann::json obj;
      obj["op"] = "schedule_operations";
      obj["id"] = _nextOperationId;
      std::vector<nlohmann::json> operationsArray;
      for (auto &operation : operations)
        operationsArray.push_back(json::serialize(operation));
      obj["operations"]= operationsArray;
      submit(obj.dump());

      return UniqueTaskHandle(this, sharedState);
    }

    persistence::UniqueDataStreamHandle NetClientBackend::createStream(DataStreamObserver* observer,
                                                                       StreamableType type, const std::string& service,
                                                                       const nlohmann::json& options)
    {
      auto stream = std::make_shared<DataStream>(type, service, options);
      stream->connect(_nextStreamId, observer);
      _changeQueue.addStream(stream);

      // Schedule stream creation...
      nlohmann::json obj;
      obj["op"] = "create_stream";
      obj["id"] = _nextStreamId;
      obj["type"] = (int)type;
      obj["service"] = service;
      obj["options"] = options;
      submit(obj.dump());

      _nextStreamId++;

      return persistence::UniqueDataStreamHandle(this, stream);
    }

    void NetClientBackend::removeStream(std::shared_ptr<DataStream> stream)
    {
      nlohmann::json obj;
      obj["op"] = "remove_stream";
      obj["id"] = stream->streamId();
      submit(obj.dump());
    }

    void NetClientBackend::removeTask(std::shared_ptr<Task> task)
    {
      // TODO: Remove tasks?
    }

    void NetClientBackend::socketConnected(boost::system::error_code ec)
    {
      std::lock_guard<std::mutex> lock(_communicationMutex);
      if(!ec)
      {
        _status = Connected;
        std::cout << "Succesfully connected to " << _host << ":" << _port << std::endl;
        if (!_unsubmittedMessages.empty())
          doSumitMessages();
        doReadNextMessageHeader();
      }
      else
      {
        _status = NotConnected;
        std::cerr << "Failed to connect to " << _host << ":" << _port << " " << ec.message() << std::endl;
      }
    }

    void NetClientBackend::doSumitMessages()
    {
      assert(!_unsubmittedMessages.empty());
      //auto& message = _unsubmittedMessages.front();

      // TODO: Serialize message
      auto &data = _unsubmittedMessages.front();

      // Make a message...
      int messageSize = data.size();
      _writeBuffer.resize(messageSize + 4);
      _writeBuffer[0] = (messageSize >>  0) & 0xff;
      _writeBuffer[1] = (messageSize >>  8) & 0xff;
      _writeBuffer[2] = (messageSize >> 16) & 0xff;
      _writeBuffer[3] = (messageSize >> 24) & 0xff;
      memcpy(_writeBuffer.data() + 4, data.data(), messageSize);

      boost::asio::async_write(_socket, boost::asio::buffer(_writeBuffer.data(), _writeBuffer.size()),
                               [this](boost::system::error_code ec, std::size_t /*length*/)
      {
        if (!ec)
        {
          _unsubmittedMessages.pop();
          if (!_unsubmittedMessages.empty())
            doSumitMessages();
        }
        else
        {
          // TODO: Handle error...
          std::cerr << "Failed to submit message (server disconnected...)" << std::endl;
        }
      });
    }

    void NetClientBackend::doReadNextMessageHeader()
    {
      boost::asio::async_read(_socket, boost::asio::buffer(_headerBuffer.data(), _headerBuffer.size()),
                              [this](boost::system::error_code ec, std::size_t length){
        if (!ec)
        {
          size_t size = static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[0])) <<  0 |
                        static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[1])) <<  8 |
                        static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[2])) << 16 |
                        static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[3])) << 24;
          this->doReadNextMessageBody(size);
        } else
        {
          std::cerr << "Error during receive header " << ec.message() << std::endl;
        }
      });
    }

    void NetClientBackend::doReadNextMessageBody(size_t size)
    {
      _bodyBuffer.resize(size);
      boost::asio::async_read(_socket, boost::asio::buffer(_bodyBuffer.data(), _bodyBuffer.size()),
                              [this](boost::system::error_code ec, std::size_t length){
        if (!ec)
        {
          std::string msg(_bodyBuffer.data(), _bodyBuffer.size());
          this->processMessage(nlohmann::json::parse(msg));
          this->doReadNextMessageHeader();
        } else
        {
          std::cerr << "Error during receive body " << ec.message() << std::endl;
        }
      });

    }

    void NetClientBackend::processMessage(const nlohmann::json &obj)
    {
      std::string operation = obj["op"];
      if (operation == "stream_initialize")
      {
        _changeQueue.addStreamChange(obj["id"], DataStreamInitialized{});
      }
      else if (operation == "stream_add")
      {
        int id;
        persistence::StreamableItems items;
        std::tie(id, items) = persistence::net::JsonSerializer::deserializeStreamAddMessage(obj);
        _changeQueue.addStreamChange(id, DataStreamItemsAdded{std::move(items)});
      }
      else if (operation == "stream_update")
      {
        int id;
        persistence::StreamableItems items;
        std::tie(id, items) = persistence::net::JsonSerializer::deserializeStreamUpdateMessage(obj);
        _changeQueue.addStreamChange(id, DataStreamItemsUpdated{std::move(items)});
      }
      else if (operation == "stream_remove")
      {
        int id = obj["id"];
        std::vector<int> ids = obj["items"];
        _changeQueue.addStreamChange(id, DataStreamItemsRemoved{std::move(ids)});
      }
      else if (operation == "task_results")
      {
        int id;
        std::vector<TaskResult> items;
        std::tie(id, items) = persistence::net::JsonSerializer::deserializeTaskResultsMessage(obj);
        auto it = _tasks.find(id);
        if (it != _tasks.end())
        {
          _changeQueue.addTaskChange(it->second->taskId(), std::move(items));
          _tasks.erase(it);
        }
      }
      else
      {
        std::cout << "Unknown operation " << obj << std::endl;
      }
    }

    void NetClientBackend::submit(std::string message)
    {
      _ioService.post([this, message=std::move(message)]() mutable {
        bool submitInProgress = !_unsubmittedMessages.empty();
        _unsubmittedMessages.emplace(std::move(message));
        if (!submitInProgress && _status == Connected)
        {
          doSumitMessages();
        }
      });
    }

  } // namespace net
} // namespace persistence
<commit_msg>Fixed compatibility issue with boost version <1.66<commit_after>#include "persistence/net/netclientbackend.h"

#include "persistence/json/jsonserializer.h"
#include "persistence/net/jsonserializer.h"

#include "persistence/changequeue.h"

#include <boost/asio/connect.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/read.hpp>

namespace persistence
{
  namespace net
  {

    NetClientBackend::NetClientBackend(const std::string& host, int port)
        : _host(host), _port(port), _status(NotConnected), _ioService(), _socket(_ioService), _nextOperationId(1),
          _nextStreamId(1)
    {
      start();
    }

    NetClientBackend::~NetClientBackend()
    {
      stopAndJoin();
    }

    void NetClientBackend::start()
    {
      // Try to connect to the server
      {
        std::lock_guard<std::mutex> lock(_communicationMutex);
        assert(_status == NotConnected);
        _status = Connecting;
        boost::asio::ip::tcp::resolver resolver(_ioService);
        auto endpointIterator = resolver.resolve({_host, std::to_string(_port)});
#if BOOST_VERSION >= 106600
        boost::asio::async_connect(_socket, endpointIterator, [this](boost::system::error_code ec, boost::asio::ip::tcp::endpoint) { this->socketConnected(ec); });
#else
        boost::asio::async_connect(_socket, endpointIterator, [this](boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator) { this->socketConnected(ec); });
#endif

      }

      // Start processing the communication on a separate thread
      _communicationThread = std::thread([this]() {
        _ioService.run();
        std::cout << "IO service has terminated!" << std::endl;
      });
    }

    void NetClientBackend::stopAndJoin()
    {
      _ioService.post([this](){ _socket.close(); });
      _communicationThread.join();
    }

    ChangeQueue &NetClientBackend::changeQueue()
    {
      return _changeQueue;
    }

    UniqueTaskHandle NetClientBackend::queueOperations(op::Operations operations, TaskObserver *observer)
    {
      // Create a task
      _nextOperationId++;
      auto sharedState = std::make_shared<Task>(_nextOperationId);
      sharedState->connect(observer);
      _tasks[_nextOperationId] = sharedState;
      _changeQueue.addTask(sharedState);

      nlohmann::json obj;
      obj["op"] = "schedule_operations";
      obj["id"] = _nextOperationId;
      std::vector<nlohmann::json> operationsArray;
      for (auto &operation : operations)
        operationsArray.push_back(json::serialize(operation));
      obj["operations"]= operationsArray;
      submit(obj.dump());

      return UniqueTaskHandle(this, sharedState);
    }

    persistence::UniqueDataStreamHandle NetClientBackend::createStream(DataStreamObserver* observer,
                                                                       StreamableType type, const std::string& service,
                                                                       const nlohmann::json& options)
    {
      auto stream = std::make_shared<DataStream>(type, service, options);
      stream->connect(_nextStreamId, observer);
      _changeQueue.addStream(stream);

      // Schedule stream creation...
      nlohmann::json obj;
      obj["op"] = "create_stream";
      obj["id"] = _nextStreamId;
      obj["type"] = (int)type;
      obj["service"] = service;
      obj["options"] = options;
      submit(obj.dump());

      _nextStreamId++;

      return persistence::UniqueDataStreamHandle(this, stream);
    }

    void NetClientBackend::removeStream(std::shared_ptr<DataStream> stream)
    {
      nlohmann::json obj;
      obj["op"] = "remove_stream";
      obj["id"] = stream->streamId();
      submit(obj.dump());
    }

    void NetClientBackend::removeTask(std::shared_ptr<Task> task)
    {
      // TODO: Remove tasks?
    }

    void NetClientBackend::socketConnected(boost::system::error_code ec)
    {
      std::lock_guard<std::mutex> lock(_communicationMutex);
      if(!ec)
      {
        _status = Connected;
        std::cout << "Succesfully connected to " << _host << ":" << _port << std::endl;
        if (!_unsubmittedMessages.empty())
          doSumitMessages();
        doReadNextMessageHeader();
      }
      else
      {
        _status = NotConnected;
        std::cerr << "Failed to connect to " << _host << ":" << _port << " " << ec.message() << std::endl;
      }
    }

    void NetClientBackend::doSumitMessages()
    {
      assert(!_unsubmittedMessages.empty());
      //auto& message = _unsubmittedMessages.front();

      // TODO: Serialize message
      auto &data = _unsubmittedMessages.front();

      // Make a message...
      int messageSize = data.size();
      _writeBuffer.resize(messageSize + 4);
      _writeBuffer[0] = (messageSize >>  0) & 0xff;
      _writeBuffer[1] = (messageSize >>  8) & 0xff;
      _writeBuffer[2] = (messageSize >> 16) & 0xff;
      _writeBuffer[3] = (messageSize >> 24) & 0xff;
      memcpy(_writeBuffer.data() + 4, data.data(), messageSize);

      boost::asio::async_write(_socket, boost::asio::buffer(_writeBuffer.data(), _writeBuffer.size()),
                               [this](boost::system::error_code ec, std::size_t /*length*/)
      {
        if (!ec)
        {
          _unsubmittedMessages.pop();
          if (!_unsubmittedMessages.empty())
            doSumitMessages();
        }
        else
        {
          // TODO: Handle error...
          std::cerr << "Failed to submit message (server disconnected...)" << std::endl;
        }
      });
    }

    void NetClientBackend::doReadNextMessageHeader()
    {
      boost::asio::async_read(_socket, boost::asio::buffer(_headerBuffer.data(), _headerBuffer.size()),
                              [this](boost::system::error_code ec, std::size_t length){
        if (!ec)
        {
          size_t size = static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[0])) <<  0 |
                        static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[1])) <<  8 |
                        static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[2])) << 16 |
                        static_cast<size_t>(static_cast<unsigned char>(_headerBuffer[3])) << 24;
          this->doReadNextMessageBody(size);
        } else
        {
          std::cerr << "Error during receive header " << ec.message() << std::endl;
        }
      });
    }

    void NetClientBackend::doReadNextMessageBody(size_t size)
    {
      _bodyBuffer.resize(size);
      boost::asio::async_read(_socket, boost::asio::buffer(_bodyBuffer.data(), _bodyBuffer.size()),
                              [this](boost::system::error_code ec, std::size_t length){
        if (!ec)
        {
          std::string msg(_bodyBuffer.data(), _bodyBuffer.size());
          this->processMessage(nlohmann::json::parse(msg));
          this->doReadNextMessageHeader();
        } else
        {
          std::cerr << "Error during receive body " << ec.message() << std::endl;
        }
      });

    }

    void NetClientBackend::processMessage(const nlohmann::json &obj)
    {
      std::string operation = obj["op"];
      if (operation == "stream_initialize")
      {
        _changeQueue.addStreamChange(obj["id"], DataStreamInitialized{});
      }
      else if (operation == "stream_add")
      {
        int id;
        persistence::StreamableItems items;
        std::tie(id, items) = persistence::net::JsonSerializer::deserializeStreamAddMessage(obj);
        _changeQueue.addStreamChange(id, DataStreamItemsAdded{std::move(items)});
      }
      else if (operation == "stream_update")
      {
        int id;
        persistence::StreamableItems items;
        std::tie(id, items) = persistence::net::JsonSerializer::deserializeStreamUpdateMessage(obj);
        _changeQueue.addStreamChange(id, DataStreamItemsUpdated{std::move(items)});
      }
      else if (operation == "stream_remove")
      {
        int id = obj["id"];
        std::vector<int> ids = obj["items"];
        _changeQueue.addStreamChange(id, DataStreamItemsRemoved{std::move(ids)});
      }
      else if (operation == "task_results")
      {
        int id;
        std::vector<TaskResult> items;
        std::tie(id, items) = persistence::net::JsonSerializer::deserializeTaskResultsMessage(obj);
        auto it = _tasks.find(id);
        if (it != _tasks.end())
        {
          _changeQueue.addTaskChange(it->second->taskId(), std::move(items));
          _tasks.erase(it);
        }
      }
      else
      {
        std::cout << "Unknown operation " << obj << std::endl;
      }
    }

    void NetClientBackend::submit(std::string message)
    {
      _ioService.post([this, message=std::move(message)]() mutable {
        bool submitInProgress = !_unsubmittedMessages.empty();
        _unsubmittedMessages.emplace(std::move(message));
        if (!submitInProgress && _status == Connected)
        {
          doSumitMessages();
        }
      });
    }

  } // namespace net
} // namespace persistence
<|endoftext|>


<commit_before>/*****************************************************************************
 * libVLC backend for the Phonon library                                     *
 *                                                                           *
 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
 * Copyright (C) 2009-2010 vlc-phonon AUTHORS                                *
 *                                                                           *
 * This program is free software; you can redistribute it and/or             *
 * modify it under the terms of the GNU Lesser General Public                *
 * License as published by the Free Software Foundation; either              *
 * version 2.1 of the License, or (at your option) any later version.        *
 *                                                                           *
 * This 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         *
 * Lesser General Public License for more details.                           *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public          *
 * License along with this package; if not, write to the Free Software       *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "devicemanager.h"
#include "backend.h"
//#include "videowidget.h"
//#include "widgetrenderer.h"
#include "vlcloader.h"

#ifdef PHONON_PULSESUPPORT
#  include <phonon/pulsesupport.h>
#endif

#ifdef HAVE_LIBV4L2
#  include <v4l2devices.h>
#endif

/**
 * This class manages the list of currently active output devices.
 */

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace VLC {

Device::Device(DeviceManager *manager, const QByteArray &deviceId, const QByteArray &hw_id)
{
    Q_UNUSED(manager)

    // Get an id
    static int counter = 0;
    id = counter++;
    // Get name from device
    if (nameId == "default") {
        description = "Default audio device";
    } else {
        nameId = deviceId;
        description = "";
    }
    hwId = hw_id;
}

DeviceManager::DeviceManager(Backend *parent)
        : QObject(parent)
        , m_backend(parent)
{
    updateDeviceList();
}

DeviceManager::~DeviceManager()
{
    m_audioCaptureDeviceList.clear();
    m_videoCaptureDeviceList.clear();
    m_audioOutputDeviceList.clear();
}

bool DeviceManager::canOpenDevice() const
{
    return true;
}

/**
 * Return a positive device id or -1 if device does not exist.
 */
int DeviceManager::deviceId(const QByteArray &nameId) const
{
    for (int i = 0 ; i < m_audioCaptureDeviceList.size() ; ++i) {
        if (m_audioCaptureDeviceList[i].nameId == nameId)
            return m_audioCaptureDeviceList[i].id;
    }

    for (int i = 0 ; i < m_videoCaptureDeviceList.size() ; ++i) {
        if (m_videoCaptureDeviceList[i].nameId == nameId)
            return m_videoCaptureDeviceList[i].id;
    }

    for (int i = 0 ; i < m_audioOutputDeviceList.size() ; ++i) {
        if (m_audioOutputDeviceList[i].nameId == nameId)
            return m_audioOutputDeviceList[i].id;
    }

    return -1;
}

/**
 * Get a human-readable description from a device id.
 */
QByteArray DeviceManager::deviceDescription(int i_id) const
{
    for (int i = 0 ; i < m_audioCaptureDeviceList.size() ; ++i) {
        if (m_audioCaptureDeviceList[i].id == i_id)
            return m_audioCaptureDeviceList[i].description;
    }

    for (int i = 0 ; i < m_videoCaptureDeviceList.size() ; ++i) {
        if (m_videoCaptureDeviceList[i].id == i_id)
            return m_videoCaptureDeviceList[i].description;
    }

    for (int i = 0 ; i < m_audioOutputDeviceList.size() ; ++i) {
        if (m_audioOutputDeviceList[i].id == i_id)
            return m_audioOutputDeviceList[i].description;
    }

    return QByteArray();
}

void DeviceManager::updateDeviceSublist(const QList<QByteArray> &namesList, const QList<QByteArray> &hwidList, QList<Device> &deviceList)
{
    bool hasHwids = !hwidList.isEmpty();

    for (int i = 0 ; i < namesList.size() ; ++i) {
        QByteArray nameId = namesList.at(i);
        QByteArray hwId = hasHwids ? hwidList.at(i) : QByteArray();
        if (deviceId(nameId) == -1) {
            // This is a new device, add it
            qDebug() << "added device " << nameId.data();
            deviceList.append(Device(this, nameId, hwId));
            emit deviceAdded(deviceId(nameId));
        }
    }
    if (namesList.size() < deviceList.size()) {
        // A device was removed
        for (int i = deviceList.size() - 1 ; i >= 0 ; --i) {
            QByteArray currId = deviceList[i].nameId;
            bool b_found = false;
            for (int k = namesList.size() - 1  ; k >= 0 ; --k) {
                if (currId == namesList[k]) {
                    b_found = true;
                    break;
                }
            }
            if (!b_found) {
                emit deviceRemoved(deviceId(currId));
                deviceList.removeAt(i);
            }
        }
    }
}

/**
 * Update the current list of active devices.
 */
void DeviceManager::updateDeviceList()
{
#ifdef HAVE_LIBV4L2
    // Lists for capture devices
    QList<QByteArray> vc_names, ac_names, hwids;

    qDebug() << "probing for v4l devices";

    // Get the list of available v4l2 capture devices
    V4L2Support::scanDevices(vc_names, ac_names);

    updateDeviceSublist(vc_names, hwids, m_videoCaptureDeviceList);
    updateDeviceSublist(ac_names, hwids, m_audioCaptureDeviceList);
#endif

    // Lists for audio output devices
    QList<QByteArray> ao_names, ao_hw_names;
    ao_names.append("default");
    ao_hw_names.append("");

    // Get the list of available audio outputs
    libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(vlc_instance);
    if(!p_ao_list)
        qDebug() << "libvlc exception:" << libvlc_errmsg();
    libvlc_audio_output_t *p_start = p_ao_list;

    bool checkpulse = false;
#ifdef PHONON_PULSESUPPORT
    PulseSupport *pulse = PulseSupport::getInstance();
    checkpulse = pulse->isActive();
#endif
    bool haspulse = false;
    while (p_ao_list) {
        if (checkpulse && 0 == strcmp(p_ao_list->psz_name, "pulse")) {
            haspulse = true;
            break;
        }
        ao_names.append(p_ao_list->psz_name);
        ao_hw_names.append("");
        p_ao_list = p_ao_list->p_next;
    }
    libvlc_audio_output_list_release(p_start);

#ifdef PHONON_PULSESUPPORT
    if (haspulse)
        return;
    pulse->enable(false);
#endif

    updateDeviceSublist(ao_names, ao_hw_names, m_audioOutputDeviceList);
}

/**
* Return a list of name identifiers for audio capture devices.
*/
const QList<Device> DeviceManager::audioCaptureDevices() const
{
    return m_audioCaptureDeviceList;
}

/**
* Return a list of name identifiers for video capture devices.
*/
const QList<Device> DeviceManager::videoCaptureDevices() const
{
    return m_videoCaptureDeviceList;
}

/**
 * Return a list of name identifiers for audio output devices.
 */
const QList<Device> DeviceManager::audioOutputDevices() const
{
    return m_audioOutputDeviceList;
}

}
}

QT_END_NAMESPACE
<commit_msg>DeviceManager: Modified the handling of default name id<commit_after>/*****************************************************************************
 * libVLC backend for the Phonon library                                     *
 *                                                                           *
 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
 * Copyright (C) 2009-2010 vlc-phonon AUTHORS                                *
 *                                                                           *
 * This program is free software; you can redistribute it and/or             *
 * modify it under the terms of the GNU Lesser General Public                *
 * License as published by the Free Software Foundation; either              *
 * version 2.1 of the License, or (at your option) any later version.        *
 *                                                                           *
 * This 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         *
 * Lesser General Public License for more details.                           *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public          *
 * License along with this package; if not, write to the Free Software       *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "devicemanager.h"
#include "backend.h"
//#include "videowidget.h"
//#include "widgetrenderer.h"
#include "vlcloader.h"

#ifdef PHONON_PULSESUPPORT
#  include <phonon/pulsesupport.h>
#endif

#ifdef HAVE_LIBV4L2
#  include <v4l2devices.h>
#endif

/**
 * This class manages the list of currently active output devices.
 */

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace VLC {

Device::Device(DeviceManager *manager, const QByteArray &deviceId, const QByteArray &hw_id)
{
    Q_UNUSED(manager)

    // Get an id
    static int counter = 0;
    id = counter++;
    // Get name from device
    if (deviceId == "default") {
        description = "Default device";
    } else {
        nameId = deviceId;
        description = "";
    }
    hwId = hw_id;
}

DeviceManager::DeviceManager(Backend *parent)
        : QObject(parent)
        , m_backend(parent)
{
    updateDeviceList();
}

DeviceManager::~DeviceManager()
{
    m_audioCaptureDeviceList.clear();
    m_videoCaptureDeviceList.clear();
    m_audioOutputDeviceList.clear();
}

bool DeviceManager::canOpenDevice() const
{
    return true;
}

/**
 * Return a positive device id or -1 if device does not exist.
 */
int DeviceManager::deviceId(const QByteArray &nameId) const
{
    for (int i = 0 ; i < m_audioCaptureDeviceList.size() ; ++i) {
        if (m_audioCaptureDeviceList[i].nameId == nameId)
            return m_audioCaptureDeviceList[i].id;
    }

    for (int i = 0 ; i < m_videoCaptureDeviceList.size() ; ++i) {
        if (m_videoCaptureDeviceList[i].nameId == nameId)
            return m_videoCaptureDeviceList[i].id;
    }

    for (int i = 0 ; i < m_audioOutputDeviceList.size() ; ++i) {
        if (m_audioOutputDeviceList[i].nameId == nameId)
            return m_audioOutputDeviceList[i].id;
    }

    return -1;
}

/**
 * Get a human-readable description from a device id.
 */
QByteArray DeviceManager::deviceDescription(int i_id) const
{
    for (int i = 0 ; i < m_audioCaptureDeviceList.size() ; ++i) {
        if (m_audioCaptureDeviceList[i].id == i_id)
            return m_audioCaptureDeviceList[i].description;
    }

    for (int i = 0 ; i < m_videoCaptureDeviceList.size() ; ++i) {
        if (m_videoCaptureDeviceList[i].id == i_id)
            return m_videoCaptureDeviceList[i].description;
    }

    for (int i = 0 ; i < m_audioOutputDeviceList.size() ; ++i) {
        if (m_audioOutputDeviceList[i].id == i_id)
            return m_audioOutputDeviceList[i].description;
    }

    return QByteArray();
}

void DeviceManager::updateDeviceSublist(const QList<QByteArray> &namesList, const QList<QByteArray> &hwidList, QList<Device> &deviceList)
{
    bool hasHwids = !hwidList.isEmpty();

    for (int i = 0 ; i < namesList.size() ; ++i) {
        QByteArray nameId = namesList.at(i);
        QByteArray hwId = hasHwids ? hwidList.at(i) : QByteArray();
        if (deviceId(nameId) == -1) {
            // This is a new device, add it
            qDebug() << "added device " << nameId.data();
            deviceList.append(Device(this, nameId, hwId));
            emit deviceAdded(deviceId(nameId));
        }
    }
    if (namesList.size() < deviceList.size()) {
        // A device was removed
        for (int i = deviceList.size() - 1 ; i >= 0 ; --i) {
            QByteArray currId = deviceList[i].nameId;
            bool b_found = false;
            for (int k = namesList.size() - 1  ; k >= 0 ; --k) {
                if (currId == namesList[k]) {
                    b_found = true;
                    break;
                }
            }
            if (!b_found) {
                emit deviceRemoved(deviceId(currId));
                deviceList.removeAt(i);
            }
        }
    }
}

/**
 * Update the current list of active devices.
 */
void DeviceManager::updateDeviceList()
{
#ifdef HAVE_LIBV4L2
    // Lists for capture devices
    QList<QByteArray> vc_names, ac_names, hwids;

    qDebug() << "probing for v4l devices";

    // Get the list of available v4l2 capture devices
    V4L2Support::scanDevices(vc_names, ac_names);

    updateDeviceSublist(vc_names, hwids, m_videoCaptureDeviceList);
    updateDeviceSublist(ac_names, hwids, m_audioCaptureDeviceList);
#endif

    // Lists for audio output devices
    QList<QByteArray> ao_names, ao_hw_names;
    ao_names.append("default");
    ao_hw_names.append("");

    // Get the list of available audio outputs
    libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(vlc_instance);
    if(!p_ao_list)
        qDebug() << "libvlc exception:" << libvlc_errmsg();
    libvlc_audio_output_t *p_start = p_ao_list;

    bool checkpulse = false;
#ifdef PHONON_PULSESUPPORT
    PulseSupport *pulse = PulseSupport::getInstance();
    checkpulse = pulse->isActive();
#endif
    bool haspulse = false;
    while (p_ao_list) {
        if (checkpulse && 0 == strcmp(p_ao_list->psz_name, "pulse")) {
            haspulse = true;
            break;
        }
        ao_names.append(p_ao_list->psz_name);
        ao_hw_names.append("");
        p_ao_list = p_ao_list->p_next;
    }
    libvlc_audio_output_list_release(p_start);

#ifdef PHONON_PULSESUPPORT
    if (haspulse)
        return;
    pulse->enable(false);
#endif

    updateDeviceSublist(ao_names, ao_hw_names, m_audioOutputDeviceList);
}

/**
* Return a list of name identifiers for audio capture devices.
*/
const QList<Device> DeviceManager::audioCaptureDevices() const
{
    return m_audioCaptureDeviceList;
}

/**
* Return a list of name identifiers for video capture devices.
*/
const QList<Device> DeviceManager::videoCaptureDevices() const
{
    return m_videoCaptureDeviceList;
}

/**
 * Return a list of name identifiers for audio output devices.
 */
const QList<Device> DeviceManager::audioOutputDevices() const
{
    return m_audioOutputDeviceList;
}

}
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>/*  This file is part of the KDE project.

    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 2.1 or 3 of the License.

    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, see <http://www.gnu.org/licenses/>.
*/

#include "devicemanager.h"
#include "backend.h"
//#include "videowidget.h"
//#include "widgetrenderer.h"
#include "vlcloader.h"

#ifdef PHONON_PULSESUPPORT
#  include <phonon/pulsesupport.h>
#endif

/**
 * This class manages the list of currently active output devices.
 */

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace VLC {

AudioDevice::AudioDevice(DeviceManager *manager, const QByteArray &deviceId, const QByteArray &hw_id)
{
    // Get an id
    static int counter = 0;
    id = counter++;
    // Get name from device
    if (vlcId == "default") {
        description = "Default audio device";
    } else {
        vlcId = deviceId;
        description = "";
    }
    hwId = hw_id;
}

DeviceManager::DeviceManager(Backend *parent)
        : QObject(parent)
        , m_backend(parent)
{
    updateDeviceList();
}

DeviceManager::~DeviceManager()
{
    m_audioDeviceList.clear();
}

bool DeviceManager::canOpenDevice() const
{
    return true;
}

/**
 * Return a positive device id or -1 if device does not exist.
 */
int DeviceManager::deviceId(const QByteArray &nameId) const
{
    for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) {
        if (m_audioDeviceList[i].vlcId == nameId)
            return m_audioDeviceList[i].id;
    }
    return -1;
}

/**
 * Get a human-readable description from a device id.
 */
QByteArray DeviceManager::deviceDescription(int i_id) const
{
    for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) {
        if (m_audioDeviceList[i].id == i_id)
            return m_audioDeviceList[i].description;
    }
    return QByteArray();
}

/**
 * Update the current list of active devices.
 */
void DeviceManager::updateDeviceList()
{
    QList<QByteArray> list, list_hw;
    list.append("default");
    list_hw.append("");

    // Get the list of available audio outputs
    libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(vlc_instance);
    if(!p_ao_list)
        qDebug() << "libvlc exception:" << libvlc_errmsg();
    libvlc_audio_output_t *p_start = p_ao_list;

    bool checkpulse = false;
#ifdef PHONON_PULSESUPPORT
    PulseSupport *pulse = PulseSupport::getInstance();
    checkpulse = pulse->isActive();
#endif
    bool haspulse = false;
    while (p_ao_list) {
        if (checkpulse && 0 == strcmp(p_ao_list->psz_name, "pulse")) {
            haspulse = true;
            break;
        }
        list.append(p_ao_list->psz_name);
        list_hw.append("");
        p_ao_list = p_ao_list->p_next;
    }
    libvlc_audio_output_list_release(p_start);

#ifdef PHONON_PULSESUPPORT
    if (haspulse)
        return;
    pulse->enable(false);
#endif

    for (int i = 0 ; i < list.size() ; ++i) {
        QByteArray nameId = list.at(i);
        QByteArray hwId = list_hw.at(i);
        if (deviceId(nameId) == -1) {
            // This is a new device, add it
            qDebug() << "add aout " << nameId.data();
            m_audioDeviceList.append(AudioDevice(this, nameId, hwId));
            emit deviceAdded(deviceId(nameId));
        }
    }
    if (list.size() < m_audioDeviceList.size()) {
        // A device was removed
        for (int i = m_audioDeviceList.size() - 1 ; i >= 0 ; --i) {
            QByteArray currId = m_audioDeviceList[i].vlcId;
            bool b_found = false;
            for (int k = list.size() - 1  ; k >= 0 ; --k) {
                if (currId == list[k]) {
                    b_found = true;
                    break;
                }
            }
            if (!b_found) {
                emit deviceRemoved(deviceId(currId));
                m_audioDeviceList.removeAt(i);
            }
        }
    }
}

/**
 * Return a list of hardware id.
 */
const QList<AudioDevice> DeviceManager::audioOutputDevices() const
{
    return m_audioDeviceList;
}

}
}

QT_END_NAMESPACE
<commit_msg>Fix compiler warning: Unused variable.<commit_after>/*  This file is part of the KDE project.

    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 2.1 or 3 of the License.

    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, see <http://www.gnu.org/licenses/>.
*/

#include "devicemanager.h"
#include "backend.h"
//#include "videowidget.h"
//#include "widgetrenderer.h"
#include "vlcloader.h"

#ifdef PHONON_PULSESUPPORT
#  include <phonon/pulsesupport.h>
#endif

/**
 * This class manages the list of currently active output devices.
 */

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace VLC {

AudioDevice::AudioDevice(DeviceManager *manager, const QByteArray &deviceId, const QByteArray &hw_id)
{
    Q_UNUSED(manager)

    // Get an id
    static int counter = 0;
    id = counter++;
    // Get name from device
    if (vlcId == "default") {
        description = "Default audio device";
    } else {
        vlcId = deviceId;
        description = "";
    }
    hwId = hw_id;
}

DeviceManager::DeviceManager(Backend *parent)
        : QObject(parent)
        , m_backend(parent)
{
    updateDeviceList();
}

DeviceManager::~DeviceManager()
{
    m_audioDeviceList.clear();
}

bool DeviceManager::canOpenDevice() const
{
    return true;
}

/**
 * Return a positive device id or -1 if device does not exist.
 */
int DeviceManager::deviceId(const QByteArray &nameId) const
{
    for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) {
        if (m_audioDeviceList[i].vlcId == nameId)
            return m_audioDeviceList[i].id;
    }
    return -1;
}

/**
 * Get a human-readable description from a device id.
 */
QByteArray DeviceManager::deviceDescription(int i_id) const
{
    for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) {
        if (m_audioDeviceList[i].id == i_id)
            return m_audioDeviceList[i].description;
    }
    return QByteArray();
}

/**
 * Update the current list of active devices.
 */
void DeviceManager::updateDeviceList()
{
    QList<QByteArray> list, list_hw;
    list.append("default");
    list_hw.append("");

    // Get the list of available audio outputs
    libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(vlc_instance);
    if(!p_ao_list)
        qDebug() << "libvlc exception:" << libvlc_errmsg();
    libvlc_audio_output_t *p_start = p_ao_list;

    bool checkpulse = false;
#ifdef PHONON_PULSESUPPORT
    PulseSupport *pulse = PulseSupport::getInstance();
    checkpulse = pulse->isActive();
#endif
    bool haspulse = false;
    while (p_ao_list) {
        if (checkpulse && 0 == strcmp(p_ao_list->psz_name, "pulse")) {
            haspulse = true;
            break;
        }
        list.append(p_ao_list->psz_name);
        list_hw.append("");
        p_ao_list = p_ao_list->p_next;
    }
    libvlc_audio_output_list_release(p_start);

#ifdef PHONON_PULSESUPPORT
    if (haspulse)
        return;
    pulse->enable(false);
#endif

    for (int i = 0 ; i < list.size() ; ++i) {
        QByteArray nameId = list.at(i);
        QByteArray hwId = list_hw.at(i);
        if (deviceId(nameId) == -1) {
            // This is a new device, add it
            qDebug() << "add aout " << nameId.data();
            m_audioDeviceList.append(AudioDevice(this, nameId, hwId));
            emit deviceAdded(deviceId(nameId));
        }
    }
    if (list.size() < m_audioDeviceList.size()) {
        // A device was removed
        for (int i = m_audioDeviceList.size() - 1 ; i >= 0 ; --i) {
            QByteArray currId = m_audioDeviceList[i].vlcId;
            bool b_found = false;
            for (int k = list.size() - 1  ; k >= 0 ; --k) {
                if (currId == list[k]) {
                    b_found = true;
                    break;
                }
            }
            if (!b_found) {
                emit deviceRemoved(deviceId(currId));
                m_audioDeviceList.removeAt(i);
            }
        }
    }
}

/**
 * Return a list of hardware id.
 */
const QList<AudioDevice> DeviceManager::audioOutputDevices() const
{
    return m_audioDeviceList;
}

}
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>/*
This file is part of KDE

  Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "kcolorchooser_version.h"

#include <KAboutData>
#include <KLocalizedString>
#include <KHelpMenu>

#include <QApplication>
#include <QClipboard>
#include <QColorDialog>
#include <QCommandLineParser>
#include <QDialogButtonBox>
#include <QMenu>
#include <QMimeData>
#include <QPushButton>

#include <iostream>

static const char description[] = I18N_NOOP("KDE Color Chooser");

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
    QApplication app(argc, argv);

    KLocalizedString::setApplicationDomain("kcolorchooser");

    KAboutData aboutData(QStringLiteral("kcolorchooser"),
                         i18n("KColorChooser"),
                         QStringLiteral(KCOLORCHOOSER_VERSION_STRING),
                         i18n(description),
                         KAboutLicense::BSDL,
                         i18n("(c) 2000, Waldo Bastian"));
    aboutData.addAuthor(i18n("Waldo Bastian"), QString(), QStringLiteral("bastian@kde.org"));
    aboutData.addAuthor(i18n("Hugo Parente Lima"),i18n("KF5 port"), QStringLiteral("hugo.pl@gmail.com"));
    aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
    KAboutData::setApplicationData(aboutData);

    QCommandLineParser parser;
    parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
    aboutData.setupCommandLine(&parser);
    QCommandLineOption print(QStringLiteral("print"), i18n("Print the selected color to stdout."));
    parser.addOption(print);
    QCommandLineOption color(QStringLiteral("color"), i18n("Set initially selected color."), QStringLiteral("color"));
    parser.addOption(color);
    parser.process(app);
    aboutData.processCommandLine(&parser);

    QColorDialog dlg;
    dlg.setOption(QColorDialog::DontUseNativeDialog);
    QDialogButtonBox *box = dlg.findChild<QDialogButtonBox*>();
    if (!box) {
        return 1;
    }

    box->addButton(QDialogButtonBox::Help);

    KHelpMenu *help = new KHelpMenu(&dlg, aboutData);
    QObject::connect(box, &QDialogButtonBox::helpRequested, [=] () {
        QPushButton *button = box->button(QDialogButtonBox::Help);
        QPoint pos = button->pos();
        pos.ry() += button->height();
        pos = box->mapToGlobal(pos);
        help->menu()->exec(pos);
    });

    if (parser.isSet(color)) {
        dlg.setCurrentColor(QColor(parser.value(color)));
    } else {
        const QMimeData *mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
        if (mimeData) {
            QColor clipboardColor = mimeData->colorData().value<QColor>();
            if (clipboardColor.isValid()) {
                dlg.setCurrentColor(clipboardColor);
            }
        }
    }

    dlg.show();
    app.exec();

    const  QColor c = dlg.currentColor();
    if (parser.isSet(print) && c.isValid()) {
        std::cout << c.name().toUtf8().constData() << std::endl;
    }
}
<commit_msg>Not neccessary to use I18N_NOOP here<commit_after>/*
This file is part of KDE

  Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "kcolorchooser_version.h"

#include <KAboutData>
#include <KLocalizedString>
#include <KHelpMenu>

#include <QApplication>
#include <QClipboard>
#include <QColorDialog>
#include <QCommandLineParser>
#include <QDialogButtonBox>
#include <QMenu>
#include <QMimeData>
#include <QPushButton>

#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
    QApplication app(argc, argv);

    KLocalizedString::setApplicationDomain("kcolorchooser");

    KAboutData aboutData(QStringLiteral("kcolorchooser"),
                         i18n("KColorChooser"),
                         QStringLiteral(KCOLORCHOOSER_VERSION_STRING),
                         i18n("KDE Color Chooser"),
                         KAboutLicense::BSDL,
                         i18n("(c) 2000, Waldo Bastian"));
    aboutData.addAuthor(i18n("Waldo Bastian"), QString(), QStringLiteral("bastian@kde.org"));
    aboutData.addAuthor(i18n("Hugo Parente Lima"),i18n("KF5 port"), QStringLiteral("hugo.pl@gmail.com"));
    aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
    KAboutData::setApplicationData(aboutData);

    QCommandLineParser parser;
    parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
    aboutData.setupCommandLine(&parser);
    QCommandLineOption print(QStringLiteral("print"), i18n("Print the selected color to stdout."));
    parser.addOption(print);
    QCommandLineOption color(QStringLiteral("color"), i18n("Set initially selected color."), QStringLiteral("color"));
    parser.addOption(color);
    parser.process(app);
    aboutData.processCommandLine(&parser);

    QColorDialog dlg;
    dlg.setOption(QColorDialog::DontUseNativeDialog);
    QDialogButtonBox *box = dlg.findChild<QDialogButtonBox*>();
    if (!box) {
        return 1;
    }

    box->addButton(QDialogButtonBox::Help);

    KHelpMenu *help = new KHelpMenu(&dlg, aboutData);
    QObject::connect(box, &QDialogButtonBox::helpRequested, [=] () {
        QPushButton *button = box->button(QDialogButtonBox::Help);
        QPoint pos = button->pos();
        pos.ry() += button->height();
        pos = box->mapToGlobal(pos);
        help->menu()->exec(pos);
    });

    if (parser.isSet(color)) {
        dlg.setCurrentColor(QColor(parser.value(color)));
    } else {
        const QMimeData *mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
        if (mimeData) {
            QColor clipboardColor = mimeData->colorData().value<QColor>();
            if (clipboardColor.isValid()) {
                dlg.setCurrentColor(clipboardColor);
            }
        }
    }

    dlg.show();
    app.exec();

    const  QColor c = dlg.currentColor();
    if (parser.isSet(print) && c.isValid()) {
        std::cout << c.name().toUtf8().constData() << std::endl;
    }
}
<|endoftext|>


<commit_before>/*
This file is part of KDE

  Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <iostream>

#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>

#include "kcolordialog.h"

static const char description[] =
	I18N_NOOP("KDE Color Chooser");

static const char version[] = "v1.0.1";

int main(int argc, char *argv[])
{
  KAboutData aboutData( "kcolorchooser", "kdelibs4", ki18n("KColorChooser"),
		version, ki18n(description), KAboutData::License_BSD,
		ki18n("(c) 2000, Waldo Bastian"));
  aboutData.addAuthor(ki18n("Waldo Bastian"),KLocalizedString(), "bastian@kde.org");
  KCmdLineArgs::init( argc, argv, &aboutData );

  KCmdLineOptions options;
  options.add("print", ki18n("Print the selected color to stdout"));
  KCmdLineArgs::addCmdLineOptions( options );

  KApplication app;

  KColorDialog dlg;

  dlg.setColor(Qt::blue); // Just a color

  app.connect(&dlg, SIGNAL(finished()), SLOT(quit()));

  dlg.show();
  app.exec();

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
  const  QColor c = dlg.color();
  if ( args->isSet("print") && c.isValid() ) {
      std::cout << c.name().toUtf8().constData() << std::endl;
  }
  args->clear();
}
<commit_msg>KColorChooser has its own catalog, setting it as kdelibs4 is probably a leftover from some earlier state.<commit_after>/*
This file is part of KDE

  Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <iostream>

#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>

#include "kcolordialog.h"

static const char description[] =
	I18N_NOOP("KDE Color Chooser");

static const char version[] = "v1.0.1";

int main(int argc, char *argv[])
{
  KAboutData aboutData("kcolorchooser", 0, ki18n("KColorChooser"),
		version, ki18n(description), KAboutData::License_BSD,
		ki18n("(c) 2000, Waldo Bastian"));
  aboutData.addAuthor(ki18n("Waldo Bastian"),KLocalizedString(), "bastian@kde.org");
  KCmdLineArgs::init( argc, argv, &aboutData );

  KCmdLineOptions options;
  options.add("print", ki18n("Print the selected color to stdout"));
  KCmdLineArgs::addCmdLineOptions( options );

  KApplication app;

  KColorDialog dlg;

  dlg.setColor(Qt::blue); // Just a color

  app.connect(&dlg, SIGNAL(finished()), SLOT(quit()));

  dlg.show();
  app.exec();

  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
  const  QColor c = dlg.color();
  if ( args->isSet("print") && c.isValid() ) {
      std::cout << c.name().toUtf8().constData() << std::endl;
  }
  args->clear();
}
<|endoftext|>