<commit_before>/**
 * @file main.cpp
 *
 * @brief File containing main Q-Learning algorithm and all necessary associated functions to implementing this routine.
 *
 * @author Machine Learning Team 2015-2016
 * @date March, 2016
 */

#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <fstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
* @brief Gives a std::string representation of a primitive type.
*
* @remark Can be used to print priority queue contents.
* @param x Primitive type such as int, double, long ...
* @return std::string conversion of param x
*/
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution, computes 'evolution variable' of system.
 *
 * This function computes a normal distribution over the parameterised number of loop iterations in order
 * to provide a function which explores the state space dilligently initially which then decays off to the
 * optimal solution after a large number of loop iterations.
 *
 * The normal distribution used by this function is:
 *
 * \f[ a e^{-\frac{bt^2}{c}} + \epsilon \f]
 *
 * where a, b and c are scaling coefficients (see method body) and \f$\epsilon\f$ is some small offset.
 *
 * @param t Number of loop iterations.
 * @return Value of normal distribution at t loop iterations.
 */
double probabilityFluxDensityCoeffieicent(unsigned long t);

//function to select next action

/**
 * @brief Selects an action to perform based on experience, iterations and probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @param iterations Number of loop iterations completed.
 * @return integer corresponding to chosen action
 */
int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations);

/**
 * @brief Updates the utility (Q-value) of the system.
 *
 * Utility (Q-Value) of the system is updated via the Temporal Difference Learning Rule given by the following equation,
 *
 * \f[ Q_{i+1} (s,a) = Q_i (s,a) + \alpha [R(s') + \gamma \underset{a}{max} Q(s',a) - Q_i (s,a)] \f]
 *
 * where Q represents the utility of a state-action pair, \f$ \alpha \f$ is the learning rate, \f$ \gamma \f$ is the discount
 * factor and \f$ max_a (Q) \f$ yields the action-maximum of the Q space. The learning rate should be set to a low value for
 * highly stochastic, asymmetric systems or a high value for a lowly stochastic, symmetric system - this value lies between 0 and 1.
 * The discount factor (also in the interval [0,1]) represents the time considerations of the learning algorithm, lower values indicate
 * "living in the moment", whilst higher values indicate "planning for the future".
 *
 * @param space Reference to StateSpace object
 * @param action Integer code to previous performed action
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm (in the interval [0,1])
 * @param gamma Discount factor applied to q-learning equation (in the interval [0,1])
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

/**
 * @brief Program launcher!
 *
 * Contains all initialisations including setting up the StateSpace and connecting to robot via a proxy. Holds main
 * program loop to perform algorithm continuously using calls to selectAction and updateQ sequentially to update
 * utilities and choose most optimal actions to perform based on position and velocity.
 *
 * @return Program exit code
 */
int main() {
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try {
		broker = AL::ALBroker::createBroker(
			brokerName,
			brokerIp,
			brokerPort,
			pip,
			pport,
			0);
	}
	// Throw error and quit if a broker could not be created
	catch (...) {
		std::cerr << "Failed to connect broker to: "
			<< pip
			<< ":"
			<< pport
			<< std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha = 0.8;
	//discount factor
	const double gamma = 0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int, double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards, 0);
	initiator_queue.enqueueWithPriority(action_backwards, 0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//pause briefly to allow the robot to be given a push if desired
	qi::os::msleep(5000);

	//create the state space
	StateSpace space(100, 50, M_PI * 0.25, 1.0, initiator_queue);

	//state objects
	State current_state(0, 0, FORWARD);
	State old_state(0, 0, FORWARD);

	for( unsigned long i = 0; i<500 ;++i ) {
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta = M_PI * (encoder.GetAngle()) / 180;
		current_state.theta_dot = (current_state.theta - old_state.theta) / 700; //Needs actual time
		current_state.robot_state = static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		// set old_state to current_state
		old_state = current_state;

		// determine chosen_action for current state
		chosen_action = selectAction(space[current_state], i);

		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action) ? movementToolsProxy.callVoid("swingForwards") : movementToolsProxy.callVoid("swingBackwards");
	}

	std::ofstream outout("output.txt");
	output<<space;
	output.close();

	return 1;
}

double probabilityFluxDensityCoeffieicent(unsigned long t) {
	return 100.0*std::exp((-8.0*t*t) / (2600.0*2600.0)) + 0.1;//0.1 is an offset
}

int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations) {

	typedef std::vector<std::pair<int, double> > VecPair ;

	//turn priority queue into a vector of pairs
	VecPair vec = a_queue.saveOrderedQueueAsVector();

    //sum for partition function
	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / probabilityFluxDensityCoeffieicent(iterations));
	}

	// compute Boltzmann factors for action-values and enqueue to vec
	for (VecPair::iterator iter = vec.begin(); iter < vec.end(); ++iter) {
		iter->second = std::exp(iter->second / probabilityFluxDensityCoeffieicent(iterations)) / sum;
	}

	// calculate cumulative probability distribution
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
        //second member of pair becomes addition of its current value
        //and that of the index before it
        	if (iter != vec.begin())
			iter->second += (iter-1)->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}

void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma) {
	//oldQ value reference
	double oldQ = space[old_state].search(action).second;

	//reward given to current state
	double R = new_state.getReward();

	//optimal Q value for new state i.e. first element
	double maxQ = space[new_state].peekFront().second;

	//new Q value determined by Q learning algorithm
	double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

	// change priority of action to new Q value
	space[old_state].changePriority(action, newQ);
}
/* OLD SELECT ACTION
int selectAction(const PriorityQueue<int, double>& a_queue, unsigned long iterations) {
	/*
	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);
	double sum = 0.0;
	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}
	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature(iterations)) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}
	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}
	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;
	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached

	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	return (rand_num > 0.5)?0:1;
}
*/
<commit_msg>Update Main.cpp<commit_after>/**
 * @file main.cpp
 *
 * @brief File containing main Q-Learning algorithm and all necessary associated functions to implementing this routine.
 *
 * @author Machine Learning Team 2015-2016
 * @date March, 2016
 */

#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <fstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
* @brief Gives a std::string representation of a primitive type.
*
* @remark Can be used to print priority queue contents.
* @param x Primitive type such as int, double, long ...
* @return std::string conversion of param x
*/
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution, computes 'evolution variable' of system.
 *
 * This function computes a normal distribution over the parameterised number of loop iterations in order
 * to provide a function which explores the state space dilligently initially which then decays off to the
 * optimal solution after a large number of loop iterations.
 *
 * The normal distribution used by this function is:
 *
 * \f[ a e^{-\frac{bt^2}{c}} + \epsilon \f]
 *
 * where a, b and c are scaling coefficients (see method body) and \f$\epsilon\f$ is some small offset.
 *
 * @param t Number of loop iterations.
 * @return Value of normal distribution at t loop iterations.
 */
double probabilityFluxDensityCoeffieicent(unsigned long t);

//function to select next action

/**
 * @brief Selects an action to perform based on experience, iterations and probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @param iterations Number of loop iterations completed.
 * @return integer corresponding to chosen action
 */
int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations);

/**
 * @brief Updates the utility (Q-value) of the system.
 *
 * Utility (Q-Value) of the system is updated via the Temporal Difference Learning Rule given by the following equation,
 *
 * \f[ Q_{i+1} (s,a) = Q_i (s,a) + \alpha [R(s') + \gamma \underset{a}{max} Q(s',a) - Q_i (s,a)] \f]
 *
 * where Q represents the utility of a state-action pair, \f$ \alpha \f$ is the learning rate, \f$ \gamma \f$ is the discount
 * factor and \f$ max_a (Q) \f$ yields the action-maximum of the Q space. The learning rate should be set to a low value for
 * highly stochastic, asymmetric systems or a high value for a lowly stochastic, symmetric system - this value lies between 0 and 1.
 * The discount factor (also in the interval [0,1]) represents the time considerations of the learning algorithm, lower values indicate
 * "living in the moment", whilst higher values indicate "planning for the future".
 *
 * @param space Reference to StateSpace object
 * @param action Integer code to previous performed action
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm (in the interval [0,1])
 * @param gamma Discount factor applied to q-learning equation (in the interval [0,1])
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

/**
 * @brief Program launcher!
 *
 * Contains all initialisations including setting up the StateSpace and connecting to robot via a proxy. Holds main
 * program loop to perform algorithm continuously using calls to selectAction and updateQ sequentially to update
 * utilities and choose most optimal actions to perform based on position and velocity.
 *
 * @return Program exit code
 */
int main() {
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try {
		broker = AL::ALBroker::createBroker(
			brokerName,
			brokerIp,
			brokerPort,
			pip,
			pport,
			0);
	}
	// Throw error and quit if a broker could not be created
	catch (...) {
		std::cerr << "Failed to connect broker to: "
			<< pip
			<< ":"
			<< pport
			<< std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha = 0.8;
	//discount factor
	const double gamma = 0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int, double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards, 0);
	initiator_queue.enqueueWithPriority(action_backwards, 0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//pause briefly to allow the robot to be given a push if desired
	qi::os::msleep(5000);

	//create the state space
	StateSpace space(100, 50, M_PI * 0.25, 1.0, initiator_queue);

	//state objects
	State current_state(0, 0, FORWARD);
	State old_state(0, 0, FORWARD);

	std::cout << "Initialisation complete!" << std::endl;
	for( unsigned long i = 0; i<500 ;++i ) {
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta = M_PI * (encoder.GetAngle()) / 180;
		current_state.theta_dot = (current_state.theta - old_state.theta) / 700; //Needs actual time
		current_state.robot_state = static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);
		std::cout << "Update Q completed!" << std::endl;
		// set old_state to current_state
		old_state = current_state;

		// determine chosen_action for current state
		chosen_action = selectAction(space[current_state], i);
		std::cout << "Select Action completed!" << std::endl;
		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action) ? movementToolsProxy.callVoid("swingForwards") : movementToolsProxy.callVoid("swingBackwards");
	}

//	std::ofstream output("output.txt");
//	output<<space;
//	output.close();

	return 1;
}

double probabilityFluxDensityCoeffieicent(unsigned long t) {
	return 100.0*std::exp((-8.0*t*t) / (2600.0*2600.0)) + 0.1;//0.1 is an offset
}

int selectAction(PriorityQueue<int, double>& a_queue, unsigned long iterations) {

	typedef std::vector<std::pair<int, double> > VecPair ;

	//turn priority queue into a vector of pairs
	VecPair vec = a_queue.saveOrderedQueueAsVector();

    //sum for partition function
	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / probabilityFluxDensityCoeffieicent(iterations));
	}

	// compute Boltzmann factors for action-values and enqueue to vec
	for (VecPair::iterator iter = vec.begin(); iter < vec.end(); ++iter) {
		iter->second = std::exp(iter->second / probabilityFluxDensityCoeffieicent(iterations)) / sum;
	}

	// calculate cumulative probability distribution
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
        //second member of pair becomes addition of its current value
        //and that of the index before it
        	if (iter != vec.begin())
			iter->second += (iter-1)->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}

void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma) {
	//oldQ value reference
	double oldQ = space[old_state].search(action).second;

	//reward given to current state
	double R = new_state.getReward();

	//optimal Q value for new state i.e. first element
	double maxQ = space[new_state].peekFront().second;

	//new Q value determined by Q learning algorithm
	double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

	// change priority of action to new Q value
	space[old_state].changePriority(action, newQ);
}
/* OLD SELECT ACTION
int selectAction(const PriorityQueue<int, double>& a_queue, unsigned long iterations) {
	/*
	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);
	double sum = 0.0;
	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature(iterations));
	}
	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature(iterations)) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}
	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}
	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;
	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached

	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	return (rand_num > 0.5)?0:1;
}
*/
<|endoftext|>


<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    mainwindow.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

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

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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "mainwindow.h"

#include "searchbar.h"
#include "tabwidget.h"

#include "certificatewizardimpl.h"
#include "searchbarstatehandler.h"
#include "models/keylistmodel.h"
#include "models/keylistsortfilterproxymodel.h"
#include "controllers/keylistcontroller.h"
#include "commands/exportcertificatecommand.h"
#include "commands/importcertificatecommand.h"
#include "commands/refreshkeyscommand.h"
#include "commands/detailscommand.h"

#include <KActionCollection>
#include <KLocale>
#include <KTabWidget>
#include <KStatusBar>
#include <KStandardAction>
#include <KAction>
#include <KAboutData>
#include <KMessageBox>
#include <KStandardGuiItem>

#include <QAbstractItemView>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QFileDialog>
#include <QToolBar>
#include <QWidgetAction>
#include <QProgressBar>
#include <QApplication>
#include <QCloseEvent>
#include <QTimer>

#include <gpgme++/key.h>

#include <boost/shared_ptr.hpp>

#include <vector>

using namespace Kleo;
using namespace boost;
using namespace GpgME;

namespace {
    class ProgressBar : public QProgressBar {
        Q_OBJECT
    public:
        explicit ProgressBar( QWidget * p=0 ) : QProgressBar( p ) {}

    public Q_SLOTS:
        void setProgress( int current, int total ) {
            setRange( 0, total );
            setValue( current );
        }
    };
}

KGuiItem KStandardGuiItem_quit() {
    static const QString app = KGlobal::mainComponent().aboutData()->programName();
    KGuiItem item = KStandardGuiItem::quit();
    item.setText( i18n( "&Quit %1", app ) );
    return item;
}

KGuiItem KStandardGuiItem_close() {
    KGuiItem item = KStandardGuiItem::close();
    item.setText( i18n("Only &Close the Window" ) );
    return item;
}

class MainWindow::Private {
    friend class ::MainWindow;
    MainWindow * const q;

public:
    explicit Private( MainWindow * qq );
    ~Private();

    void closeAndQuit() {
        const QString app = KGlobal::mainComponent().aboutData()->programName();
        const int rc = KMessageBox::questionYesNoCancel( q,
                                                         i18n("%1 may be used by other applications as a service.\n"
                                                              "You may instead want to close this window without exiting %1.", app ),
                                                         i18n("Really quit?"), KStandardGuiItem_quit(), KStandardGuiItem_close(), KStandardGuiItem::cancel(),
                                                         "really-quit-" + app.toLower() );
        if ( rc == KMessageBox::Cancel )
            return;
        q->close();
        // WARNING: 'this' might be deleted at this point!
        if ( rc == KMessageBox::Yes )
            qApp->quit();
    }
    void certificateDetails() {
        ( new DetailsCommand( currentView(), &controller ) )->start();
    }
    void refreshCertificates() {
        ( new RefreshKeysCommand( RefreshKeysCommand::Normal, currentView(), &controller ) )->start();
    }
    void validateCertificates() {
        ( new RefreshKeysCommand( RefreshKeysCommand::Validate, currentView(), &controller ) )->start();
    }
    void exportCertificates() {
        ( new ExportCertificateCommand( currentView(), &controller ) )->start();
    }
    void importCertificates() {
        ( new ImportCertificateCommand( currentView(), &controller ) )->start();
    }
    void newCertificate();

private:
    void setupActions();
    void setupViews();
    void saveViews();

    void addView( const QString & title, const QString & keyFilterID=QString(), const QString & searchString=QString() );
    void addView( const KConfigGroup & group );

    unsigned int numViews() const {
        return ui.tabWidget.count();
    }

    QAbstractItemView * currentView() const {
        return ui.tabWidget.currentView();
    }

private:

    Kleo::AbstractKeyListModel * model;
    Kleo::KeyListController controller;

    QTimer refreshTimer;

    struct Actions {
        //QAction file_new_certificate;
        //QAction file_export_certificate;
        //QAction file_export_secret_keys;
        //QAction file_import_certificates;
        //QAction file_import_crls;
        QAction * file_close;
        QAction * file_quit;

        //QAction view_stop_operations;
        //QAction view_certificate_details;
        //QAction view_hierarchical;
        //QAction view_expandall;
        //QAction view_collapseall;

        explicit Actions( MainWindow * q )
            : file_close( KStandardAction::close( q, SLOT(close()), q->actionCollection() ) ),
              file_quit( KStandardAction::quit( q, SLOT(closeAndQuit()), q->actionCollection() ) )
        {

        }

    } actions;

    struct UI {

        TabWidget tabWidget;
	ProgressBar progressBar;

	explicit UI( MainWindow * q )
	    : tabWidget( q ),
	      progressBar( q->statusBar() )
	{
	    KDAB_SET_OBJECT_NAME( tabWidget );
	    KDAB_SET_OBJECT_NAME( progressBar );

            progressBar.setFixedSize( progressBar.sizeHint() );

            q->setCentralWidget( &tabWidget );
            q->statusBar()->addPermanentWidget( &progressBar );
	}
    } ui;
};

MainWindow::Private::Private( MainWindow * qq )
    : q( qq ),
      model( AbstractKeyListModel::createFlatKeyListModel( q ) ),
      controller( q ),
      refreshTimer(),
      actions( q ),
      ui( q )
{
    KDAB_SET_OBJECT_NAME( controller );
    KDAB_SET_OBJECT_NAME( refreshTimer );

    refreshTimer.setInterval( 5 * 60 * 1000 );
    refreshTimer.setSingleShot( false );
    refreshTimer.start();
    connect( &refreshTimer, SIGNAL(timeout()), q, SLOT(validateCertificates()) );

    controller.setModel( model );
    setupActions();

    connect( &controller, SIGNAL(progress(int,int)), &ui.progressBar, SLOT(setProgress(int,int)) );
    connect( &controller, SIGNAL(message(QString,int)),  q->statusBar(), SLOT(showMessage(QString,int)) );

    q->createGUI( "kleopatra_newui.rc" );

    q->resize( 640, 480 );

    setupViews();
}

MainWindow::Private::~Private() {}

MainWindow::MainWindow( QWidget* parent, Qt::WindowFlags flags )
    : KXmlGuiWindow( parent, flags ), d( new Private( this ) )
{

}

MainWindow::~MainWindow() {}

void MainWindow::Private::addView( const QString & title, const QString & id, const QString & text ) {
    QAbstractItemView * const view = ui.tabWidget.addView( model, title, id, text );
    assert( view );
    controller.addView( view );
}

void MainWindow::Private::addView( const KConfigGroup & group ) {
    if ( QAbstractItemView * const view = ui.tabWidget.addView( model, group ) )
        controller.addView( view );
}

void MainWindow::Private::setupActions() {

    KActionCollection * const coll = q->actionCollection();

    QWidgetAction * const searchBarAction = new QWidgetAction( q );
    SearchBar * const searchBar = new SearchBar( q );
    new SearchBarStateHandler( &ui.tabWidget, searchBar, searchBar );
    connect( searchBar, SIGNAL(textChanged(QString)),
             &ui.tabWidget, SLOT(setStringFilter(QString)) );
    connect( searchBar, SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
             &ui.tabWidget, SLOT(setKeyFilter(boost::shared_ptr<Kleo::KeyFilter>)) );
    searchBarAction->setDefaultWidget( searchBar );
    coll->addAction( "key_search_bar", searchBarAction );

    QAction* action;

    // File menu

    action = coll->addAction( "file_new_certificate" );
    action->setText( i18n( "New Certificate..." ) );
    action->setIcon( KIcon( "document-new" ) );
    connect( action, SIGNAL(triggered()), q, SLOT(newCertificate()) );
    action->setShortcuts( KShortcut( i18n("Ctrl+N") ) );

    action = coll->addAction( "file_export_certificates" );
    action->setText( i18n( "Export Certificates..." ) );
    action->setIcon( KIcon("export") );
    connect( action, SIGNAL(triggered()), q, SLOT(exportCertificates()) );
    action->setShortcuts( KShortcut( i18n("Ctrl+E") ) );

    action = coll->addAction( "file_import_certificates" );
    action->setText( i18n( "Import Certificates..." ) );
    connect( action, SIGNAL(triggered()), q, SLOT(importCertificates()) );
    action->setShortcuts( KShortcut( i18n("Ctrl+I") ) );

    // View menu

    action = coll->addAction( "view_redisplay" );
    action->setText( i18n( "Redisplay" ) );
    action->setIcon( KIcon( "view-refresh" ) );
    connect( action, SIGNAL(triggered()), q, SLOT(refreshCertificates()) );
    action->setShortcuts( KShortcut( i18n("F5") ) );

    action = coll->addAction( "view_stop_operations" );
    action->setText( i18n( "Stop Operation" ) );
    action->setIcon( KIcon( "process-stop" ) );
    connect( action, SIGNAL(triggered()), &controller, SLOT(cancelCommands()) );
    connect( &controller, SIGNAL(commandsExecuting(bool)), action, SLOT(setEnabled(bool)) );
    action->setShortcuts( KShortcut( i18n("Escape") ) );
    action->setEnabled( false );

    action = coll->addAction( "view_certificate_details" );
    action->setText( i18n( "Certificate Details..." ) );
    //action->setIcon( KIcon( "view-details" ) );
    connect( action, SIGNAL(triggered()), q, SLOT(certificateDetails()) );

    // Certificates menu

    action = coll->addAction( "certificates_validate" );
    action->setText( i18n("Validate" ) );
    action->setIcon( KIcon( "view-refresh" ) );
    //action->setToolTip( i18n("Validate selected certificates") );
    connect( action, SIGNAL(triggered()), q, SLOT(validateCertificates()) );
    action->setShortcuts( KShortcut( i18n("SHIFT+F5") ) );

    // CRLs menu

    // Tools menu

    // Settings menu

}

static QStringList extractViewGroups( const KSharedConfig::Ptr & config ) {
    return config->groupList().filter( QRegExp( "^View #\\d+$" ) );
}

void MainWindow::Private::setupViews() {

    if ( const KSharedConfig::Ptr config = KGlobal::config() ) {

        const QStringList groups = extractViewGroups( config );

        Q_FOREACH( const QString & groupName, groups ) {
            const KConfigGroup group( config, groupName );
            addView( group );
        }

    }

    if ( numViews() == 0 ) {

        // add defaults:

        addView( QString(), "my-certificates" );
        addView( QString(), "trusted-certificates" );
        addView( QString(), "other-certificates" );

    }

}

void MainWindow::Private::saveViews() {

    KSharedConfig::Ptr config = KGlobal::config();
    if ( !config )
        return;

    Q_FOREACH( QString group, extractViewGroups( config ) )
        config->deleteGroup( group );

    for ( unsigned int i = 0, end = numViews() ; i != end ; ++i ) {
        KConfigGroup group( config, QString().sprintf( "View #%u", i ) );
        ui.tabWidget.saveTab( i, group );
    }

}

void MainWindow::Private::newCertificate() {
    QPointer<CertificateWizardImpl> wiz( new CertificateWizardImpl( q ) );
    wiz->exec();
    delete wiz;
}

void MainWindow::closeEvent( QCloseEvent * e ) {
    // KMainWindow::closeEvent() insists on quitting the application,
    // so do not let it touch the event...
    qDebug( "MainWindow::closeEvent()" );
    d->saveViews();
    e->accept();
}

#include "mainwindow.moc"
#include "moc_mainwindow.cpp"
<commit_msg>use existing icon<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    mainwindow.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

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

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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "mainwindow.h"

#include "searchbar.h"
#include "tabwidget.h"

#include "certificatewizardimpl.h"
#include "searchbarstatehandler.h"
#include "models/keylistmodel.h"
#include "models/keylistsortfilterproxymodel.h"
#include "controllers/keylistcontroller.h"
#include "commands/exportcertificatecommand.h"
#include "commands/importcertificatecommand.h"
#include "commands/refreshkeyscommand.h"
#include "commands/detailscommand.h"

#include <KActionCollection>
#include <KLocale>
#include <KTabWidget>
#include <KStatusBar>
#include <KStandardAction>
#include <KAction>
#include <KAboutData>
#include <KMessageBox>
#include <KStandardGuiItem>

#include <QAbstractItemView>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QFileDialog>
#include <QToolBar>
#include <QWidgetAction>
#include <QProgressBar>
#include <QApplication>
#include <QCloseEvent>
#include <QTimer>

#include <gpgme++/key.h>

#include <boost/shared_ptr.hpp>

#include <vector>

using namespace Kleo;
using namespace boost;
using namespace GpgME;

namespace {
    class ProgressBar : public QProgressBar {
        Q_OBJECT
    public:
        explicit ProgressBar( QWidget * p=0 ) : QProgressBar( p ) {}

    public Q_SLOTS:
        void setProgress( int current, int total ) {
            setRange( 0, total );
            setValue( current );
        }
    };
}

KGuiItem KStandardGuiItem_quit() {
    static const QString app = KGlobal::mainComponent().aboutData()->programName();
    KGuiItem item = KStandardGuiItem::quit();
    item.setText( i18n( "&Quit %1", app ) );
    return item;
}

KGuiItem KStandardGuiItem_close() {
    KGuiItem item = KStandardGuiItem::close();
    item.setText( i18n("Only &Close the Window" ) );
    return item;
}

class MainWindow::Private {
    friend class ::MainWindow;
    MainWindow * const q;

public:
    explicit Private( MainWindow * qq );
    ~Private();

    void closeAndQuit() {
        const QString app = KGlobal::mainComponent().aboutData()->programName();
        const int rc = KMessageBox::questionYesNoCancel( q,
                                                         i18n("%1 may be used by other applications as a service.\n"
                                                              "You may instead want to close this window without exiting %1.", app ),
                                                         i18n("Really quit?"), KStandardGuiItem_quit(), KStandardGuiItem_close(), KStandardGuiItem::cancel(),
                                                         "really-quit-" + app.toLower() );
        if ( rc == KMessageBox::Cancel )
            return;
        q->close();
        // WARNING: 'this' might be deleted at this point!
        if ( rc == KMessageBox::Yes )
            qApp->quit();
    }
    void certificateDetails() {
        ( new DetailsCommand( currentView(), &controller ) )->start();
    }
    void refreshCertificates() {
        ( new RefreshKeysCommand( RefreshKeysCommand::Normal, currentView(), &controller ) )->start();
    }
    void validateCertificates() {
        ( new RefreshKeysCommand( RefreshKeysCommand::Validate, currentView(), &controller ) )->start();
    }
    void exportCertificates() {
        ( new ExportCertificateCommand( currentView(), &controller ) )->start();
    }
    void importCertificates() {
        ( new ImportCertificateCommand( currentView(), &controller ) )->start();
    }
    void newCertificate();

private:
    void setupActions();
    void setupViews();
    void saveViews();

    void addView( const QString & title, const QString & keyFilterID=QString(), const QString & searchString=QString() );
    void addView( const KConfigGroup & group );

    unsigned int numViews() const {
        return ui.tabWidget.count();
    }

    QAbstractItemView * currentView() const {
        return ui.tabWidget.currentView();
    }

private:

    Kleo::AbstractKeyListModel * model;
    Kleo::KeyListController controller;

    QTimer refreshTimer;

    struct Actions {
        //QAction file_new_certificate;
        //QAction file_export_certificate;
        //QAction file_export_secret_keys;
        //QAction file_import_certificates;
        //QAction file_import_crls;
        QAction * file_close;
        QAction * file_quit;

        //QAction view_stop_operations;
        //QAction view_certificate_details;
        //QAction view_hierarchical;
        //QAction view_expandall;
        //QAction view_collapseall;

        explicit Actions( MainWindow * q )
            : file_close( KStandardAction::close( q, SLOT(close()), q->actionCollection() ) ),
              file_quit( KStandardAction::quit( q, SLOT(closeAndQuit()), q->actionCollection() ) )
        {

        }

    } actions;

    struct UI {

        TabWidget tabWidget;
	ProgressBar progressBar;

	explicit UI( MainWindow * q )
	    : tabWidget( q ),
	      progressBar( q->statusBar() )
	{
	    KDAB_SET_OBJECT_NAME( tabWidget );
	    KDAB_SET_OBJECT_NAME( progressBar );

            progressBar.setFixedSize( progressBar.sizeHint() );

            q->setCentralWidget( &tabWidget );
            q->statusBar()->addPermanentWidget( &progressBar );
	}
    } ui;
};

MainWindow::Private::Private( MainWindow * qq )
    : q( qq ),
      model( AbstractKeyListModel::createFlatKeyListModel( q ) ),
      controller( q ),
      refreshTimer(),
      actions( q ),
      ui( q )
{
    KDAB_SET_OBJECT_NAME( controller );
    KDAB_SET_OBJECT_NAME( refreshTimer );

    refreshTimer.setInterval( 5 * 60 * 1000 );
    refreshTimer.setSingleShot( false );
    refreshTimer.start();
    connect( &refreshTimer, SIGNAL(timeout()), q, SLOT(validateCertificates()) );

    controller.setModel( model );
    setupActions();

    connect( &controller, SIGNAL(progress(int,int)), &ui.progressBar, SLOT(setProgress(int,int)) );
    connect( &controller, SIGNAL(message(QString,int)),  q->statusBar(), SLOT(showMessage(QString,int)) );

    q->createGUI( "kleopatra_newui.rc" );

    q->resize( 640, 480 );

    setupViews();
}

MainWindow::Private::~Private() {}

MainWindow::MainWindow( QWidget* parent, Qt::WindowFlags flags )
    : KXmlGuiWindow( parent, flags ), d( new Private( this ) )
{

}

MainWindow::~MainWindow() {}

void MainWindow::Private::addView( const QString & title, const QString & id, const QString & text ) {
    QAbstractItemView * const view = ui.tabWidget.addView( model, title, id, text );
    assert( view );
    controller.addView( view );
}

void MainWindow::Private::addView( const KConfigGroup & group ) {
    if ( QAbstractItemView * const view = ui.tabWidget.addView( model, group ) )
        controller.addView( view );
}

void MainWindow::Private::setupActions() {

    KActionCollection * const coll = q->actionCollection();

    QWidgetAction * const searchBarAction = new QWidgetAction( q );
    SearchBar * const searchBar = new SearchBar( q );
    new SearchBarStateHandler( &ui.tabWidget, searchBar, searchBar );
    connect( searchBar, SIGNAL(textChanged(QString)),
             &ui.tabWidget, SLOT(setStringFilter(QString)) );
    connect( searchBar, SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
             &ui.tabWidget, SLOT(setKeyFilter(boost::shared_ptr<Kleo::KeyFilter>)) );
    searchBarAction->setDefaultWidget( searchBar );
    coll->addAction( "key_search_bar", searchBarAction );

    QAction* action;

    // File menu

    action = coll->addAction( "file_new_certificate" );
    action->setText( i18n( "New Certificate..." ) );
    action->setIcon( KIcon( "document-new" ) );
    connect( action, SIGNAL(triggered()), q, SLOT(newCertificate()) );
    action->setShortcuts( KShortcut( i18n("Ctrl+N") ) );

    action = coll->addAction( "file_export_certificates" );
    action->setText( i18n( "Export Certificates..." ) );
    action->setIcon( KIcon("document-export") );
    connect( action, SIGNAL(triggered()), q, SLOT(exportCertificates()) );
    action->setShortcuts( KShortcut( i18n("Ctrl+E") ) );

    action = coll->addAction( "file_import_certificates" );
    action->setText( i18n( "Import Certificates..." ) );
    connect( action, SIGNAL(triggered()), q, SLOT(importCertificates()) );
    action->setShortcuts( KShortcut( i18n("Ctrl+I") ) );

    // View menu

    action = coll->addAction( "view_redisplay" );
    action->setText( i18n( "Redisplay" ) );
    action->setIcon( KIcon( "view-refresh" ) );
    connect( action, SIGNAL(triggered()), q, SLOT(refreshCertificates()) );
    action->setShortcuts( KShortcut( i18n("F5") ) );

    action = coll->addAction( "view_stop_operations" );
    action->setText( i18n( "Stop Operation" ) );
    action->setIcon( KIcon( "process-stop" ) );
    connect( action, SIGNAL(triggered()), &controller, SLOT(cancelCommands()) );
    connect( &controller, SIGNAL(commandsExecuting(bool)), action, SLOT(setEnabled(bool)) );
    action->setShortcuts( KShortcut( i18n("Escape") ) );
    action->setEnabled( false );

    action = coll->addAction( "view_certificate_details" );
    action->setText( i18n( "Certificate Details..." ) );
    //action->setIcon( KIcon( "view-details" ) );
    connect( action, SIGNAL(triggered()), q, SLOT(certificateDetails()) );

    // Certificates menu

    action = coll->addAction( "certificates_validate" );
    action->setText( i18n("Validate" ) );
    action->setIcon( KIcon( "view-refresh" ) );
    //action->setToolTip( i18n("Validate selected certificates") );
    connect( action, SIGNAL(triggered()), q, SLOT(validateCertificates()) );
    action->setShortcuts( KShortcut( i18n("SHIFT+F5") ) );

    // CRLs menu

    // Tools menu

    // Settings menu

}

static QStringList extractViewGroups( const KSharedConfig::Ptr & config ) {
    return config->groupList().filter( QRegExp( "^View #\\d+$" ) );
}

void MainWindow::Private::setupViews() {

    if ( const KSharedConfig::Ptr config = KGlobal::config() ) {

        const QStringList groups = extractViewGroups( config );

        Q_FOREACH( const QString & groupName, groups ) {
            const KConfigGroup group( config, groupName );
            addView( group );
        }

    }

    if ( numViews() == 0 ) {

        // add defaults:

        addView( QString(), "my-certificates" );
        addView( QString(), "trusted-certificates" );
        addView( QString(), "other-certificates" );

    }

}

void MainWindow::Private::saveViews() {

    KSharedConfig::Ptr config = KGlobal::config();
    if ( !config )
        return;

    Q_FOREACH( QString group, extractViewGroups( config ) )
        config->deleteGroup( group );

    for ( unsigned int i = 0, end = numViews() ; i != end ; ++i ) {
        KConfigGroup group( config, QString().sprintf( "View #%u", i ) );
        ui.tabWidget.saveTab( i, group );
    }

}

void MainWindow::Private::newCertificate() {
    QPointer<CertificateWizardImpl> wiz( new CertificateWizardImpl( q ) );
    wiz->exec();
    delete wiz;
}

void MainWindow::closeEvent( QCloseEvent * e ) {
    // KMainWindow::closeEvent() insists on quitting the application,
    // so do not let it touch the event...
    qDebug( "MainWindow::closeEvent()" );
    d->saveViews();
    e->accept();
}

#include "mainwindow.moc"
#include "moc_mainwindow.cpp"
<|endoftext|>


<commit_before>// This file is part of the RiftWM project
// Licensing information can be found in the LICENSE file
// (C) 2013 The RiftWM Project. All rights reserved.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <OpenNI.h>
#include <NiTE.h>
#include "riftwm.h"
#include "kinect.h"
#include "renderer.h"

typedef struct kinect_t
{
  riftwm_t      *wm;
  nite::UserTracker* tracker;
  nite::UserId first_id;
  bool found;

  float x_shift,y_shift,z_shift;

} kinect_t;

kinect_t *
kinect_init(riftwm_t * wm)
{
  kinect_t *k;
  k = new kinect_t;
  k->wm = wm;

  if (openni::OpenNI::initialize() != openni::STATUS_OK)
  {
    riftwm_error(wm,"Couldnt initialize OpenNI");
  }
  if (nite::NiTE::initialize() != nite::STATUS_OK)
  {
    riftwm_error(wm,"Couldnt initialize NiTE");
  }

  k->tracker = new nite::UserTracker();
  if ( k->tracker->create() != nite::STATUS_OK)
  {
    riftwm_error(wm,"Couldnt initialize UserTracker");
  }

  k->found = false;
  return k;
}

void
kinect_update(kinect_t *k)
{
  nite::UserTrackerFrameRef frame;
  k->tracker->readFrame(&frame);
  const nite::Array<nite::UserData>& users = frame.getUsers();
  if (!users.isEmpty())
  {

    for (int i = 0; i < users.getSize(); ++i)
    {
      const nite::Skeleton & skeleton = users[i].getSkeleton();

      if (skeleton.getState() == nite::SKELETON_TRACKED)
      {
        if (!k->found) {
          k->found = true;
          k->first_id = users[i].getId();
        }
        if (users[i].getId() == k->first_id)
        {
          const nite::SkeletonJoint & head = skeleton.getJoint(nite::JOINT_HEAD);
          const nite::Point3f & head_point = head.getPosition();

          k->wm->renderer->pos[0] = -(head_point.x / 1000.0f - k->x_shift) * 10.0f;
          k->wm->renderer->pos[1] = 5.0f -(head_point.y / 1000.0f - k->y_shift) * 5.0f;
          k->wm->renderer->pos[2] = -(head_point.z / 1000.0f - k->z_shift) * 10.0f;
          fprintf(stderr, "%f %f %f\n", k->wm->renderer->pos[0],
                                        k->wm->renderer->pos[1],
                                        k->wm->renderer->pos[2]);
        }
      }

      if (skeleton.getState() == nite::SKELETON_NONE) {
        k->tracker->startSkeletonTracking(users[i].getId());
        fprintf(stderr, "User found! : none\n");
      }
    }
  }
}

void
kinect_destroy(kinect_t *k)
{
  delete k->tracker;
  delete k;
}
<commit_msg>hand updates<commit_after>// This file is part of the RiftWM project
// Licensing information can be found in the LICENSE file
// (C) 2013 The RiftWM Project. All rights reserved.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <OpenNI.h>
#include <NiTE.h>
#include "riftwm.h"
#include "kinect.h"
#include "renderer.h"

typedef struct kinect_t
{
  riftwm_t      *wm;
  nite::UserTracker* tracker;
  nite::UserId first_id;
  bool found;

  float x_shift,y_shift,z_shift;

} kinect_t;

kinect_t *
kinect_init(riftwm_t * wm)
{
  kinect_t *k;
  k = new kinect_t;
  k->wm = wm;

  if (openni::OpenNI::initialize() != openni::STATUS_OK)
  {
    riftwm_error(wm,"Couldnt initialize OpenNI");
  }
  if (nite::NiTE::initialize() != nite::STATUS_OK)
  {
    riftwm_error(wm,"Couldnt initialize NiTE");
  }

  k->tracker = new nite::UserTracker();
  if ( k->tracker->create() != nite::STATUS_OK)
  {
    riftwm_error(wm,"Couldnt initialize UserTracker");
  }

  k->found = false;
  return k;
}

void
kinect_update(kinect_t *k)
{
  nite::UserTrackerFrameRef frame;
  k->tracker->readFrame(&frame);
  const nite::Array<nite::UserData>& users = frame.getUsers();
  if (!users.isEmpty())
  {

    for (int i = 0; i < users.getSize(); ++i)
    {
      const nite::Skeleton & skeleton = users[i].getSkeleton();

      if (skeleton.getState() == nite::SKELETON_TRACKED)
      {
        if (!k->found) {
          k->found = true;
          k->first_id = users[i].getId();
        }
        if (users[i].getId() == k->first_id)
        {

          // updating the position of the head
          const nite::SkeletonJoint & head = skeleton.getJoint(nite::JOINT_HEAD);
          const nite::Point3f & head_point = head.getPosition();

          k->wm->renderer->pos[0] = -(head_point.x / 1000.0f ) * 10.0f;
          k->wm->renderer->pos[1] = 5.0f -(head_point.y / 1000.0f ) * 5.0f;
          k->wm->renderer->pos[2] = -(head_point.z / 1000.0f ) * 10.0f;
          fprintf(stderr, "%f %f %f\n", k->wm->renderer->pos[0],
                                        k->wm->renderer->pos[1],
                                        k->wm->renderer->pos[2]);
          // updating the posintion of hands

          const nite::SkeletonJoint & left_hand = skeleton.getJoint(nite::JOINT_LEFT_HAND);
          const nite::Point3f & left_hand_point = left_hand.getPosition();

          k->wm->renderer->leftHand[0] = -(left_hand_point.x / 1000.0f ) * 10.0f;
          k->wm->renderer->leftHand[1] = 5.0f -(left_hand_point.y / 1000.0f ) * 5.0f;
          k->wm->renderer->leftHand[2] = -(left_hand_point.z / 1000.0f ) * 10.0f;
          fprintf(stderr, "%f %f %f\n", k->wm->renderer->leftHand[0],
                                        k->wm->renderer->leftHand[1],
                                        k->wm->renderer->leftHand[2]);

          const nite::SkeletonJoint & right_hand = skeleton.getJoint(nite::JOINT_RIGHT_HAND);
          const nite::Point3f & right_hand_point = right_hand.getPosition();

          k->wm->renderer->rightHand[0] = -(right_hand_point.x / 1000.0f ) * 10.0f;
          k->wm->renderer->rightHand[1] = 5.0f -(right_hand_point.y / 1000.0f ) * 5.0f;
          k->wm->renderer->rightHand[2] = -(right_hand_point.z / 1000.0f ) * 10.0f;
          fprintf(stderr, "%f %f %f\n", k->wm->renderer->rightHand[0],
                                        k->wm->renderer->rightHand[1],
                                        k->wm->renderer->rightHand[2]);

        }
      }

      if (skeleton.getState() == nite::SKELETON_NONE) {
        k->tracker->startSkeletonTracking(users[i].getId());
        fprintf(stderr, "User found! : none\n");
      }
    }
  }
}

void
kinect_destroy(kinect_t *k)
{
  delete k->tracker;
  delete k;
}
<|endoftext|>


<commit_before>/*  -*- mode: C++; c-file-style: "gnu" -*-
    identitydialog.cpp

    This file is part of KMail, the KDE mail client.
    Copyright (c) 2002 Marc Mutz <mutz@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "identitydialog.h"

// other KMail headers:
#include "signatureconfigurator.h"
#include "kmfoldercombobox.h"
#include "kmfoldermgr.h"
#include "transportmanager.h"
#include "kmkernel.h"
#include "dictionarycombobox.h"

// other kdenetwork headers:
#include <kpgpui.h>

// other KDE headers:
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kconfig.h>

// Qt headers:
#include <qtabwidget.h>
#include <qlabel.h>
#include <qwhatsthis.h>

// other headers: (none)

namespace KMail {

  IdentityDialog::IdentityDialog( QWidget * parent, const char * name )
    : KDialogBase( Plain, i18n("Edit Identity"), Ok|Cancel|Help, Ok,
                   parent, name )
  {
    // tmp. vars:
    QWidget * tab;
    QLabel  * label;
    int row;
    QGridLayout * glay;
    QString msg;

    //
    // Tab Widget: General
    //
    row = -1;
    QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
    QTabWidget *tabWidget = new QTabWidget( plainPage(), "config-identity-tab" );
    vlay->addWidget( tabWidget );

    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&General") );
    glay = new QGridLayout( tab, 4, 2, marginHint(), spacingHint() );
    glay->setRowStretch( 3, 1 );
    glay->setColStretch( 1, 1 );

    // "Name" line edit and label:
    ++row;
    mNameEdit = new KLineEdit( tab );
    glay->addWidget( mNameEdit, row, 1 );
    label = new QLabel( mNameEdit, i18n("&Your name:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Your name
"
               "
This field should have your name, as you'd like "
               "it to appear in the email header that is sent out.
"
               "
If you leave this blank, your real name won't "
               "appear, only the email address.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mNameEdit, msg );

    // "Organization" line edit and label:
    ++row;
    mOrganizationEdit = new KLineEdit( tab );
    glay->addWidget( mOrganizationEdit, row, 1 );
    label =  new QLabel( mOrganizationEdit, i18n("Organi&zation:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Organization
"
               "
This field should have the name of your organization "
               "if you'd like it to be shown in the email header that "
               "is sent out.
"
               "
It is safe (and normal) to leave this blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mOrganizationEdit, msg );

    // "Email Address" line edit and label:
    // (row 3: spacer)
    ++row;
    mEmailEdit = new KLineEdit( tab );
    glay->addWidget( mEmailEdit, row, 1 );
    label = new QLabel( mEmailEdit, i18n("&Email address:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Email address
"
               "
This field should have your full email address.
"
               "
If you leave this blank, or get it wrong, people "
               "will have trouble replying to you.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mEmailEdit, msg );

    //
    // Tab Widget: Advanced
    //
    row = -1;
    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&Advanced") );
    glay = new QGridLayout( tab, 7, 2, marginHint(), spacingHint() );
    // the last (empty) row takes all the remaining space
    glay->setRowStretch( 7-1, 1 );
    glay->setColStretch( 1, 1 );

    // "Reply-To Address" line edit and label:
    ++row;
    mReplyToEdit = new KLineEdit( tab );
    glay->addWidget( mReplyToEdit, row, 1 );
    label = new QLabel ( mReplyToEdit, i18n("&Reply-To address:"), tab);
    glay->addWidget( label , row, 0 );
    msg = i18n("<qt>
Reply-To addresses
"
               "
This sets the <tt>Reply-to:</tt> header to contain a "
               "different email address to the normal <tt>From:</tt> "
               "address.
"
               "
This can be useful when you have a group of people "
               "working together in similar roles. For example, you "
               "might want any emails sent to have your email in the "
               "<tt>From:</tt> field, but any responses to go to "
               "a group address.
"
               "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mReplyToEdit, msg );

    // "BCC addresses" line edit and label:
    ++row;
    mBccEdit = new KLineEdit( tab );
    glay->addWidget( mBccEdit, row, 1 );
    label = new QLabel( mBccEdit, i18n("&BCC addresses:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
BCC (Blind Carbon Copy) addresses
"
               "
The addresses that you enter here will be added to each "
               "outgoing mail that is sent with this identity. They will not "
               "be visible to other recipients.
"
               "
This is commonly used to send a copy of each sent message to "
               "another account of yours.
"
               "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mBccEdit, msg );

    // "OpenPGP Key" requester and label:
    ++row;
    mPgpKeyRequester = new Kpgp::SecretKeyRequester( tab );
    mPgpKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
    mPgpKeyRequester->setDialogCaption( i18n("Your OpenPGP Key") );
    mPgpKeyRequester->setDialogMessage( i18n("Select the OpenPGP key which "
                                             "should be used to sign your "
                                             "messages and when encrypting to "
                                             "yourself.") );
    msg = i18n("<qt>
The OpenPGP key you choose here will be used "
               "to sign messages and to encrypt messages to "
               "yourself. You can also use GnuPG keys.
"
               "You can leave this blank, but KMail won't be able "
               "to cryptographically sign emails. Normal mail functions won't "
               "be affected.
"
               "You can find out more about keys at http://www.gnupg.org</qt>");

    label = new QLabel( mPgpKeyRequester, i18n("OpenPGP key:"), tab );
    QWhatsThis::add( mPgpKeyRequester, msg );
    QWhatsThis::add( label, msg );

    glay->addWidget( label, row, 0 );
    glay->addWidget( mPgpKeyRequester, row, 1 );

    // "Dictionary" combo box and label:
    ++row;
    mDictionaryCombo = new DictionaryComboBox( tab );
    glay->addWidget( mDictionaryCombo, row, 1 );
    glay->addWidget( new QLabel( mDictionaryCombo, i18n("D&ictionary:"), tab ),
                     row, 0 );

    // "Sent-mail Folder" combo box and label:
    ++row;
    mFccCombo = new KMFolderComboBox( tab );
    mFccCombo->showOutboxFolder( false );
    glay->addWidget( mFccCombo, row, 1 );
    glay->addWidget( new QLabel( mFccCombo, i18n("Sent-mail &folder:"), tab ),
                     row, 0 );

    // "Drafts Folder" combo box and label:
    ++row;
    mDraftsCombo = new KMFolderComboBox( tab );
    mDraftsCombo->showOutboxFolder( false );
    glay->addWidget( mDraftsCombo, row, 1 );
    glay->addWidget( new QLabel( mDraftsCombo, i18n("&Drafts folder:"), tab ),
                     row, 0 );

    // "Special transport" combobox and label:
    ++row;
    mTransportCheck = new QCheckBox( i18n("Special &transport:"), tab );
    glay->addWidget( mTransportCheck, row, 0 );
    mTransportCombo = new QComboBox( true, tab );
    mTransportCombo->setEnabled( false ); // since !mTransportCheck->isChecked()
    mTransportCombo->insertStringList( KMail::TransportManager::transportNames() );
    glay->addWidget( mTransportCombo, row, 1 );
    connect( mTransportCheck, SIGNAL(toggled(bool)),
             mTransportCombo, SLOT(setEnabled(bool)) );

    // the last row is a spacer

    //
    // Tab Widget: Signature
    //
    mSignatureConfigurator = new SignatureConfigurator( tabWidget );
    mSignatureConfigurator->layout()->setMargin( KDialog::marginHint() );
    tabWidget->addTab( mSignatureConfigurator, i18n("&Signature") );

    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    if ( geometry.hasKey( "Identity Dialog size" ) )
      resize( geometry.readSizeEntry( "Identity Dialog size" ) );
    mNameEdit->setFocus();
  }

  IdentityDialog::~IdentityDialog() {
    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    geometry.writeEntry( "Identity Dialog size", size() );
  }

  bool IdentityDialog::checkFolderExists( const QString & folderID,
                                          const QString & msg ) {
    KMFolder * folder = kmkernel->folderMgr()->findIdString( folderID );
    if ( !folder )
      folder = kmkernel->imapFolderMgr()->findIdString( folderID );
    if ( !folder )
      folder = kmkernel->dimapFolderMgr()->findIdString( folderID );
    if ( !folder ) {
      KMessageBox::sorry( this, msg );
      return false;
    }
    return true;
  }

  void IdentityDialog::setIdentity( KMIdentity & ident ) {

    setCaption( i18n("Edit Identity \"%1\"").arg( ident.identityName() ) );

    // "General" tab:
    mNameEdit->setText( ident.fullName() );
    mOrganizationEdit->setText( ident.organization() );
    mEmailEdit->setText( ident.emailAddr() );

    // "Advanced" tab:
    mPgpKeyRequester->setKeyIDs( Kpgp::KeyIDList() << ident.pgpIdentity() );
    mReplyToEdit->setText( ident.replyToAddr() );
    mBccEdit->setText( ident.bcc() );
    mTransportCheck->setChecked( !ident.transport().isEmpty() );
    mTransportCombo->setEditText( ident.transport() );
    mTransportCombo->setEnabled( !ident.transport().isEmpty() );
    mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );

    if ( ident.fcc().isEmpty() ||
         !checkFolderExists( ident.fcc(),
                             i18n("The custom sent-mail folder for identity "
                                  "\"%1\" doesn't exist (anymore). "
                                  "Therefore the default sent-mail folder "
                                  "will be used.")
                             .arg( ident.identityName() ) ) )
      mFccCombo->setFolder( kmkernel->sentFolder() );
    else
      mFccCombo->setFolder( ident.fcc() );

    if ( ident.drafts().isEmpty() ||
         !checkFolderExists( ident.drafts(),
                             i18n("The custom drafts folder for identity "
                                  "\"%1\" doesn't exist (anymore). "
                                  "Therefore the default drafts folder "
                                  "will be used.")
                             .arg( ident.identityName() ) ) )
      mDraftsCombo->setFolder( kmkernel->draftsFolder() );
    else
      mDraftsCombo->setFolder( ident.drafts() );

    // "Signature" tab:
    mSignatureConfigurator->setSignature( ident.signature() );
  }

  void IdentityDialog::updateIdentity( KMIdentity & ident ) {
    // "General" tab:
    ident.setFullName( mNameEdit->text() );
    ident.setOrganization( mOrganizationEdit->text() );
    QString email = mEmailEdit->text();
    int atCount = email.contains('@');
    if ( email.isEmpty() || atCount == 0 )
      KMessageBox::sorry( this, "<qt>"+
                          i18n("Your email address is not valid because it "
                               "doesn't contain a @. "
                               "You won't create valid messages if you don't "
                               "change your address.") + "</qt>",
                          i18n("Invalid Email Address") );
    else if ( atCount > 1 ) {
      KMessageBox::sorry( this, "<qt>" +
                          i18n("Your email address is not valid because it "
                               "contains more than one @. "
                               "You won't create valid messages if you don't "
                               "change your address.") + "</qt>",
                          i18n("Invalid Email Address") );
    }
    ident.setEmailAddr( email );
    // "Advanced" tab:
    ident.setPgpIdentity( mPgpKeyRequester->keyIDs().first() );
    ident.setReplyToAddr( mReplyToEdit->text() );
    ident.setBcc( mBccEdit->text() );
    ident.setTransport( ( mTransportCheck->isChecked() ) ?
                        mTransportCombo->currentText() : QString::null );
    ident.setDictionary( mDictionaryCombo->currentDictionary() );
    ident.setFcc( mFccCombo->getFolder() ?
                  mFccCombo->getFolder()->idString() : QString::null );
    ident.setDrafts( mDraftsCombo->getFolder() ?
                     mDraftsCombo->getFolder()->idString() : QString::null );
    // "Signature" tab:
    ident.setSignature( mSignatureConfigurator->signature() );
  }

  void IdentityDialog::slotUpdateTransportCombo( const QStringList & sl ) {
    // save old setting:
    QString content = mTransportCombo->currentText();
    // update combo box:
    mTransportCombo->clear();
    mTransportCombo->insertStringList( sl );
    // restore saved setting:
    mTransportCombo->setEditText( content );
  }

}

#include "identitydialog.moc"
<commit_msg>cvsrevertlast - the change in tags isn't necessary. Now that the <qt>s are there, it won't be marked up at all - which should be fine enough in string fix. I originally thought they are the cause<commit_after>/*  -*- mode: C++; c-file-style: "gnu" -*-
    identitydialog.cpp

    This file is part of KMail, the KDE mail client.
    Copyright (c) 2002 Marc Mutz <mutz@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "identitydialog.h"

// other KMail headers:
#include "signatureconfigurator.h"
#include "kmfoldercombobox.h"
#include "kmfoldermgr.h"
#include "transportmanager.h"
#include "kmkernel.h"
#include "dictionarycombobox.h"

// other kdenetwork headers:
#include <kpgpui.h>

// other KDE headers:
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kconfig.h>

// Qt headers:
#include <qtabwidget.h>
#include <qlabel.h>
#include <qwhatsthis.h>

// other headers: (none)

namespace KMail {

  IdentityDialog::IdentityDialog( QWidget * parent, const char * name )
    : KDialogBase( Plain, i18n("Edit Identity"), Ok|Cancel|Help, Ok,
                   parent, name )
  {
    // tmp. vars:
    QWidget * tab;
    QLabel  * label;
    int row;
    QGridLayout * glay;
    QString msg;

    //
    // Tab Widget: General
    //
    row = -1;
    QVBoxLayout * vlay = new QVBoxLayout( plainPage(), 0, spacingHint() );
    QTabWidget *tabWidget = new QTabWidget( plainPage(), "config-identity-tab" );
    vlay->addWidget( tabWidget );

    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&General") );
    glay = new QGridLayout( tab, 4, 2, marginHint(), spacingHint() );
    glay->setRowStretch( 3, 1 );
    glay->setColStretch( 1, 1 );

    // "Name" line edit and label:
    ++row;
    mNameEdit = new KLineEdit( tab );
    glay->addWidget( mNameEdit, row, 1 );
    label = new QLabel( mNameEdit, i18n("&Your name:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Your name
"
               "
This field should have your name, as you'd like "
               "it to appear in the email header that is sent out.
"
               "
If you leave this blank, your real name won't "
               "appear, only the email address.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mNameEdit, msg );

    // "Organization" line edit and label:
    ++row;
    mOrganizationEdit = new KLineEdit( tab );
    glay->addWidget( mOrganizationEdit, row, 1 );
    label =  new QLabel( mOrganizationEdit, i18n("Organi&zation:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Organization
"
               "
This field should have the name of your organization "
               "if you'd like it to be shown in the email header that "
               "is sent out.
"
               "
It is safe (and normal) to leave this blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mOrganizationEdit, msg );

    // "Email Address" line edit and label:
    // (row 3: spacer)
    ++row;
    mEmailEdit = new KLineEdit( tab );
    glay->addWidget( mEmailEdit, row, 1 );
    label = new QLabel( mEmailEdit, i18n("&Email address:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
Email address
"
               "
This field should have your full email address.
"
               "
If you leave this blank, or get it wrong, people "
               "will have trouble replying to you.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mEmailEdit, msg );

    //
    // Tab Widget: Advanced
    //
    row = -1;
    tab = new QWidget( tabWidget );
    tabWidget->addTab( tab, i18n("&Advanced") );
    glay = new QGridLayout( tab, 7, 2, marginHint(), spacingHint() );
    // the last (empty) row takes all the remaining space
    glay->setRowStretch( 7-1, 1 );
    glay->setColStretch( 1, 1 );

    // "Reply-To Address" line edit and label:
    ++row;
    mReplyToEdit = new KLineEdit( tab );
    glay->addWidget( mReplyToEdit, row, 1 );
    label = new QLabel ( mReplyToEdit, i18n("&Reply-To address:"), tab);
    glay->addWidget( label , row, 0 );
    msg = i18n("<qt>
Reply-To addresses
"
               "
This sets the <tt>Reply-to:</tt> header to contain a "
               "different email address to the normal <tt>From:</tt> "
               "address.
"
               "
This can be useful when you have a group of people "
               "working together in similar roles. For example, you "
               "might want any emails sent to have your email in the "
               "<tt>From:</tt> field, but any responses to go to "
               "a group address.
"
               "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mReplyToEdit, msg );

    // "BCC addresses" line edit and label:
    ++row;
    mBccEdit = new KLineEdit( tab );
    glay->addWidget( mBccEdit, row, 1 );
    label = new QLabel( mBccEdit, i18n("&BCC addresses:"), tab );
    glay->addWidget( label, row, 0 );
    msg = i18n("<qt>
BCC (Blind Carbon Copy) addresses
"
               "
The addresses that you enter here will be added to each "
               "outgoing mail that is sent with this identity. They will not "
               "be visible to other recipients.
"
               "
This is commonly used to send a copy of each sent message to "
               "another account of yours.
"
               "
If in doubt, leave this field blank.
</qt>");
    QWhatsThis::add( label, msg );
    QWhatsThis::add( mBccEdit, msg );

    // "OpenPGP Key" requester and label:
    ++row;
    mPgpKeyRequester = new Kpgp::SecretKeyRequester( tab );
    mPgpKeyRequester->dialogButton()->setText( i18n("Chang&e...") );
    mPgpKeyRequester->setDialogCaption( i18n("Your OpenPGP Key") );
    mPgpKeyRequester->setDialogMessage( i18n("Select the OpenPGP key which "
                                             "should be used to sign your "
                                             "messages and when encrypting to "
                                             "yourself.") );
    msg = i18n("<qt>
The OpenPGP key you choose here will be used "
               "to sign messages and to encrypt messages to "
               "yourself. You can also use GnuPG keys.
"
               "You can leave this blank, but KMail won't be able "
               "to cryptographically sign emails. Normal mail functions won't "
               "be affected.
"
               "You can find out more about keys at http://www.gnupg.org</qt>");

    label = new QLabel( mPgpKeyRequester, i18n("OpenPGP key:"), tab );
    QWhatsThis::add( mPgpKeyRequester, msg );
    QWhatsThis::add( label, msg );

    glay->addWidget( label, row, 0 );
    glay->addWidget( mPgpKeyRequester, row, 1 );

    // "Dictionary" combo box and label:
    ++row;
    mDictionaryCombo = new DictionaryComboBox( tab );
    glay->addWidget( mDictionaryCombo, row, 1 );
    glay->addWidget( new QLabel( mDictionaryCombo, i18n("D&ictionary:"), tab ),
                     row, 0 );

    // "Sent-mail Folder" combo box and label:
    ++row;
    mFccCombo = new KMFolderComboBox( tab );
    mFccCombo->showOutboxFolder( false );
    glay->addWidget( mFccCombo, row, 1 );
    glay->addWidget( new QLabel( mFccCombo, i18n("Sent-mail &folder:"), tab ),
                     row, 0 );

    // "Drafts Folder" combo box and label:
    ++row;
    mDraftsCombo = new KMFolderComboBox( tab );
    mDraftsCombo->showOutboxFolder( false );
    glay->addWidget( mDraftsCombo, row, 1 );
    glay->addWidget( new QLabel( mDraftsCombo, i18n("&Drafts folder:"), tab ),
                     row, 0 );

    // "Special transport" combobox and label:
    ++row;
    mTransportCheck = new QCheckBox( i18n("Special &transport:"), tab );
    glay->addWidget( mTransportCheck, row, 0 );
    mTransportCombo = new QComboBox( true, tab );
    mTransportCombo->setEnabled( false ); // since !mTransportCheck->isChecked()
    mTransportCombo->insertStringList( KMail::TransportManager::transportNames() );
    glay->addWidget( mTransportCombo, row, 1 );
    connect( mTransportCheck, SIGNAL(toggled(bool)),
             mTransportCombo, SLOT(setEnabled(bool)) );

    // the last row is a spacer

    //
    // Tab Widget: Signature
    //
    mSignatureConfigurator = new SignatureConfigurator( tabWidget );
    mSignatureConfigurator->layout()->setMargin( KDialog::marginHint() );
    tabWidget->addTab( mSignatureConfigurator, i18n("&Signature") );

    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    if ( geometry.hasKey( "Identity Dialog size" ) )
      resize( geometry.readSizeEntry( "Identity Dialog size" ) );
    mNameEdit->setFocus();
  }

  IdentityDialog::~IdentityDialog() {
    KConfigGroup geometry( KMKernel::config(), "Geometry" );
    geometry.writeEntry( "Identity Dialog size", size() );
  }

  bool IdentityDialog::checkFolderExists( const QString & folderID,
                                          const QString & msg ) {
    KMFolder * folder = kmkernel->folderMgr()->findIdString( folderID );
    if ( !folder )
      folder = kmkernel->imapFolderMgr()->findIdString( folderID );
    if ( !folder )
      folder = kmkernel->dimapFolderMgr()->findIdString( folderID );
    if ( !folder ) {
      KMessageBox::sorry( this, msg );
      return false;
    }
    return true;
  }

  void IdentityDialog::setIdentity( KMIdentity & ident ) {

    setCaption( i18n("Edit Identity \"%1\"").arg( ident.identityName() ) );

    // "General" tab:
    mNameEdit->setText( ident.fullName() );
    mOrganizationEdit->setText( ident.organization() );
    mEmailEdit->setText( ident.emailAddr() );

    // "Advanced" tab:
    mPgpKeyRequester->setKeyIDs( Kpgp::KeyIDList() << ident.pgpIdentity() );
    mReplyToEdit->setText( ident.replyToAddr() );
    mBccEdit->setText( ident.bcc() );
    mTransportCheck->setChecked( !ident.transport().isEmpty() );
    mTransportCombo->setEditText( ident.transport() );
    mTransportCombo->setEnabled( !ident.transport().isEmpty() );
    mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );

    if ( ident.fcc().isEmpty() ||
         !checkFolderExists( ident.fcc(),
                             i18n("The custom sent-mail folder for identity "
                                  "\"%1\" doesn't exist (anymore). "
                                  "Therefore the default sent-mail folder "
                                  "will be used.")
                             .arg( ident.identityName() ) ) )
      mFccCombo->setFolder( kmkernel->sentFolder() );
    else
      mFccCombo->setFolder( ident.fcc() );

    if ( ident.drafts().isEmpty() ||
         !checkFolderExists( ident.drafts(),
                             i18n("The custom drafts folder for identity "
                                  "\"%1\" doesn't exist (anymore). "
                                  "Therefore the default drafts folder "
                                  "will be used.")
                             .arg( ident.identityName() ) ) )
      mDraftsCombo->setFolder( kmkernel->draftsFolder() );
    else
      mDraftsCombo->setFolder( ident.drafts() );

    // "Signature" tab:
    mSignatureConfigurator->setSignature( ident.signature() );
  }

  void IdentityDialog::updateIdentity( KMIdentity & ident ) {
    // "General" tab:
    ident.setFullName( mNameEdit->text() );
    ident.setOrganization( mOrganizationEdit->text() );
    QString email = mEmailEdit->text();
    int atCount = email.contains('@');
    if ( email.isEmpty() || atCount == 0 )
      KMessageBox::sorry( this, "<qt>"+
                          i18n("Your email address is not valid because it "
                               "doesn't contain a <emph>@</emph>. "
                               "You won't create valid messages if you don't "
                               "change your address.") + "</qt>",
                          i18n("Invalid Email Address") );
    else if ( atCount > 1 ) {
      KMessageBox::sorry( this, "<qt>" +
                          i18n("Your email address is not valid because it "
                               "contains more than one <emph>@</emph>. "
                               "You won't create valid messages if you don't "
                               "change your address.") + "</qt>",
                          i18n("Invalid Email Address") );
    }
    ident.setEmailAddr( email );
    // "Advanced" tab:
    ident.setPgpIdentity( mPgpKeyRequester->keyIDs().first() );
    ident.setReplyToAddr( mReplyToEdit->text() );
    ident.setBcc( mBccEdit->text() );
    ident.setTransport( ( mTransportCheck->isChecked() ) ?
                        mTransportCombo->currentText() : QString::null );
    ident.setDictionary( mDictionaryCombo->currentDictionary() );
    ident.setFcc( mFccCombo->getFolder() ?
                  mFccCombo->getFolder()->idString() : QString::null );
    ident.setDrafts( mDraftsCombo->getFolder() ?
                     mDraftsCombo->getFolder()->idString() : QString::null );
    // "Signature" tab:
    ident.setSignature( mSignatureConfigurator->signature() );
  }

  void IdentityDialog::slotUpdateTransportCombo( const QStringList & sl ) {
    // save old setting:
    QString content = mTransportCombo->currentText();
    // update combo box:
    mTransportCombo->clear();
    mTransportCombo->insertStringList( sl );
    // restore saved setting:
    mTransportCombo->setEditText( content );
  }

}

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


<commit_before>/*
* Discrete Logarithm Parameters
* (C) 1999-2008,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/dl_group.h>
#include <botan/parsing.h>
#include <botan/numthry.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/pem.h>
#include <botan/workfactor.h>

namespace Botan {

/*
* DL_Group Constructor
*/
DL_Group::DL_Group()
   {
   m_initialized = false;
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(const std::string& name)
   {
   const char* pem = PEM_for_named_group(name);

   if(!pem)
      throw Invalid_Argument("DL_Group: Unknown group " + name);

   PEM_decode(pem);
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(RandomNumberGenerator& rng,
                   PrimeType type, size_t pbits, size_t qbits)
   {
   if(pbits < 1024)
      throw Invalid_Argument("DL_Group: prime size " + std::to_string(pbits) +
                             " is too small");

   if(type == Strong)
      {
      m_p = random_safe_prime(rng, pbits);
      m_q = (m_p - 1) / 2;
      m_g = 2;
      }
   else if(type == Prime_Subgroup)
      {
      if(!qbits)
         qbits = dl_exponent_size(pbits);

      m_q = random_prime(rng, qbits);
      BigInt X;
      while(m_p.bits() != pbits || !is_prime(m_p, rng))
         {
         X.randomize(rng, pbits);
         m_p = X - (X % (2*m_q) - 1);
         }

      m_g = make_dsa_generator(m_p, m_q);
      }
   else if(type == DSA_Kosherizer)
      {
      qbits = qbits ? qbits : ((pbits <= 1024) ? 160 : 256);

      generate_dsa_primes(rng, m_p, m_q, pbits, qbits);

      m_g = make_dsa_generator(m_p, m_q);
      }

   m_initialized = true;
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(RandomNumberGenerator& rng,
                   const std::vector<byte>& seed,
                   size_t pbits, size_t qbits)
   {
   if(!generate_dsa_primes(rng, m_p, m_q, pbits, qbits, seed))
      throw Invalid_Argument("DL_Group: The seed given does not "
                             "generate a DSA group");

   m_g = make_dsa_generator(m_p, m_q);

   m_initialized = true;
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(const BigInt& p1, const BigInt& g1)
   {
   initialize(p1, 0, g1);
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(const BigInt& p1, const BigInt& q1, const BigInt& g1)
   {
   initialize(p1, q1, g1);
   }

/*
* DL_Group Initializer
*/
void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1)
   {
   if(p1 < 3)
      throw Invalid_Argument("DL_Group: Prime invalid");
   if(g1 < 2 || g1 >= p1)
      throw Invalid_Argument("DL_Group: Generator invalid");
   if(q1 < 0 || q1 >= p1)
      throw Invalid_Argument("DL_Group: Subgroup invalid");

   m_p = p1;
   m_g = g1;
   m_q = q1;

   m_initialized = true;
   }

/*
* Verify that the group has been set
*/
void DL_Group::init_check() const
   {
   if(!m_initialized)
      throw Invalid_State("DLP group cannot be used uninitialized");
   }

/*
* Verify the parameters
*/
bool DL_Group::verify_group(RandomNumberGenerator& rng,
                            bool strong) const
   {
   init_check();

   if(m_g < 2 || m_p < 3 || m_q < 0)
      return false;
   if((m_q != 0) && ((m_p - 1) % m_q != 0))
      return false;

   const size_t prob = (strong) ? 56 : 10;

   if(!is_prime(m_p, rng, prob))
      return false;
   if((m_q > 0) && !is_prime(m_q, rng, prob))
      return false;
   return true;
   }

/*
* Return the prime
*/
const BigInt& DL_Group::get_p() const
   {
   init_check();
   return m_p;
   }

/*
* Return the generator
*/
const BigInt& DL_Group::get_g() const
   {
   init_check();
   return m_g;
   }

/*
* Return the subgroup
*/
const BigInt& DL_Group::get_q() const
   {
   init_check();
   if(m_q == 0)
      throw Invalid_State("DLP group has no q prime specified");
   return m_q;
   }

/*
* DER encode the parameters
*/
std::vector<byte> DL_Group::DER_encode(Format format) const
   {
   init_check();

   if((m_q == 0) && (format != PKCS_3))
      throw Encoding_Error("The ANSI DL parameter formats require a subgroup");

   if(format == ANSI_X9_57)
      {
      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(m_p)
            .encode(m_q)
            .encode(m_g)
         .end_cons()
      .get_contents_unlocked();
      }
   else if(format == ANSI_X9_42)
      {
      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(m_p)
            .encode(m_g)
            .encode(m_q)
         .end_cons()
      .get_contents_unlocked();
      }
   else if(format == PKCS_3)
      {
      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(m_p)
            .encode(m_g)
         .end_cons()
      .get_contents_unlocked();
      }

   throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
   }

/*
* PEM encode the parameters
*/
std::string DL_Group::PEM_encode(Format format) const
   {
   const std::vector<byte> encoding = DER_encode(format);

   if(format == PKCS_3)
      return PEM_Code::encode(encoding, "DH PARAMETERS");
   else if(format == ANSI_X9_57)
      return PEM_Code::encode(encoding, "DSA PARAMETERS");
   else if(format == ANSI_X9_42)
      return PEM_Code::encode(encoding, "X942 DH PARAMETERS");
   else
      throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
   }

/*
* Decode BER encoded parameters
*/
void DL_Group::BER_decode(const std::vector<byte>& data,
                          Format format)
   {
   BigInt new_p, new_q, new_g;

   BER_Decoder decoder(data);
   BER_Decoder ber = decoder.start_cons(SEQUENCE);

   if(format == ANSI_X9_57)
      {
      ber.decode(new_p)
         .decode(new_q)
         .decode(new_g)
         .verify_end();
      }
   else if(format == ANSI_X9_42)
      {
      ber.decode(new_p)
         .decode(new_g)
         .decode(new_q)
         .discard_remaining();
      }
   else if(format == PKCS_3)
      {
      ber.decode(new_p)
         .decode(new_g)
         .discard_remaining();
      }
   else
      throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));

   initialize(new_p, new_q, new_g);
   }

/*
* Decode PEM encoded parameters
*/
void DL_Group::PEM_decode(const std::string& pem)
   {
   std::string label;

   auto ber = unlock(PEM_Code::decode(pem, label));

   if(label == "DH PARAMETERS")
      BER_decode(ber, PKCS_3);
   else if(label == "DSA PARAMETERS")
      BER_decode(ber, ANSI_X9_57);
   else if(label == "X942 DH PARAMETERS")
      BER_decode(ber, ANSI_X9_42);
   else
      throw Decoding_Error("DL_Group: Invalid PEM label " + label);
   }

/*
* Create generator of the q-sized subgroup (DSA style generator)
*/
BigInt DL_Group::make_dsa_generator(const BigInt& p, const BigInt& q)
   {
   const BigInt e = (p - 1) / q;

   if(e == 0 || (p - 1) % q > 0)
      throw Invalid_Argument("make_dsa_generator q does not divide p-1");

   for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i)
      {
      BigInt g = power_mod(PRIMES[i], e, p);
      if(g > 1)
         return g;
      }

   throw Internal_Error("DL_Group: Couldn't create a suitable generator");
   }

}
<commit_msg>Improved DL_Group verification. The group is invalid, if g^q mod p !=1 and increased number of Miller-Rabin iterations, if strong is set (we pass 128 as prob in make_prm.cpp).<commit_after>/*
* Discrete Logarithm Parameters
* (C) 1999-2008,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/dl_group.h>
#include <botan/parsing.h>
#include <botan/numthry.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/pem.h>
#include <botan/workfactor.h>
#include <botan/pow_mod.h>

namespace Botan {

/*
* DL_Group Constructor
*/
DL_Group::DL_Group()
   {
   m_initialized = false;
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(const std::string& name)
   {
   const char* pem = PEM_for_named_group(name);

   if(!pem)
      throw Invalid_Argument("DL_Group: Unknown group " + name);

   PEM_decode(pem);
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(RandomNumberGenerator& rng,
                   PrimeType type, size_t pbits, size_t qbits)
   {
   if(pbits < 1024)
      throw Invalid_Argument("DL_Group: prime size " + std::to_string(pbits) +
                             " is too small");

   if(type == Strong)
      {
      m_p = random_safe_prime(rng, pbits);
      m_q = (m_p - 1) / 2;
      m_g = 2;
      }
   else if(type == Prime_Subgroup)
      {
      if(!qbits)
         qbits = dl_exponent_size(pbits);

      m_q = random_prime(rng, qbits);
      BigInt X;
      while(m_p.bits() != pbits || !is_prime(m_p, rng))
         {
         X.randomize(rng, pbits);
         m_p = X - (X % (2*m_q) - 1);
         }

      m_g = make_dsa_generator(m_p, m_q);
      }
   else if(type == DSA_Kosherizer)
      {
      qbits = qbits ? qbits : ((pbits <= 1024) ? 160 : 256);

      generate_dsa_primes(rng, m_p, m_q, pbits, qbits);

      m_g = make_dsa_generator(m_p, m_q);
      }

   m_initialized = true;
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(RandomNumberGenerator& rng,
                   const std::vector<byte>& seed,
                   size_t pbits, size_t qbits)
   {
   if(!generate_dsa_primes(rng, m_p, m_q, pbits, qbits, seed))
      throw Invalid_Argument("DL_Group: The seed given does not "
                             "generate a DSA group");

   m_g = make_dsa_generator(m_p, m_q);

   m_initialized = true;
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(const BigInt& p1, const BigInt& g1)
   {
   initialize(p1, 0, g1);
   }

/*
* DL_Group Constructor
*/
DL_Group::DL_Group(const BigInt& p1, const BigInt& q1, const BigInt& g1)
   {
   initialize(p1, q1, g1);
   }

/*
* DL_Group Initializer
*/
void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1)
   {
   if(p1 < 3)
      throw Invalid_Argument("DL_Group: Prime invalid");
   if(g1 < 2 || g1 >= p1)
      throw Invalid_Argument("DL_Group: Generator invalid");
   if(q1 < 0 || q1 >= p1)
      throw Invalid_Argument("DL_Group: Subgroup invalid");

   m_p = p1;
   m_g = g1;
   m_q = q1;

   m_initialized = true;
   }

/*
* Verify that the group has been set
*/
void DL_Group::init_check() const
   {
   if(!m_initialized)
      throw Invalid_State("DLP group cannot be used uninitialized");
   }

/*
* Verify the parameters
*/
bool DL_Group::verify_group(RandomNumberGenerator& rng,
                            bool strong) const
   {
   init_check();

   if(m_g < 2 || m_p < 3 || m_q < 0)
      return false;

   const size_t prob = (strong) ? 128 : 10;

   if(m_q != 0)
      {
      if((m_p - 1) % m_q != 0)
         {
         return false;
         }
      if(power_mod(m_g, m_q, m_p) != 1)
         {
         return false;
         }
      if(!is_prime(m_q, rng, prob))
         {
         return false;
         }
      }
   if(!is_prime(m_p, rng, prob))
      {
      return false;
      }
   return true;
   }

/*
* Return the prime
*/
const BigInt& DL_Group::get_p() const
   {
   init_check();
   return m_p;
   }

/*
* Return the generator
*/
const BigInt& DL_Group::get_g() const
   {
   init_check();
   return m_g;
   }

/*
* Return the subgroup
*/
const BigInt& DL_Group::get_q() const
   {
   init_check();
   if(m_q == 0)
      throw Invalid_State("DLP group has no q prime specified");
   return m_q;
   }

/*
* DER encode the parameters
*/
std::vector<byte> DL_Group::DER_encode(Format format) const
   {
   init_check();

   if((m_q == 0) && (format != PKCS_3))
      throw Encoding_Error("The ANSI DL parameter formats require a subgroup");

   if(format == ANSI_X9_57)
      {
      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(m_p)
            .encode(m_q)
            .encode(m_g)
         .end_cons()
      .get_contents_unlocked();
      }
   else if(format == ANSI_X9_42)
      {
      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(m_p)
            .encode(m_g)
            .encode(m_q)
         .end_cons()
      .get_contents_unlocked();
      }
   else if(format == PKCS_3)
      {
      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode(m_p)
            .encode(m_g)
         .end_cons()
      .get_contents_unlocked();
      }

   throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
   }

/*
* PEM encode the parameters
*/
std::string DL_Group::PEM_encode(Format format) const
   {
   const std::vector<byte> encoding = DER_encode(format);

   if(format == PKCS_3)
      return PEM_Code::encode(encoding, "DH PARAMETERS");
   else if(format == ANSI_X9_57)
      return PEM_Code::encode(encoding, "DSA PARAMETERS");
   else if(format == ANSI_X9_42)
      return PEM_Code::encode(encoding, "X942 DH PARAMETERS");
   else
      throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));
   }

/*
* Decode BER encoded parameters
*/
void DL_Group::BER_decode(const std::vector<byte>& data,
                          Format format)
   {
   BigInt new_p, new_q, new_g;

   BER_Decoder decoder(data);
   BER_Decoder ber = decoder.start_cons(SEQUENCE);

   if(format == ANSI_X9_57)
      {
      ber.decode(new_p)
         .decode(new_q)
         .decode(new_g)
         .verify_end();
      }
   else if(format == ANSI_X9_42)
      {
      ber.decode(new_p)
         .decode(new_g)
         .decode(new_q)
         .discard_remaining();
      }
   else if(format == PKCS_3)
      {
      ber.decode(new_p)
         .decode(new_g)
         .discard_remaining();
      }
   else
      throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format));

   initialize(new_p, new_q, new_g);
   }

/*
* Decode PEM encoded parameters
*/
void DL_Group::PEM_decode(const std::string& pem)
   {
   std::string label;

   auto ber = unlock(PEM_Code::decode(pem, label));

   if(label == "DH PARAMETERS")
      BER_decode(ber, PKCS_3);
   else if(label == "DSA PARAMETERS")
      BER_decode(ber, ANSI_X9_57);
   else if(label == "X942 DH PARAMETERS")
      BER_decode(ber, ANSI_X9_42);
   else
      throw Decoding_Error("DL_Group: Invalid PEM label " + label);
   }

/*
* Create generator of the q-sized subgroup (DSA style generator)
*/
BigInt DL_Group::make_dsa_generator(const BigInt& p, const BigInt& q)
   {
   const BigInt e = (p - 1) / q;

   if(e == 0 || (p - 1) % q > 0)
      throw Invalid_Argument("make_dsa_generator q does not divide p-1");

   for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i)
      {
      BigInt g = power_mod(PRIMES[i], e, p);
      if(g > 1)
         return g;
      }

   throw Internal_Error("DL_Group: Couldn't create a suitable generator");
   }

}
<|endoftext|>