<commit_before>#include <Disp.h>
#include <GPIO.h>
#include <IRadio.h>

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sstream>
#include <string>

// FUNCTION PROTOTYPING
void msleep( unsigned milisec );
void sig_handler( int sig );

// GLOBAL VARIABLES
bool ctrl_c_pressed = false;

int main()
{
	if( signal(SIGINT, sig_handler) == SIG_ERR )
		std::cout << "Can't catch SIGINT" << std::endl;

	GPIO* led1 = new GPIO(4, OUT);
	GPIO* led2 = new GPIO(3, OUT);
	GPIO* led3 = new GPIO(2, OUT);

	GPIO* button1 = new GPIO(17, IN, 0.5);
	GPIO* button2 = new GPIO(27, IN, 0.5);
	GPIO* button3 = new GPIO(22, IN, 0.5);

	Disp* lcd = new Disp{14,15,18,11,23,24,9,25,8,7,10};
	std::string line1{}, line2{}, str{};

	IRadio* rstream = new IRadio();
	rstream->startStream();

	std::string welcomeMessageLine1 = "  Welcome to:   ";
	std::string welcomeMessageLine2 = "  Mats' iRadio  ";
	line1 = welcomeMessageLine1;
	line2 = welcomeMessageLine2;

	std::chrono::time_point<std::chrono::system_clock> start_1, start_2;
	std::chrono::duration<double> elapsed_time;
	start_1 = start_2 = std::chrono::system_clock::now();

	while(1)
	{
		led1->setValue( button1->getValue() );
		led2->setValue( button2->getValue() );
		led3->setValue( button3->getValue() );

		elapsed_time = std::chrono::system_clock::now() - start_1;
		if( elapsed_time.count() >= 15.0 )
		{
			start_1 = std::chrono::system_clock::now();

			if( !rstream->streamIsRunning() )
			{
				line1 = welcomeMessageLine1;
				line2 = welcomeMessageLine2;
			}
			else
			{
				rstream->getStreamInfos();
				if( rstream->streamHasChanged() )
				{
					line1 = "[" + std::to_string(rstream->getStreamNr()) + "] " + rstream->getStreamName() + "   ";
					line2 = rstream->getInterpret() + " - " + rstream->getTitle()  + "   ";

					std::cout << "[" << rstream->getStreamNr() << "] " <<  rstream->getStreamName() << ", " << rstream->getInterpret() << " - " << rstream->getTitle() << "\n";
				}
			}
		}

		elapsed_time = std::chrono::system_clock::now() - start_2;
		if( elapsed_time.count() >= 1.0 )
		{
			start_2 = std::chrono::system_clock::now();
			if( lcd->disp_job==lcd->no_job )
			{
				if( !line1.empty() )
				{
					if( line1.size()<DISP_LINE_LENGTH+3 )
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 1 );
					}
					else
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						line1 = line1.substr(1) + line1.at(0);
						lcd->writeText( &str, 1 );
					}
				}
				if( !line2.empty() )
				{
					if( line2.size()<DISP_LINE_LENGTH+3 )
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 2 );
					}
					else
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						line2 = line2.substr(1) + line2.at(0);
						lcd->writeText( &str, 2 );
					}
				}
			}
		}

		lcd->process();

		if( !button1->getDebouncedValue() )
			rstream->increaseStreamNr();
		if( !button2->getDebouncedValue() )
			rstream->stopOrResumeStream();
		if( !button3->getDebouncedValue() )
			rstream->decreaseStreamNr();

		if( ctrl_c_pressed )
			break;
	}

	delete lcd;
	delete led1; delete led2; delete led3;
	delete button1; delete button2; delete button3;
	delete rstream;
}

void msleep( unsigned milisec )
{
	for(unsigned i=0; i<milisec; ++i)
		usleep( 1000 );
}

void sig_handler( int sig )
{
	if (sig == SIGINT)
		ctrl_c_pressed = true;
}
<commit_msg>Change to 20sec refreshing time<commit_after>#include <Disp.h>
#include <GPIO.h>
#include <IRadio.h>

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sstream>
#include <string>

// FUNCTION PROTOTYPING
void msleep( unsigned milisec );
void sig_handler( int sig );

// GLOBAL VARIABLES
bool ctrl_c_pressed = false;

int main()
{
	if( signal(SIGINT, sig_handler) == SIG_ERR )
		std::cout << "Can't catch SIGINT" << std::endl;

	GPIO* led1 = new GPIO(4, OUT);
	GPIO* led2 = new GPIO(3, OUT);
	GPIO* led3 = new GPIO(2, OUT);

	GPIO* button1 = new GPIO(17, IN, 0.5);
	GPIO* button2 = new GPIO(27, IN, 0.5);
	GPIO* button3 = new GPIO(22, IN, 0.5);

	Disp* lcd = new Disp{14,15,18,11,23,24,9,25,8,7,10};
	std::string line1{}, line2{}, str{};

	IRadio* rstream = new IRadio();
	rstream->startStream();

	std::string welcomeMessageLine1 = "  Welcome to:   ";
	std::string welcomeMessageLine2 = "  Mats' iRadio  ";
	line1 = welcomeMessageLine1;
	line2 = welcomeMessageLine2;

	std::chrono::time_point<std::chrono::system_clock> start_1, start_2;
	std::chrono::duration<double> elapsed_time;
	start_1 = start_2 = std::chrono::system_clock::now();

	while(1)
	{
		led1->setValue( button1->getValue() );
		led2->setValue( button2->getValue() );
		led3->setValue( button3->getValue() );

		elapsed_time = std::chrono::system_clock::now() - start_1;
		if( elapsed_time.count() >= 20.0 )
		{
			start_1 = std::chrono::system_clock::now();

			if( !rstream->streamIsRunning() )
			{
				line1 = welcomeMessageLine1;
				line2 = welcomeMessageLine2;
			}
			else
			{
				rstream->getStreamInfos();
				if( rstream->streamHasChanged() )
				{
					line1 = "[" + std::to_string(rstream->getStreamNr()) + "] " + rstream->getStreamName() + "   ";
					line2 = rstream->getInterpret() + " - " + rstream->getTitle()  + "   ";

					//std::cout << "[" << rstream->getStreamNr() << "] " <<  rstream->getStreamName() << ", " << rstream->getInterpret() << " - " << rstream->getTitle() << "\n";
				}
			}
		}

		elapsed_time = std::chrono::system_clock::now() - start_2;
		if( elapsed_time.count() >= 1.0 )
		{
			start_2 = std::chrono::system_clock::now();
			if( lcd->disp_job==lcd->no_job )
			{
				if( !line1.empty() )
				{
					if( line1.size()<DISP_LINE_LENGTH+3 )
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 1 );
					}
					else
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						line1 = line1.substr(1) + line1.at(0);
						lcd->writeText( &str, 1 );
					}
				}
				if( !line2.empty() )
				{
					if( line2.size()<DISP_LINE_LENGTH+3 )
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 2 );
					}
					else
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						line2 = line2.substr(1) + line2.at(0);
						lcd->writeText( &str, 2 );
					}
				}
			}
		}

		lcd->process();

		if( !button1->getDebouncedValue() )
			rstream->increaseStreamNr();
		if( !button2->getDebouncedValue() )
			rstream->stopOrResumeStream();
		if( !button3->getDebouncedValue() )
			rstream->decreaseStreamNr();

		if( ctrl_c_pressed )
			break;
	}

	delete lcd;
	delete led1; delete led2; delete led3;
	delete button1; delete button2; delete button3;
	delete rstream;
}

void msleep( unsigned milisec )
{
	for(unsigned i=0; i<milisec; ++i)
		usleep( 1000 );
}

void sig_handler( int sig )
{
	if (sig == SIGINT)
		ctrl_c_pressed = true;
}
<|endoftext|>


<commit_before>//Includes.
#include <fstream>
#include <iostream>
#include <string>
#include "game.h"
#include "main.h"
#include "baseFunctions.h"

//We'll only use what we need.
using std::cout;
using std::cin;
using std::string;
using std::getline;
using std::ifstream;

void cls();
void prompt(string tPrompt);
void newGame();
void mainMenu();

//Location the user is in the game, used for labeling input.
string currentMenu = "____LOADING____";

//All variables.
string gName = "vAttack";
string gVersion = "Alpha 0.1.0";

//Files.
string line;
ifstream information;

int main()
{

    mainMenu();

    return 0;
}

void mainMenu()
{
    //General input variables for the game.
    int uInp;

    //Loop variables.
    int mLoop = 0;

    //Menu loop.
    while (mLoop <= 10)
    {
        mLoop = 0;
        //Main menu.
        currentMenu = "Main";
        cout << "Welcome to " << gName << "\nVersion: " << gVersion << "\n";
        cout << "================================================\n";
        cout << "| 1 = New game | 2 = Load game | 3 = Save game |\n";
        cout << "|   4 = Help   |   5 = About   |   9 = Exit.   |\n";
        cout << "================================================\n";
        cout << currentMenu << " > ";
        cin >> uInp;

        //Make sure the input is an int.
        if (cin.fail())
        {
            cin.clear(); cin.ignore(); cin.sync();
            mLoop++;
        }

        cls();

        switch(uInp)
        {
            case 9:
                //Exit the game.
                mLoop = 11;
                break;

            case 5:
                //Show information about the game.
                information.open("about.txt");
                if (information.is_open())
                {
                    while (getline(information,line)) { cout << line << "\n"; }
                    prompt("Press enter to return to the main menu.");
                    information.close();
                    cls();
                    break;
                } else { prompt("Unable to open file. Press enter to return to main menu."); information.close(); break; }

            case 4:
                //Help the poor user figure out what this is.
                information.open("help.txt");
                if (information.is_open())
                {
                    while (getline(information,line)) { cout << line << "\n"; }
                    prompt("Press enter to return to the main menu.");
                    information.close();
                    cls();
                    break;
                }

            case 3:
                //TODO: Save the game.

            case 2:
                //TODO: Load a game.

            case 1:
                newGame();

            default:
                prompt("Not a menu item, press enter.");
                cls();
        }

        //Continue the loop.
        mLoop++;
    }

    //Make sure the file is closed before exit.
    information.close();
}<commit_msg>Added a comment.<commit_after>//Includes.
#include <fstream>
#include <iostream>
#include <string>
#include "game.h"
#include "main.h"
#include "baseFunctions.h"

//We'll only use what we need.
using std::cout;
using std::cin;
using std::string;
using std::getline;
using std::ifstream;

void cls();
void prompt(string tPrompt);
void newGame();
void mainMenu();

//Location the user is in the game, used for labeling input.
string currentMenu = "____LOADING____";

//All variables.
string gName = "vAttack";
string gVersion = "Alpha 0.1.0";

//Files.
string line;
ifstream information;

int main()
{
    //Run the main menu loop, and wait for instruction.
    mainMenu();

    return 0;
}

void mainMenu()
{
    //General input variables for the game.
    int uInp;

    //Loop variables.
    int mLoop = 0;

    //Menu loop.
    while (mLoop <= 10)
    {
        mLoop = 0;
        //Main menu.
        currentMenu = "Main";
        cout << "Welcome to " << gName << "\nVersion: " << gVersion << "\n";
        cout << "================================================\n";
        cout << "| 1 = New game | 2 = Load game | 3 = Save game |\n";
        cout << "|   4 = Help   |   5 = About   |   9 = Exit.   |\n";
        cout << "================================================\n";
        cout << currentMenu << " > ";
        cin >> uInp;

        //Make sure the input is an int.
        if (cin.fail())
        {
            cin.clear(); cin.ignore(); cin.sync();
            mLoop++;
        }

        cls();

        switch(uInp)
        {
            case 9:
                //Exit the game.
                mLoop = 11;
                break;

            case 5:
                //Show information about the game.
                information.open("about.txt");
                if (information.is_open())
                {
                    while (getline(information,line)) { cout << line << "\n"; }
                    prompt("Press enter to return to the main menu.");
                    information.close();
                    cls();
                    break;
                } else { prompt("Unable to open file. Press enter to return to main menu."); information.close(); break; }

            case 4:
                //Help the poor user figure out what this is.
                information.open("help.txt");
                if (information.is_open())
                {
                    while (getline(information,line)) { cout << line << "\n"; }
                    prompt("Press enter to return to the main menu.");
                    information.close();
                    cls();
                    break;
                }

            case 3:
                //TODO: Save the game.

            case 2:
                //TODO: Load a game.

            case 1:
                newGame();

            default:
                prompt("Not a menu item, press enter.");
                cls();
        }

        //Continue the loop.
        mLoop++;
    }

    //Make sure the file is closed before exit.
    information.close();
}<|endoftext|>


<commit_before>#include "cells.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <set>

struct format_exception : virtual std::exception, virtual boost::exception {};
typedef boost::error_info<struct row_, std::string> format_row;

void load(boost::filesystem::path const& directory, cells_type& cells)
{
	std::size_t const expected_columns(126);

	boost::filesystem::directory_iterator end;
	for(boost::filesystem::directory_iterator iter(directory); iter != end; ++ iter)
	{
		auto const path(iter->path());
		if(boost::iequals(path.extension().string(), ".txt"))
		{
			boost::filesystem::ifstream stream(path);
			bool header(true);
			std::string row;
			while(std::getline(stream, row))
			{
				std::vector<std::string> columns;
				boost::split(columns, row, boost::is_any_of("\t"));
				if(header)
				{
					if(columns.size() == expected_columns)
					{
						std::cout << "Loading " << path << std::endl;
						header = false;
						continue;
					}
					else
					{
						std::cout << "Ignoring " << path << std::endl;
						break;
					}
				}

				if(columns.size() != expected_columns)
				{
					BOOST_THROW_EXCEPTION(format_exception() << format_row(row));
				}

				cell_type cell;
				cell.path = path;
				cell.id = boost::lexical_cast<std::int64_t>(columns[3]);
				cell.x = boost::lexical_cast<std::int64_t>(columns[7]);
				cell.y = boost::lexical_cast<std::int64_t>(columns[8]);
				cell.phenotype = boost::trim_copy(columns[123]);
				if(cell.phenotype.empty())
				{
					std::cout << "\tDiscarding cell id " << cell.id << " with unknown phenotype" << std::endl;
				}
				else
				{
					cells.push_back(cell);
				}
			}
		}
	}
}

void generate(boost::filesystem::path const& directory, cells_type& cells)
{
	std::set<std::string> phenotypes;
	for(auto const& cell: cells)
	{
		phenotypes.insert(cell.phenotype);
	}

	for(auto const& phenotype: phenotypes)
	{
		boost::filesystem::path path(directory / (phenotype + ".txt"));
		std::cout << "Generating " << path << std::endl;
		boost::filesystem::ofstream stream(path, std::ios::trunc);
		stream << "Path\tCell ID\tCell X Position\tCell Y Position";
		for(auto const& other_phenotype: phenotypes)
		{
			if(other_phenotype != phenotype)
			{
				stream << "\t" << other_phenotype << " Min. Distance" << "\t" << other_phenotype << " Nearest ID";
			}
		}
		stream << std::endl;
		for(auto const& cell: cells)
		{
			if(cell.phenotype != phenotype)
			{
				continue;
			}
			stream << cell.path << "\t" << cell.id << "\t" << cell.x << "\t" << cell.y;
			for(auto const& other_phenotype: phenotypes)
			{
				if(other_phenotype != phenotype)
				{
					double nearest_distance(std::numeric_limits<double>::max());
					std::int64_t nearest_id;
					for(auto const& other_cell: cells)
					{
						if(other_cell.phenotype == other_phenotype)
						{
							std::int64_t const x_distance(cell.x - other_cell.x);
							std::int64_t const y_distance(cell.y - other_cell.y);
							double const distance(std::sqrt((x_distance * x_distance) + (y_distance * y_distance)));
							if(distance < nearest_distance)
							{
								nearest_distance = distance;
								nearest_id = other_cell.id;
							}
						}
					}
					stream << "\t" << std::fixed << std::setprecision(0) << nearest_distance << "\t" << nearest_id;
				}
			}
			stream << std::endl;
		}
	}
}

int main(int argc, char* argv[])
{
	try
	{
		auto const directory(boost::filesystem::current_path());
		cells_type cells;
		load(directory, cells);
		generate(directory, cells);
		return 0;
	}

	catch(...)
	{
		std::cout << boost::current_exception_diagnostic_information() << std::endl;
		return 1;
	}
}<commit_msg>Make loading more robust to format changes<commit_after>#include "cells.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <map>
#include <set>

struct format_exception : virtual std::exception, virtual boost::exception {};
typedef boost::error_info<struct row_, std::string> format_row;

void load(boost::filesystem::path const& directory, cells_type& cells)
{
	char const* cell_id_field("Cell ID");
	char const* cell_x_field("Cell X Position");
	char const* cell_y_field("Cell Y Position");
	char const* phenotype_field("Phenotype");

	boost::filesystem::directory_iterator end;
	for(boost::filesystem::directory_iterator iter(directory); iter != end; ++ iter)
	{
		auto const path(iter->path());
		if(boost::iequals(path.extension().string(), ".txt"))
		{
			boost::filesystem::ifstream stream(path);
			std::map<std::string, std::size_t> header;
			std::string row;
			while(std::getline(stream, row))
			{
				std::vector<std::string> columns;
				boost::split(columns, row, boost::is_any_of("\t"));
				if(header.empty())
				{
					std::size_t index(0);
					for(auto const& column: columns)
					{
						header.insert(std::make_pair(column, index ++));
					}

					if(header.count(cell_id_field) && header.count(cell_x_field) && header.count(cell_y_field) && header.count(phenotype_field))
					{
						std::cout << "Loading " << path << std::endl;
						continue;
					}
					else
					{
						std::cout << "Ignoring " << path << std::endl;
						break;
					}
				}

				if(columns.size() != header.size())
				{
					BOOST_THROW_EXCEPTION(format_exception() << format_row(row));
				}

				cell_type cell;
				cell.path = path;
				cell.id = boost::lexical_cast<std::int64_t>(columns[header[cell_id_field]]);
				cell.x = boost::lexical_cast<std::int64_t>(columns[header[cell_x_field]]);
				cell.y = boost::lexical_cast<std::int64_t>(columns[header[cell_y_field]]);
				cell.phenotype = boost::trim_copy(columns[header[phenotype_field]]);
				if(cell.phenotype.empty())
				{
					std::cout << "\tDiscarding cell id " << cell.id << " with unknown phenotype" << std::endl;
				}
				else
				{
					cells.push_back(cell);
				}
			}
		}
	}
}

void generate(boost::filesystem::path const& directory, cells_type& cells)
{
	std::set<std::string> phenotypes;
	for(auto const& cell: cells)
	{
		phenotypes.insert(cell.phenotype);
	}

	for(auto const& phenotype: phenotypes)
	{
		boost::filesystem::path path(directory / (phenotype + ".txt"));
		std::cout << "Generating " << path << std::endl;
		boost::filesystem::ofstream stream(path, std::ios::trunc);
		stream << "Path\tCell ID\tCell X Position\tCell Y Position";
		for(auto const& other_phenotype: phenotypes)
		{
			if(other_phenotype != phenotype)
			{
				stream << "\t" << other_phenotype << " Min. Distance" << "\t" << other_phenotype << " Nearest ID";
			}
		}
		stream << std::endl;
		for(auto const& cell: cells)
		{
			if(cell.phenotype != phenotype)
			{
				continue;
			}
			stream << cell.path << "\t" << cell.id << "\t" << cell.x << "\t" << cell.y;
			for(auto const& other_phenotype: phenotypes)
			{
				if(other_phenotype != phenotype)
				{
					double nearest_distance(std::numeric_limits<double>::max());
					std::int64_t nearest_id;
					for(auto const& other_cell: cells)
					{
						if(other_cell.phenotype == other_phenotype)
						{
							std::int64_t const x_distance(cell.x - other_cell.x);
							std::int64_t const y_distance(cell.y - other_cell.y);
							double const distance(std::sqrt((x_distance * x_distance) + (y_distance * y_distance)));
							if(distance < nearest_distance)
							{
								nearest_distance = distance;
								nearest_id = other_cell.id;
							}
						}
					}
					stream << "\t" << std::fixed << std::setprecision(0) << nearest_distance << "\t" << nearest_id;
				}
			}
			stream << std::endl;
		}
	}
}

int main(int argc, char* argv[])
{
	try
	{
		auto const directory(boost::filesystem::current_path());
		cells_type cells;
		load(directory, cells);
		generate(directory, cells);
		return 0;
	}

	catch(...)
	{
		std::cout << boost::current_exception_diagnostic_information() << std::endl;
		return 1;
	}
}<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "kdepluginfactory.h"
#include "kiomediastream.h"

#include <QtCore/QFile>
#include <QtCore/QtPlugin>
#include <QtCore/QCoreApplication>

#include <kaboutdata.h>
#include <kdebug.h>
#include <kcomponentdata.h>
#include <kglobal.h>
#include <kicon.h>
#include <klibloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kmimetype.h>
#include <knotification.h>
#include <kservice.h>
#include <kservicetypetrader.h>

namespace Phonon
{

K_GLOBAL_STATIC_WITH_ARGS(KComponentData, mainComponentData, (QCoreApplication::applicationName().toUtf8()))
K_GLOBAL_STATIC_WITH_ARGS(KComponentData, phononComponentData, ("phonon"))

static void ensureMainComponentData()
{
    if (!KGlobal::hasMainComponent()) {
        // a pure Qt application does not have a KComponentData object,
        // we'll give it one.
        *mainComponentData;
        qAddPostRoutine(mainComponentData.destroy);
        Q_ASSERT(KGlobal::hasMainComponent());
    }
}

static const KComponentData &componentData()
{
    ensureMainComponentData();
    return *phononComponentData;
}

KdePlatformPlugin::KdePlatformPlugin()
{
    ensureMainComponentData();
    KGlobal::locale()->insertCatalog(QLatin1String("phonon_kde"));
}

AbstractMediaStream *KdePlatformPlugin::createMediaStream(const QUrl &url, QObject *parent)
{
    return new KioMediaStream(url, parent);
}

QIcon KdePlatformPlugin::icon(const QString &name) const
{
    return KIcon(name);
}

void KdePlatformPlugin::notification(const char *notificationName, const QString &text,
        const QStringList &actions, QObject *receiver,
        const char *actionSlot) const
{
    KNotification *notification = new KNotification(notificationName);
    notification->setComponentData(componentData());
    notification->setText(text);
    //notification->setPixmap(...);
    notification->addContext(QLatin1String("Application"), KGlobal::mainComponent().componentName());
    if (!actions.isEmpty() && receiver && actionSlot) {
        notification->setActions(actions);
        QObject::connect(notification, SIGNAL(activated(unsigned int)), receiver, actionSlot);
    }
    notification->sendEvent();
}

QString KdePlatformPlugin::applicationName() const
{
    ensureMainComponentData();
    const KAboutData *ad = KGlobal::mainComponent().aboutData();
    if (ad) {
        const QString programName = ad->programName();
        if (programName.isEmpty()) {
            return KGlobal::mainComponent().componentName();
        }
        return programName;
    }
    return KGlobal::mainComponent().componentName();
}

#undef PHONON_LOAD_BACKEND_GLOBAL

QObject *KdePlatformPlugin::createBackend(KService::Ptr newService)
{
    KPluginFactory *factory = 0;
    QString errorReason;
#ifdef PHONON_LOAD_BACKEND_GLOBAL
    // This code is in here temporarily until NMM gets fixed.
    // Currently the NMM backend will fail with undefined symbols if
    // the backend is not loaded with global symbol resolution
    //KLibrary *library = KLibLoader::self()->factory(newService->library(), QLibrary::ExportExternalSymbolsHint);
    //if (library) {
    //    factory = library->factory();
    //}
    factory = KLibLoader::self()->factory(QFile::encodeName(newService->library()), QLibrary::ExportExternalSymbolsHint);
    if (!factory) {
        errorReason = KLibLoader::self()->lastErrorMessage();
    }
#else
    KPluginLoader loader(QFile::encodeName(newService->library()));
    factory = loader.factory();
    if (!factory) {
        errorReason = loader.errorString();
    }
#endif
    if (!factory) {
        kError(600) << "Can not create factory for " << newService->name() <<
            ":\n" << errorReason << endl;

        KMessageBox::error(0,
                QLatin1String("")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String(""));
        return false;
    }

    QObject *backend = factory->create<QObject>();
    if (0 == backend) {
        QString errorReason = i18n("create method returned 0");
        kError(600) << "Can not create backend object from factory for " <<
            newService->name() << ", " << newService->library() << ":\n" << errorReason << endl;

        KMessageBox::error(0,
                QLatin1String("<qt>")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String("<qt>"));
        return false;
    }

    kDebug() << "using backend: " << newService->name();
    return backend;
}

QObject *KdePlatformPlugin::createBackend()
{
    ensureMainComponentData();
    const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
            "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
    if (offers.isEmpty()) {
        KMessageBox::error(0, i18n("Unable to find a Multimedia Backend"));
        return 0;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end) {
        QObject *backend = createBackend(*it);
        if (backend) {
            return backend;
        }
        ++it;
    }
    return 0;
}

QObject *KdePlatformPlugin::createBackend(const QString &library, const QString &version)
{
    ensureMainComponentData();
    QString additionalConstraints = QLatin1String(" and Library == '") + library + QLatin1Char('\'');
    if (!version.isEmpty()) {
        additionalConstraints += QLatin1String(" and [X-KDE-PhononBackendInfo-Version] == '")
            + version + QLatin1Char('\'');
    }
    const KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("PhononBackend"),
            QString("Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1%1")
            .arg(additionalConstraints));
    if (offers.isEmpty()) {
        KMessageBox::error(0, i18n("Unable to find the requested Multimedia Backend"));
        return 0;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end) {
        QObject *backend = createBackend(*it);
        if (backend) {
            return backend;
        }
        ++it;
    }
    return 0;
}

bool KdePlatformPlugin::isMimeTypeAvailable(const QString &mimeType) const
{
    ensureMainComponentData();
    const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
            "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
    if (!offers.isEmpty()) {
        return offers.first()->hasMimeType(KMimeType::mimeType(mimeType).data());
    }
    return false;
}

void KdePlatformPlugin::saveVolume(const QString &outputName, qreal volume)
{
    ensureMainComponentData();
    KConfigGroup config(KGlobal::config(), "Phonon::AudioOutput");
    config.writeEntry(outputName + "_Volume", volume);
}

qreal KdePlatformPlugin::loadVolume(const QString &outputName) const
{
    ensureMainComponentData();
    KConfigGroup config(KGlobal::config(), "Phonon::AudioOutput");
    return config.readEntry<qreal>(outputName + "_Volume", 1.0);
}

} // namespace Phonon

Q_EXPORT_PLUGIN2(phonon_platform_kde, Phonon::KdePlatformPlugin)

#include "kdepluginfactory.moc"
// vim: sw=4 sts=4 et tw=100
<commit_msg>simplify backend loading code for the non-ExportExternalSymbols case<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "kdepluginfactory.h"
#include "kiomediastream.h"

#include <QtCore/QFile>
#include <QtCore/QtPlugin>
#include <QtCore/QCoreApplication>

#include <kaboutdata.h>
#include <kdebug.h>
#include <kcomponentdata.h>
#include <kglobal.h>
#include <kicon.h>
#include <klibloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kmimetype.h>
#include <knotification.h>
#include <kservice.h>
#include <kservicetypetrader.h>

namespace Phonon
{

K_GLOBAL_STATIC_WITH_ARGS(KComponentData, mainComponentData, (QCoreApplication::applicationName().toUtf8()))
K_GLOBAL_STATIC_WITH_ARGS(KComponentData, phononComponentData, ("phonon"))

static void ensureMainComponentData()
{
    if (!KGlobal::hasMainComponent()) {
        // a pure Qt application does not have a KComponentData object,
        // we'll give it one.
        *mainComponentData;
        qAddPostRoutine(mainComponentData.destroy);
        Q_ASSERT(KGlobal::hasMainComponent());
    }
}

static const KComponentData &componentData()
{
    ensureMainComponentData();
    return *phononComponentData;
}

KdePlatformPlugin::KdePlatformPlugin()
{
    ensureMainComponentData();
    KGlobal::locale()->insertCatalog(QLatin1String("phonon_kde"));
}

AbstractMediaStream *KdePlatformPlugin::createMediaStream(const QUrl &url, QObject *parent)
{
    return new KioMediaStream(url, parent);
}

QIcon KdePlatformPlugin::icon(const QString &name) const
{
    return KIcon(name);
}

void KdePlatformPlugin::notification(const char *notificationName, const QString &text,
        const QStringList &actions, QObject *receiver,
        const char *actionSlot) const
{
    KNotification *notification = new KNotification(notificationName);
    notification->setComponentData(componentData());
    notification->setText(text);
    //notification->setPixmap(...);
    notification->addContext(QLatin1String("Application"), KGlobal::mainComponent().componentName());
    if (!actions.isEmpty() && receiver && actionSlot) {
        notification->setActions(actions);
        QObject::connect(notification, SIGNAL(activated(unsigned int)), receiver, actionSlot);
    }
    notification->sendEvent();
}

QString KdePlatformPlugin::applicationName() const
{
    ensureMainComponentData();
    const KAboutData *ad = KGlobal::mainComponent().aboutData();
    if (ad) {
        const QString programName = ad->programName();
        if (programName.isEmpty()) {
            return KGlobal::mainComponent().componentName();
        }
        return programName;
    }
    return KGlobal::mainComponent().componentName();
}

#undef PHONON_LOAD_BACKEND_GLOBAL

QObject *KdePlatformPlugin::createBackend(KService::Ptr newService)
{
    QString errorReason;
#ifdef PHONON_LOAD_BACKEND_GLOBAL
    KLibFactory *factory = 0;
    // This code is in here temporarily until NMM gets fixed.
    // Currently the NMM backend will fail with undefined symbols if
    // the backend is not loaded with global symbol resolution
    factory = KLibLoader::self()->factory(newService->library(), QLibrary::ExportExternalSymbolsHint);
    if (!factory) {
        errorReason = KLibLoader::self()->lastErrorMessage();
        kError(600) << "Can not create factory for " << newService->name() <<
            ":\n" << errorReason << endl;

        KMessageBox::error(0,
                QLatin1String("")
                + i18n("Unable to use the %1 Multimedia Backend:", newService->name())
                + QLatin1Char('\n')
                + errorReason
                + QLatin1String(""));
        return false;
    }
    QObject *backend = factory->create<QObject>();
    if (0 == backend) {
        errorReason = i18n("create method returned 0");
    }
#else
    QObject *backend = newService->createInstance<QObject>(0, QVariantList(), &errorReason);
#endif
    if (0 == backend) {
        kError(600) << "Can not create backend object from factory for " <<
            newService->name() << ", " << newService->library() << ":\n" << errorReason << endl;

        KMessageBox::error(0,
                i18n("<qt>Unable to use the %1 Multimedia Backend:
%2</qt>",
                    newService->name(), errorReason));
        return false;
    }

    kDebug() << "using backend: " << newService->name();
    return backend;
}

QObject *KdePlatformPlugin::createBackend()
{
    ensureMainComponentData();
    const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
            "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
    if (offers.isEmpty()) {
        KMessageBox::error(0, i18n("Unable to find a Multimedia Backend"));
        return 0;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end) {
        QObject *backend = createBackend(*it);
        if (backend) {
            return backend;
        }
        ++it;
    }
    return 0;
}

QObject *KdePlatformPlugin::createBackend(const QString &library, const QString &version)
{
    ensureMainComponentData();
    QString additionalConstraints = QLatin1String(" and Library == '") + library + QLatin1Char('\'');
    if (!version.isEmpty()) {
        additionalConstraints += QLatin1String(" and [X-KDE-PhononBackendInfo-Version] == '")
            + version + QLatin1Char('\'');
    }
    const KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("PhononBackend"),
            QString("Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1%1")
            .arg(additionalConstraints));
    if (offers.isEmpty()) {
        KMessageBox::error(0, i18n("Unable to find the requested Multimedia Backend"));
        return 0;
    }

    KService::List::const_iterator it = offers.begin();
    const KService::List::const_iterator end = offers.end();
    while (it != end) {
        QObject *backend = createBackend(*it);
        if (backend) {
            return backend;
        }
        ++it;
    }
    return 0;
}

bool KdePlatformPlugin::isMimeTypeAvailable(const QString &mimeType) const
{
    ensureMainComponentData();
    const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
            "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
    if (!offers.isEmpty()) {
        return offers.first()->hasMimeType(KMimeType::mimeType(mimeType).data());
    }
    return false;
}

void KdePlatformPlugin::saveVolume(const QString &outputName, qreal volume)
{
    ensureMainComponentData();
    KConfigGroup config(KGlobal::config(), "Phonon::AudioOutput");
    config.writeEntry(outputName + "_Volume", volume);
}

qreal KdePlatformPlugin::loadVolume(const QString &outputName) const
{
    ensureMainComponentData();
    KConfigGroup config(KGlobal::config(), "Phonon::AudioOutput");
    return config.readEntry<qreal>(outputName + "_Volume", 1.0);
}

} // namespace Phonon

Q_EXPORT_PLUGIN2(phonon_platform_kde, Phonon::KdePlatformPlugin)

#include "kdepluginfactory.moc"
// vim: sw=4 sts=4 et tw=100
<|endoftext|>


<commit_before>89c51bde-4b02-11e5-bad8-28cfe9171a43<commit_msg>Added that feature we discussed on... Was it monday?<commit_after>89d2394a-4b02-11e5-824f-28cfe9171a43<|endoftext|>


<commit_before>#include "HttpSession.hpp"

#include <boost/asio/connect.hpp>
#include <boost/asio/ssl/rfc2818_verification.hpp>
#include <boost/beast/core/detail/base64.hpp>
#include <boost/beast/http/read.hpp>
#include <boost/beast/http/write.hpp>

namespace ph = std::placeholders;

HttpSession::HttpSession(boost::asio::io_context& ioc) : resolver_{ioc}
{
    ssl::context ctx{ssl::context::sslv23_client};
    ctx.set_default_verify_paths();
    ctx.set_verify_mode(ssl::verify_peer);

    socket_ = std::make_unique<ssl::stream<ip::tcp::socket>>(ioc, ctx);
    response_.body_limit(std::numeric_limits<std::uint64_t>::max());
}

boost::future<HttpResponseResult> HttpSession::send(const Uri& uri, const http::request<http::string_body>& request)
{
    useSsl_ = uri.scheme() == Uri::HttpsScheme;
    request_ = request;

    auto host = uri.authority().host();
    auto hostString = static_cast<std::string>(host);

    socket_->set_verify_callback(ssl::rfc2818_verification(hostString));
    if (!SSL_set_tlsext_host_name(socket_->native_handle(), hostString.data()))
    {
        boost::beast::error_code ec{static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()};
        sessionFinished(ec);
    }

    resolve(uri.authority().host(),
            uri.authority().port(),
            std::bind(&HttpSession::onResolved, shared_from_this(), ph::_1, ph::_2));

    return result_.get_future();
}

template <typename Callback>
void HttpSession::resolve(const Uri::Host& host, const Uri::Port& port, Callback callback)
{
    resolver_.async_resolve(
        static_cast<std::string>(host), port.string(), ip::resolver_base::numeric_service, callback);
}

void HttpSession::onResolved(const boost::system::error_code& ec, ip::tcp::resolver::results_type results)
{
    if (!ec)
    {
        connect(results, std::bind(&HttpSession::onConnected, shared_from_this(), ph::_1, ph::_2));
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::connect(ip::tcp::resolver::results_type results, Callback callback)
{
    boost::asio::async_connect(socket_->next_layer(), results.begin(), results.end(), callback);
}

void HttpSession::onConnected(const boost::system::error_code& ec, ip::tcp::resolver::iterator)
{
    if (!ec)
    {
        if (useSsl_)
        {
            handshake(std::bind(&HttpSession::onHandshaked, shared_from_this(), ph::_1));
        }
        else
        {
            write(std::bind(&HttpSession::onWritten, shared_from_this(), ph::_1, ph::_2));
        }
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::handshake(Callback callback)
{
    socket_->async_handshake(ssl::stream_base::client, callback);
}

void HttpSession::onHandshaked(const boost::system::error_code& ec)
{
    if (!ec)
    {
        write(std::bind(&HttpSession::onWritten, shared_from_this(), ph::_1, ph::_2));
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::write(Callback callback)
{
    if (useSsl_)
    {
        http::async_write(*socket_, request_, callback);
    }
    else
    {
        http::async_write(socket_->next_layer(), request_, callback);
    }
}

void HttpSession::onWritten(const boost::system::error_code& ec, std::size_t /*bytes*/)
{
    if (!ec)
    {
        read(std::bind(&HttpSession::onRead, shared_from_this(), ph::_1, ph::_2));
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::read(Callback callback)
{
    if (useSsl_)
    {
        http::async_read(*socket_, buffer_, response_, callback);
    }
    else
    {
        http::async_read(socket_->next_layer(), buffer_, response_, callback);
    }
}

void HttpSession::onRead(const boost::system::error_code& ec, std::size_t /*bytes*/)
{
    sessionFinished(ec);
}

void HttpSession::sessionFinished(const boost::system::error_code& ec)
{
    if (!ec)
    {
        setHttpResult(HttpResponseResult{PlayerError{}, response_.get().body()});
    }
    else
    {
        PlayerError error{"HTTP", ec.message()};
        setHttpResult(HttpResponseResult{error, {}});
    }
}

void HttpSession::cancel()
{
    setHttpResult(HttpResponseResult{PlayerError{"HTTP", "Operation Aborted"}, {}});
}

void HttpSession::setHttpResult(const HttpResponseResult& result)
{
    if (!resultSet_)
    {
        resultSet_ = true;
        result_.set_value(result);
    }
}
<commit_msg>fix: xibosignage#90 handle http error<commit_after>#include "HttpSession.hpp"

#include <boost/asio/connect.hpp>
#include <boost/asio/ssl/rfc2818_verification.hpp>
#include <boost/beast/core/detail/base64.hpp>
#include <boost/beast/http/read.hpp>
#include <boost/beast/http/write.hpp>

namespace ph = std::placeholders;

HttpSession::HttpSession(boost::asio::io_context& ioc) : resolver_{ioc}
{
    ssl::context ctx{ssl::context::sslv23_client};
    ctx.set_default_verify_paths();
    ctx.set_verify_mode(ssl::verify_peer);

    socket_ = std::make_unique<ssl::stream<ip::tcp::socket>>(ioc, ctx);
    response_.body_limit(std::numeric_limits<std::uint64_t>::max());
}

boost::future<HttpResponseResult> HttpSession::send(const Uri& uri, const http::request<http::string_body>& request)
{
    useSsl_ = uri.scheme() == Uri::HttpsScheme;
    request_ = request;

    auto host = uri.authority().host();
    auto hostString = static_cast<std::string>(host);

    socket_->set_verify_callback(ssl::rfc2818_verification(hostString));
    if (!SSL_set_tlsext_host_name(socket_->native_handle(), hostString.data()))
    {
        boost::beast::error_code ec{static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()};
        sessionFinished(ec);
    }

    resolve(uri.authority().host(),
            uri.authority().port(),
            std::bind(&HttpSession::onResolved, shared_from_this(), ph::_1, ph::_2));

    return result_.get_future();
}

template <typename Callback>
void HttpSession::resolve(const Uri::Host& host, const Uri::Port& port, Callback callback)
{
    resolver_.async_resolve(
        static_cast<std::string>(host), port.string(), ip::resolver_base::numeric_service, callback);
}

void HttpSession::onResolved(const boost::system::error_code& ec, ip::tcp::resolver::results_type results)
{
    if (!ec)
    {
        connect(results, std::bind(&HttpSession::onConnected, shared_from_this(), ph::_1, ph::_2));
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::connect(ip::tcp::resolver::results_type results, Callback callback)
{
    boost::asio::async_connect(socket_->next_layer(), results.begin(), results.end(), callback);
}

void HttpSession::onConnected(const boost::system::error_code& ec, ip::tcp::resolver::iterator)
{
    if (!ec)
    {
        if (useSsl_)
        {
            handshake(std::bind(&HttpSession::onHandshaked, shared_from_this(), ph::_1));
        }
        else
        {
            write(std::bind(&HttpSession::onWritten, shared_from_this(), ph::_1, ph::_2));
        }
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::handshake(Callback callback)
{
    socket_->async_handshake(ssl::stream_base::client, callback);
}

void HttpSession::onHandshaked(const boost::system::error_code& ec)
{
    if (!ec)
    {
        write(std::bind(&HttpSession::onWritten, shared_from_this(), ph::_1, ph::_2));
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::write(Callback callback)
{
    if (useSsl_)
    {
        http::async_write(*socket_, request_, callback);
    }
    else
    {
        http::async_write(socket_->next_layer(), request_, callback);
    }
}

void HttpSession::onWritten(const boost::system::error_code& ec, std::size_t /*bytes*/)
{
    if (!ec)
    {
        read(std::bind(&HttpSession::onRead, shared_from_this(), ph::_1, ph::_2));
    }
    else
    {
        sessionFinished(ec);
    }
}

template <typename Callback>
void HttpSession::read(Callback callback)
{
    if (useSsl_)
    {
        http::async_read(*socket_, buffer_, response_, callback);
    }
    else
    {
        http::async_read(socket_->next_layer(), buffer_, response_, callback);
    }
}

void HttpSession::onRead(const boost::system::error_code& ec, std::size_t /*bytes*/)
{
    sessionFinished(ec);
}

#include "common/logger/Logging.hpp"

void HttpSession::sessionFinished(const boost::system::error_code& ec)
{
    if (!ec)
    {
        auto&& message = response_.get();
        if (message.result() == http::status::ok)
        {
            setHttpResult(HttpResponseResult{PlayerError{}, response_.get().body()});
        }
        else
        {
            std::string responseMessage{message.reason()};
            std::string errorMessage = std::to_string(message.result_int());
            if (!responseMessage.empty())
            {
                errorMessage += " " + responseMessage;
            }
            PlayerError error{"HTTP", errorMessage};
            setHttpResult(HttpResponseResult{error, {}});
        }
    }
    else
    {
        PlayerError error{"HTTP", ec.message()};
        setHttpResult(HttpResponseResult{error, {}});
    }
}

void HttpSession::cancel()
{
    setHttpResult(HttpResponseResult{PlayerError{"HTTP", "Operation Aborted"}, {}});
}

void HttpSession::setHttpResult(const HttpResponseResult& result)
{
    if (!resultSet_)
    {
        resultSet_ = true;
        result_.set_value(result);
    }
}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2020 LXQt team
 * Authors:
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <QVBoxLayout>
#include <QFrame>
#include <QEvent>
#include <QDebug>
#include "sliderdialog.h"

SliderDialog::SliderDialog(QWidget *parent) : QDialog(parent, Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint)
{
    setWindowFlags(Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint);
    m_backlight = new LXQt::Backlight(this);

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(2);

    m_upButton = new QToolButton();
    m_upButton->setText(QStringLiteral("☀"));
    m_upButton->setAutoRepeat(true);
    layout->addWidget(m_upButton, 0, Qt::AlignHCenter);

    m_slider = new QSlider(this);
    layout->addWidget(m_slider, 0, Qt::AlignHCenter);

    m_downButton = new QToolButton();
    m_downButton->setText(QStringLiteral("☼"));
    m_downButton->setAutoRepeat(true);
    layout->addWidget(m_downButton, 0, Qt::AlignHCenter);

    layout->addWidget(m_slider, 0, Qt::AlignHCenter);

    m_downButton = new QToolButton();
    m_downButton->setText(QStringLiteral("☀"));
    layout->addWidget(m_downButton, 0, Qt::AlignHCenter);

    if(m_backlight->isBacklightAvailable() || m_backlight->isBacklightOff()) {
        // Set the minimum to 5% of the maximum to prevent a black screen
        int minBacklight = qMax(qRound((qreal)(m_backlight->getMaxBacklight())*0.05), 1);
        int maxBacklight = m_backlight->getMaxBacklight();
        int interval = maxBacklight - minBacklight;
        if(interval <= 100) {
            m_slider->setMaximum(maxBacklight);
            m_slider->setMinimum(minBacklight);
            m_slider->setValue(m_backlight->getBacklight());
        } else {
            m_slider->setMaximum(100);
            // Set the minimum to 5% of the maximum to prevent a black screen
            m_slider->setMinimum(5);
            m_slider->setValue( (m_backlight->getBacklight() * 100) / maxBacklight);
        }
    } else {
        m_slider->setValue(0);
        m_slider->setEnabled(false);
        m_upButton->setEnabled(false);
        m_downButton->setEnabled(false);
    }

    connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
    connect(m_upButton, SIGNAL(clicked(bool)), this, SLOT(upButtonClicked(bool)));
    connect(m_downButton, SIGNAL(clicked(bool)), this, SLOT(downButtonClicked(bool)));
}

void SliderDialog::sliderValueChanged(int value)
{
    // Set the minimum to 5% of the maximum to prevent a black screen
    int minBacklight = qMax(qRound((qreal)(m_backlight->getMaxBacklight())*0.05), 1);
    int maxBacklight = m_backlight->getMaxBacklight();
    int interval = maxBacklight - minBacklight;
    if(interval > 100)
        value = (value * maxBacklight) / 100;
    m_backlight->setBacklight(value);
}

void SliderDialog::updateBacklight()
{
    // Set the minimum to 5% of the maximum to prevent a black screen
    int minBacklight = qMax(qRound((qreal)(m_backlight->getMaxBacklight())*0.05), 1);
    int maxBacklight = m_backlight->getMaxBacklight();
    int interval = maxBacklight - minBacklight;
    if(interval <= 100)
        m_slider->setValue(m_backlight->getBacklight());
    else
        m_slider->setValue( (m_backlight->getBacklight() * 100) / maxBacklight);
}

void SliderDialog::downButtonClicked(bool)
{
    m_slider->setValue(m_slider->value() - 1);
}

void SliderDialog::upButtonClicked(bool)
{
    m_slider->setValue(m_slider->value() + 1);
}

bool SliderDialog::event(QEvent * event)
{
    if(event->type() == QEvent::WindowDeactivate || event->type() == QEvent::Hide) {
        hide();
        //printf("emit dialogClosed()\n");
        emit dialogClosed();
    }
    return QDialog::event(event);
}

<commit_msg>Set the number of steps of the backlight slider to 100 steps.<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * https://lxqt.org
 *
 * Copyright: 2020 LXQt team
 * Authors:
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <QVBoxLayout>
#include <QFrame>
#include <QEvent>
#include <QDebug>
#include "sliderdialog.h"

SliderDialog::SliderDialog(QWidget *parent) : QDialog(parent, Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint)
{
    setWindowFlags(Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint);
    m_backlight = new LXQt::Backlight(this);

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(2);

    m_upButton = new QToolButton();
    m_upButton->setText(QStringLiteral("☀"));
    m_upButton->setAutoRepeat(true);
    layout->addWidget(m_upButton, 0, Qt::AlignHCenter);

    m_slider = new QSlider(this);
    layout->addWidget(m_slider, 0, Qt::AlignHCenter);

    m_downButton = new QToolButton();
    m_downButton->setText(QStringLiteral("☼"));
    m_downButton->setAutoRepeat(true);
    layout->addWidget(m_downButton, 0, Qt::AlignHCenter);

    if(m_backlight->isBacklightAvailable() || m_backlight->isBacklightOff()) {
        // Set the minimum to 5% of the maximum to prevent a black screen
        int minBacklight = qMax(qRound((qreal)(m_backlight->getMaxBacklight())*0.05), 1);
        int maxBacklight = m_backlight->getMaxBacklight();
        int interval = maxBacklight - minBacklight;
        if(interval <= 100) {
            m_slider->setMaximum(maxBacklight);
            m_slider->setMinimum(minBacklight);
            m_slider->setValue(m_backlight->getBacklight());
        } else {
            m_slider->setMaximum(100);
            // Set the minimum to 5% of the maximum to prevent a black screen
            m_slider->setMinimum(5);
            m_slider->setValue( (m_backlight->getBacklight() * 100) / maxBacklight);
        }
    } else {
        m_slider->setValue(0);
        m_slider->setEnabled(false);
        m_upButton->setEnabled(false);
        m_downButton->setEnabled(false);
    }

    connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
    connect(m_upButton, SIGNAL(clicked(bool)), this, SLOT(upButtonClicked(bool)));
    connect(m_downButton, SIGNAL(clicked(bool)), this, SLOT(downButtonClicked(bool)));
}

void SliderDialog::sliderValueChanged(int value)
{
    // Set the minimum to 5% of the maximum to prevent a black screen
    int minBacklight = qMax(qRound((qreal)(m_backlight->getMaxBacklight())*0.05), 1);
    int maxBacklight = m_backlight->getMaxBacklight();
    int interval = maxBacklight - minBacklight;
    if(interval > 100)
        value = (value * maxBacklight) / 100;
    m_backlight->setBacklight(value);
}

void SliderDialog::updateBacklight()
{
    // Set the minimum to 5% of the maximum to prevent a black screen
    int minBacklight = qMax(qRound((qreal)(m_backlight->getMaxBacklight())*0.05), 1);
    int maxBacklight = m_backlight->getMaxBacklight();
    int interval = maxBacklight - minBacklight;
    if(interval <= 100)
        m_slider->setValue(m_backlight->getBacklight());
    else
        m_slider->setValue( (m_backlight->getBacklight() * 100) / maxBacklight);
}

void SliderDialog::downButtonClicked(bool)
{
    m_slider->setValue(m_slider->value() - 1);
}

void SliderDialog::upButtonClicked(bool)
{
    m_slider->setValue(m_slider->value() + 1);
}

bool SliderDialog::event(QEvent * event)
{
    if(event->type() == QEvent::WindowDeactivate || event->type() == QEvent::Hide) {
        hide();
        //printf("emit dialogClosed()\n");
        emit dialogClosed();
    }
    return QDialog::event(event);
}

<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Razor - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "razormainmenu.h"
#include "razormainmenuconfiguration.h"
#include <QDebug>
#include <qtxdg/xdgdesktopfile.h>
#include <qtxdg/xmlhelper.h>
#include <QSettings>
#include <QFileInfo>
#include <QAction>
#include <QtCore/QTimer>
#include <QtGui/QMessageBox>
#include <razorqt/powermanager.h>
#include <razorqt/screensaver.h>
#include <razor-global-key-shortcuts-client/razor-global-key-shortcuts-client.h>
#include <razorqt/xfitman.h>

#include <qtxdg/xdgicon.h>
#include <qtxdg/xdgdesktopfile.h>
#include <qtxdg/xdgmenuwidget.h>

#include <QPixmap>
#include <QStack>

#include <QCursor>

Q_EXPORT_PLUGIN2(mainmenu, RazorMainMenuPluginLibrary)

#define DEFAULT_SHORTCUT "Alt+F1"

/************************************************

 ************************************************/
RazorMainMenu::RazorMainMenu(const IRazorPanelPluginStartupInfo &startupInfo):
    QObject(),
    IRazorPanelPlugin(startupInfo),
    mMenu(0),
    mShortcut(0),
    mLockCascadeChanges(false)
{
    mButton.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);

    connect(&mButton, SIGNAL(clicked()), this, SLOT(showMenu()));

    mPowerManager = new PowerManager(this);
    mScreenSaver = new ScreenSaver(this);

    settingsChanged();

    connect(mShortcut, SIGNAL(activated()), this, SLOT(showHideMenu()));
    connect(mShortcut, SIGNAL(shortcutChanged(QString,QString)), this, SLOT(shortcutChanged(QString,QString)));
}

/************************************************

 ************************************************/
RazorMainMenu::~RazorMainMenu()
{
}

/************************************************

 ************************************************/
void RazorMainMenu::showHideMenu()
{
    if (mMenu && mMenu->isVisible())
        mMenu->hide();
    else
        showMenu();
}

/************************************************

 ************************************************/
void RazorMainMenu::shortcutChanged(const QString &/*oldShortcut*/, const QString &newShortcut)
{
    if (!newShortcut.isEmpty())
    {
        mLockCascadeChanges = true;

        settings()->setValue("dialog/shortcut", newShortcut);
        settings()->sync();

        mLockCascadeChanges = false;
    }
}

/************************************************

 ************************************************/
void RazorMainMenu::showMenu()
{
    if (!mMenu)
        return;

    int x=0, y=0;

    switch (panel()->position())
    {
        case IRazorPanel::PositionTop:
            x = mButton.mapToGlobal(QPoint(0, 0)).x();
            y = panel()->globalGometry().bottom();
            break;

        case IRazorPanel::PositionBottom:
            x = mButton.mapToGlobal(QPoint(0, 0)).x();
            y = panel()->globalGometry().top() - mMenu->sizeHint().height();
            break;

        case IRazorPanel::PositionLeft:
            x = panel()->globalGometry().right();
            y = mButton.mapToGlobal(QPoint(0, 0)).y();
            break;

        case IRazorPanel::PositionRight:
            x = panel()->globalGometry().left() - mMenu->sizeHint().width();
            y = mButton.mapToGlobal(QPoint(0, 0)).y();
            break;
    }

    // Just using Qt`s activateWindow() won't work on some WMs like Kwin.
    // There are two solutions:
    //  activate window with Qt call and then execute menu 1ms later using timer,
    //  or use native X11 API calls:
    xfitMan().raiseWindow(mButton.effectiveWinId());
    mMenu->exec(QPoint(x, y));
}

/************************************************

 ************************************************/
void RazorMainMenu::settingsChanged()
{
    if (mLockCascadeChanges)
        return;

    if (settings()->value("showText", false).toBool())
    {
        mButton.setText(settings()->value("text", "Start").toString());
        mButton.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    }
    else
    {
        mButton.setText("");
        mButton.setToolButtonStyle(Qt::ToolButtonIconOnly);
    }

    mLogDir = settings()->value("log_dir", "").toString();

    QString mMenuFile = settings()->value("menu_file", "").toString();
    if (mMenuFile.isEmpty())
        mMenuFile = XdgMenu::getMenuFileName();

    mXdgMenu.setEnvironments(QStringList() << "X-RAZOR" << "Razor");
    mXdgMenu.setLogDir(mLogDir);

    bool res = mXdgMenu.read(mMenuFile);
    connect(&mXdgMenu, SIGNAL(changed()), this, SLOT(buildMenu()));
    if (res)
    {
        QTimer::singleShot(1000, this, SLOT(buildMenu()));
    }
    else
    {
        QMessageBox::warning(0, "Parse error", mXdgMenu.errorString());
        return;
    }

    QString shortcut = settings()->value("shortcut", DEFAULT_SHORTCUT).toString();
    if (shortcut.isEmpty())
        shortcut = DEFAULT_SHORTCUT;

    if (!mShortcut)
        mShortcut = GlobalKeyShortcut::Client::instance()->addAction(shortcut, QString("/panel/%1/show_hide").arg(settings()->group()), tr("Show/hide main menu"), this);
    else if (mShortcut->shortcut() != shortcut)
    {
        mShortcut->changeShortcut(shortcut);
    }

    realign();
}

/************************************************

 ************************************************/
void RazorMainMenu::buildMenu()
{
    XdgMenuWidget *menu = new XdgMenuWidget(mXdgMenu, "", &mButton);
    menu->setObjectName("TopLevelMainMenu");
    menu->setStyle(&mTopMenuStyle);

    menu->addSeparator();

    QMenu* leaveMenu = menu->addMenu(XdgIcon::fromTheme("system-shutdown"), tr("Leave"));
    leaveMenu->addActions(mPowerManager->availableActions());
    menu->addActions(mScreenSaver->availableActions());

    QMenu *oldMenu = mMenu;
    mMenu = menu;
    delete oldMenu;
}

/************************************************

 ************************************************/
QDialog *RazorMainMenu::configureDialog()
{
    return new RazorMainMenuConfiguration(*settings(), DEFAULT_SHORTCUT);
}

/************************************************

 ************************************************/
void RazorMainMenu::realign()
{
    QSize minSize = QSize(0, 0);
    QSize maxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);

    if (panel()->isHorizontal())
    {
        minSize.setHeight(panel()->lineCount() * panel()->lineSize());
        maxSize.setHeight(minSize.height());

        minSize.setWidth(minSize.height());
    }
    else
    {
        minSize.setWidth(panel()->lineCount() * panel()->lineSize());
        minSize.setHeight(panel()->lineSize());
    }

    mButton.setMinimumSize(minSize);
    mButton.setMaximumSize(maxSize);
    mButton.updateGeometry();
}

#undef DEFAULT_SHORTCUT
<commit_msg>Fix for Issue #531 This work for me in the OpenBox and KWin<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Razor - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "razormainmenu.h"
#include "razormainmenuconfiguration.h"
#include <QDebug>
#include <qtxdg/xdgdesktopfile.h>
#include <qtxdg/xmlhelper.h>
#include <QSettings>
#include <QFileInfo>
#include <QAction>
#include <QtCore/QTimer>
#include <QtGui/QMessageBox>
#include <razorqt/powermanager.h>
#include <razorqt/screensaver.h>
#include <razor-global-key-shortcuts-client/razor-global-key-shortcuts-client.h>
#include <razorqt/xfitman.h>

#include <qtxdg/xdgicon.h>
#include <qtxdg/xdgdesktopfile.h>
#include <qtxdg/xdgmenuwidget.h>

#include <QPixmap>
#include <QStack>

#include <QCursor>

Q_EXPORT_PLUGIN2(mainmenu, RazorMainMenuPluginLibrary)

#define DEFAULT_SHORTCUT "Alt+F1"

/************************************************

 ************************************************/
RazorMainMenu::RazorMainMenu(const IRazorPanelPluginStartupInfo &startupInfo):
    QObject(),
    IRazorPanelPlugin(startupInfo),
    mMenu(0),
    mShortcut(0),
    mLockCascadeChanges(false)
{
    mButton.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);

    connect(&mButton, SIGNAL(clicked()), this, SLOT(showMenu()));

    mPowerManager = new PowerManager(this);
    mScreenSaver = new ScreenSaver(this);

    settingsChanged();

    connect(mShortcut, SIGNAL(activated()), this, SLOT(showHideMenu()));
    connect(mShortcut, SIGNAL(shortcutChanged(QString,QString)), this, SLOT(shortcutChanged(QString,QString)));
}

/************************************************

 ************************************************/
RazorMainMenu::~RazorMainMenu()
{
}

/************************************************

 ************************************************/
void RazorMainMenu::showHideMenu()
{
    if (mMenu && mMenu->isVisible())
        mMenu->hide();
    else
        showMenu();
}

/************************************************

 ************************************************/
void RazorMainMenu::shortcutChanged(const QString &/*oldShortcut*/, const QString &newShortcut)
{
    if (!newShortcut.isEmpty())
    {
        mLockCascadeChanges = true;

        settings()->setValue("dialog/shortcut", newShortcut);
        settings()->sync();

        mLockCascadeChanges = false;
    }
}

/************************************************

 ************************************************/
void RazorMainMenu::showMenu()
{
    if (!mMenu)
        return;

    int x=0, y=0;

    switch (panel()->position())
    {
        case IRazorPanel::PositionTop:
            x = mButton.mapToGlobal(QPoint(0, 0)).x();
            y = panel()->globalGometry().bottom();
            break;

        case IRazorPanel::PositionBottom:
            x = mButton.mapToGlobal(QPoint(0, 0)).x();
            y = panel()->globalGometry().top() - mMenu->sizeHint().height();
            break;

        case IRazorPanel::PositionLeft:
            x = panel()->globalGometry().right();
            y = mButton.mapToGlobal(QPoint(0, 0)).y();
            break;

        case IRazorPanel::PositionRight:
            x = panel()->globalGometry().left() - mMenu->sizeHint().width();
            y = mButton.mapToGlobal(QPoint(0, 0)).y();
            break;
    }

    // Just using Qt`s activateWindow() won't work on some WMs like Kwin.
    // There are two solutions:
    //  activate window with Qt call and then execute menu 1ms later using timer,
    //  or use native X11 API calls:
    //xfitMan().raiseWindow(mButton.effectiveWinId());
    mButton.activateWindow();
    mMenu->exec(QPoint(x, y));
}

/************************************************

 ************************************************/
void RazorMainMenu::settingsChanged()
{
    if (mLockCascadeChanges)
        return;

    if (settings()->value("showText", false).toBool())
    {
        mButton.setText(settings()->value("text", "Start").toString());
        mButton.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    }
    else
    {
        mButton.setText("");
        mButton.setToolButtonStyle(Qt::ToolButtonIconOnly);
    }

    mLogDir = settings()->value("log_dir", "").toString();

    QString mMenuFile = settings()->value("menu_file", "").toString();
    if (mMenuFile.isEmpty())
        mMenuFile = XdgMenu::getMenuFileName();

    mXdgMenu.setEnvironments(QStringList() << "X-RAZOR" << "Razor");
    mXdgMenu.setLogDir(mLogDir);

    bool res = mXdgMenu.read(mMenuFile);
    connect(&mXdgMenu, SIGNAL(changed()), this, SLOT(buildMenu()));
    if (res)
    {
        QTimer::singleShot(1000, this, SLOT(buildMenu()));
    }
    else
    {
        QMessageBox::warning(0, "Parse error", mXdgMenu.errorString());
        return;
    }

    QString shortcut = settings()->value("shortcut", DEFAULT_SHORTCUT).toString();
    if (shortcut.isEmpty())
        shortcut = DEFAULT_SHORTCUT;

    if (!mShortcut)
        mShortcut = GlobalKeyShortcut::Client::instance()->addAction(shortcut, QString("/panel/%1/show_hide").arg(settings()->group()), tr("Show/hide main menu"), this);
    else if (mShortcut->shortcut() != shortcut)
    {
        mShortcut->changeShortcut(shortcut);
    }

    realign();
}

/************************************************

 ************************************************/
void RazorMainMenu::buildMenu()
{
    XdgMenuWidget *menu = new XdgMenuWidget(mXdgMenu, "", &mButton);
    menu->setObjectName("TopLevelMainMenu");
    menu->setStyle(&mTopMenuStyle);

    menu->addSeparator();

    QMenu* leaveMenu = menu->addMenu(XdgIcon::fromTheme("system-shutdown"), tr("Leave"));
    leaveMenu->addActions(mPowerManager->availableActions());
    menu->addActions(mScreenSaver->availableActions());

    QMenu *oldMenu = mMenu;
    mMenu = menu;
    delete oldMenu;
}

/************************************************

 ************************************************/
QDialog *RazorMainMenu::configureDialog()
{
    return new RazorMainMenuConfiguration(*settings(), DEFAULT_SHORTCUT);
}

/************************************************

 ************************************************/
void RazorMainMenu::realign()
{
    QSize minSize = QSize(0, 0);
    QSize maxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);

    if (panel()->isHorizontal())
    {
        minSize.setHeight(panel()->lineCount() * panel()->lineSize());
        maxSize.setHeight(minSize.height());

        minSize.setWidth(minSize.height());
    }
    else
    {
        minSize.setWidth(panel()->lineCount() * panel()->lineSize());
        minSize.setHeight(panel()->lineSize());
    }

    mButton.setMinimumSize(minSize);
    mButton.setMaximumSize(maxSize);
    mButton.updateGeometry();
}

#undef DEFAULT_SHORTCUT
<|endoftext|>


<commit_before>/*
  ==============================================================================

    This file was auto-generated by the Introjucer!

    It contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

const char* RP2A03AudioProcessor::paramPulse1Level      = "pulse1Level";
const char* RP2A03AudioProcessor::paramPulse1DutyCycle  = "pulse1Duty";
const char* RP2A03AudioProcessor::paramPulse2Level      = "pulse2Level";
const char* RP2A03AudioProcessor::paramPulse2DutyCycle  = "pulse2Duty";
const char* RP2A03AudioProcessor::paramTriangleLevel    = "triangleLevel";
const char* RP2A03AudioProcessor::paramNoiseLevel       = "noiseLevel";
const char* RP2A03AudioProcessor::paramNoiseShort       = "noisePeriod";
const char* RP2A03AudioProcessor::paramOutput           = "output";
const char* RP2A03AudioProcessor::paramPulse1Tune       = "pulse1Tune";
const char* RP2A03AudioProcessor::paramPulse1TuneFine   = "pulse1TuneFine";
const char* RP2A03AudioProcessor::paramPulse2Tune       = "pulse2Tune";
const char* RP2A03AudioProcessor::paramPulse2TuneFine   = "pulse2TuneFine";
const char* RP2A03AudioProcessor::paramTriangleTune     = "triangleTune";
const char* RP2A03AudioProcessor::paramTriangleTuneFine = "triangleTuneFine";

//==============================================================================
String percentTextFunction (const slParameter& p, float v)
{
    return String::formatted("%.0f%%", v / p.getUserRangeEnd() * 100);
}

String onOffTextFunction (const slParameter& p, float v)
{
    return v > 0.0f ? "On" : "Off";
}

String dutyTextFunction (const slParameter& p, float v)
{
    const int duty = int (v);
    switch (duty)
    {
        case 0: return "12.5%";
        case 1: return "25%";
        case 2: return "50%";
        case 3: return "75%";
    }
    return "";
}

//==============================================================================
RP2A03AudioProcessor::RP2A03AudioProcessor()
{
    addPluginParameter (new slParameter (paramPulse1Level,     "Pulse 1 Level",      "Pulse",       "", 0.0f, 1.0f,  0.0f, 1.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramPulse1DutyCycle, "Pulse 1 Duty Cycle", "Duty Cycle",  "", 0.0f, 3.0f,  1.0f, 0.0f, 1.0f, dutyTextFunction));
    addPluginParameter (new slParameter (paramPulse2Level,     "Pulse 2 Level",      "Pulse",       "", 0.0f, 1.0f,  0.0f, 0.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramPulse2DutyCycle, "Pulse 2 Duty Cycle", "Duty Cycle",  "", 0.0f, 3.0f,  1.0f, 0.0f, 1.0f, dutyTextFunction));
    addPluginParameter (new slParameter (paramNoiseLevel,      "Noise Level",        "Noise",       "", 0.0f, 1.0f,  0.0f, 0.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramNoiseShort,      "Noise Short",        "Short",       "", 0.0f, 1.0f,  1.0f, 0.0f, 1.0f, onOffTextFunction));
    addPluginParameter (new slParameter (paramTriangleLevel,   "Triangle Level",     "Triangle",    "", 0.0f, 1.0f,  1.0f, 0.0f, 1.0f, onOffTextFunction));
    addPluginParameter (new slParameter (paramOutput,          "Output",             "Output",      "", 0.0f, 1.0f,  0.0f, 1.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramPulse1Tune,      "Pulse 1 Tune",       "Tune",        "", -48.0f, 48.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramPulse1TuneFine,  "Pulse 1 Tune Fine",  "Fine",        "", -100.0f, 100.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramPulse2Tune,      "Pulse 2 Tune",       "Tune",        "", -48.0f, 48.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramPulse2TuneFine,  "Pulse 2 Tune Fine",  "Fine",        "", -100.0f, 100.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramTriangleTune,    "Triangle Tune",      "Tune",        "", -48.0f, 48.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramTriangleTuneFine,"Triangle Tune Fine", "Fine",        "", -100.0f, 100.0f, 1.0f, 0.0f, 1.0f));
}

RP2A03AudioProcessor::~RP2A03AudioProcessor()
{
}

//==============================================================================
void RP2A03AudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    apu.sample_rate (long (sampleRate));
    apu.write_register (0x4015, 0x0F);

    outputSmoothed.reset (sampleRate, 0.05);
}

void RP2A03AudioProcessor::releaseResources()
{
}

void RP2A03AudioProcessor::runUntil (int& done, AudioSampleBuffer& buffer, int pos)
{
    int todo = jmin (pos, buffer.getNumSamples()) - done;

    while (todo > 0)
    {
        if (apu.samples_avail() == 0)
            apu.step();

        Simple_Apu::sample_t out[1024];
        int count = apu.read_samples(out, jmin (todo, int (apu.samples_avail()), 1024));

        float* data = buffer.getWritePointer (0, done);
        for (int i = 0; i < count; i++)
            data[i] = out[i] / 32768.0f;

        done += count;
        todo -= count;
    }

}

void RP2A03AudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midi)
{
    const float p1Level = parameterValue (paramPulse1Level);
    const int p1Duty    = parameterIntValue (paramPulse1DutyCycle);
    const int p1Tune    = parameterIntValue (paramPulse1Tune);
    const int p1Fine    = parameterIntValue (paramPulse1TuneFine);
    const float p2Level = parameterValue (paramPulse2Level);
    const int p2Duty    = parameterIntValue (paramPulse2DutyCycle);
    const int p2Tune    = parameterIntValue (paramPulse2Tune);
    const int p2Fine    = parameterIntValue (paramPulse2TuneFine);
    const float tLevel  = parameterValue (paramTriangleLevel);
    const int tTune     = parameterIntValue (paramTriangleTune);
    const int tFine     = parameterIntValue (paramTriangleTuneFine);
    const float nLevel  = parameterValue (paramNoiseLevel);
    const bool nShort   = parameterValue (paramNoiseShort) > 0.0f;

    outputSmoothed.setValue (getParameter (paramOutput)->getUserValue());

    int done = 0;
    runUntil (done, buffer, 0);

    int pos = 0;
    MidiMessage msg;
    MidiBuffer::Iterator itr (midi);
    while (itr.getNextEvent (msg, pos))
    {
        runUntil (done, buffer, pos);

        if (msg.isNoteOn())
        {
            noteQueue.add (msg.getNoteNumber());
            velocity = msg.getVelocity();
        }
        else if (msg.isNoteOff())
        {
            noteQueue.removeFirstMatchingValue (msg.getNoteNumber());
        }
        else if (msg.isAllNotesOff())
        {
            noteQueue.clear();
        }

        const int curNote = noteQueue.size() > 0 ? noteQueue.getFirst() : -1;

        if (curNote != lastNote)
        {
            int v = curNote == -1 ? 0 : velocity;

            // Pulse 1
            apu.write_register (0x4000, (p1Duty << 6) | 0x30 | int (p1Level * v / 127.0 * 0xF));

            if (curNote != -1)
            {
                int period = int (111860.8 / getMidiNoteInHertz (curNote + p1Tune + p1Fine / 100.0) - 1);

                apu.write_register (0x4002, period & 0xFF);
                apu.write_register (0x4003, (period >> 8) & 0x7);
            }

            // Pulse 2
            apu.write_register (0x4004, (p2Duty << 6) | 0x30 | int (p2Level * v / 127.0 * 0xF));

            if (curNote != -1)
            {
                int period = int (111860.8 / getMidiNoteInHertz (curNote + p2Tune + p2Fine / 100.0) - 1);

                apu.write_register (0x4006, period & 0xFF);
                apu.write_register (0x4007, (period >> 8) & 0x7);
            }

            // Triangle
            apu.write_register (0x4008, curNote == -1 ? 0x00 : 0xFF);
            if (curNote != -1)
            {
                int period = int (tLevel == 1.0f ? 111860.8 / getMidiNoteInHertz (curNote + tTune + tFine / 100.0) * 2 - 1 : 0);

                apu.write_register (0x400A, period & 0xFF);
                apu.write_register (0x400B, (period >> 8) & 0x7);
            }

            // Noise
            apu.write_register (0x400C, 0x30 | int (nLevel * v / 127.0 * 0xF));

            if (curNote != -1)
            {
                apu.write_register (0x400E, (nShort ? 0x80 : 0x00) | (curNote % 16));
                apu.write_register (0x400F, 0xFF);
            }

            lastNote = curNote;
        }
    }

    runUntil (done, buffer, buffer.getNumSamples());

    float* data = buffer.getWritePointer (0);
    for (int i = 0; i < buffer.getNumSamples(); i++)
        data[i] *= outputSmoothed.getNextValue();

     if (editor)
         editor->scope.addSamples (data, buffer.getNumSamples());
}

//==============================================================================
bool RP2A03AudioProcessor::hasEditor() const
{
    return true;
}

AudioProcessorEditor* RP2A03AudioProcessor::createEditor()
{
    editor = new RP2A03AudioProcessorEditor (*this);
    return editor;
}

//==============================================================================
// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
    return new RP2A03AudioProcessor();
}
<commit_msg>Fixed note handling<commit_after>/*
  ==============================================================================

    This file was auto-generated by the Introjucer!

    It contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

const char* RP2A03AudioProcessor::paramPulse1Level      = "pulse1Level";
const char* RP2A03AudioProcessor::paramPulse1DutyCycle  = "pulse1Duty";
const char* RP2A03AudioProcessor::paramPulse2Level      = "pulse2Level";
const char* RP2A03AudioProcessor::paramPulse2DutyCycle  = "pulse2Duty";
const char* RP2A03AudioProcessor::paramTriangleLevel    = "triangleLevel";
const char* RP2A03AudioProcessor::paramNoiseLevel       = "noiseLevel";
const char* RP2A03AudioProcessor::paramNoiseShort       = "noisePeriod";
const char* RP2A03AudioProcessor::paramOutput           = "output";
const char* RP2A03AudioProcessor::paramPulse1Tune       = "pulse1Tune";
const char* RP2A03AudioProcessor::paramPulse1TuneFine   = "pulse1TuneFine";
const char* RP2A03AudioProcessor::paramPulse2Tune       = "pulse2Tune";
const char* RP2A03AudioProcessor::paramPulse2TuneFine   = "pulse2TuneFine";
const char* RP2A03AudioProcessor::paramTriangleTune     = "triangleTune";
const char* RP2A03AudioProcessor::paramTriangleTuneFine = "triangleTuneFine";

//==============================================================================
String percentTextFunction (const slParameter& p, float v)
{
    return String::formatted("%.0f%%", v / p.getUserRangeEnd() * 100);
}

String onOffTextFunction (const slParameter& p, float v)
{
    return v > 0.0f ? "On" : "Off";
}

String dutyTextFunction (const slParameter& p, float v)
{
    const int duty = int (v);
    switch (duty)
    {
        case 0: return "12.5%";
        case 1: return "25%";
        case 2: return "50%";
        case 3: return "75%";
    }
    return "";
}

//==============================================================================
RP2A03AudioProcessor::RP2A03AudioProcessor()
{
    addPluginParameter (new slParameter (paramPulse1Level,     "Pulse 1 Level",      "Pulse",       "", 0.0f, 1.0f,  0.0f, 1.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramPulse1DutyCycle, "Pulse 1 Duty Cycle", "Duty Cycle",  "", 0.0f, 3.0f,  1.0f, 0.0f, 1.0f, dutyTextFunction));
    addPluginParameter (new slParameter (paramPulse2Level,     "Pulse 2 Level",      "Pulse",       "", 0.0f, 1.0f,  0.0f, 0.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramPulse2DutyCycle, "Pulse 2 Duty Cycle", "Duty Cycle",  "", 0.0f, 3.0f,  1.0f, 0.0f, 1.0f, dutyTextFunction));
    addPluginParameter (new slParameter (paramNoiseLevel,      "Noise Level",        "Noise",       "", 0.0f, 1.0f,  0.0f, 0.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramNoiseShort,      "Noise Short",        "Short",       "", 0.0f, 1.0f,  1.0f, 0.0f, 1.0f, onOffTextFunction));
    addPluginParameter (new slParameter (paramTriangleLevel,   "Triangle Level",     "Triangle",    "", 0.0f, 1.0f,  1.0f, 0.0f, 1.0f, onOffTextFunction));
    addPluginParameter (new slParameter (paramOutput,          "Output",             "Output",      "", 0.0f, 1.0f,  0.0f, 1.0f, 1.0f, percentTextFunction));
    addPluginParameter (new slParameter (paramPulse1Tune,      "Pulse 1 Tune",       "Tune",        "", -48.0f, 48.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramPulse1TuneFine,  "Pulse 1 Tune Fine",  "Fine",        "", -100.0f, 100.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramPulse2Tune,      "Pulse 2 Tune",       "Tune",        "", -48.0f, 48.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramPulse2TuneFine,  "Pulse 2 Tune Fine",  "Fine",        "", -100.0f, 100.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramTriangleTune,    "Triangle Tune",      "Tune",        "", -48.0f, 48.0f, 1.0f, 0.0f, 1.0f));
    addPluginParameter (new slParameter (paramTriangleTuneFine,"Triangle Tune Fine", "Fine",        "", -100.0f, 100.0f, 1.0f, 0.0f, 1.0f));
}

RP2A03AudioProcessor::~RP2A03AudioProcessor()
{
}

//==============================================================================
void RP2A03AudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    apu.sample_rate (long (sampleRate));
    apu.write_register (0x4015, 0x0F);

    outputSmoothed.reset (sampleRate, 0.05);
}

void RP2A03AudioProcessor::releaseResources()
{
}

void RP2A03AudioProcessor::runUntil (int& done, AudioSampleBuffer& buffer, int pos)
{
    int todo = jmin (pos, buffer.getNumSamples()) - done;

    while (todo > 0)
    {
        if (apu.samples_avail() == 0)
            apu.step();

        Simple_Apu::sample_t out[1024];
        int count = apu.read_samples(out, jmin (todo, int (apu.samples_avail()), 1024));

        float* data = buffer.getWritePointer (0, done);
        for (int i = 0; i < count; i++)
            data[i] = out[i] / 32768.0f;

        done += count;
        todo -= count;
    }

}

void RP2A03AudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midi)
{
    const float p1Level = parameterValue (paramPulse1Level);
    const int p1Duty    = parameterIntValue (paramPulse1DutyCycle);
    const int p1Tune    = parameterIntValue (paramPulse1Tune);
    const int p1Fine    = parameterIntValue (paramPulse1TuneFine);
    const float p2Level = parameterValue (paramPulse2Level);
    const int p2Duty    = parameterIntValue (paramPulse2DutyCycle);
    const int p2Tune    = parameterIntValue (paramPulse2Tune);
    const int p2Fine    = parameterIntValue (paramPulse2TuneFine);
    const float tLevel  = parameterValue (paramTriangleLevel);
    const int tTune     = parameterIntValue (paramTriangleTune);
    const int tFine     = parameterIntValue (paramTriangleTuneFine);
    const float nLevel  = parameterValue (paramNoiseLevel);
    const bool nShort   = parameterValue (paramNoiseShort) > 0.0f;

    outputSmoothed.setValue (getParameter (paramOutput)->getUserValue());

    int done = 0;
    runUntil (done, buffer, 0);

    int pos = 0;
    MidiMessage msg;
    MidiBuffer::Iterator itr (midi);
    while (itr.getNextEvent (msg, pos))
    {
        runUntil (done, buffer, pos);

        if (msg.isNoteOn())
        {
            noteQueue.add (msg.getNoteNumber());
            velocity = msg.getVelocity();
        }
        else if (msg.isNoteOff())
        {
            noteQueue.removeFirstMatchingValue (msg.getNoteNumber());
        }
        else if (msg.isAllNotesOff())
        {
            noteQueue.clear();
        }

        const int curNote = noteQueue.size() > 0 ? noteQueue.getLast() : -1;

        if (curNote != lastNote)
        {
            int v = curNote == -1 ? 0 : velocity;

            // Pulse 1
            apu.write_register (0x4000, (p1Duty << 6) | 0x30 | int (p1Level * v / 127.0 * 0xF));

            if (curNote != -1)
            {
                int period = int (111860.8 / getMidiNoteInHertz (curNote + p1Tune + p1Fine / 100.0) - 1);

                apu.write_register (0x4002, period & 0xFF);
                apu.write_register (0x4003, (period >> 8) & 0x7);
            }

            // Pulse 2
            apu.write_register (0x4004, (p2Duty << 6) | 0x30 | int (p2Level * v / 127.0 * 0xF));

            if (curNote != -1)
            {
                int period = int (111860.8 / getMidiNoteInHertz (curNote + p2Tune + p2Fine / 100.0) - 1);

                apu.write_register (0x4006, period & 0xFF);
                apu.write_register (0x4007, (period >> 8) & 0x7);
            }

            // Triangle
            apu.write_register (0x4008, curNote == -1 ? 0x00 : 0xFF);
            if (curNote != -1)
            {
                int period = int (tLevel == 1.0f ? 111860.8 / getMidiNoteInHertz (curNote + tTune + tFine / 100.0) * 2 - 1 : 0);

                apu.write_register (0x400A, period & 0xFF);
                apu.write_register (0x400B, (period >> 8) & 0x7);
            }

            // Noise
            apu.write_register (0x400C, 0x30 | int (nLevel * v / 127.0 * 0xF));

            if (curNote != -1)
            {
                apu.write_register (0x400E, (nShort ? 0x80 : 0x00) | (curNote % 16));
                apu.write_register (0x400F, 0xFF);
            }

            lastNote = curNote;
        }
    }

    runUntil (done, buffer, buffer.getNumSamples());

    float* data = buffer.getWritePointer (0);
    for (int i = 0; i < buffer.getNumSamples(); i++)
        data[i] *= outputSmoothed.getNextValue();

     if (editor)
         editor->scope.addSamples (data, buffer.getNumSamples());
}

//==============================================================================
bool RP2A03AudioProcessor::hasEditor() const
{
    return true;
}

AudioProcessorEditor* RP2A03AudioProcessor::createEditor()
{
    editor = new RP2A03AudioProcessorEditor (*this);
    return editor;
}

//==============================================================================
// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
    return new RP2A03AudioProcessor();
}
<|endoftext|>