<commit_before>/*
 * THIS SHOULD BE RENAMED AS PROCESS_HKL.CPP
 */
#include <iostream>
#include <iomanip>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_errno.h>
#include <algorithm>
#include "detector.h"
#include "beam.h"
#include "particle.h"
#include "diffraction.h"
#include "toolbox.h"
#include "diffraction.cuh"
#include "io.h"
#include <fstream>
#include <string>

#ifdef COMPILE_WITH_CXX11
	#define ARMA_DONT_USE_CXX11
#endif
#include <armadillo>

#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace arma;
using namespace detector;
using namespace beam;
using namespace particle;
using namespace diffraction;
using namespace toolbox;

#define USE_CUDA 0

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

    string imageList;
    string eulerList;
    string quaternionList;
    string rotationList;
    string beamFile;
    string geomFile;
    int numImages = 0;
    int mySize = 0;
    string output;
    string format;
    // Let's parse input
    for (int n = 1; n < argc; n++) {
    cout << argv [ n ] << endl;
        if(boost::algorithm::iequals(argv[ n ], "-i")) {
            imageList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-e")) {
            eulerList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-q")) {
		    quaternionList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-r")) {
		    rotationList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-b")) {
            beamFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-g")) {
            geomFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "--num_images")) {
            numImages = atoi(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--vol_dim")) {
            mySize = atof(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--output_name")) {
            output = argv[ n+2 ];
        } else if (boost::algorithm::iequals(argv[ n ], "--format")) {
            format = argv[ n+2 ];
        }
    }
    //cout << numImages << endl;
    //cout << inc_res << endl;
    // image.lst and euler.lst are not neccessarily in the same order! So can not use like this. Perhaps use hdf5 to combine the two.

	/****** Beam ******/
	// Let's read in our beam file
	double photon_energy = 0;
	string line;
	ifstream myFile(beamFile.c_str());
	while (getline(myFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"beam/photon_energy") ) {
                    string temp = *++tok_iter;
                    photon_energy = atof(temp.c_str()); // photon energy to wavelength
                    break;
                }
            }
        }
    }
	CBeam beam = CBeam();
	beam.set_photon_energy(photon_energy);

	/****** Detector ******/
    double d = 0;					// (m) detector distance
	double pix_width = 0;			// (m)
	int px_in = 0;                  // number of pixel along x
	string badpixmap = ""; // this information should go into the detector class
	// Parse the geom file
	ifstream myGeomFile(geomFile.c_str());
	while (getline(myGeomFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"geom/d") ) {
                    string temp = *++tok_iter;
                    d = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/pix_width") ) {
                    string temp = *++tok_iter;
                    pix_width = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/px") ) {
                    string temp = *++tok_iter;
                    px_in = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/badpixmap") ) {
                    string temp = *++tok_iter;
                    cout << temp << endl;
                    badpixmap = temp;
                    break;
                }
            }
        }
    }
	double pix_height = pix_width;		// (m)
	const int px = px_in;				// number of pixels in x
	const int py = px;					// number of pixels in y
	double cx = ((double) px-1)/2;		// this can be user defined
	double cy = ((double) py-1)/2;		// this can be user defined

	CDetector det = CDetector();
	det.set_detector_dist(d);
	det.set_pix_width(pix_width);
	det.set_pix_height(pix_height);
	det.set_numPix(py,px);
	det.set_center_x(cx);
	det.set_center_y(cy);
	det.set_pixelMap(badpixmap);
	det.init_dp(&beam);

    uvec goodpix;
    goodpix = det.get_goodPixelMap();
    //cout << "Good pix:" << goodpix << endl;

	double theta = atan((px/2*pix_height)/d);
	double qmax = 2/beam.get_wavelength()*sin(theta/2);
	double dmin = 1/(2*qmax);
	cout << "max q to the edge: " << qmax << " m^-1" << endl;
	cout << "Half period resolution: " << dmin << " m" << endl;

	if(!USE_CUDA) {

		fmat pix = det.pixSpace;
		float pix_max = det.pixSpaceMax;

  		string filename;

  		fmat myDP;
  		fmat myR;
  		myR.zeros(3,3);
  		float psi,theta,phi;

		fcube myWeight;
		myWeight.zeros(mySize,mySize,mySize);
		fcube myIntensity;
		myIntensity.zeros(mySize,mySize,mySize);

		cout << "Start" << endl;
		//cout << mySize << endl;

		int active = 1;
		string interpolate = "linear";// "nearest";

		cout << format << endl;
  		for (int r = 0; r < numImages; r++) {
			if (format == "S2E") {
				// Get image from hdf
				stringstream sstm;
				sstm << imageList << "/diffr_out_" << setfill('0') << setw(7) << r+1 << ".h5";
				string inputName;
				inputName = sstm.str();
				// Read in diffraction
				myDP = hdf5readT<fmat>(inputName,"/data/data");
				// Read angle
				fvec quat = hdf5readT<fvec>(inputName,"/data/angle");
				myR = CToolbox::quaternion2rot3D(quat);
				myR = trans(myR);
			} else {
				// Get image from dat file
		  		std::stringstream sstm;
	  			sstm << imageList << setfill('0') << setw(7) << r << ".dat";
				filename = sstm.str();
				cout << filename << endl;
				myDP = load_asciiImage(filename);
			    // Get rotation matrix from dat file
	  			std::stringstream sstm1;
				sstm1 << rotationList << setfill('0') << setw(7) << r << ".dat";
				string rotationName = sstm1.str();
				cout << rotationName << endl;
				myR = load_asciiRotation(rotationName);
			}
        	CToolbox::merge3D(&myDP, &pix, &goodpix, &myR, pix_max, &myIntensity, &myWeight, active, interpolate);
  		}
  		// Normalize here
  		CToolbox::normalize(&myIntensity,&myWeight);

  		// ########### Save diffraction volume ##############
  		cout << "Saving diffraction volume..." << endl;
		for (int i = 0; i < mySize; i++) {
			std::stringstream sstm;
			sstm << output << "vol_" << setfill('0') << setw(7) << i << ".dat";
			string outputName = sstm.str();
			myIntensity.slice(i).save(outputName,raw_ascii);
			// empty voxels
			std::stringstream sstm1;
			sstm1 << output << "volGoodVoxels_" << setfill('0') << setw(7) << i << ".dat";
			string outputName1 = sstm1.str();
			fmat goodVoxels = sign(myWeight.slice(i));
			goodVoxels.save(outputName1,raw_ascii);
		}

    }
  	return 0;
}

<commit_msg>get rid of mySize dependence<commit_after>/*
 * THIS SHOULD BE RENAMED AS PROCESS_HKL.CPP
 */
#include <iostream>
#include <iomanip>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_errno.h>
#include <algorithm>
#include "detector.h"
#include "beam.h"
#include "particle.h"
#include "diffraction.h"
#include "toolbox.h"
#include "diffraction.cuh"
#include "io.h"
#include <fstream>
#include <string>

#ifdef COMPILE_WITH_CXX11
	#define ARMA_DONT_USE_CXX11
#endif
#include <armadillo>

#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace arma;
using namespace detector;
using namespace beam;
using namespace particle;
using namespace diffraction;
using namespace toolbox;

#define USE_CUDA 0

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

    string imageList;
    string eulerList;
    string quaternionList;
    string rotationList;
    string beamFile;
    string geomFile;
    int numImages = 0;
    int mySize = 0;
    string output;
    string format;
    // Let's parse input
    for (int n = 1; n < argc; n++) {
    cout << argv [ n ] << endl;
        if(boost::algorithm::iequals(argv[ n ], "-i")) {
            imageList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-e")) {
            eulerList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-q")) {
		    quaternionList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-r")) {
		    rotationList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-b")) {
            beamFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-g")) {
            geomFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "--num_images")) {
            numImages = atoi(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--vol_dim")) {
            mySize = atof(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--output_name")) {
            output = argv[ n+2 ];
        } else if (boost::algorithm::iequals(argv[ n ], "--format")) {
            format = argv[ n+2 ];
        }
    }
    //cout << numImages << endl;
    //cout << inc_res << endl;
    // image.lst and euler.lst are not neccessarily in the same order! So can not use like this. Perhaps use hdf5 to combine the two.

	/****** Beam ******/
	// Let's read in our beam file
	double photon_energy = 0;
	string line;
	ifstream myFile(beamFile.c_str());
	while (getline(myFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"beam/photon_energy") ) {
                    string temp = *++tok_iter;
                    photon_energy = atof(temp.c_str()); // photon energy to wavelength
                    break;
                }
            }
        }
    }
	CBeam beam = CBeam();
	beam.set_photon_energy(photon_energy);

	/****** Detector ******/
    double d = 0;					// (m) detector distance
	double pix_width = 0;			// (m)
	int px_in = 0;                  // number of pixel along x
	string badpixmap = ""; // this information should go into the detector class
	// Parse the geom file
	ifstream myGeomFile(geomFile.c_str());
	while (getline(myGeomFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"geom/d") ) {
                    string temp = *++tok_iter;
                    d = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/pix_width") ) {
                    string temp = *++tok_iter;
                    pix_width = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/px") ) {
                    string temp = *++tok_iter;
                    px_in = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/badpixmap") ) {
                    string temp = *++tok_iter;
                    cout << temp << endl;
                    badpixmap = temp;
                    break;
                }
            }
        }
    }
	double pix_height = pix_width;		// (m)
	const int px = px_in;				// number of pixels in x
	const int py = px;					// number of pixels in y
	double cx = ((double) px-1)/2;		// this can be user defined
	double cy = ((double) py-1)/2;		// this can be user defined

	CDetector det = CDetector();
	det.set_detector_dist(d);
	det.set_pix_width(pix_width);
	det.set_pix_height(pix_height);
	det.set_numPix(py,px);
	det.set_center_x(cx);
	det.set_center_y(cy);
	det.set_pixelMap(badpixmap);
	det.init_dp(&beam);

    uvec goodpix;
    goodpix = det.get_goodPixelMap();

	double theta = atan((px/2*pix_height)/d);
	double qmax = 2/beam.get_wavelength()*sin(theta/2);
	double dmin = 1/(2*qmax);
	cout << "max q to the edge: " << qmax << " m^-1" << endl;
	cout << "Half period resolution: " << dmin << " m" << endl;

	if(!USE_CUDA) {

		fmat pix = det.pixSpace;
		float pix_max = det.pixSpaceMax;

  		string filename;

  		fmat myDP;
  		fmat myR;
  		myR.zeros(3,3);
  		float psi,theta,phi;

		fcube myWeight;
		myWeight.zeros(px,px,px);
		fcube myIntensity;
		myIntensity.zeros(px,px,px);

		cout << "Start" << endl;

		int active = 1;
		string interpolate = "linear";// "nearest";

		cout << format << endl;
  		for (int r = 0; r < numImages; r++) {
			if (format == "S2E") {
				// Get image from hdf
				stringstream sstm;
				sstm << imageList << "/diffr_out_" << setfill('0') << setw(7) << r+1 << ".h5";
				string inputName;
				inputName = sstm.str();
				// Read in diffraction
				myDP = hdf5readT<fmat>(inputName,"/data/data");
				// Read angle
				fvec quat = hdf5readT<fvec>(inputName,"/data/angle");
				myR = CToolbox::quaternion2rot3D(quat);
				myR = trans(myR);
			} else {
				// Get image from dat file
		  		std::stringstream sstm;
	  			sstm << imageList << setfill('0') << setw(7) << r << ".dat";
				filename = sstm.str();
				cout << filename << endl;
				myDP = load_asciiImage(filename);
			    // Get rotation matrix from dat file
	  			std::stringstream sstm1;
				sstm1 << rotationList << setfill('0') << setw(7) << r << ".dat";
				string rotationName = sstm1.str();
				cout << rotationName << endl;
				myR = load_asciiRotation(rotationName);
			}
        	CToolbox::merge3D(&myDP, &pix, &goodpix, &myR, pix_max, &myIntensity, &myWeight, active, interpolate);
  		}
  		// Normalize here
  		CToolbox::normalize(&myIntensity,&myWeight);

  		// ########### Save diffraction volume ##############
  		cout << "Saving diffraction volume..." << endl;
		for (int i = 0; i < px; i++) {
			std::stringstream sstm;
			sstm << output << "vol_" << setfill('0') << setw(7) << i << ".dat";
			string outputName = sstm.str();
			myIntensity.slice(i).save(outputName,raw_ascii);
			// empty voxels
			std::stringstream sstm1;
			sstm1 << output << "volGoodVoxels_" << setfill('0') << setw(7) << i << ".dat";
			string outputName1 = sstm1.str();
			fmat goodVoxels = sign(myWeight.slice(i));
			goodVoxels.save(outputName1,raw_ascii);
		}

    }
  	return 0;
}

<|endoftext|>


<commit_before>/*
 * THIS SHOULD BE RENAMED AS PROCESS_HKL.CPP
 */
#include <iostream>
#include <iomanip>
#include <sys/time.h>
#include <armadillo>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_errno.h>
#include <algorithm>
#include "detector.h"
#include "beam.h"
#include "particle.h"
#include "diffraction.h"
#include "toolbox.h"
#include "diffraction.cuh"
#include "io.h"
#include <fstream>
#include <string>

#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace arma;
using namespace detector;
using namespace beam;
using namespace particle;
using namespace diffraction;
using namespace toolbox;

#define USE_CUDA 0

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

    string imageList;
    string eulerList;
    string quaternionList;
    string rotationList;
    string beamFile;
    string geomFile;
    int numImages = 0;
    int mySize = 0;
    string output;
    // Let's parse input
    for (int n = 1; n < argc; n++) {
    cout << argv [ n ] << endl;
        if(boost::algorithm::iequals(argv[ n ], "-i")) {
            imageList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-e")) {
            eulerList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-q")) {
		    quaternionList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-r")) {
		    rotationList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-b")) {
            beamFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-g")) {
            geomFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "--num_images")) {
            numImages = atoi(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--vol_dim")) {
            mySize = atof(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--output_name")) {
            output = argv[ n+2 ];
        }
    }
    //cout << numImages << endl;
    //cout << inc_res << endl;
    // image.lst and euler.lst are not neccessarily in the same order! So can not use like this. Perhaps use hdf5 to combine the two.

	/****** Beam ******/
	// Let's read in our beam file
	double photon_energy = 0;
	string line;
	ifstream myFile(beamFile.c_str());
	while (getline(myFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"beam/photon_energy") ) {
                    string temp = *++tok_iter;
                    photon_energy = atof(temp.c_str()); // photon energy to wavelength
                    break;
                }
            }
        }
    }
	CBeam beam = CBeam();
	beam.set_photon_energy(photon_energy);

	/****** Detector ******/
    double d = 0;					// (m) detector distance
	double pix_width = 0;			// (m)
	int px_in = 0;                  // number of pixel along x
	string badpixmap = ""; // this information should go into the detector class
	// Parse the geom file
	ifstream myGeomFile(geomFile.c_str());
	while (getline(myGeomFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"geom/d") ) {
                    string temp = *++tok_iter;
                    d = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/pix_width") ) {
                    string temp = *++tok_iter;
                    pix_width = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/px") ) {
                    string temp = *++tok_iter;
                    px_in = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/badpixmap") ) {
                    string temp = *++tok_iter;
                    cout << temp << endl;
                    badpixmap = temp;
                    break;
                }
            }
        }
    }
	double pix_height = pix_width;		// (m)
	const int px = px_in;				// number of pixels in x
	const int py = px;					// number of pixels in y
	double cx = ((double) px-1)/2;		// this can be user defined
	double cy = ((double) py-1)/2;		// this can be user defined

	CDetector det = CDetector();
	det.set_detector_dist(d);
	det.set_pix_width(pix_width);
	det.set_pix_height(pix_height);
	det.set_numPix(py,px);
	det.set_center_x(cx);
	det.set_center_y(cy);
	det.set_pixelMap(badpixmap);
	det.init_dp(&beam);

    uvec goodpix;
    goodpix = det.get_goodPixelMap();
    //cout << "Good pix:" << goodpix << endl;

	double theta = atan((px/2*pix_height)/d);
	double qmax = 2/beam.get_wavelength()*sin(theta/2);
	double dmin = 1/(2*qmax);
	cout << "max q to the edge: " << qmax << " m^-1" << endl;
	cout << "Half period resolution: " << dmin << " m" << endl;

	if(!USE_CUDA) {

		int counter = 0;
		fmat pix;
		pix.zeros(det.numPix,3);
		for (int i = 0; i < px; i++) {
			for (int j = 0; j < py; j++) { // column-wise
				pix(counter,0) = det.q_xyz(j,i,0);
				pix(counter,1) = det.q_xyz(j,i,1);
				pix(counter,2) = det.q_xyz(j,i,2);
				counter++;
			}
		}
        fvec pix_mod;
		float pix_max;
		pix = pix * 1e-10; // (nm)
		pix_mod = sqrt(sum(pix%pix,1));
		pix_max = max(pix_mod);
        //cout << "pix_max: " << pix_max << endl;
        float inc_res = (mySize-1)/(2*pix_max);
        pix = pix * inc_res;
        pix_mod = sqrt(sum(pix%pix,1));
		pix_max = max(pix_mod);
		//cout << "pix_max: " << pix_max << endl;
        //pix = pix * 1e-10 * inc_res; // (A^-1)
		//int mySize = vol_dim;//2*ceil(pix_max)+1;
		//cout << "mySize: " << mySize << endl;

		// Determine number of image
		//int numImages = 3;

		/*
		cout << numImages << endl;

		// Read in stream file
		fcube Astar;
		Astar.zeros(3,3,numImages);

		for (int i = 0; i < numImages; i++) {
			std::stringstream sstm1;
			sstm1 << "/home/beams/EPIX34ID/yoon/singfel/dataShrine/euler" << i+1 << ".dat";
			string eulerName = sstm1.str();
			//cout << eulerName << endl;

			fvec euler;
			euler = load_asciiEuler(eulerName);
			fmat R;
			R = zeros<fmat>(3,3);
			float phi = euler(0);
			float theta = euler(1);
			float psi = euler(2);
			//cout << psi << endl;

			R(0,0) = cos(psi)*cos(phi) - cos(theta)*sin(phi)*sin(psi);
			R(0,1) = cos(psi)*sin(phi) + cos(theta)*cos(phi)*sin(psi);
			R(0,2) = sin(psi)*sin(theta);
			R(1,0) = -sin(psi)*cos(phi) - cos(theta)*sin(phi)*cos(psi);
			R(1,1) = -sin(psi)*sin(phi) + cos(theta)*cos(phi)*cos(psi);
			R(1,2) = cos(psi)*sin(theta);
			R(2,0) = sin(theta)*sin(phi);
			R(2,1) = -sin(theta)*cos(phi);
			R(2,2) = cos(theta);
			cout << R << endl;

			R = CToolbox::euler2rot3D(psi,theta,phi);
    		//R.print();

    		Astar.slice(i) = R;
		}
		//cout << "R: " << Astar.slice(0) << endl;
		*/

  		string filename;
  		//string datasetname = "/data/data";

  		fmat myDP;
  		//CDetector myDet;

  		//mat B;
  		//fmat temp;
  		fmat myR;
  		myR.zeros(3,3);
  		float psi,theta,phi;

		/*fmat pixRot;
		pixRot.zeros(det.numPix,3);
		imat myGrid;
		myGrid.zeros(det.numPix,3);
		fmat fxyz;
		fxyz.zeros(det.numPix,3);
		fmat cxyz;
		cxyz.zeros(det.numPix,3);
		*/
		fcube myWeight;
		myWeight.zeros(mySize,mySize,mySize);
		fcube myIntensity;
		myIntensity.zeros(mySize,mySize,mySize);

		cout << "Start" << endl;
		//cout << mySize << endl;

		int active = 1;
		string interpolate = "linear";// "nearest";

  		for (int r = 0; r < 1; r++) {//(int r = 0; r < numImages; r++) {
	  		// Get image
	  		std::stringstream sstm;
  			sstm << imageList << setfill('0') << setw(7) << r << ".dat";
			filename = sstm.str();
			cout << filename << endl;
			myDP = load_asciiImage(filename);
			//myDet.apply_badPixels();
			//cout << "myDP(0): " << myDP(0) << endl; // 0
			//cout << "myDP(1): " << myDP(1) << endl; // 2.94
			//cout << "myDP(130): " << myDP(130) << endl; // 5.08 <-- mask out
	        // Get rotation matrix
  			std::stringstream sstm1;
			sstm1 << rotationList << setfill('0') << setw(7) << r << ".dat";
			string rotationName = sstm1.str();
			cout << rotationName << endl;
			myR = load_asciiRotation(rotationName);
			//fvec euler;
			//psi = euler(0);
			//theta = euler(1);
			//phi = euler(2);
			//euler.print("euler:");
			myR = eye<fmat>(3,3);
			//myR = CToolbox::euler2rot3D(psi,theta,phi); // WARNING: euler2rot3D changed sign 24/7/14
			myR.print("myR: ");
			//myR = trans(myR);

        	CToolbox::merge3D(&myDP, &pix, &goodpix, &myR, pix_max, &myIntensity, &myWeight, active, interpolate);

  		}
  		// Normalize here
  		CToolbox::normalize(&myIntensity,&myWeight);

  		// ########### Save diffraction volume ##############
		for (int i = 0; i < mySize; i++) {
			std::stringstream sstm;
			sstm << output << "vol_" << setfill('0') << setw(7) << i << ".dat";
			string outputName = sstm.str();
			myIntensity.slice(i).save(outputName,raw_ascii);
		}

    }

	//cout << "Total time: " <<timerMaster.toc()<<" seconds."<<endl;

  	return 0;

}

<commit_msg>added sqrt(2) for proper size<commit_after>/*
 * THIS SHOULD BE RENAMED AS PROCESS_HKL.CPP
 */
#include <iostream>
#include <iomanip>
#include <sys/time.h>
#include <armadillo>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_errno.h>
#include <algorithm>
#include "detector.h"
#include "beam.h"
#include "particle.h"
#include "diffraction.h"
#include "toolbox.h"
#include "diffraction.cuh"
#include "io.h"
#include <fstream>
#include <string>

#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace arma;
using namespace detector;
using namespace beam;
using namespace particle;
using namespace diffraction;
using namespace toolbox;

#define USE_CUDA 0

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

    string imageList;
    string eulerList;
    string quaternionList;
    string rotationList;
    string beamFile;
    string geomFile;
    int numImages = 0;
    int mySize = 0;
    string output;
    // Let's parse input
    for (int n = 1; n < argc; n++) {
    cout << argv [ n ] << endl;
        if(boost::algorithm::iequals(argv[ n ], "-i")) {
            imageList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-e")) {
            eulerList = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-q")) {
		    quaternionList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-r")) {
		    rotationList = argv[ n+1 ];
		} else if (boost::algorithm::iequals(argv[ n ], "-b")) {
            beamFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "-g")) {
            geomFile = argv[ n+1 ];
        } else if (boost::algorithm::iequals(argv[ n ], "--num_images")) {
            numImages = atoi(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--vol_dim")) {
            mySize = atof(argv[ n+2 ]);
        } else if (boost::algorithm::iequals(argv[ n ], "--output_name")) {
            output = argv[ n+2 ];
        }
    }
    //cout << numImages << endl;
    //cout << inc_res << endl;
    // image.lst and euler.lst are not neccessarily in the same order! So can not use like this. Perhaps use hdf5 to combine the two.

	/****** Beam ******/
	// Let's read in our beam file
	double photon_energy = 0;
	string line;
	ifstream myFile(beamFile.c_str());
	while (getline(myFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"beam/photon_energy") ) {
                    string temp = *++tok_iter;
                    photon_energy = atof(temp.c_str()); // photon energy to wavelength
                    break;
                }
            }
        }
    }
	CBeam beam = CBeam();
	beam.set_photon_energy(photon_energy);

	/****** Detector ******/
    double d = 0;					// (m) detector distance
	double pix_width = 0;			// (m)
	int px_in = 0;                  // number of pixel along x
	string badpixmap = ""; // this information should go into the detector class
	// Parse the geom file
	ifstream myGeomFile(geomFile.c_str());
	while (getline(myGeomFile, line)) {
        if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
            // line now contains a valid input
            cout << line << endl;
            typedef boost::tokenizer<boost::char_separator<char> > Tok;
            boost::char_separator<char> sep(" ="); // default constructed
            Tok tok(line, sep);
            for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
                if ( boost::algorithm::iequals(*tok_iter,"geom/d") ) {
                    string temp = *++tok_iter;
                    d = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/pix_width") ) {
                    string temp = *++tok_iter;
                    pix_width = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/px") ) {
                    string temp = *++tok_iter;
                    px_in = atof(temp.c_str());
                    break;
                } else if ( boost::algorithm::iequals(*tok_iter,"geom/badpixmap") ) {
                    string temp = *++tok_iter;
                    cout << temp << endl;
                    badpixmap = temp;
                    break;
                }
            }
        }
    }
	double pix_height = pix_width;		// (m)
	const int px = px_in;				// number of pixels in x
	const int py = px;					// number of pixels in y
	double cx = ((double) px-1)/2;		// this can be user defined
	double cy = ((double) py-1)/2;		// this can be user defined

	CDetector det = CDetector();
	det.set_detector_dist(d);
	det.set_pix_width(pix_width);
	det.set_pix_height(pix_height);
	det.set_numPix(py,px);
	det.set_center_x(cx);
	det.set_center_y(cy);
	det.set_pixelMap(badpixmap);
	det.init_dp(&beam);

    uvec goodpix;
    goodpix = det.get_goodPixelMap();
    //cout << "Good pix:" << goodpix << endl;

	double theta = atan((px/2*pix_height)/d);
	double qmax = 2/beam.get_wavelength()*sin(theta/2);
	double dmin = 1/(2*qmax);
	cout << "max q to the edge: " << qmax << " m^-1" << endl;
	cout << "Half period resolution: " << dmin << " m" << endl;

	if(!USE_CUDA) {

		int counter = 0;
		fmat pix;
		pix.zeros(det.numPix,3);
		for (int i = 0; i < px; i++) {
			for (int j = 0; j < py; j++) { // column-wise
				pix(counter,0) = det.q_xyz(j,i,0);
				pix(counter,1) = det.q_xyz(j,i,1);
				pix(counter,2) = det.q_xyz(j,i,2);
				counter++;
			}
		}
        fvec pix_mod;
		float pix_max;
		pix = pix * 1e-10; // (nm)
		pix_mod = sqrt(sum(pix%pix,1));
		pix_max = max(pix_mod);
        //cout << "pix_max: " << pix_max << endl;
        float inc_res = (mySize-1)/(2*pix_max/sqrt(2));
        pix = pix * inc_res;
        pix_mod = sqrt(sum(pix%pix,1));
		pix_max = cx;//max(pix_mod);
		//cout << "pix_max: " << pix_max << endl;
        //pix = pix * 1e-10 * inc_res; // (A^-1)
		//int mySize = vol_dim;//2*ceil(pix_max)+1;
		//cout << "mySize: " << mySize << endl;

		// Determine number of image
		//int numImages = 3;

		/*
		cout << numImages << endl;

		// Read in stream file
		fcube Astar;
		Astar.zeros(3,3,numImages);

		for (int i = 0; i < numImages; i++) {
			std::stringstream sstm1;
			sstm1 << "/home/beams/EPIX34ID/yoon/singfel/dataShrine/euler" << i+1 << ".dat";
			string eulerName = sstm1.str();
			//cout << eulerName << endl;

			fvec euler;
			euler = load_asciiEuler(eulerName);
			fmat R;
			R = zeros<fmat>(3,3);
			float phi = euler(0);
			float theta = euler(1);
			float psi = euler(2);
			//cout << psi << endl;

			R(0,0) = cos(psi)*cos(phi) - cos(theta)*sin(phi)*sin(psi);
			R(0,1) = cos(psi)*sin(phi) + cos(theta)*cos(phi)*sin(psi);
			R(0,2) = sin(psi)*sin(theta);
			R(1,0) = -sin(psi)*cos(phi) - cos(theta)*sin(phi)*cos(psi);
			R(1,1) = -sin(psi)*sin(phi) + cos(theta)*cos(phi)*cos(psi);
			R(1,2) = cos(psi)*sin(theta);
			R(2,0) = sin(theta)*sin(phi);
			R(2,1) = -sin(theta)*cos(phi);
			R(2,2) = cos(theta);
			cout << R << endl;

			R = CToolbox::euler2rot3D(psi,theta,phi);
    		//R.print();

    		Astar.slice(i) = R;
		}
		//cout << "R: " << Astar.slice(0) << endl;
		*/

  		string filename;
  		//string datasetname = "/data/data";

  		fmat myDP;
  		//CDetector myDet;

  		//mat B;
  		//fmat temp;
  		fmat myR;
  		myR.zeros(3,3);
  		float psi,theta,phi;

		/*fmat pixRot;
		pixRot.zeros(det.numPix,3);
		imat myGrid;
		myGrid.zeros(det.numPix,3);
		fmat fxyz;
		fxyz.zeros(det.numPix,3);
		fmat cxyz;
		cxyz.zeros(det.numPix,3);
		*/
		fcube myWeight;
		myWeight.zeros(mySize,mySize,mySize);
		fcube myIntensity;
		myIntensity.zeros(mySize,mySize,mySize);

		cout << "Start" << endl;
		//cout << mySize << endl;

		int active = 1;
		string interpolate = "linear";// "nearest";

  		for (int r = 0; r < 1; r++) {//(int r = 0; r < numImages; r++) {
	  		// Get image
	  		std::stringstream sstm;
  			sstm << imageList << setfill('0') << setw(7) << r << ".dat";
			filename = sstm.str();
			cout << filename << endl;
			myDP = load_asciiImage(filename);
			//myDet.apply_badPixels();
			//cout << "myDP(0): " << myDP(0) << endl; // 0
			//cout << "myDP(1): " << myDP(1) << endl; // 2.94
			//cout << "myDP(130): " << myDP(130) << endl; // 5.08 <-- mask out
	        // Get rotation matrix
  			std::stringstream sstm1;
			sstm1 << rotationList << setfill('0') << setw(7) << r << ".dat";
			string rotationName = sstm1.str();
			cout << rotationName << endl;
			myR = load_asciiRotation(rotationName);
			//fvec euler;
			//psi = euler(0);
			//theta = euler(1);
			//phi = euler(2);
			//euler.print("euler:");
			myR = eye<fmat>(3,3);
			//myR = CToolbox::euler2rot3D(psi,theta,phi); // WARNING: euler2rot3D changed sign 24/7/14
			myR.print("myR: ");
			//myR = trans(myR);

        	CToolbox::merge3D(&myDP, &pix, &goodpix, &myR, pix_max, &myIntensity, &myWeight, active, interpolate);

  		}
  		// Normalize here
  		CToolbox::normalize(&myIntensity,&myWeight);

  		// ########### Save diffraction volume ##############
		for (int i = 0; i < mySize; i++) {
			std::stringstream sstm;
			sstm << output << "vol_" << setfill('0') << setw(7) << i << ".dat";
			string outputName = sstm.str();
			myIntensity.slice(i).save(outputName,raw_ascii);
		}

    }

	//cout << "Total time: " <<timerMaster.toc()<<" seconds."<<endl;

  	return 0;

}

<|endoftext|>


<commit_before>#include "RobotArm.h"
#include "CommandLogger.h"
#include "CommandTracer.h"
#include "PeriodicCommand.h"
#include "SequentialCommands.h"
#include "ParallelCommands.h"
#include "TimeLimitedCommand.h"
#include "RetryableCommand.h"
#include "CommandTimeoutException.h"
#include "ReportPositionCommand.h"
#include "MoveRobotArmCommand.h"
#include <iostream>
#include <algorithm>

// This application demonstrates how to wrap an aysnchronous operation (Robot::Move) with an AsyncCommand-derived class,
// and makes use of ParallelCommands, SequentialCommands, PeriodicCommand, TimeLimitedCommand and RetryableCommand.
class RetryHandler : public CommandLib::RetryableCommand::RetryCallback
{
public:
	virtual bool OnCommandFailed(size_t, const std::exception& reason, long long* waitTimeMS) override final
	{
		*waitTimeMS = 0;

		if (dynamic_cast<const CommandLib::CommandTimeoutException*>(&reason) != nullptr)
		{
			std::cout << "Would you like to give more time to move the robot arm to the origin (y/n)? ";
			char letter;
			std::cin >> letter;
			return letter == 'y';
		}

		return false;
	}
};

int main(int argc, char* argv[])
{
	try
	{
		std::unique_ptr<CommandLib::CommandLogger> logger;

		if (argc > 2)
		{
			// Output all the command activity to the file specified. This is a simple text file, and can be viewed using CommandLogViewer
			// from the C# CommandLib project.
			logger.reset(new CommandLib::CommandLogger(argv[1]));
			CommandLib::Command::sm_monitors.push_back(logger.get());
		}

		RobotArm robotArm(100, 126);

		// Create a command to move the robot arm to position 0,0
		MoveRobotArmCommand::Ptr moveToOriginCmd = MoveRobotArmCommand::Create(&robotArm, 0, 0);

		// Create a command to report the robot arm's position every second
		CommandLib::PeriodicCommand::Ptr periodicReportPositionCmd = CommandLib::PeriodicCommand::Create(
			ReportPositionCommand::Create(robotArm), // the command to execute
			std::numeric_limits<size_t>::max(), // no fixed upper limit on repetitions
			1000, // execute the command every second
			CommandLib::PeriodicCommand::IntervalType::PauseBefore, // wait a second before executing the command the first time
			true, // the second to wait is inclusive of the time it actually takes to report the position
			moveToOriginCmd->DoneEvent()); // stop when this command is finished (in other words, when both robots reach 0,0)

		// Create a command that will concurrently move the robot arm and periodically report its position
		CommandLib::ParallelCommands::Ptr moveAndReportCmd = CommandLib::ParallelCommands::Create(true);
		moveAndReportCmd->Add(moveToOriginCmd);
		moveAndReportCmd->Add(periodicReportPositionCmd);

		// Create a command that will first report the starting position, then perform the simulataneous move
		// and position reporting, then report the final position.
		CommandLib::SequentialCommands::Ptr moveAndGreetCmd = CommandLib::SequentialCommands::Create();
		moveAndGreetCmd->Add(ReportPositionCommand::Create(robotArm));
		moveAndGreetCmd->Add(moveAndReportCmd);
		moveAndGreetCmd->Add(ReportPositionCommand::Create(robotArm));

		// Wrap the above command in a command that throws a TimeoutException if it takes longer than 20 seconds.
		CommandLib::TimeLimitedCommand::Ptr timeLimitedCmd = CommandLib::TimeLimitedCommand::Create(moveAndGreetCmd, 20000);

		// Allow retries, because we will time out
		RetryHandler retryHandler;
		CommandLib::RetryableCommand::Ptr retryableCmd = CommandLib::RetryableCommand::Create(timeLimitedCmd, &retryHandler);

		// Execute our top-level command. Every command created by this app is a ultimately owned by this command.
		try
		{
			retryableCmd->SyncExecute();
			std::cout << "Robot arm successfully moved to the origin" << std::endl;
		}
		catch (std::exception& err)
		{
			std::cerr << err.what() << std::endl;
		}

		return 0;
	}
	catch (std::exception& exc)
	{
		std::cerr << exc.what() << std::endl;
		throw;
	}
}
<commit_msg>Updated some comments<commit_after>#include "RobotArm.h"
#include "CommandLogger.h"
#include "CommandTracer.h"
#include "PeriodicCommand.h"
#include "SequentialCommands.h"
#include "ParallelCommands.h"
#include "TimeLimitedCommand.h"
#include "RetryableCommand.h"
#include "CommandTimeoutException.h"
#include "ReportPositionCommand.h"
#include "MoveRobotArmCommand.h"
#include <iostream>
#include <algorithm>

// This application demonstrates how to wrap an aysnchronous operation (RobotArm::Move) with an AsyncCommand-derived class,
// and makes use of ParallelCommands, SequentialCommands, PeriodicCommand, TimeLimitedCommand and RetryableCommand.
class RetryHandler : public CommandLib::RetryableCommand::RetryCallback
{
public:
	virtual bool OnCommandFailed(size_t, const std::exception& reason, long long* waitTimeMS) override final
	{
		*waitTimeMS = 0;

		if (dynamic_cast<const CommandLib::CommandTimeoutException*>(&reason) != nullptr)
		{
			std::cout << "Would you like to give more time to move the robot arm to the origin (y/n)? ";
			char letter;
			std::cin >> letter;
			return letter == 'y';
		}

		return false;
	}
};

int main(int argc, char* argv[])
{
	try
	{
		std::unique_ptr<CommandLib::CommandLogger> logger;

		if (argc > 2)
		{
			// Output all the command activity to the file specified. This is a simple text file, and can be viewed using CommandLogViewer
			// from the C# CommandLib project.
			logger.reset(new CommandLib::CommandLogger(argv[1]));
			CommandLib::Command::sm_monitors.push_back(logger.get());
		}

		RobotArm robotArm(100, 126);

		// Create a command to move the robot arm to position 0,0
		MoveRobotArmCommand::Ptr moveToOriginCmd = MoveRobotArmCommand::Create(&robotArm, 0, 0);

		// Create a command to report the robot arm's position every second
		CommandLib::PeriodicCommand::Ptr periodicReportPositionCmd = CommandLib::PeriodicCommand::Create(
			ReportPositionCommand::Create(robotArm), // the command to execute
			std::numeric_limits<size_t>::max(), // no fixed upper limit on repetitions
			1000, // execute the command every second
			CommandLib::PeriodicCommand::IntervalType::PauseBefore, // wait a second before executing the command the first time
			true, // the second to wait is inclusive of the time it actually takes to report the position
			moveToOriginCmd->DoneEvent()); // stop when this command is finished (in other words, when both robots reach 0,0)

		// Create a command that will concurrently move the robot arm and periodically report its position
		CommandLib::ParallelCommands::Ptr moveAndReportCmd = CommandLib::ParallelCommands::Create(true);
		moveAndReportCmd->Add(moveToOriginCmd);
		moveAndReportCmd->Add(periodicReportPositionCmd);

		// Create a command that will first report the starting position, then perform the simulataneous move
		// and position reporting, then report the final position.
		CommandLib::SequentialCommands::Ptr moveAndGreetCmd = CommandLib::SequentialCommands::Create();
		moveAndGreetCmd->Add(ReportPositionCommand::Create(robotArm));
		moveAndGreetCmd->Add(moveAndReportCmd);
		moveAndGreetCmd->Add(ReportPositionCommand::Create(robotArm));

		// Wrap the above command in a command that throws a TimeoutException if it takes longer than 20 seconds.
		CommandLib::TimeLimitedCommand::Ptr timeLimitedCmd = CommandLib::TimeLimitedCommand::Create(moveAndGreetCmd, 20000);

		// Allow retries, because we will time out
		RetryHandler retryHandler;
		CommandLib::RetryableCommand::Ptr retryableCmd = CommandLib::RetryableCommand::Create(timeLimitedCmd, &retryHandler);

		// Execute our top-level command. Every command created by this app is a ultimately owned by this command.
		try
		{
			retryableCmd->SyncExecute();
			std::cout << "Robot arm successfully moved to the origin" << std::endl;
		}
		catch (std::exception& err)
		{
			std::cerr << err.what() << std::endl;
		}

		return 0;
	}
	catch (std::exception& exc)
	{
		std::cerr << exc.what() << std::endl;
		throw;
	}
}
<|endoftext|>


<commit_before>#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QFile>
#include <QMenu>
#include <QTreeWidget>

#include "about.h"
#include "settings.h"
#include "ipobjects.h"
#include "messenger.h"
#include "messagedialog.h"
#include "qommunicate.h"

Qommunicate::Qommunicate(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    createTrayIcon();

    MemberUtils::init();
    populateTree();
    firstRun();
    messenger()->login();

    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));

    connect(messenger(), SIGNAL(msg_ansEntry(Message)), this, SLOT(addMember(Message)));
    connect(messenger(), SIGNAL(msg_entry(Message)), this, SLOT(addMemberAndAnswer(Message)));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(openDialog(Message)));
}

void Qommunicate::on_searchEdit_textChanged(const QString &text)
{
    filterModel->setFilterFixedString(text);
    ui.memberTree->expandAll();
}

void Qommunicate::on_action_About_triggered()
{
    AboutDialog(this).exec();
}

void Qommunicate::on_action_Settings_triggered()
{
    SettingsDialog(this).exec();
}

void Qommunicate::on_actionMulticast_triggered()
{
    MessageDialog dlg;
    dlg.setModal(false);
    dlg.exec();
}

void Qommunicate::on_actionQuit_triggered()
{
    qApp->quit();
}

void Qommunicate::closeEvent(QCloseEvent * event)
{
    setVisible(false);
    event->ignore();
}

void Qommunicate::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if( reason == QSystemTrayIcon::Trigger )
        setVisible(!isVisible());
}

void Qommunicate::createTrayIcon()
{
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(windowIcon());

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    QMenu *menu = new QMenu;
    menu->addAction(ui.actionMulticast);
    menu->addAction(ui.actionQuit);
    trayIcon->setContextMenu(menu);

    trayIcon->show();
}

void Qommunicate::populateTree()
{
    model = new MemberModel(this);
    filterModel = new MemberFilter(this);

    QStandardItem *parent = model->invisibleRootItem();
    for(int i = 0; i < 5 ; i++) {
        parent->appendRow( new Group(QString("group %1").arg(i)) );
    }

    model->item(2)->appendRow( new Member("nsm", "ironik", "192.168.0.2", "Available") );
    model->item(0)->appendRow( new Member("nikhil", "jupiter", "192.168.0.5", "Available"));
    model->item(0)->appendRow( new Member("canada", "montreal", "192.168.23.5", "Available"));

    filterModel->setSourceModel(model);
    filterModel->setDynamicSortFilter(true);

    ui.memberTree->setSelectionMode(ui.memberTree->ExtendedSelection);
    ui.memberTree->setModel(filterModel);
    ui.memberTree->setHeaderHidden(true);
    ui.memberTree->setExpandsOnDoubleClick(false);
    ui.memberTree->expandAll();
}

/*
If item is a group, adds all submembers to receivers and returns true.
otherwise assumes item is a member, inserts in receivers and returns false
*/
bool Qommunicate::createGroupMemberList(QStandardItem* item, QSet<Member*>& receivers)
{
    if(item->type() == TYPE_GROUP)
    {
        if(!item->hasChildren())
            return true;

        for(int i = 0; i < item->rowCount(); i++)
        {
            receivers << (Member*)item->child(i, 0);
        }
        return true;
    }
    receivers << (Member*)item;
    return false;
}

void Qommunicate::on_memberTree_doubleClicked(const QModelIndex& proxyIndex)
{

    MessageDialog* dlg;
    QSet<Member*> receivers;

    MemberModel* model = (MemberModel*) ( (MemberFilter*) ui.memberTree->model() )->sourceModel();
    QModelIndex index = ((MemberFilter*)ui.memberTree->model())->mapToSource(proxyIndex);

    if(index.isValid())
    {
        // only single item clicked
        createGroupMemberList(model->itemFromIndex(index), receivers);
    }
    else
    {
        QModelIndex i;
        foreach(i, ui.memberTree->selectionModel()->selectedRows())
        {
            QStandardItem* item = model->itemFromIndex(((MemberFilter*)ui.memberTree->model())->mapToSource(i));
            createGroupMemberList(item, receivers);
        }
    }

    if(receivers.isEmpty())
        return;

    QList<Member*> toDialog = receivers.toList();
    if(toDialog.size() == 1 && MemberUtils::contains("open_conversations", toDialog[0]))
        return;

    if(toDialog.size() == 1)
    {
        if(!MemberUtils::contains("open_conversations", toDialog[0]))
            dlg = new MessageDialog( toDialog[0], this );
    }
    else
        dlg = new MessageDialog( toDialog, this );

    dlg->setModal(false);
    dlg->show();
}

void Qommunicate::on_statusCombo_currentIndexChanged(const QString& text)
{
    //TODO: status change
}

void Qommunicate::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return) {
        event->accept();
        on_memberTree_doubleClicked(QModelIndex());
        return;
    }
    event->ignore();
}

void Qommunicate::firstRun()
{
    QSettings s;
    if( ! s.contains(tr("nick")) )
        ui.action_Settings->trigger();
}

void Qommunicate::dialogOpened(Member* m)
{
    MemberUtils::insert("open_conversations", m);
}

void Qommunicate::dialogClosed(Member *m)
{
    MemberUtils::remove("open_conversations", m);
}

void Qommunicate::cleanup()
{
    messenger()->logout();
    delete messenger();
}

// Message handling slots
void Qommunicate::addMember(Message msg)
{
    msg.sender()->setName(msg.payload().split('\a')[0]);
    model->appendRow(msg.sender());
}

void Qommunicate::addMemberAndAnswer(Message msg)
{
    addMember(msg);
    messenger()->sendMessage(QOM_ANSENTRY, me().name()+'\0'+myGroup().name(), msg.sender());
}

void Qommunicate::openDialog(Message msg)
{
    if(MemberUtils::contains("open_conversations", msg.sender()))
        return;

    Member* with = MemberUtils::get("members_list", msg.sender());
    if(!with->isValid())
        with = msg.sender();
    MessageDialog *dlg = new MessageDialog(with, this);
    dlg->setModal(false);
    dlg->show();
    dlg->incomingMessage(msg);
}<commit_msg>Removed fake tree entries<commit_after>#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QFile>
#include <QMenu>
#include <QTreeWidget>

#include "about.h"
#include "settings.h"
#include "ipobjects.h"
#include "messenger.h"
#include "messagedialog.h"
#include "qommunicate.h"

Qommunicate::Qommunicate(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    createTrayIcon();

    MemberUtils::init();
    populateTree();
    firstRun();
    messenger()->login();

    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));

    connect(messenger(), SIGNAL(msg_ansEntry(Message)), this, SLOT(addMember(Message)));
    connect(messenger(), SIGNAL(msg_entry(Message)), this, SLOT(addMemberAndAnswer(Message)));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(openDialog(Message)));
}

void Qommunicate::on_searchEdit_textChanged(const QString &text)
{
    filterModel->setFilterFixedString(text);
    ui.memberTree->expandAll();
}

void Qommunicate::on_action_About_triggered()
{
    AboutDialog(this).exec();
}

void Qommunicate::on_action_Settings_triggered()
{
    SettingsDialog(this).exec();
}

void Qommunicate::on_actionMulticast_triggered()
{
    MessageDialog dlg(this);
    dlg.exec();
}

void Qommunicate::on_actionQuit_triggered()
{
    qApp->quit();
}

void Qommunicate::closeEvent(QCloseEvent * event)
{
    setVisible(false);
    event->ignore();
}

void Qommunicate::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    if( reason == QSystemTrayIcon::Trigger )
        setVisible(!isVisible());
}

void Qommunicate::createTrayIcon()
{
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(windowIcon());

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

    QMenu *menu = new QMenu;
    menu->addAction(ui.actionMulticast);
    menu->addAction(ui.actionQuit);
    trayIcon->setContextMenu(menu);

    trayIcon->show();
}

void Qommunicate::populateTree()
{
    model = new MemberModel(this);
    filterModel = new MemberFilter(this);

    filterModel->setSourceModel(model);
    filterModel->setDynamicSortFilter(true);

    ui.memberTree->setSelectionMode(ui.memberTree->ExtendedSelection);
    ui.memberTree->setModel(filterModel);
    ui.memberTree->setHeaderHidden(true);
    ui.memberTree->setExpandsOnDoubleClick(false);
    ui.memberTree->expandAll();
}

/*
If item is a group, adds all submembers to receivers and returns true.
otherwise assumes item is a member, inserts in receivers and returns false
*/
bool Qommunicate::createGroupMemberList(QStandardItem* item, QSet<Member*>& receivers)
{
    if(item->type() == TYPE_GROUP)
    {
        if(!item->hasChildren())
            return true;

        for(int i = 0; i < item->rowCount(); i++)
        {
            receivers << (Member*)item->child(i, 0);
        }
        return true;
    }
    receivers << (Member*)item;
    return false;
}

void Qommunicate::on_memberTree_doubleClicked(const QModelIndex& proxyIndex)
{

    MessageDialog* dlg;
    QSet<Member*> receivers;

    MemberModel* model = (MemberModel*) ( (MemberFilter*) ui.memberTree->model() )->sourceModel();
    QModelIndex index = ((MemberFilter*)ui.memberTree->model())->mapToSource(proxyIndex);

    if(index.isValid())
    {
        // only single item clicked
        createGroupMemberList(model->itemFromIndex(index), receivers);
    }
    else
    {
        QModelIndex i;
        foreach(i, ui.memberTree->selectionModel()->selectedRows())
        {
            QStandardItem* item = model->itemFromIndex(((MemberFilter*)ui.memberTree->model())->mapToSource(i));
            createGroupMemberList(item, receivers);
        }
    }

    if(receivers.isEmpty())
        return;

    QList<Member*> toDialog = receivers.toList();
    if(toDialog.size() == 1 && MemberUtils::contains("open_conversations", toDialog[0]))
        return;

    if(toDialog.size() == 1)
    {
        if(!MemberUtils::contains("open_conversations", toDialog[0]))
            dlg = new MessageDialog( toDialog[0], this );
    }
    else
        dlg = new MessageDialog( toDialog, this );

    dlg->setModal(false);
    dlg->show();
}

void Qommunicate::on_statusCombo_currentIndexChanged(const QString& text)
{
    //TODO: status change
}

void Qommunicate::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return) {
        event->accept();
        on_memberTree_doubleClicked(QModelIndex());
        return;
    }
    event->ignore();
}

void Qommunicate::firstRun()
{
    QSettings s;
    if( ! s.contains(tr("nick")) )
        ui.action_Settings->trigger();
}

void Qommunicate::dialogOpened(Member* m)
{
    MemberUtils::insert("open_conversations", m);
}

void Qommunicate::dialogClosed(Member *m)
{
    MemberUtils::remove("open_conversations", m);
}

void Qommunicate::cleanup()
{
    messenger()->logout();
    delete messenger();
}

// Message handling slots
void Qommunicate::addMember(Message msg)
{
    msg.sender()->setName(msg.payload().split('\a')[0]);
    model->appendRow(msg.sender());
}

void Qommunicate::addMemberAndAnswer(Message msg)
{
    addMember(msg);
    messenger()->sendMessage(QOM_ANSENTRY, me().name()+'\0'+myGroup().name(), msg.sender());
}

void Qommunicate::openDialog(Message msg)
{
    if(MemberUtils::contains("open_conversations", msg.sender()))
        return;

    Member* with = MemberUtils::get("members_list", msg.sender());
    if(!with->isValid())
        with = msg.sender();
    MessageDialog *dlg = new MessageDialog(with, this);
    dlg->setModal(false);
    dlg->show();
    dlg->incomingMessage(msg);
}<|endoftext|>


<commit_before>#include "qrctoken.h"
#include "ui_qrctoken.h"
#include "tokenitemmodel.h"
#include "walletmodel.h"
#include "tokentransactionview.h"
#include "platformstyle.h"
#include "styleSheet.h"

#include <QPainter>
#include <QAbstractItemDelegate>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QSizePolicy>
#include <QMenu>

#define TOKEN_SIZE 54
#define SYMBOL_WIDTH 60
#define MARGIN 5
#define SELECTION_WIDTH 4

class TokenViewDelegate : public QAbstractItemDelegate
{
public:

    TokenViewDelegate(const PlatformStyle *_platformStyle, QObject *parent) :
        QAbstractItemDelegate(parent),
        platformStyle(_platformStyle)
    {}

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const
    {
        painter->save();

        QIcon tokenIcon = platformStyle->TextColorIcon(":/icons/token");
        QString tokenSymbol = index.data(TokenItemModel::SymbolRole).toString();
        QString tokenBalance = index.data(TokenItemModel::BalanceRole).toString();
        QString receiveAddress = index.data(TokenItemModel::SenderRole).toString();

        QRect mainRect = option.rect;
        painter->fillRect(mainRect, QColor("#2e2e2e"));

        QRect selectionRect(mainRect.topLeft(), QSize(SELECTION_WIDTH, mainRect.height()));
        bool selected = option.state & QStyle::State_Selected;
        if(selected)
        {
            painter->fillRect(selectionRect,QColor("#078dc9"));
        }
        else
        {
            painter->fillRect(selectionRect,QColor("#2e2e2e"));
        }

        QColor foreground("#bebebe");
        painter->setPen(foreground);

        int decorationSize = TOKEN_SIZE - 20;
        int leftTopMargin = 10;
        QRect decorationRect(selectionRect.topRight() + QPoint(leftTopMargin, leftTopMargin), QSize(decorationSize, decorationSize));
        tokenIcon.paint(painter, decorationRect);

        QFontMetrics fmName(option.font);
        QString clippedSymbol = fmName.elidedText(tokenSymbol, Qt::ElideRight, SYMBOL_WIDTH);
        QRect tokenSymbolRect(decorationRect.right() + MARGIN, decorationRect.top(), SYMBOL_WIDTH, decorationSize / 2);
        painter->drawText(tokenSymbolRect, Qt::AlignLeft|Qt::AlignTop, clippedSymbol);

        QFont font = option.font;
        font.setBold(true);
        painter->setFont(font);
        QColor amounColor("#ffffff");
        painter->setPen(amounColor);
        int amountWidth = (mainRect.width() - SELECTION_WIDTH - decorationRect.width() - 2 * MARGIN - tokenSymbolRect.width() - leftTopMargin);
        QFontMetrics fmAmount(font);
        QString clippedAmount = fmAmount.elidedText(tokenBalance, Qt::ElideRight, amountWidth);
        QRect tokenBalanceRect(tokenSymbolRect.right(), decorationRect.top(), amountWidth, decorationSize / 2);
        painter->drawText(tokenBalanceRect, Qt::AlignRight|Qt::AlignTop, clippedAmount);

        QFont addressFont = option.font;
        addressFont.setPointSizeF(option.font.pointSizeF() * 0.8);
        painter->setFont(addressFont);
        painter->setPen(foreground);
        int receiveAddressWidth = (mainRect.width() - SELECTION_WIDTH - decorationRect.width() - 2 * MARGIN - leftTopMargin);
        QRect receiveAddressRect(decorationRect.right() + MARGIN, tokenSymbolRect.bottom(), receiveAddressWidth, decorationSize / 2);
        painter->drawText(receiveAddressRect, Qt::AlignLeft|Qt::AlignBottom, receiveAddress);

        painter->restore();
    }

    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(TOKEN_SIZE, TOKEN_SIZE);
    }

    const PlatformStyle *platformStyle;
};

QRCToken::QRCToken(const PlatformStyle *platformStyle, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QRCToken),
    m_model(0),
    m_clientModel(0),
    m_tokenModel(0),
    m_tokenDelegate(0),
    m_tokenTransactionView(0)
{
    ui->setupUi(this);

    SetObjectStyleSheet(ui->tokensList, StyleSheetNames::ScrollBarDark);

    m_platformStyle = platformStyle;

    m_sendTokenPage = new SendTokenPage(this);
    m_receiveTokenPage = new ReceiveTokenPage(this);
    m_addTokenPage = new AddTokenPage(this);
    m_tokenDelegate = new TokenViewDelegate(platformStyle, this);

    m_sendTokenPage->setEnabled(false);
    m_receiveTokenPage->setEnabled(false);

    ui->stackedWidgetToken->addWidget(m_sendTokenPage);
    ui->stackedWidgetToken->addWidget(m_receiveTokenPage);
    ui->stackedWidgetToken->addWidget(m_addTokenPage);

    m_tokenTransactionView = new TokenTransactionView(m_platformStyle, this);
    m_tokenTransactionView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    ui->tokenViewLayout->addWidget(m_tokenTransactionView);

    ui->tokensList->setItemDelegate(m_tokenDelegate);
    ui->tokensList->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->tokensList->setAttribute(Qt::WA_MacShowFocusRect, false);

    QAction *copySenderAction = new QAction(tr("Copy receive address"), this);
    QAction *copyTokenBalanceAction = new QAction(tr("Copy token balance"), this);
    QAction *copyTokenNameAction = new QAction(tr("Copy token name"), this);
    QAction *copyTokenAddressAction = new QAction(tr("Copy contract address"), this);
    QAction *removeTokenAction = new QAction(tr("Remove token"), this);

    contextMenu = new QMenu(ui->tokensList);
    contextMenu->addAction(copySenderAction);
    contextMenu->addAction(copyTokenBalanceAction);
    contextMenu->addAction(copyTokenNameAction);
    contextMenu->addAction(copyTokenAddressAction);
    contextMenu->addAction(removeTokenAction);

    connect(copyTokenAddressAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenAddress()));
    connect(copyTokenBalanceAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenBalance()));
    connect(copyTokenNameAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenName()));
    connect(copySenderAction, SIGNAL(triggered(bool)), this, SLOT(copySenderAddress()));
    connect(removeTokenAction, SIGNAL(triggered(bool)), this, SLOT(removeToken()));

    connect(ui->tokensList, SIGNAL(clicked(QModelIndex)), this, SLOT(on_currentTokenChanged(QModelIndex)));
    connect(ui->tokensList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));

    on_goToSendTokenPage();
}

QRCToken::~QRCToken()
{
    delete ui;
}

void QRCToken::setModel(WalletModel *_model)
{
    m_model = _model;
    m_addTokenPage->setModel(m_model);
    m_sendTokenPage->setModel(m_model);
    m_tokenTransactionView->setModel(_model);
    if(m_model && m_model->getTokenItemModel())
    {
        // Sort tokens by symbol
        QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
        TokenItemModel* tokenModel = m_model->getTokenItemModel();
        proxyModel->setSourceModel(tokenModel);
        proxyModel->sort(1, Qt::AscendingOrder);
        m_tokenModel = proxyModel;

        // Set tokens model
        ui->tokensList->setModel(m_tokenModel);
        connect(ui->tokensList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(on_currentChanged(QModelIndex,QModelIndex)));

        // Set current token
        connect(m_tokenModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), SLOT(on_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        connect(m_tokenModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(on_rowsInserted(QModelIndex,int,int)));
        if(m_tokenModel->rowCount() > 0)
        {
            QModelIndex currentToken(m_tokenModel->index(0, 0));
            ui->tokensList->setCurrentIndex(currentToken);
            on_currentTokenChanged(currentToken);
        }
    }
}

void QRCToken::setClientModel(ClientModel *_clientModel)
{
    m_clientModel = _clientModel;
    m_sendTokenPage->setClientModel(_clientModel);
    m_addTokenPage->setClientModel(_clientModel);
}

void QRCToken::on_goToSendTokenPage()
{
    ui->stackedWidgetToken->setCurrentIndex(0);
}

void QRCToken::on_goToReceiveTokenPage()
{
    ui->stackedWidgetToken->setCurrentIndex(1);
}

void QRCToken::on_goToAddTokenPage()
{
    ui->stackedWidgetToken->setCurrentIndex(2);
}

void QRCToken::on_currentTokenChanged(QModelIndex index)
{
    if(m_tokenModel)
    {
        if(index.isValid())
        {
            m_selectedTokenHash = m_tokenModel->data(index, TokenItemModel::HashRole).toString();
            std::string address = m_tokenModel->data(index, TokenItemModel::AddressRole).toString().toStdString();
            std::string symbol = m_tokenModel->data(index, TokenItemModel::SymbolRole).toString().toStdString();
            std::string sender = m_tokenModel->data(index, TokenItemModel::SenderRole).toString().toStdString();
            int8_t decimals = m_tokenModel->data(index, TokenItemModel::DecimalsRole).toInt();
            std::string balance = m_tokenModel->data(index, TokenItemModel::RawBalanceRole).toString().toStdString();
            m_sendTokenPage->setTokenData(address, sender, symbol, decimals, balance);
            m_receiveTokenPage->setAddress(QString::fromStdString(sender));

            if(!m_sendTokenPage->isEnabled())
                m_sendTokenPage->setEnabled(true);
            if(!m_receiveTokenPage->isEnabled())
                m_receiveTokenPage->setEnabled(true);
        }
        else
        {
            m_sendTokenPage->setEnabled(false);
            m_receiveTokenPage->setEnabled(false);
            m_receiveTokenPage->setAddress(QString::fromStdString(""));
        }
    }
}

void QRCToken::on_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    Q_UNUSED(bottomRight);
    Q_UNUSED(roles);

    if(m_tokenModel)
    {
        QString tokenHash = m_tokenModel->data(topLeft, TokenItemModel::HashRole).toString();
        if(m_selectedTokenHash.isEmpty() ||
                tokenHash == m_selectedTokenHash)
        {
            on_currentTokenChanged(topLeft);
        }
    }
}

void QRCToken::on_currentChanged(QModelIndex current, QModelIndex previous)
{
    Q_UNUSED(previous);

    on_currentTokenChanged(current);
}

void QRCToken::on_rowsInserted(QModelIndex index, int first, int last)
{
    Q_UNUSED(index);
    Q_UNUSED(first);
    Q_UNUSED(last);

    if(m_tokenModel->rowCount() == 1)
    {
        QModelIndex currentToken(m_tokenModel->index(0, 0));
        ui->tokensList->setCurrentIndex(currentToken);
        on_currentTokenChanged(currentToken);
    }
}

void QRCToken::contextualMenu(const QPoint &point)
{
    QModelIndex index = ui->tokensList->indexAt(point);
    QModelIndexList selection = ui->tokensList->selectionModel()->selectedIndexes();
    if (selection.empty())
        return;

    if(index.isValid())
    {
        contextMenu->exec(QCursor::pos());
    }
}

void QRCToken::copyTokenAddress()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::AddressRole);
}

void QRCToken::copyTokenBalance()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::BalanceRole);
}

void QRCToken::copyTokenName()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::NameRole);
}

void QRCToken::copySenderAddress()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::SenderRole);
}

void QRCToken::removeToken()
{
    QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm token remove"), tr("The selected token will be removed from the list. Are you sure?"),
        QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);

    if(btnRetVal == QMessageBox::Yes)
    {
        QModelIndexList selection = ui->tokensList->selectionModel()->selectedIndexes();
        if (selection.empty() && !m_model)
            return;

        QModelIndex index = selection[0];
        std::string sHash = index.data(TokenItemModel::HashRole).toString().toStdString();
        m_model->removeTokenEntry(sHash);
    }
}
<commit_msg>Update qrc token list view GUI<commit_after>#include "qrctoken.h"
#include "ui_qrctoken.h"
#include "tokenitemmodel.h"
#include "walletmodel.h"
#include "tokentransactionview.h"
#include "platformstyle.h"
#include "styleSheet.h"

#include <QPainter>
#include <QAbstractItemDelegate>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QSizePolicy>
#include <QMenu>

#define TOKEN_SIZE 54
#define SYMBOL_WIDTH 60
#define MARGIN 5

class TokenViewDelegate : public QAbstractItemDelegate
{
public:

    TokenViewDelegate(const PlatformStyle *_platformStyle, QObject *parent) :
        QAbstractItemDelegate(parent),
        platformStyle(_platformStyle)
    {}

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const
    {
        painter->save();

        QString tokenSymbol = index.data(TokenItemModel::SymbolRole).toString();
        QString tokenBalance = index.data(TokenItemModel::BalanceRole).toString();
        QString receiveAddress = index.data(TokenItemModel::SenderRole).toString();

        QRect mainRect = option.rect;

        bool selected = option.state & QStyle::State_Selected;
        if(selected)
        {
            painter->fillRect(mainRect,QColor("#009ee5"));
        }
        else
        {
            painter->fillRect(mainRect,QColor("#383938"));
        }

        QRect hLineRect(mainRect.left(), mainRect.bottom(), mainRect.width(), 1);
        painter->fillRect(hLineRect, QColor("#2e2e2e"));

        QColor foreground("#dddddd");
        painter->setPen(foreground);

        QFont font = option.font;
        font.setPointSizeF(option.font.pointSizeF() * 1.1);
        font.setBold(true);
        painter->setFont(font);
        QColor amounColor("#ffffff");
        painter->setPen(amounColor);

        QFontMetrics fmName(option.font);
        QString clippedSymbol = fmName.elidedText(tokenSymbol, Qt::ElideRight, SYMBOL_WIDTH);
        QRect tokenSymbolRect(mainRect.left() + MARGIN, mainRect.top() + MARGIN, SYMBOL_WIDTH, mainRect.height() / 2 - MARGIN);
        painter->drawText(tokenSymbolRect, Qt::AlignLeft|Qt::AlignVCenter, clippedSymbol);

        int amountWidth = (mainRect.width() - 4 * MARGIN - tokenSymbolRect.width());
        QFontMetrics fmAmount(font);
        QString clippedAmount = fmAmount.elidedText(tokenBalance, Qt::ElideRight, amountWidth);
        QRect tokenBalanceRect(tokenSymbolRect.right() + 2 * MARGIN, tokenSymbolRect.top(), amountWidth, tokenSymbolRect.height());
        painter->drawText(tokenBalanceRect, Qt::AlignLeft|Qt::AlignVCenter, clippedAmount);

        QFont addressFont = option.font;
        addressFont.setPointSizeF(option.font.pointSizeF() * 0.8);
        painter->setFont(addressFont);
        painter->setPen(foreground);
        QRect receiveAddressRect(mainRect.left() + MARGIN, tokenSymbolRect.bottom(), mainRect.width() - 2 * MARGIN, mainRect.height() / 2 - 2 * MARGIN);
        painter->drawText(receiveAddressRect, Qt::AlignLeft|Qt::AlignVCenter, receiveAddress);

        painter->restore();
    }

    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(TOKEN_SIZE, TOKEN_SIZE);
    }

    const PlatformStyle *platformStyle;
};

QRCToken::QRCToken(const PlatformStyle *platformStyle, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QRCToken),
    m_model(0),
    m_clientModel(0),
    m_tokenModel(0),
    m_tokenDelegate(0),
    m_tokenTransactionView(0)
{
    ui->setupUi(this);

    SetObjectStyleSheet(ui->tokensList, StyleSheetNames::ScrollBarDark);

    m_platformStyle = platformStyle;

    m_sendTokenPage = new SendTokenPage(this);
    m_receiveTokenPage = new ReceiveTokenPage(this);
    m_addTokenPage = new AddTokenPage(this);
    m_tokenDelegate = new TokenViewDelegate(platformStyle, this);

    m_sendTokenPage->setEnabled(false);
    m_receiveTokenPage->setEnabled(false);

    ui->stackedWidgetToken->addWidget(m_sendTokenPage);
    ui->stackedWidgetToken->addWidget(m_receiveTokenPage);
    ui->stackedWidgetToken->addWidget(m_addTokenPage);

    m_tokenTransactionView = new TokenTransactionView(m_platformStyle, this);
    m_tokenTransactionView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    ui->tokenViewLayout->addWidget(m_tokenTransactionView);

    ui->tokensList->setItemDelegate(m_tokenDelegate);
    ui->tokensList->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->tokensList->setAttribute(Qt::WA_MacShowFocusRect, false);

    QAction *copySenderAction = new QAction(tr("Copy receive address"), this);
    QAction *copyTokenBalanceAction = new QAction(tr("Copy token balance"), this);
    QAction *copyTokenNameAction = new QAction(tr("Copy token name"), this);
    QAction *copyTokenAddressAction = new QAction(tr("Copy contract address"), this);
    QAction *removeTokenAction = new QAction(tr("Remove token"), this);

    contextMenu = new QMenu(ui->tokensList);
    contextMenu->addAction(copySenderAction);
    contextMenu->addAction(copyTokenBalanceAction);
    contextMenu->addAction(copyTokenNameAction);
    contextMenu->addAction(copyTokenAddressAction);
    contextMenu->addAction(removeTokenAction);

    connect(copyTokenAddressAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenAddress()));
    connect(copyTokenBalanceAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenBalance()));
    connect(copyTokenNameAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenName()));
    connect(copySenderAction, SIGNAL(triggered(bool)), this, SLOT(copySenderAddress()));
    connect(removeTokenAction, SIGNAL(triggered(bool)), this, SLOT(removeToken()));

    connect(ui->tokensList, SIGNAL(clicked(QModelIndex)), this, SLOT(on_currentTokenChanged(QModelIndex)));
    connect(ui->tokensList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));

    on_goToSendTokenPage();
}

QRCToken::~QRCToken()
{
    delete ui;
}

void QRCToken::setModel(WalletModel *_model)
{
    m_model = _model;
    m_addTokenPage->setModel(m_model);
    m_sendTokenPage->setModel(m_model);
    m_tokenTransactionView->setModel(_model);
    if(m_model && m_model->getTokenItemModel())
    {
        // Sort tokens by symbol
        QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
        TokenItemModel* tokenModel = m_model->getTokenItemModel();
        proxyModel->setSourceModel(tokenModel);
        proxyModel->sort(1, Qt::AscendingOrder);
        m_tokenModel = proxyModel;

        // Set tokens model
        ui->tokensList->setModel(m_tokenModel);
        connect(ui->tokensList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(on_currentChanged(QModelIndex,QModelIndex)));

        // Set current token
        connect(m_tokenModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), SLOT(on_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
        connect(m_tokenModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(on_rowsInserted(QModelIndex,int,int)));
        if(m_tokenModel->rowCount() > 0)
        {
            QModelIndex currentToken(m_tokenModel->index(0, 0));
            ui->tokensList->setCurrentIndex(currentToken);
            on_currentTokenChanged(currentToken);
        }
    }
}

void QRCToken::setClientModel(ClientModel *_clientModel)
{
    m_clientModel = _clientModel;
    m_sendTokenPage->setClientModel(_clientModel);
    m_addTokenPage->setClientModel(_clientModel);
}

void QRCToken::on_goToSendTokenPage()
{
    ui->stackedWidgetToken->setCurrentIndex(0);
}

void QRCToken::on_goToReceiveTokenPage()
{
    ui->stackedWidgetToken->setCurrentIndex(1);
}

void QRCToken::on_goToAddTokenPage()
{
    ui->stackedWidgetToken->setCurrentIndex(2);
}

void QRCToken::on_currentTokenChanged(QModelIndex index)
{
    if(m_tokenModel)
    {
        if(index.isValid())
        {
            m_selectedTokenHash = m_tokenModel->data(index, TokenItemModel::HashRole).toString();
            std::string address = m_tokenModel->data(index, TokenItemModel::AddressRole).toString().toStdString();
            std::string symbol = m_tokenModel->data(index, TokenItemModel::SymbolRole).toString().toStdString();
            std::string sender = m_tokenModel->data(index, TokenItemModel::SenderRole).toString().toStdString();
            int8_t decimals = m_tokenModel->data(index, TokenItemModel::DecimalsRole).toInt();
            std::string balance = m_tokenModel->data(index, TokenItemModel::RawBalanceRole).toString().toStdString();
            m_sendTokenPage->setTokenData(address, sender, symbol, decimals, balance);
            m_receiveTokenPage->setAddress(QString::fromStdString(sender));

            if(!m_sendTokenPage->isEnabled())
                m_sendTokenPage->setEnabled(true);
            if(!m_receiveTokenPage->isEnabled())
                m_receiveTokenPage->setEnabled(true);
        }
        else
        {
            m_sendTokenPage->setEnabled(false);
            m_receiveTokenPage->setEnabled(false);
            m_receiveTokenPage->setAddress(QString::fromStdString(""));
        }
    }
}

void QRCToken::on_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    Q_UNUSED(bottomRight);
    Q_UNUSED(roles);

    if(m_tokenModel)
    {
        QString tokenHash = m_tokenModel->data(topLeft, TokenItemModel::HashRole).toString();
        if(m_selectedTokenHash.isEmpty() ||
                tokenHash == m_selectedTokenHash)
        {
            on_currentTokenChanged(topLeft);
        }
    }
}

void QRCToken::on_currentChanged(QModelIndex current, QModelIndex previous)
{
    Q_UNUSED(previous);

    on_currentTokenChanged(current);
}

void QRCToken::on_rowsInserted(QModelIndex index, int first, int last)
{
    Q_UNUSED(index);
    Q_UNUSED(first);
    Q_UNUSED(last);

    if(m_tokenModel->rowCount() == 1)
    {
        QModelIndex currentToken(m_tokenModel->index(0, 0));
        ui->tokensList->setCurrentIndex(currentToken);
        on_currentTokenChanged(currentToken);
    }
}

void QRCToken::contextualMenu(const QPoint &point)
{
    QModelIndex index = ui->tokensList->indexAt(point);
    QModelIndexList selection = ui->tokensList->selectionModel()->selectedIndexes();
    if (selection.empty())
        return;

    if(index.isValid())
    {
        contextMenu->exec(QCursor::pos());
    }
}

void QRCToken::copyTokenAddress()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::AddressRole);
}

void QRCToken::copyTokenBalance()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::BalanceRole);
}

void QRCToken::copyTokenName()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::NameRole);
}

void QRCToken::copySenderAddress()
{
    GUIUtil::copyEntryDataFromList(ui->tokensList, TokenItemModel::SenderRole);
}

void QRCToken::removeToken()
{
    QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm token remove"), tr("The selected token will be removed from the list. Are you sure?"),
        QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);

    if(btnRetVal == QMessageBox::Yes)
    {
        QModelIndexList selection = ui->tokensList->selectionModel()->selectedIndexes();
        if (selection.empty() && !m_model)
            return;

        QModelIndex index = selection[0];
        std::string sHash = index.data(TokenItemModel::HashRole).toString().toStdString();
        m_model->removeTokenEntry(sHash);
    }
}
<|endoftext|>


<commit_before>#include "emitterstate.h"
#include "yaml-cpp/exceptions.h"
#include <limits>

namespace YAML
{
	EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
	{
		// set default global manipulators
		m_charset.set(EmitNonAscii);
		m_strFmt.set(Auto);
		m_boolFmt.set(TrueFalseBool);
		m_boolLengthFmt.set(LongBool);
		m_boolCaseFmt.set(LowerCase);
		m_intFmt.set(Dec);
		m_indent.set(2);
		m_preCommentIndent.set(2);
		m_postCommentIndent.set(1);
		m_seqFmt.set(Block);
		m_mapFmt.set(Block);
		m_mapKeyFmt.set(Auto);
        m_floatPrecision.set(6);
        m_doublePrecision.set(15);
	}

	EmitterState::~EmitterState()
	{
	}

	// SetLocalValue
	// . We blindly tries to set all possible formatters to this value
	// . Only the ones that make sense will be accepted
	void EmitterState::SetLocalValue(EMITTER_MANIP value)
	{
		SetOutputCharset(value, FmtScope::Local);
		SetStringFormat(value, FmtScope::Local);
		SetBoolFormat(value, FmtScope::Local);
		SetBoolCaseFormat(value, FmtScope::Local);
		SetBoolLengthFormat(value, FmtScope::Local);
		SetIntFormat(value, FmtScope::Local);
		SetFlowType(GroupType::Seq, value, FmtScope::Local);
		SetFlowType(GroupType::Map, value, FmtScope::Local);
		SetMapKeyFormat(value, FmtScope::Local);
	}

    void EmitterState::SetAnchor()
    {
        m_hasAnchor = true;
    }

    void EmitterState::SetTag()
    {
        m_hasTag = true;
    }

    void EmitterState::SetNonContent()
    {
        m_hasNonContent = true;
    }

    void EmitterState::SetLongKey()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        assert(m_groups.top().type == GroupType::Map);
        m_groups.top().longKey = true;
    }

    void EmitterState::ForceFlow()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        m_groups.top().flowType = FlowType::Flow;
    }

    void EmitterState::StartedNode()
    {
        if(m_groups.empty()) {
            m_docCount++;
        } else {
            m_groups.top().childCount++;
            if(m_groups.top().childCount % 2 == 0)
                m_groups.top().longKey = false;
        }

        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const
    {
        if(type == GroupType::Seq) {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockSeq;
            else
                return EmitterNodeType::FlowSeq;
        } else {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockMap;
            else
                return EmitterNodeType::FlowMap;
        }

        // can't happen
        assert(false);
        return EmitterNodeType::None;
    }

    void EmitterState::StartedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::EndedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::StartedScalar()
    {
        StartedNode();
        ClearModifiedSettings();
    }

	void EmitterState::StartedGroup(GroupType::value type)
	{
        StartedNode();

		const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		m_curIndent += lastGroupIndent;

		std::auto_ptr<Group> pGroup(new Group(type));

		// transfer settings (which last until this group is done)
		pGroup->modifiedSettings = m_modifiedSettings;

		// set up group
        if(GetFlowType(type) == Block)
            pGroup->flowType = FlowType::Block;
        else
            pGroup->flowType = FlowType::Flow;
		pGroup->indent = GetIndent();

		m_groups.push(pGroup);
	}

	void EmitterState::EndedGroup(GroupType::value type)
	{
		if(m_groups.empty())
			return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);

		// get rid of the current group
		{
			std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
			if(pFinishedGroup->type != type)
				return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
		}

		// reset old settings
		unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		assert(m_curIndent >= lastIndent);
		m_curIndent -= lastIndent;

		// some global settings that we changed may have been overridden
		// by a local setting we just popped, so we need to restore them
		m_globalModifiedSettings.restore();

        ClearModifiedSettings();
	}

    EmitterNodeType::value EmitterState::CurGroupNodeType() const
    {
        if(m_groups.empty())
            return EmitterNodeType::None;

        return m_groups.top().NodeType();
    }

    GroupType::value EmitterState::CurGroupType() const
	{
        return m_groups.empty() ? GroupType::None : m_groups.top().type;
	}

    FlowType::value EmitterState::CurGroupFlowType() const
	{
        return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
	}

    int EmitterState::CurGroupIndent() const
    {
        return m_groups.empty() ? 0 : m_groups.top().indent;
    }

    std::size_t EmitterState::CurGroupChildCount() const
    {
        return m_groups.empty() ? m_docCount : m_groups.top().childCount;
    }

    bool EmitterState::CurGroupLongKey() const
    {
        return m_groups.empty() ? false : m_groups.top().longKey;
    }

    int EmitterState::LastIndent() const
    {
        if(m_groups.size() <= 1)
            return 0;

        return m_curIndent - m_groups.top(-1).indent;
    }

	void EmitterState::ClearModifiedSettings()
	{
		m_modifiedSettings.clear();
	}

	bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case EmitNonAscii:
			case EscapeNonAscii:
				_Set(m_charset, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case SingleQuoted:
			case DoubleQuoted:
			case Literal:
				_Set(m_strFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case OnOffBool:
			case TrueFalseBool:
			case YesNoBool:
				_Set(m_boolFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case LongBool:
			case ShortBool:
				_Set(m_boolLengthFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case UpperCase:
			case LowerCase:
			case CamelCase:
				_Set(m_boolCaseFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Dec:
			case Hex:
			case Oct:
				_Set(m_intFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_indent, value, scope);
		return true;
	}

	bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_preCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_postCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Block:
			case Flow:
				_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const
	{
		// force flow style if we're currently in a flow
		if(CurGroupFlowType() == FlowType::Flow)
			return Flow;

		// otherwise, go with what's asked of us
		return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
	}

	bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case LongKey:
				_Set(m_mapKeyFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

    bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<float>::digits10)
            return false;
        _Set(m_floatPrecision, value, scope);
        return true;
    }

    bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<double>::digits10)
            return false;
        _Set(m_doublePrecision, value, scope);
        return true;
    }
}

<commit_msg>Fixed end seq/map error msg<commit_after>#include "emitterstate.h"
#include "yaml-cpp/exceptions.h"
#include <limits>

namespace YAML
{
	EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0)
	{
		// set default global manipulators
		m_charset.set(EmitNonAscii);
		m_strFmt.set(Auto);
		m_boolFmt.set(TrueFalseBool);
		m_boolLengthFmt.set(LongBool);
		m_boolCaseFmt.set(LowerCase);
		m_intFmt.set(Dec);
		m_indent.set(2);
		m_preCommentIndent.set(2);
		m_postCommentIndent.set(1);
		m_seqFmt.set(Block);
		m_mapFmt.set(Block);
		m_mapKeyFmt.set(Auto);
        m_floatPrecision.set(6);
        m_doublePrecision.set(15);
	}

	EmitterState::~EmitterState()
	{
	}

	// SetLocalValue
	// . We blindly tries to set all possible formatters to this value
	// . Only the ones that make sense will be accepted
	void EmitterState::SetLocalValue(EMITTER_MANIP value)
	{
		SetOutputCharset(value, FmtScope::Local);
		SetStringFormat(value, FmtScope::Local);
		SetBoolFormat(value, FmtScope::Local);
		SetBoolCaseFormat(value, FmtScope::Local);
		SetBoolLengthFormat(value, FmtScope::Local);
		SetIntFormat(value, FmtScope::Local);
		SetFlowType(GroupType::Seq, value, FmtScope::Local);
		SetFlowType(GroupType::Map, value, FmtScope::Local);
		SetMapKeyFormat(value, FmtScope::Local);
	}

    void EmitterState::SetAnchor()
    {
        m_hasAnchor = true;
    }

    void EmitterState::SetTag()
    {
        m_hasTag = true;
    }

    void EmitterState::SetNonContent()
    {
        m_hasNonContent = true;
    }

    void EmitterState::SetLongKey()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        assert(m_groups.top().type == GroupType::Map);
        m_groups.top().longKey = true;
    }

    void EmitterState::ForceFlow()
    {
        assert(!m_groups.empty());
        if(m_groups.empty())
            return;

        m_groups.top().flowType = FlowType::Flow;
    }

    void EmitterState::StartedNode()
    {
        if(m_groups.empty()) {
            m_docCount++;
        } else {
            m_groups.top().childCount++;
            if(m_groups.top().childCount % 2 == 0)
                m_groups.top().longKey = false;
        }

        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const
    {
        if(type == GroupType::Seq) {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockSeq;
            else
                return EmitterNodeType::FlowSeq;
        } else {
            if(GetFlowType(type) == Block)
                return EmitterNodeType::BlockMap;
            else
                return EmitterNodeType::FlowMap;
        }

        // can't happen
        assert(false);
        return EmitterNodeType::None;
    }

    void EmitterState::StartedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::EndedDoc()
    {
        m_hasAnchor = false;
        m_hasTag = false;
        m_hasNonContent = false;
    }

    void EmitterState::StartedScalar()
    {
        StartedNode();
        ClearModifiedSettings();
    }

	void EmitterState::StartedGroup(GroupType::value type)
	{
        StartedNode();

		const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		m_curIndent += lastGroupIndent;

		std::auto_ptr<Group> pGroup(new Group(type));

		// transfer settings (which last until this group is done)
		pGroup->modifiedSettings = m_modifiedSettings;

		// set up group
        if(GetFlowType(type) == Block)
            pGroup->flowType = FlowType::Block;
        else
            pGroup->flowType = FlowType::Flow;
		pGroup->indent = GetIndent();

		m_groups.push(pGroup);
	}

	void EmitterState::EndedGroup(GroupType::value type)
	{
		if(m_groups.empty()) {
            if(type == GroupType::Seq)
                return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
            else
                return SetError(ErrorMsg::UNEXPECTED_END_MAP);
        }

		// get rid of the current group
		{
			std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
			if(pFinishedGroup->type != type)
				return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
		}

		// reset old settings
		unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
		assert(m_curIndent >= lastIndent);
		m_curIndent -= lastIndent;

		// some global settings that we changed may have been overridden
		// by a local setting we just popped, so we need to restore them
		m_globalModifiedSettings.restore();

        ClearModifiedSettings();
	}

    EmitterNodeType::value EmitterState::CurGroupNodeType() const
    {
        if(m_groups.empty())
            return EmitterNodeType::None;

        return m_groups.top().NodeType();
    }

    GroupType::value EmitterState::CurGroupType() const
	{
        return m_groups.empty() ? GroupType::None : m_groups.top().type;
	}

    FlowType::value EmitterState::CurGroupFlowType() const
	{
        return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
	}

    int EmitterState::CurGroupIndent() const
    {
        return m_groups.empty() ? 0 : m_groups.top().indent;
    }

    std::size_t EmitterState::CurGroupChildCount() const
    {
        return m_groups.empty() ? m_docCount : m_groups.top().childCount;
    }

    bool EmitterState::CurGroupLongKey() const
    {
        return m_groups.empty() ? false : m_groups.top().longKey;
    }

    int EmitterState::LastIndent() const
    {
        if(m_groups.size() <= 1)
            return 0;

        return m_curIndent - m_groups.top(-1).indent;
    }

	void EmitterState::ClearModifiedSettings()
	{
		m_modifiedSettings.clear();
	}

	bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case EmitNonAscii:
			case EscapeNonAscii:
				_Set(m_charset, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case SingleQuoted:
			case DoubleQuoted:
			case Literal:
				_Set(m_strFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case OnOffBool:
			case TrueFalseBool:
			case YesNoBool:
				_Set(m_boolFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case LongBool:
			case ShortBool:
				_Set(m_boolLengthFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case UpperCase:
			case LowerCase:
			case CamelCase:
				_Set(m_boolCaseFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Dec:
			case Hex:
			case Oct:
				_Set(m_intFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	bool EmitterState::SetIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_indent, value, scope);
		return true;
	}

	bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_preCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope)
	{
		if(value == 0)
			return false;

		_Set(m_postCommentIndent, value, scope);
		return true;
	}

	bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Block:
			case Flow:
				_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

	EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const
	{
		// force flow style if we're currently in a flow
		if(CurGroupFlowType() == FlowType::Flow)
			return Flow;

		// otherwise, go with what's asked of us
		return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
	}

	bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope)
	{
		switch(value) {
			case Auto:
			case LongKey:
				_Set(m_mapKeyFmt, value, scope);
				return true;
			default:
				return false;
		}
	}

    bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<float>::digits10)
            return false;
        _Set(m_floatPrecision, value, scope);
        return true;
    }

    bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope)
    {
        if(value < 0 || value > std::numeric_limits<double>::digits10)
            return false;
        _Set(m_doublePrecision, value, scope);
        return true;
    }
}

<|endoftext|>