<commit_before>#include <iostream>
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include "errno.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <cmath>
#include <string.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <algorithm>

using namespace std;

void list_output(vector<char*> &v)
{
	struct passwd *pws;
	pws = getpwuid(geteuid());

	struct group *grp;
	grp = getgrgid(getgid());

	int width = 0;
	int total = 0;

	for(auto x : v) {
		int tempWidth = 0;
		struct stat fileStat;
		if(stat(x, &fileStat) < 0)
			perror("Failed");

		total += ceil(fileStat.st_blocks);

		for(; fileStat.st_size != 0; fileStat.st_size /= 10, tempWidth++);
		tempWidth > width ? width = tempWidth : width;
	}

	cout << "total " << total/2 << endl;

    for(auto x : v) {
		struct stat fileStat;
	    if(stat(x, &fileStat) < 0)
			perror("Failed");

        bool directory = (S_ISDIR(fileStat.st_mode));
        bool executable = (fileStat.st_mode > 0) && (S_IEXEC & fileStat.st_mode);
		bool hidden = (x[0] == '.');

		printf( directory ? "d" : "-");
	    printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
		printf("  ");
        cout << fileStat.st_nlink << " ";
		printf("%s  ", pws->pw_name);
		printf("%s  ", grp->gr_name);
		cout.width(width);
		cout << std::right << fileStat.st_size << " ";

        struct tm *tm;
        char datestring[256];
        tm = localtime(&fileStat.st_mtime);
        strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);
        printf("%s ", datestring);

        if(directory) {
            if(hidden)
                cout << "\x1b[34;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[34;40m" << x << "\x1b[0m" << endl;
        }
        else if(executable) {
            if(hidden)
                cout << "\x1b[1;32;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[1;32;40m" << x << "\x1b[0m" << endl;
        }
        else if(hidden)
            cout << "\x1b[30;47m" << x << "\x1b[0m" << endl;
        else
            cout << x << endl;
	}
}

void standard_output(vector<char*> &v, int length)
{
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
    int check_width = v.size()*length-1;
    int num_rows = ceil((double)check_width/(double)w.ws_col);

    for(int i = 0; i < num_rows; ++i)
    {
        for(unsigned a = i; a < v.size(); a += num_rows) {

    		struct stat fileStat;

            bool directory = (S_ISDIR(fileStat.st_mode));
            bool executable = (fileStat.st_mode > 0) && (S_IEXEC & fileStat.st_mode);
    		bool hidden = ((v.at(a))[0] == '.');

            if(directory) {
                if(hidden)
                    cout << "\x1b[34;47m" << v.at(a) << "\x1b[0m";
                else
                    cout << "\x1b[34;40m" << v.at(a) << "\x1b[0m";
            }
            else if(executable) {
                if(hidden)
                    cout << "\x1b[1;32;47m" << v.at(a) << "\x1b[0m";
                else
                    cout << "\x1b[1;32;40m" << v.at(a) << "\x1b[0m";
            }
            else if(hidden)
                cout << "\x1b[30;47m" << v.at(a) << "\x1b[0m";
            else
                cout << v.at(a);

            for(int i = strlen(v.at(a)); i < length; ++i)
                cout << " ";
        }
        cout << endl;
    }
}

bool comparisonFunc(const char *c1, const char *c2) {
    return strcasecmp(c1, c2) < 0;
}

int main (int argc, char const *argv[])
{
    DIR *dirp;
    string direc = "./";
    bool list = false;
    bool all = false;
    bool recursive = false;
    vector<char*> files;
    unsigned max_length = 9;

    if(argc == 2) {
        string first = argv[1];
        if(first[0] == '-') {
            if(first.find('a') != string::npos)
                all = true;
            if(first.find('l') != string::npos)
                list = true;
            if(first.find('R') != string::npos)
                recursive = true;
        }
        else
            direc = argv[1];
    }

    if(argc > 2) {
        direc = argv[2];
    }

    if(NULL == (dirp = opendir(const_cast<char*>(direc.c_str())))) {
        perror("There was an error with opendir(). ");
        exit(1);
    }

    struct dirent *filespecs;
    errno = 0;
    while(NULL != (filespecs = readdir(dirp))) {
        if(filespecs->d_name[0] == '.' && !all)
            continue;
        files.push_back(filespecs->d_name);
        strlen(filespecs->d_name) > max_length ? max_length = strlen(filespecs->d_name) : max_length;
    }
    if(errno != 0) {
        perror("There was an error with readdir(). ");
        exit(1);
    }

    sort(files.begin(), files.end(), comparisonFunc);

    if(!list)
        standard_output(files, ++max_length);
    else
        list_output(files);

    if(recursive)
        cout << "rec" << endl;

    if(-1 == closedir(dirp)) {
        perror("There was an error with closedir(). ");
        exit(1);
    }
    return 0;
}<commit_msg>Removing trailing space<commit_after>#include <iostream>
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include "errno.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <cmath>
#include <string.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <algorithm>

using namespace std;

void list_output(vector<char*> &v)
{
	struct passwd *pws;
	pws = getpwuid(geteuid());

	struct group *grp;
	grp = getgrgid(getgid());

	int width = 0;
	int total = 0;

	for(auto x : v) {
		int tempWidth = 0;
		struct stat fileStat;
		if(stat(x, &fileStat) < 0)
			perror("Failed");

		total += ceil(fileStat.st_blocks);

		for(; fileStat.st_size != 0; fileStat.st_size /= 10, tempWidth++);
		tempWidth > width ? width = tempWidth : width;
	}

	cout << "total " << total/2 << endl;

    for(auto x : v) {
		struct stat fileStat;
	    if(stat(x, &fileStat) < 0)
			perror("Failed");

        bool directory = (S_ISDIR(fileStat.st_mode));
        bool executable = (fileStat.st_mode > 0) && (S_IEXEC & fileStat.st_mode);
		bool hidden = (x[0] == '.');

		printf( directory ? "d" : "-");
	    printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
		printf("  ");
        cout << fileStat.st_nlink << " ";
		printf("%s  ", pws->pw_name);
		printf("%s  ", grp->gr_name);
		cout.width(width);
		cout << std::right << fileStat.st_size << " ";

        struct tm *tm;
        char datestring[256];
        tm = localtime(&fileStat.st_mtime);
        strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);
        printf("%s ", datestring);

        if(directory) {
            if(hidden)
                cout << "\x1b[34;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[34;40m" << x << "\x1b[0m" << endl;
        }
        else if(executable) {
            if(hidden)
                cout << "\x1b[1;32;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[1;32;40m" << x << "\x1b[0m" << endl;
        }
        else if(hidden)
            cout << "\x1b[30;47m" << x << "\x1b[0m" << endl;
        else
            cout << x << endl;
	}
}

void standard_output(vector<char*> &v, int length)
{
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
    int check_width = v.size()*length-1;
    int num_rows = ceil((double)check_width/(double)w.ws_col);

    for(int i = 0; i < num_rows; ++i)
    {
        for(unsigned a = i; a < v.size(); a += num_rows) {

    		struct stat fileStat;

            bool directory = (S_ISDIR(fileStat.st_mode));
            bool executable = (fileStat.st_mode > 0) && (S_IEXEC & fileStat.st_mode);
    		bool hidden = ((v.at(a))[0] == '.');

            if(directory) {
                if(hidden)
                    cout << "\x1b[34;47m" << v.at(a) << "\x1b[0m";
                else
                    cout << "\x1b[34;40m" << v.at(a) << "\x1b[0m";
            }
            else if(executable) {
                if(hidden)
                    cout << "\x1b[1;32;47m" << v.at(a) << "\x1b[0m";
                else
                    cout << "\x1b[1;32;40m" << v.at(a) << "\x1b[0m";
            }
            else if(hidden)
                cout << "\x1b[30;47m" << v.at(a) << "\x1b[0m";
            else
                cout << v.at(a);

            for(int i = strlen(v.at(a)); i < length && a < (v.size() - num_rows); ++i)
                cout << " ";
        }
        cout << endl;
    }
}

bool comparisonFunc(const char *c1, const char *c2) {
    return strcasecmp(c1, c2) < 0;
}

int main (int argc, char const *argv[])
{
    DIR *dirp;
    string direc = "./";
    bool list = false;
    bool all = false;
    bool recursive = false;
    vector<char*> files;
    unsigned max_length = 9;

    if(argc == 2) {
        string first = argv[1];
        if(first[0] == '-') {
            if(first.find('a') != string::npos)
                all = true;
            if(first.find('l') != string::npos)
                list = true;
            if(first.find('R') != string::npos)
                recursive = true;
        }
        else
            direc = argv[1];
    }

    if(argc > 2) {
        direc = argv[2];
    }

    if(NULL == (dirp = opendir(const_cast<char*>(direc.c_str())))) {
        perror("There was an error with opendir(). ");
        exit(1);
    }

    struct dirent *filespecs;
    errno = 0;
    while(NULL != (filespecs = readdir(dirp))) {
        if(filespecs->d_name[0] == '.' && !all)
            continue;
        files.push_back(filespecs->d_name);
        strlen(filespecs->d_name) > max_length ? max_length = strlen(filespecs->d_name) : max_length;
    }
    if(errno != 0) {
        perror("There was an error with readdir(). ");
        exit(1);
    }

    sort(files.begin(), files.end(), comparisonFunc);

    if(!list)
        standard_output(files, ++max_length);
    else
        list_output(files);

    if(recursive)
        cout << "rec" << endl;

    if(-1 == closedir(dirp)) {
        perror("There was an error with closedir(). ");
        exit(1);
    }
    return 0;
}<|endoftext|>


<commit_before>#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <vector>
#include <sstream>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
using namespace std;

bool isDirectory(char* directoryName) {

	struct stat directoryInCurrent;

	if (-1 == (stat(directoryName, &directoryInCurrent))) {

		perror("stat failed");
		return false;
	}

	if (directoryInCurrent.st_mode & S_IFDIR) {
		return true;
	}
	else {
		return false;
	}
}

int ls(char* directoryName) {

		char const *dirName = ".";
		DIR *dirp;
		if (!(dirp = opendir(dirName))) {
			cerr << "Error(" << errno << ") opening " << dirName << endl;
		}

		dirent *direntp;
		while ((direntp = readdir(dirp))) {
			if (direntp->d_name[0] != '.') {

				//cout << direntp->d_name << endl; // use stat here to find attributes of a file
				printf(direntp->d_name, 8);
				cout << " ";
			}
		}
		cout << endl;
		closedir(dirp);
		return 0;
}
bool lsWithFlags(char* directoryName, vector<string> flags) {

	bool isA = false;
	bool isL = false;
	bool isR = false;
	for (unsigned i = 0; i < flags.size(); ++i) {

		if (flags.at(i) == "a")
			isA = true;
		else if (flags.at(i) == "l")
			isL = true;
		else if (flags.at(i) == "R")
			isR = true;

	}
	char const *dirName = directoryName;
	DIR *dirp;
	if (!(dirp = opendir(dirName))) {
		cerr << "Error(" << errno << ") opening " << dirName << endl;
		return errno;
	}

	dirent *direntp;
	while ((direntp = readdir(dirp))) {
		if (direntp->d_name[0] != '.') {

			//cout << direntp->d_name << endl; // use stat here to find attributes of a file
			printf(direntp->d_name, 8);
			cout << " ";
		}
	}
	cout << endl;
	closedir(dirp);
}

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

	if (argc == 1) {

		if (errno == ls(".")) {

			return errno;
		}
	}

	/*else {

		vector<string> directories;
		vector<string> flags;
		for (int i = 1; i < argc; ++i) {

			if (argv[i][0] == '-') {
				flags.push_back(argv[i]);
			}
			else {

				if (isDirectory(
			}
		}
	}*/

}

<commit_msg>commented lswithflags function<commit_after>#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <vector>
#include <sstream>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
using namespace std;

bool isDirectory(char* directoryName) {

	struct stat directoryInCurrent;

	if (-1 == (stat(directoryName, &directoryInCurrent))) {

		perror("stat failed");
		return false;
	}

	if (directoryInCurrent.st_mode & S_IFDIR) {
		return true;
	}
	else {
		return false;
	}
}

int ls(char* directoryName) {

		char const *dirName = ".";
		DIR *dirp;
		if (!(dirp = opendir(dirName))) {
			cerr << "Error(" << errno << ") opening " << dirName << endl;
		}

		dirent *direntp;
		while ((direntp = readdir(dirp))) {
			if (direntp->d_name[0] != '.') {

				//cout << direntp->d_name << endl; // use stat here to find attributes of a file
				printf(direntp->d_name, 8);
				cout << " ";
			}
		}
		cout << endl;
		closedir(dirp);
		return 0;
}

/*bool lsWithFlags(char* directoryName, vector<string> flags) {

	bool isA = false;
	bool isL = false;
	bool isR = false;
	for (unsigned i = 0; i < flags.size(); ++i) {

		if (flags.at(i) == "a")
			isA = true;
		else if (flags.at(i) == "l")
			isL = true;
		else if (flags.at(i) == "R")
			isR = true;

	}
	char const *dirName = directoryName;
	DIR *dirp;
	if (!(dirp = opendir(dirName))) {
		cerr << "Error(" << errno << ") opening " << dirName << endl;
		return errno;
	}

	dirent *direntp;
	while ((direntp = readdir(dirp))) {
		if (direntp->d_name[0] != '.') {

			//cout << direntp->d_name << endl; // use stat here to find attributes of a file
			printf(direntp->d_name, 8);
			cout << " ";
		}
	}
	cout << endl;
	closedir(dirp);
}*/

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

	if (argc == 1) {

		if (errno == ls(".")) {

			return errno;
		}
	}

	/*else {

		vector<string> directories;
		vector<string> flags;
		for (int i = 1; i < argc; ++i) {

			if (argv[i][0] == '-') {
				flags.push_back(argv[i]);
			}
			else {

				if (isDirectory(
			}
		}
	}*/

}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include "errno.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <cmath>
#include <string.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>

using namespace std;

void list_output(vector<char*> &v)
{
	struct passwd *pws;
	pws = getpwuid(geteuid());

	struct group *grp;
	grp = getgrgid(getgid());

	int width = 0;
	int total = 0;

	for(auto x : v) {
		int tempWidth = 0;
		struct stat fileStat;
		if(stat(x, &fileStat) < 0)
			perror("Failed");

		total += ceil(fileStat.st_blocks);

		for(; fileStat.st_size != 0; fileStat.st_size /= 10, tempWidth++);
		tempWidth > width ? width = tempWidth : width;
	}

	cout << "total " << total << endl;

    for(auto x : v) {
		struct stat fileStat;
	    if(stat(x, &fileStat) < 0)
			perror("Failed");

        bool directory = (S_ISDIR(fileStat.st_mode));
        bool executable = (fileStat.st_mode > 0) && (S_IEXEC & fileStat.st_mode);
		bool hidden = (x[0] == '.');

		printf( directory ? "d" : "-");
	    printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
		printf("  ");
        cout << fileStat.st_nlink << " ";
		printf("%s  ", pws->pw_name);
		printf("%s  ", grp->gr_name);
		cout.width(width);
		cout << std::right << fileStat.st_size << " ";

        struct tm *tm;
        char datestring[256];
        tm = localtime(&fileStat.st_mtime);
        strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);
        printf("%s ", datestring);

        if(directory) {
            if(hidden)
                cout << "\x1b[34;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[34;40m" << x << "\x1b[0m" << endl;
        }
        else if(executable) {
            if(hidden)
                cout << "\x1b[1;32;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[1;32;40m" << x << "\x1b[0m" << endl;
        }
        else if(hidden)
            cout << "\x1b[30;47m" << x << "\x1b[0m" << endl;
        else
            cout << x << endl;
	}
}

void standard_output(vector<char*> &v, int length)
{
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
    int check_width = v.size()*length;
    int num_rows = ceil((double)check_width/(double)w.ws_col);

    for(int i = 0; i < num_rows; ++i)
    {
        for(unsigned a = i; a < v.size(); a += num_rows) {
            cout << v.at(a);
            for(int i = strlen(v.at(a)); i < length; ++i)
                cout << " ";
        }
        cout << endl;
    }
}

int main (int argc, char const *argv[])
{
    DIR *dirp;
    string direc = "./";
    bool list = false;
    bool all = false;
    bool recursive = false;
    vector<char*> files;
    unsigned max_length = 9;

    if(argc == 2) {
        string first = argv[1];
        if(first[0] == '-') {
            if(first.find('a') != string::npos)
                all = true;
            if(first.find('l') != string::npos)
                list = true;
            if(first.find('R') != string::npos)
                recursive = true;
        }
        else
            direc = argv[1];
    }

    if(argc > 2) {
        direc = argv[2];
    }

    if(NULL == (dirp = opendir(const_cast<char*>(direc.c_str())))) {
        perror("There was an error with opendir(). ");
        exit(1);
    }

    struct dirent *filespecs;
    errno = 0;
    while(NULL != (filespecs = readdir(dirp))) {
        if(filespecs->d_name[0] == '.' && !all)
            continue;
        files.push_back(filespecs->d_name);
        strlen(filespecs->d_name) > max_length ? max_length = strlen(filespecs->d_name) : max_length;
    }
    if(errno != 0) {
        perror("There was an error with readdir(). ");
        exit(1);
    }

    if(!list)
        standard_output(files, ++max_length);
    else
        list_output(files);

    if(-1 == closedir(dirp)) {
        perror("There was an error with closedir(). ");
        exit(1);
    }
    return 0;
}<commit_msg>Make apparently doesn't like one of my variables<commit_after>#include <iostream>
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include "errno.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <cmath>
#include <string.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>

using namespace std;

void list_output(vector<char*> &v)
{
	struct passwd *pws;
	pws = getpwuid(geteuid());

	struct group *grp;
	grp = getgrgid(getgid());

	int width = 0;
	int total = 0;

	for(auto x : v) {
		int tempWidth = 0;
		struct stat fileStat;
		if(stat(x, &fileStat) < 0)
			perror("Failed");

		total += ceil(fileStat.st_blocks);

		for(; fileStat.st_size != 0; fileStat.st_size /= 10, tempWidth++);
		tempWidth > width ? width = tempWidth : width;
	}

	cout << "total " << total << endl;

    for(auto x : v) {
		struct stat fileStat;
	    if(stat(x, &fileStat) < 0)
			perror("Failed");

        bool directory = (S_ISDIR(fileStat.st_mode));
        bool executable = (fileStat.st_mode > 0) && (S_IEXEC & fileStat.st_mode);
		bool hidden = (x[0] == '.');

		printf( directory ? "d" : "-");
	    printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
	    printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
	    printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
	    printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
		printf("  ");
        cout << fileStat.st_nlink << " ";
		printf("%s  ", pws->pw_name);
		printf("%s  ", grp->gr_name);
		cout.width(width);
		cout << std::right << fileStat.st_size << " ";

        struct tm *tm;
        char datestring[256];
        tm = localtime(&fileStat.st_mtime);
        strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);
        printf("%s ", datestring);

        if(directory) {
            if(hidden)
                cout << "\x1b[34;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[34;40m" << x << "\x1b[0m" << endl;
        }
        else if(executable) {
            if(hidden)
                cout << "\x1b[1;32;47m" << x << "\x1b[0m" << endl;
            else
                cout << "\x1b[1;32;40m" << x << "\x1b[0m" << endl;
        }
        else if(hidden)
            cout << "\x1b[30;47m" << x << "\x1b[0m" << endl;
        else
            cout << x << endl;
	}
}

void standard_output(vector<char*> &v, int length)
{
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
    int check_width = v.size()*length;
    int num_rows = ceil((double)check_width/(double)w.ws_col);

    for(int i = 0; i < num_rows; ++i)
    {
        for(unsigned a = i; a < v.size(); a += num_rows) {
            cout << v.at(a);
            for(int i = strlen(v.at(a)); i < length; ++i)
                cout << " ";
        }
        cout << endl;
    }
}

int main (int argc, char const *argv[])
{
    DIR *dirp;
    string direc = "./";
    bool list = false;
    bool all = false;
    bool recursive = false;
    vector<char*> files;
    unsigned max_length = 9;

    if(argc == 2) {
        string first = argv[1];
        if(first[0] == '-') {
            if(first.find('a') != string::npos)
                all = true;
            if(first.find('l') != string::npos)
                list = true;
            if(first.find('R') != string::npos)
                recursive = true;
        }
        else
            direc = argv[1];
    }

    if(argc > 2) {
        direc = argv[2];
    }

    if(NULL == (dirp = opendir(const_cast<char*>(direc.c_str())))) {
        perror("There was an error with opendir(). ");
        exit(1);
    }

    struct dirent *filespecs;
    errno = 0;
    while(NULL != (filespecs = readdir(dirp))) {
        if(filespecs->d_name[0] == '.' && !all)
            continue;
        files.push_back(filespecs->d_name);
        strlen(filespecs->d_name) > max_length ? max_length = strlen(filespecs->d_name) : max_length;
    }
    if(errno != 0) {
        perror("There was an error with readdir(). ");
        exit(1);
    }

    if(!list)
        standard_output(files, ++max_length);
    else
        list_output(files);

    if(recursive)
        cout << "rec" << endl;

    if(-1 == closedir(dirp)) {
        perror("There was an error with closedir(). ");
        exit(1);
    }
    return 0;
}<|endoftext|>


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

#include "i6engine/modules/gui/guiwidgets/GUIComboBox.h"

#include "i6engine/utils/Exceptions.h"

#include "i6engine/api/configs/GUIConfig.h"

#include "CEGUI/CEGUI.h"

namespace i6engine {
namespace modules {

	GUIComboBox::GUIComboBox(const std::string & name, const std::string & style) : api::GUIWidget(name), _selectedCallback() {
		CEGUI::WindowManager & wmgr = CEGUI::WindowManager::getSingleton();

		_window = wmgr.createWindow(style, name);
		_window->setProperty("RiseOnClickEnabled", "False");
		dynamic_cast<CEGUI::Combobox *>(_window)->setReadOnly(true);

		_window->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber(&GUIComboBox::selectionChanged, this));
	}

	void GUIComboBox::update(uint16_t type, api::gui::GUIUpdateMessageStruct * data) {
		if (type == api::gui::GuiAddText) {
			api::gui::GUI_Text * g = dynamic_cast<api::gui::GUI_Text *>(data);
			dynamic_cast<CEGUI::Combobox *>(_window)->addItem(new CEGUI::ListboxTextItem(g->text));
		} else if (type == api::gui::GuiSetSelectedStringCallback) {
			api::gui::GUI_SetSelectedStringCallback * g = dynamic_cast<api::gui::GUI_SetSelectedStringCallback *>(data);
			_selectedCallback = g->callback;
		} else if (api::gui::GuiSetText) {
			std::string selection = dynamic_cast<api::gui::GUI_Text *>(data)->text;
			for (size_t i = 0; i < dynamic_cast<CEGUI::Combobox *>(_window)->getItemCount(); i++) {
				CEGUI::ListboxTextItem * lti = dynamic_cast<CEGUI::ListboxTextItem *>(dynamic_cast<CEGUI::Combobox *>(_window)->getListboxItemFromIndex(i));
				if (lti->getText() == selection) {
					lti->setSelected(true);
					dynamic_cast<CEGUI::Combobox *>(_window)->setText(selection);
					break;
				}
			}
		} else {
			GUIWidget::update(type, data);
		}
	}

	bool GUIComboBox::selectionChanged(const CEGUI::EventArgs & evt) {
		if (_selectedCallback == nullptr) {
			return true;
		}
		_selectedCallback(dynamic_cast<CEGUI::ListboxTextItem *>(dynamic_cast<CEGUI::Combobox *>(_window)->getSelectedItem())->getText().c_str());
		return true;
	}

} /* namespace modules */
} /* namespace i6engine */
<commit_msg>ISIXE-1502 fixed bug<commit_after>/**
 * Copyright 2012 FAU (Friedrich Alexander University of Erlangen-Nuremberg)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "i6engine/modules/gui/guiwidgets/GUIComboBox.h"

#include "i6engine/utils/Exceptions.h"

#include "i6engine/api/configs/GUIConfig.h"

#include "CEGUI/CEGUI.h"

namespace i6engine {
namespace modules {

	GUIComboBox::GUIComboBox(const std::string & name, const std::string & style) : api::GUIWidget(name), _selectedCallback() {
		CEGUI::WindowManager & wmgr = CEGUI::WindowManager::getSingleton();

		_window = wmgr.createWindow(style, name);
		_window->setProperty("RiseOnClickEnabled", "False");
		dynamic_cast<CEGUI::Combobox *>(_window)->setReadOnly(true);

		_window->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber(&GUIComboBox::selectionChanged, this));
	}

	void GUIComboBox::update(uint16_t type, api::gui::GUIUpdateMessageStruct * data) {
		if (type == api::gui::GuiAddText) {
			api::gui::GUI_Text * g = dynamic_cast<api::gui::GUI_Text *>(data);
			dynamic_cast<CEGUI::Combobox *>(_window)->addItem(new CEGUI::ListboxTextItem(g->text));
		} else if (type == api::gui::GuiSetSelectedStringCallback) {
			api::gui::GUI_SetSelectedStringCallback * g = dynamic_cast<api::gui::GUI_SetSelectedStringCallback *>(data);
			_selectedCallback = g->callback;
		} else if (type == api::gui::GuiSetText) {
			std::string selection = dynamic_cast<api::gui::GUI_Text *>(data)->text;
			for (size_t i = 0; i < dynamic_cast<CEGUI::Combobox *>(_window)->getItemCount(); i++) {
				CEGUI::ListboxTextItem * lti = dynamic_cast<CEGUI::ListboxTextItem *>(dynamic_cast<CEGUI::Combobox *>(_window)->getListboxItemFromIndex(i));
				if (lti->getText() == selection) {
					lti->setSelected(true);
					dynamic_cast<CEGUI::Combobox *>(_window)->setText(selection);
					break;
				}
			}
		} else {
			GUIWidget::update(type, data);
		}
	}

	bool GUIComboBox::selectionChanged(const CEGUI::EventArgs & evt) {
		if (_selectedCallback == nullptr) {
			return true;
		}
		_selectedCallback(dynamic_cast<CEGUI::ListboxTextItem *>(dynamic_cast<CEGUI::Combobox *>(_window)->getSelectedItem())->getText().c_str());
		return true;
	}

} /* namespace modules */
} /* namespace i6engine */
<|endoftext|>


<commit_before>/*
 * Copyright 2000-2008, François Revol, <revol@free.fr>. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "Utils.h"
#include <FindDirectory.h>
#include <Path.h>
#include <String.h>
#include <BeBuild.h>

#include <malloc.h>
#include <stdio.h>

// some private font information structs
namespace BPrivate {

typedef struct font_folder_info {
	//char name[256];
	char *name;
	uint32 flags;
} font_folder_info;

typedef struct font_file_info {
	char *name;
	uint32 flags;
	font_family family;
	font_style style;
	uint32 dummy;
} font_file_info;

};

using namespace BPrivate;

// this is PRIVATE to libbe and NOT in R5!!!
extern long _count_font_folders_(void);
extern long _count_font_files_(long);
extern status_t _get_nth_font_file_(long, font_file_info **);
extern status_t _get_nth_font_folder_(long, font_folder_info **);

status_t
find_font_file(entry_ref *to, font_family family, font_style style, float size)
{
#ifdef B_BEOS_VERSION_DANO
	status_t err = ENOENT;
	long i, fontcount, foldercount;
	font_file_info *ffi;
	font_folder_info *fdi;
	bool found = false;
	(void)size;

	fontcount = _count_font_files_(0);
	for (i = 0; i < fontcount; i++) {
		err = _get_nth_font_file_(i, &ffi);
		if (err)
			continue;
		if (strcmp(ffi->family, family) || strcmp(ffi->style, style))
			continue;
		found = true;
		break;
	}
	if (!found)
		return ENOENT;
	foldercount = _count_font_folders_();
	for (i = 0; i < fontcount; i++) {
		err = _get_nth_font_folder_(i, &fdi);
		if (err)
			continue;
		BPath ffile(fdi->name);
		ffile.Append(ffi->name);
		printf("find_font_file: looking for '%s' in '%s'\n", ffi->name, fdi->name);
		BEntry ent(ffile.Path());
		if (ent.InitCheck())
			continue;
		printf("find_font_file: found\n.");
		return ent.GetRef(to);
	}
#endif
	return ENOENT;
}

#define _BORK(_t) \
	err = find_directory(_t, &path); \
	if (!err && (s = dir->FindFirst(path.Path())) >= 0) { \
		printf("found %s\n", #_t); \
		dir->Remove(s, strlen(path.Path()) - s); \
		BString tok(#_t); \
		tok.Prepend("${"); \
		tok.Append("}"); \
		dir->Insert(tok, s); \
		return B_OK; \
	} \

status_t
escape_find_directory(BString *dir)
{
	status_t err;
	BPath path;
	int32 s;

	/* This is just the entire directory_which from FindDirectory.h */
	_BORK(B_DESKTOP_DIRECTORY);
	_BORK(B_TRASH_DIRECTORY);

	_BORK(B_BEOS_BOOT_DIRECTORY);
	_BORK(B_BEOS_FONTS_DIRECTORY);
	_BORK(B_BEOS_LIB_DIRECTORY);
	_BORK(B_BEOS_SERVERS_DIRECTORY);
	_BORK(B_BEOS_APPS_DIRECTORY);
	_BORK(B_BEOS_BIN_DIRECTORY);
	_BORK(B_BEOS_ETC_DIRECTORY);
	_BORK(B_BEOS_DOCUMENTATION_DIRECTORY);
	_BORK(B_BEOS_PREFERENCES_DIRECTORY);
	_BORK(B_BEOS_TRANSLATORS_DIRECTORY);
	_BORK(B_BEOS_MEDIA_NODES_DIRECTORY);
	_BORK(B_BEOS_SOUNDS_DIRECTORY);
	_BORK(B_BEOS_DATA_DIRECTORY);
	// not in the declared order, so others are picked first
	_BORK(B_BEOS_ADDONS_DIRECTORY);
	_BORK(B_BEOS_SYSTEM_DIRECTORY);
	_BORK(B_BEOS_DIRECTORY);

	_BORK(B_USER_BOOT_DIRECTORY);
	_BORK(B_USER_FONTS_DIRECTORY);
	_BORK(B_USER_LIB_DIRECTORY);
	_BORK(B_USER_SETTINGS_DIRECTORY);
	_BORK(B_USER_DESKBAR_DIRECTORY);
	_BORK(B_USER_PRINTERS_DIRECTORY);
	_BORK(B_USER_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_SOUNDS_DIRECTORY);

	// Out of order again.
	_BORK(B_USER_DIRECTORY);
	_BORK(B_USER_CONFIG_DIRECTORY);
	_BORK(B_USER_ADDONS_DIRECTORY);

	_BORK(B_USER_DATA_DIRECTORY);
	_BORK(B_USER_CACHE_DIRECTORY);
	_BORK(B_USER_PACKAGES_DIRECTORY);
	_BORK(B_USER_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_ADDONS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_BIN_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DATA_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_FONTS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_SOUNDS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_LIB_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DEVELOP_DIRECTORY);
	_BORK(B_USER_DEVELOP_DIRECTORY);
	_BORK(B_USER_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_SERVERS_DIRECTORY);
	_BORK(B_USER_APPS_DIRECTORY);
	_BORK(B_USER_BIN_DIRECTORY);
	_BORK(B_USER_PREFERENCES_DIRECTORY);
	_BORK(B_USER_ETC_DIRECTORY);
	_BORK(B_USER_LOG_DIRECTORY);
	_BORK(B_USER_SPOOL_DIRECTORY);
	_BORK(B_USER_VAR_DIRECTORY);

	_BORK(B_APPS_DIRECTORY);
	_BORK(B_PREFERENCES_DIRECTORY);
	_BORK(B_UTILITIES_DIRECTORY);
	_BORK(B_PACKAGE_LINKS_DIRECTORY);

	return B_OK;
}
#undef _BORK

#define _BORK(_t) \
	if (tok == #_t) { \
		err = find_directory(_t, &path); \
		if (err) return err; \
		dir->Remove(s, e - s + 1); \
		dir->Insert(path.Path(), s); \
		return B_OK; \
	} \

status_t
unescape_find_directory(BString *dir)
{
	status_t err = B_ERROR;
	int32 s, e;
	BString tok;
	BPath path;
	s = dir->FindFirst("${");
	if (s < 0)
		return B_OK;
	e = dir->FindFirst("}", s);
	if (e < 0)
		return B_OK;
	dir->CopyInto(tok, s + 2, e - s - 2);
	//printf("tok '%s'\n", tok.String());

	/* This is just the entire directory_which from FindDirectory.h */
	_BORK(B_DESKTOP_DIRECTORY);
	_BORK(B_TRASH_DIRECTORY);

	_BORK(B_BEOS_BOOT_DIRECTORY);
	_BORK(B_BEOS_FONTS_DIRECTORY);
	_BORK(B_BEOS_LIB_DIRECTORY);
	_BORK(B_BEOS_SERVERS_DIRECTORY);
	_BORK(B_BEOS_APPS_DIRECTORY);
	_BORK(B_BEOS_BIN_DIRECTORY);
	_BORK(B_BEOS_ETC_DIRECTORY);
	_BORK(B_BEOS_DOCUMENTATION_DIRECTORY);
	_BORK(B_BEOS_PREFERENCES_DIRECTORY);
	_BORK(B_BEOS_TRANSLATORS_DIRECTORY);
	_BORK(B_BEOS_MEDIA_NODES_DIRECTORY);
	_BORK(B_BEOS_SOUNDS_DIRECTORY);
	_BORK(B_BEOS_DATA_DIRECTORY);
	// not in the declared order, so others are picked first
	_BORK(B_BEOS_ADDONS_DIRECTORY);
	_BORK(B_BEOS_SYSTEM_DIRECTORY);
	_BORK(B_BEOS_DIRECTORY);

	_BORK(B_USER_BOOT_DIRECTORY);
	_BORK(B_USER_FONTS_DIRECTORY);
	_BORK(B_USER_LIB_DIRECTORY);
	_BORK(B_USER_SETTINGS_DIRECTORY);
	_BORK(B_USER_DESKBAR_DIRECTORY);
	_BORK(B_USER_PRINTERS_DIRECTORY);
	_BORK(B_USER_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_SOUNDS_DIRECTORY);

	// Out of order again.
	_BORK(B_USER_DIRECTORY);
	_BORK(B_USER_CONFIG_DIRECTORY);
	_BORK(B_USER_ADDONS_DIRECTORY);

	_BORK(B_USER_DATA_DIRECTORY);
	_BORK(B_USER_CACHE_DIRECTORY);
	_BORK(B_USER_PACKAGES_DIRECTORY);
	_BORK(B_USER_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_ADDONS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_BIN_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DATA_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_FONTS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_SOUNDS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_LIB_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DEVELOP_DIRECTORY);
	_BORK(B_USER_DEVELOP_DIRECTORY);
	_BORK(B_USER_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_SERVERS_DIRECTORY);
	_BORK(B_USER_APPS_DIRECTORY);
	_BORK(B_USER_BIN_DIRECTORY);
	_BORK(B_USER_PREFERENCES_DIRECTORY);
	_BORK(B_USER_ETC_DIRECTORY);
	_BORK(B_USER_LOG_DIRECTORY);
	_BORK(B_USER_SPOOL_DIRECTORY);
	_BORK(B_USER_VAR_DIRECTORY);

	_BORK(B_APPS_DIRECTORY);
	_BORK(B_PREFERENCES_DIRECTORY);
	_BORK(B_UTILITIES_DIRECTORY);
	_BORK(B_PACKAGE_LINKS_DIRECTORY);

	return B_OK;
}
#undef _BORK

// copy a file including its attributes
#define BUFF_SZ 1024*1024
status_t
copy_file(entry_ref *ref, const char *to)
{
	char *buff;
	status_t err = B_OK;
	//off_t off;
	//size_t got;
	(void)ref; (void)to;

	buff = (char *)malloc(BUFF_SZ);
	// XXX: TODO

	free(buff);
	return err;
}

int
testhook()
{
	status_t err;
	BString str("/boot/home/config/fonts/ttfonts/toto.ttf");
	err = escape_find_directory(&str);
	printf("error 0x%08lx %s\n", err, str.String());
	err = unescape_find_directory(&str);
	printf("error 0x%08lx %s\n", err, str.String());
	return 0;
}

status_t
FindRGBColor(BMessage &message, const char *name, int32 index, rgb_color *c)
{
#ifdef B_BEOS_VERSION_DANO
	return message.FindRGBColor(name, index, c);
#else
	const void *data;
	ssize_t len;
	status_t err;
	err = message.FindData(name, B_RGB_COLOR_TYPE, index, &data, &len);
	if (err < B_OK)
		return err;
	if (len > (ssize_t)sizeof(*c))
		return E2BIG;
	// Hack
	memcpy((void *)c, data, len);
	return B_OK;
#endif
}

status_t
AddRGBColor(BMessage &message, const char *name, rgb_color a_color, type_code type)
{
#ifdef B_BEOS_VERSION_DANO
	return message.AddRGBColor(name, a_color, type);
#else
	return message.AddData(name, type, &a_color, sizeof(a_color));
#endif
}

status_t
FindFont(BMessage &message, const char *name, int32 index, BFont *f)
{
#ifdef B_BEOS_VERSION_DANO
	return message.FindFlat(name, index, f);
#else
	const void *data;
	ssize_t len;
	status_t err = message.FindData(name, 'FONt', index, &data, &len);
#define DERR(e) { PRINT(("%s: err: %s\n", __FUNCTION__, strerror(e))); }
	if (err < B_OK)
		return err;
	if (len > (ssize_t)sizeof(*f))
		return E2BIG;
	// Hack: only Dano has BFont : public BFlattenable
	memcpy((void *)f, data, len);
	return B_OK;
#endif
}

status_t
AddFont(BMessage &message, const char *name, BFont *f, int32 count)
{
#ifdef B_BEOS_VERSION_DANO
	return message.AddFlat(name, f, count);
#else
	return message.AddData(name, 'FONt', (void *)f, sizeof(*f), true, count);
#endif
}

<commit_msg>B_BEOS_DATA_DIRECTORY -> B_SYSTEM_DATA_DIRECTORY (#2)<commit_after>/*
 * Copyright 2000-2008, François Revol, <revol@free.fr>. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "Utils.h"
#include <FindDirectory.h>
#include <Path.h>
#include <String.h>
#include <BeBuild.h>

#include <malloc.h>
#include <stdio.h>

// some private font information structs
namespace BPrivate {

typedef struct font_folder_info {
	//char name[256];
	char *name;
	uint32 flags;
} font_folder_info;

typedef struct font_file_info {
	char *name;
	uint32 flags;
	font_family family;
	font_style style;
	uint32 dummy;
} font_file_info;

};

using namespace BPrivate;

// this is PRIVATE to libbe and NOT in R5!!!
extern long _count_font_folders_(void);
extern long _count_font_files_(long);
extern status_t _get_nth_font_file_(long, font_file_info **);
extern status_t _get_nth_font_folder_(long, font_folder_info **);

status_t
find_font_file(entry_ref *to, font_family family, font_style style, float size)
{
#ifdef B_BEOS_VERSION_DANO
	status_t err = ENOENT;
	long i, fontcount, foldercount;
	font_file_info *ffi;
	font_folder_info *fdi;
	bool found = false;
	(void)size;

	fontcount = _count_font_files_(0);
	for (i = 0; i < fontcount; i++) {
		err = _get_nth_font_file_(i, &ffi);
		if (err)
			continue;
		if (strcmp(ffi->family, family) || strcmp(ffi->style, style))
			continue;
		found = true;
		break;
	}
	if (!found)
		return ENOENT;
	foldercount = _count_font_folders_();
	for (i = 0; i < fontcount; i++) {
		err = _get_nth_font_folder_(i, &fdi);
		if (err)
			continue;
		BPath ffile(fdi->name);
		ffile.Append(ffi->name);
		printf("find_font_file: looking for '%s' in '%s'\n", ffi->name, fdi->name);
		BEntry ent(ffile.Path());
		if (ent.InitCheck())
			continue;
		printf("find_font_file: found\n.");
		return ent.GetRef(to);
	}
#endif
	return ENOENT;
}

#define _BORK(_t) \
	err = find_directory(_t, &path); \
	if (!err && (s = dir->FindFirst(path.Path())) >= 0) { \
		printf("found %s\n", #_t); \
		dir->Remove(s, strlen(path.Path()) - s); \
		BString tok(#_t); \
		tok.Prepend("${"); \
		tok.Append("}"); \
		dir->Insert(tok, s); \
		return B_OK; \
	} \

status_t
escape_find_directory(BString *dir)
{
	status_t err;
	BPath path;
	int32 s;

	/* This is just the entire directory_which from FindDirectory.h */
	_BORK(B_DESKTOP_DIRECTORY);
	_BORK(B_TRASH_DIRECTORY);

	_BORK(B_BEOS_BOOT_DIRECTORY);
	_BORK(B_BEOS_FONTS_DIRECTORY);
	_BORK(B_BEOS_LIB_DIRECTORY);
	_BORK(B_BEOS_SERVERS_DIRECTORY);
	_BORK(B_BEOS_APPS_DIRECTORY);
	_BORK(B_BEOS_BIN_DIRECTORY);
	_BORK(B_BEOS_ETC_DIRECTORY);
	_BORK(B_BEOS_DOCUMENTATION_DIRECTORY);
	_BORK(B_BEOS_PREFERENCES_DIRECTORY);
	_BORK(B_BEOS_TRANSLATORS_DIRECTORY);
	_BORK(B_BEOS_MEDIA_NODES_DIRECTORY);
	_BORK(B_BEOS_SOUNDS_DIRECTORY);
	_BORK(B_SYSTEM_DATA_DIRECTORY);
	// not in the declared order, so others are picked first
	_BORK(B_BEOS_ADDONS_DIRECTORY);
	_BORK(B_BEOS_SYSTEM_DIRECTORY);
	_BORK(B_BEOS_DIRECTORY);

	_BORK(B_USER_BOOT_DIRECTORY);
	_BORK(B_USER_FONTS_DIRECTORY);
	_BORK(B_USER_LIB_DIRECTORY);
	_BORK(B_USER_SETTINGS_DIRECTORY);
	_BORK(B_USER_DESKBAR_DIRECTORY);
	_BORK(B_USER_PRINTERS_DIRECTORY);
	_BORK(B_USER_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_SOUNDS_DIRECTORY);

	// Out of order again.
	_BORK(B_USER_DIRECTORY);
	_BORK(B_USER_CONFIG_DIRECTORY);
	_BORK(B_USER_ADDONS_DIRECTORY);

	_BORK(B_USER_DATA_DIRECTORY);
	_BORK(B_USER_CACHE_DIRECTORY);
	_BORK(B_USER_PACKAGES_DIRECTORY);
	_BORK(B_USER_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_ADDONS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_BIN_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DATA_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_FONTS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_SOUNDS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_LIB_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DEVELOP_DIRECTORY);
	_BORK(B_USER_DEVELOP_DIRECTORY);
	_BORK(B_USER_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_SERVERS_DIRECTORY);
	_BORK(B_USER_APPS_DIRECTORY);
	_BORK(B_USER_BIN_DIRECTORY);
	_BORK(B_USER_PREFERENCES_DIRECTORY);
	_BORK(B_USER_ETC_DIRECTORY);
	_BORK(B_USER_LOG_DIRECTORY);
	_BORK(B_USER_SPOOL_DIRECTORY);
	_BORK(B_USER_VAR_DIRECTORY);

	_BORK(B_APPS_DIRECTORY);
	_BORK(B_PREFERENCES_DIRECTORY);
	_BORK(B_UTILITIES_DIRECTORY);
	_BORK(B_PACKAGE_LINKS_DIRECTORY);

	return B_OK;
}
#undef _BORK

#define _BORK(_t) \
	if (tok == #_t) { \
		err = find_directory(_t, &path); \
		if (err) return err; \
		dir->Remove(s, e - s + 1); \
		dir->Insert(path.Path(), s); \
		return B_OK; \
	} \

status_t
unescape_find_directory(BString *dir)
{
	status_t err = B_ERROR;
	int32 s, e;
	BString tok;
	BPath path;
	s = dir->FindFirst("${");
	if (s < 0)
		return B_OK;
	e = dir->FindFirst("}", s);
	if (e < 0)
		return B_OK;
	dir->CopyInto(tok, s + 2, e - s - 2);
	//printf("tok '%s'\n", tok.String());

	/* This is just the entire directory_which from FindDirectory.h */
	_BORK(B_DESKTOP_DIRECTORY);
	_BORK(B_TRASH_DIRECTORY);

	_BORK(B_BEOS_BOOT_DIRECTORY);
	_BORK(B_BEOS_FONTS_DIRECTORY);
	_BORK(B_BEOS_LIB_DIRECTORY);
	_BORK(B_BEOS_SERVERS_DIRECTORY);
	_BORK(B_BEOS_APPS_DIRECTORY);
	_BORK(B_BEOS_BIN_DIRECTORY);
	_BORK(B_BEOS_ETC_DIRECTORY);
	_BORK(B_BEOS_DOCUMENTATION_DIRECTORY);
	_BORK(B_BEOS_PREFERENCES_DIRECTORY);
	_BORK(B_BEOS_TRANSLATORS_DIRECTORY);
	_BORK(B_BEOS_MEDIA_NODES_DIRECTORY);
	_BORK(B_BEOS_SOUNDS_DIRECTORY);
	_BORK(B_SYSTEM_DATA_DIRECTORY);
	// not in the declared order, so others are picked first
	_BORK(B_BEOS_ADDONS_DIRECTORY);
	_BORK(B_BEOS_SYSTEM_DIRECTORY);
	_BORK(B_BEOS_DIRECTORY);

	_BORK(B_USER_BOOT_DIRECTORY);
	_BORK(B_USER_FONTS_DIRECTORY);
	_BORK(B_USER_LIB_DIRECTORY);
	_BORK(B_USER_SETTINGS_DIRECTORY);
	_BORK(B_USER_DESKBAR_DIRECTORY);
	_BORK(B_USER_PRINTERS_DIRECTORY);
	_BORK(B_USER_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_SOUNDS_DIRECTORY);

	// Out of order again.
	_BORK(B_USER_DIRECTORY);
	_BORK(B_USER_CONFIG_DIRECTORY);
	_BORK(B_USER_ADDONS_DIRECTORY);

	_BORK(B_USER_DATA_DIRECTORY);
	_BORK(B_USER_CACHE_DIRECTORY);
	_BORK(B_USER_PACKAGES_DIRECTORY);
	_BORK(B_USER_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_ADDONS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_BIN_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DATA_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_FONTS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_SOUNDS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_LIB_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_HEADERS_DIRECTORY);
	_BORK(B_USER_NONPACKAGED_DEVELOP_DIRECTORY);
	_BORK(B_USER_DEVELOP_DIRECTORY);
	_BORK(B_USER_DOCUMENTATION_DIRECTORY);
	_BORK(B_USER_SERVERS_DIRECTORY);
	_BORK(B_USER_APPS_DIRECTORY);
	_BORK(B_USER_BIN_DIRECTORY);
	_BORK(B_USER_PREFERENCES_DIRECTORY);
	_BORK(B_USER_ETC_DIRECTORY);
	_BORK(B_USER_LOG_DIRECTORY);
	_BORK(B_USER_SPOOL_DIRECTORY);
	_BORK(B_USER_VAR_DIRECTORY);

	_BORK(B_APPS_DIRECTORY);
	_BORK(B_PREFERENCES_DIRECTORY);
	_BORK(B_UTILITIES_DIRECTORY);
	_BORK(B_PACKAGE_LINKS_DIRECTORY);

	return B_OK;
}
#undef _BORK

// copy a file including its attributes
#define BUFF_SZ 1024*1024
status_t
copy_file(entry_ref *ref, const char *to)
{
	char *buff;
	status_t err = B_OK;
	//off_t off;
	//size_t got;
	(void)ref; (void)to;

	buff = (char *)malloc(BUFF_SZ);
	// XXX: TODO

	free(buff);
	return err;
}

int
testhook()
{
	status_t err;
	BString str("/boot/home/config/fonts/ttfonts/toto.ttf");
	err = escape_find_directory(&str);
	printf("error 0x%08lx %s\n", err, str.String());
	err = unescape_find_directory(&str);
	printf("error 0x%08lx %s\n", err, str.String());
	return 0;
}

status_t
FindRGBColor(BMessage &message, const char *name, int32 index, rgb_color *c)
{
#ifdef B_BEOS_VERSION_DANO
	return message.FindRGBColor(name, index, c);
#else
	const void *data;
	ssize_t len;
	status_t err;
	err = message.FindData(name, B_RGB_COLOR_TYPE, index, &data, &len);
	if (err < B_OK)
		return err;
	if (len > (ssize_t)sizeof(*c))
		return E2BIG;
	// Hack
	memcpy((void *)c, data, len);
	return B_OK;
#endif
}

status_t
AddRGBColor(BMessage &message, const char *name, rgb_color a_color, type_code type)
{
#ifdef B_BEOS_VERSION_DANO
	return message.AddRGBColor(name, a_color, type);
#else
	return message.AddData(name, type, &a_color, sizeof(a_color));
#endif
}

status_t
FindFont(BMessage &message, const char *name, int32 index, BFont *f)
{
#ifdef B_BEOS_VERSION_DANO
	return message.FindFlat(name, index, f);
#else
	const void *data;
	ssize_t len;
	status_t err = message.FindData(name, 'FONt', index, &data, &len);
#define DERR(e) { PRINT(("%s: err: %s\n", __FUNCTION__, strerror(e))); }
	if (err < B_OK)
		return err;
	if (len > (ssize_t)sizeof(*f))
		return E2BIG;
	// Hack: only Dano has BFont : public BFlattenable
	memcpy((void *)f, data, len);
	return B_OK;
#endif
}

status_t
AddFont(BMessage &message, const char *name, BFont *f, int32 count)
{
#ifdef B_BEOS_VERSION_DANO
	return message.AddFlat(name, f, count);
#else
	return message.AddData(name, 'FONt', (void *)f, sizeof(*f), true, count);
#endif
}

<|endoftext|>


<commit_before>//===========================================
//  PC-BSD source code
//  Copyright (c) 2016, PC-BSD Software/iXsystems
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "TrayUI.h"

#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif

QHash<QString,sysadm_client*> CORES; // hostIP / core
QHash<QString, HostMessage> MESSAGES; // "hostIP/message_type", Message Structure

// === PUBLIC ===
sysadm_tray::sysadm_tray() : QSystemTrayIcon(){
  CMAN = 0; SDLG = 0;
  showNotices = false;
  iconreset = true;
  cPriority = 0;
  iconTimer = new QTimer(this);
    iconTimer->setInterval(1500); //1.5 seconds
    connect(iconTimer, SIGNAL(timeout()), this, SLOT(UpdateIcon()) );
  //Load any CORES
  updateCoreList();

  //Setup the tray icon
  UpdateIcon();
  connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivated()) );
  //Setup the message menu
  msgMenu = new QMenu();
    msgMenu->setIcon( QIcon(":/icons/black/inbox.svg") );
    QAction *act = msgMenu->addAction(QIcon(":/icons/black/trash.svg"), tr("Hide all messages"));
      act->setWhatsThis("clearall");
      QFont fnt = act->font(); fnt.setItalic(true);
      act->setFont(fnt);
    msgMenu->addSeparator();
    connect(msgMenu, SIGNAL(triggered(QAction*)), this, SLOT(MessageTriggered(QAction*)) );

  //Setup the menu
  menu = new MenuItem(0,"",msgMenu);
  this->setContextMenu(menu);
  connect(menu, SIGNAL(OpenConnectionManager()), this, SLOT(OpenConnectionManager()) );
  connect(menu, SIGNAL(OpenSettings()), this, SLOT(OpenSettings()) );
  connect(menu, SIGNAL(CloseApplication()),this, SLOT(CloseApplication()) );
  connect(menu, SIGNAL(OpenCore(QString)), this, SLOT(OpenCore(QString)) );
  connect(menu, SIGNAL(ShowMessage(HostMessage)), this, SLOT(ShowMessage(HostMessage)) );
  connect(menu, SIGNAL(ClearMessage(QString, QString)), this, SLOT(ClearMessage(QString, QString)) );
  connect(menu, SIGNAL(UnlockConnections()), this, SLOT(UnlockConnections()) );
  connect(menu, SIGNAL(UpdateTrayIcon()), this, SLOT(UpdateIconPriority()) );
  QTimer::singleShot(10, menu, SLOT(UpdateMenu()) );
  QTimer::singleShot(0,this, SLOT(updateMessageMenu()) );
}

sysadm_tray::~sysadm_tray(){
  if(CMAN!=0){ delete CMAN; }
  if(SDLG!=0){ delete SDLG; }
  delete this->contextMenu(); //Note in docs that the tray does not take ownership of this menu
}

// === PRIVATE ===
sysadm_client* sysadm_tray::getCore(QString host){
  //simplification to ensure that core always exists fot the given host
  if(!CORES.contains(host)){
    CORES.insert(host, new sysadm_client());
    CORES[host]->registerForEvents(sysadm_client::SYSSTATE);
    #ifdef __FreeBSD__
     //Also load the currently-running user for this process and place that into the UI automatically
      //Note: This will only be valid on FreeBSD systems (since the server is only for FreeBSD)
    if(host==LOCALHOST){ CORES[host]->openConnection(getlogin(),"",LOCALHOST); }
    #endif
  }
  return CORES[host];
}

// === PRIVATE SLOTS ===
void sysadm_tray::trayActivated(){
  qDebug() << "tray activated";
  if(this->contextMenu()!=0){
     this->contextMenu()->popup( this->geometry().center());
  }
}

// - Application-wide setting changed
void sysadm_tray::UpdateWindows(){
  //First check for any of the special windows (skip settings window)
  //if(CMAN!=0){ QTimer::singleShot(0, CMAN, SLOT(UpdateWindow()) ); }
  //Now do all the open client windows
  /*for(int i=0; i<CLIENTS.length(); i++){
    QTimer::singleShot(0, CLIENTS[i], SLOT(UpdateUI()) );
  }*/
}

void sysadm_tray::updateCoreList(){
  showNotices = false;
  //First add the localhost to the top of the list (if available)
  if(sysadm_client::localhostAvailable() ){
    getCore(LOCALHOST);
  }
  //Now add any known hosts (including connection status)
  if(!SSL_cfg.isNull()){
    QStringList known = settings->allKeys().filter("Hosts/").filter("/username");
    //syntax: Hosts/<hostIP>/username = <username>
    known.sort(); //sort by name
    //Now add these hosts to the menu
    for(int i=0; i<known.length(); i++){
      QString host = known[i].section("/",1,-1).section("/username",0,0);
      if(!CORES.contains(host)){
          qDebug() << "Connect To Host:" << host;
	  getCore(host);
	  QString user = settings->value(known[i]).toString();
	  CORES[host]->openConnection(host);
      }
    }
  }
  QTimer::singleShot(1000, this, SLOT(allowPopups()) );
}

void sysadm_tray::ClientClosed(MainUI* client){
  qDebug() << "Client Closed";
  int index = CLIENTS.indexOf(client);
  if(index >=0){ CLIENTS.takeAt(index)->deleteLater(); }
}

//Menu Actions
void sysadm_tray::OpenConnectionManager(){
  if(CMAN==0){
    CMAN = new C_Manager();
    connect(CMAN, SIGNAL(SettingsChanged()), menu, SLOT(UpdateMenu()) );
  }
  CMAN->showNormal();
}

void sysadm_tray::OpenSettings(){
  if(SDLG==0){
    SDLG = new SettingsDialog();
    connect(SDLG, SIGNAL(updateWindows()), this, SLOT(UpdateWindows()) );
  }
  SDLG->showNormal();
}

void sysadm_tray::CloseApplication(){
  //perform any cleanup
    // Disconnect any cores
  QStringList cores = CORES.keys();
  for(int i=0; i<cores.length(); i++){
    qDebug() << "Closing Connection:" << CORES[cores[i]]->currentHost();
    CORES[ cores[i] ]->closeConnection();
  }
    // Close any clients
  if(!CLIENTS.isEmpty()){ qDebug() << "Closing open client:" << CLIENTS.length();}
  for(int i=0; i<CLIENTS.length(); i++){
    CLIENTS[i]->close();
  }
    // Delete any cores (should be disconnected by now)
  for(int i=0; i<cores.length(); i++){
    qDebug() << "Deleting Cores...";
    delete CORES.take(cores[i]);
  }
  QCoreApplication::exit(0);
}

void sysadm_tray::OpenCore(QString host, QString page){
  //See if a window for this host is already open and use that
  qDebug() << "Open Host Window:" << host;
  for(int i=0; i<CLIENTS.length(); i++){
    if(CLIENTS[i]->currentHost()==host){
       //if(CLIENTS[i]->currentCore()->isReady()){
         CLIENTS[i]->showNormal();
      //}
      return;
    }
  }
  //Split the host ID into host/bridge if necessary
  QString b_id = host.section("/",1,-1);
  if(!b_id.isEmpty()){ host = host.section("/",0,0); }
  if(getCore(host)->isConnecting()){ return; } //wait - still trying to connect
  else if(!getCore(host)->isReady()){
    if(getCore(host)->needsBaseAuth()){
      //Need to use username/password to re-connect
      QString user = settings->value("Hosts/"+host+"/username").toString(); //Have username already in settings
      QString pass = QInputDialog::getText(0, host + ": "+tr("Password Required"), QString(tr("Password for %1")).arg(user), QLineEdit::Password);
      if(!pass.isEmpty()){ getCore(host)->openConnection(user, pass, host); }
    }else{
      getCore(host)->openConnection();
    }
    return;
  }
  if(b_id.isEmpty() && getCore(host)->isBridge()){ return; }
  //Open a new window for this host
  sysadm_client *core = getCore(host);
    MainUI *tmp = new MainUI(core, page, b_id);
    if(core->isReady()){  tmp->showNormal(); }
    connect(tmp, SIGNAL(ClientClosed(MainUI*)), this, SLOT(ClientClosed(MainUI*)) );
    CLIENTS << tmp;
}

void sysadm_tray::UnlockConnections(){
  UpdateIcon();
  //Open all the cores
  updateCoreList();
  //Update the menu
  QTimer::singleShot(0, menu, SLOT(UpdateMenu()) );
  QTimer::singleShot(50, this, SLOT(trayActivated()) );
}

//Popup Notifications
void sysadm_tray::ShowMessage(HostMessage msg){
  //qDebug() << "Got Show Message";
  bool refreshlist = true;
  //Update the internal database of messages
  if(MESSAGES.contains(msg.host_id+"/"+msg.message_id) ){
    //see if this message is new or not
    HostMessage old = MESSAGES[msg.host_id+"/"+msg.message_id];
    if(old.message==msg.message /*&& old.date_time > msg.date_time*/){ refreshlist=false; } //same hidden message - don't re-show it
    else{ MESSAGES.insert(msg.host_id+"/"+msg.message_id, msg); }
  }else{
    MESSAGES.insert(msg.host_id+"/"+msg.message_id, msg);
  }
  //Now update the user-viewable menu's
  if(refreshlist){
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
  }
}

void sysadm_tray::ClearMessage(QString host, QString msg_id){
  //qDebug() << "Clear Message:" << host << msg_id;
  if(MESSAGES.contains(host+"/"+msg_id)){
    MESSAGES.remove(host+"/"+msg_id);
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
  }
}

void sysadm_tray::MessageTriggered(QAction *act){
  if(act->whatsThis()=="clearall"){
    QStringList keys = MESSAGES.keys();
    QDateTime cdt = QDateTime::currentDateTime();
    QDateTime delay = cdt.addDays(1);
    //qDebug() << "Clear all messages:" << cdt << " -to-" << delay;
    for(int i=0; i<keys.length(); i++){
      if(MESSAGES[keys[i]].date_time.secsTo(cdt)>1 ){
        HostMessage msg = MESSAGES[keys[i]];
          msg.date_time = delay;
        MESSAGES.insert(keys[i],msg);
      }
    }
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
  }else if(MESSAGES.contains(act->whatsThis())){
    //Open the designated host and hide this message
    HostMessage msg = MESSAGES[act->whatsThis()];
      //Lower the priority down to stop the tray notifications
      if(msg.priority>2){ msg.priority=2; }
      //msg.date_time = QDateTime::currentDateTime().addDays(1); //hide for one day if unresolved in the meantime;
    MESSAGES.insert(act->whatsThis(),msg);
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
    if(act->whatsThis().section("/",-1)=="updates"){ OpenCore(msg.host_id, "page_updates"); }
    else{ OpenCore(msg.host_id); }
  }
}

//Function to update the messageMenu
void sysadm_tray::updateMessageMenu(){
  //qDebug() << "Update Message Menu:";
  QStringList keys = MESSAGES.keys();
  QList<QAction*> acts = msgMenu->actions();
  //First update the existing actions as needed
  int num = 0; //for the final tally of messages which are visible
  QDateTime cdt = QDateTime::currentDateTime();
  //qDebug() << "Current DT/keys" << cdt << keys;
  uint cdt_t = cdt.toTime_t();
  for(int i=0; i<acts.length(); i++){
    //qDebug() << " - Check Act:" << acts[i]->whatsThis();
    if(keys.contains(acts[i]->whatsThis()) && (MESSAGES[acts[i]->whatsThis()].date_time.toTime_t() < cdt_t) ){
      //qDebug() << " - Update action" << MESSAGES[acts[i]->whatsThis()].date_time;
      acts[i]->setText( MESSAGES[acts[i]->whatsThis()].message );
      acts[i]->setIcon( QIcon(MESSAGES[acts[i]->whatsThis()].iconfile) );
      num++;
      keys.removeAll(acts[i]->whatsThis()); //already handled
    }else if( acts[i]->whatsThis()!="clearall" && !acts[i]->whatsThis().isEmpty() ) {
      //qDebug() << " - Remove Action";
      msgMenu->removeAction(acts[i]);
    }
  }
  //Now add in any new messages
  for(int i=0; i<keys.length(); i++){
    if(MESSAGES[keys[i]].date_time.secsTo(cdt)>-1){
      //qDebug() << " Add new action:" << keys[i];
      QAction *act = msgMenu->addAction( QIcon(MESSAGES[keys[i]].iconfile),MESSAGES[keys[i]].message );
	act->setWhatsThis(keys[i]);
	num++;
    }
  }
  //Now update the main menu title to account for the new number of messages
  QString title = tr("Messages");
  if(num>0){ title.prepend("("+QString::number(num)+") "); }
  msgMenu->setTitle(title);
  msgMenu->setEnabled(num>0);
  UpdateIconPriority();
}

//Icon Updates
void sysadm_tray::UpdateIconPriority(){
  int pri = 0;
  QStringList keys = MESSAGES.keys();
  QDateTime cdt = QDateTime::currentDateTime();
  //qDebug() << "Update Priority:" << cdt;
  for(int i=0; i<keys.length(); i++){
    //qDebug() << "Check Key:" << keys[i] << MESSAGES[keys[i]].priority << MESSAGES[keys[i]].date_time;
    if(MESSAGES[keys[i]].date_time.secsTo(cdt) <-1 ){ continue; } //hidden message - ignore it for priorities
    if(MESSAGES[keys[i]].priority > pri){ pri = MESSAGES[keys[i]].priority; }
  }
  cPriority = pri; //save for use
  //Update the icon right now
  if(iconTimer->isActive()){ iconTimer->stop(); }
  iconreset = false;
  UpdateIcon();
  //Now setup the automatic flashing
  if(cPriority >2 && cPriority < 9){ iconTimer->start();  }
}

void sysadm_tray::UpdateIcon(){
  //qDebug() << "Update Icon:" << cPriority << QDateTime::currentDateTime();
  QString icon = ":/icons/custom/sysadm_circle.svg";
  if(iconreset || cPriority <3){
    if(SSL_cfg.isNull()){ icon = ":/icons/custom/sysadm_circle_grey.png"; }
  }else if(cPriority < 6){  icon = ":/icons/custom/sysadm_circle_yellow.png"; }
  else if(cPriority < 9){  icon = ":/icons/custom/sysadm_circle_orange.png"; }
  else if(cPriority==9){  icon = ":/icons/custom/sysadm_circle_red.png"; }
  this->setIcon( QIcon(icon) );
  //Reset the icon flag as needed (for next run)
  iconreset = !iconreset;

}
<commit_msg>Streamline a bit of the closedown operations for sysadm client.<commit_after>//===========================================
//  PC-BSD source code
//  Copyright (c) 2016, PC-BSD Software/iXsystems
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "TrayUI.h"

#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif

QHash<QString,sysadm_client*> CORES; // hostIP / core
QHash<QString, HostMessage> MESSAGES; // "hostIP/message_type", Message Structure

// === PUBLIC ===
sysadm_tray::sysadm_tray() : QSystemTrayIcon(){
  CMAN = 0; SDLG = 0;
  showNotices = false;
  iconreset = true;
  cPriority = 0;
  iconTimer = new QTimer(this);
    iconTimer->setInterval(1500); //1.5 seconds
    connect(iconTimer, SIGNAL(timeout()), this, SLOT(UpdateIcon()) );
  //Load any CORES
  updateCoreList();

  //Setup the tray icon
  UpdateIcon();
  connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivated()) );
  //Setup the message menu
  msgMenu = new QMenu();
    msgMenu->setIcon( QIcon(":/icons/black/inbox.svg") );
    QAction *act = msgMenu->addAction(QIcon(":/icons/black/trash.svg"), tr("Hide all messages"));
      act->setWhatsThis("clearall");
      QFont fnt = act->font(); fnt.setItalic(true);
      act->setFont(fnt);
    msgMenu->addSeparator();
    connect(msgMenu, SIGNAL(triggered(QAction*)), this, SLOT(MessageTriggered(QAction*)) );

  //Setup the menu
  menu = new MenuItem(0,"",msgMenu);
  this->setContextMenu(menu);
  connect(menu, SIGNAL(OpenConnectionManager()), this, SLOT(OpenConnectionManager()) );
  connect(menu, SIGNAL(OpenSettings()), this, SLOT(OpenSettings()) );
  connect(menu, SIGNAL(CloseApplication()),this, SLOT(CloseApplication()) );
  connect(menu, SIGNAL(OpenCore(QString)), this, SLOT(OpenCore(QString)) );
  connect(menu, SIGNAL(ShowMessage(HostMessage)), this, SLOT(ShowMessage(HostMessage)) );
  connect(menu, SIGNAL(ClearMessage(QString, QString)), this, SLOT(ClearMessage(QString, QString)) );
  connect(menu, SIGNAL(UnlockConnections()), this, SLOT(UnlockConnections()) );
  connect(menu, SIGNAL(UpdateTrayIcon()), this, SLOT(UpdateIconPriority()) );
  QTimer::singleShot(10, menu, SLOT(UpdateMenu()) );
  QTimer::singleShot(0,this, SLOT(updateMessageMenu()) );
}

sysadm_tray::~sysadm_tray(){
  if(CMAN!=0){ CMAN->deleteLater(); }
  if(SDLG!=0){ SDLG->deleteLater(); }
  delete this->contextMenu(); //Note in docs that the tray does not take ownership of this menu
}

// === PRIVATE ===
sysadm_client* sysadm_tray::getCore(QString host){
  //simplification to ensure that core always exists fot the given host
  if(!CORES.contains(host)){
    CORES.insert(host, new sysadm_client());
    CORES[host]->registerForEvents(sysadm_client::SYSSTATE);
    #ifdef __FreeBSD__
     //Also load the currently-running user for this process and place that into the UI automatically
      //Note: This will only be valid on FreeBSD systems (since the server is only for FreeBSD)
    if(host==LOCALHOST){ CORES[host]->openConnection(getlogin(),"",LOCALHOST); }
    #endif
  }
  return CORES[host];
}

// === PRIVATE SLOTS ===
void sysadm_tray::trayActivated(){
  qDebug() << "tray activated";
  if(this->contextMenu()!=0){
     this->contextMenu()->popup( this->geometry().center());
  }
}

// - Application-wide setting changed
void sysadm_tray::UpdateWindows(){
  //First check for any of the special windows (skip settings window)
  //if(CMAN!=0){ QTimer::singleShot(0, CMAN, SLOT(UpdateWindow()) ); }
  //Now do all the open client windows
  /*for(int i=0; i<CLIENTS.length(); i++){
    QTimer::singleShot(0, CLIENTS[i], SLOT(UpdateUI()) );
  }*/
}

void sysadm_tray::updateCoreList(){
  showNotices = false;
  //First add the localhost to the top of the list (if available)
  if(sysadm_client::localhostAvailable() ){
    getCore(LOCALHOST);
  }
  //Now add any known hosts (including connection status)
  if(!SSL_cfg.isNull()){
    QStringList known = settings->allKeys().filter("Hosts/").filter("/username");
    //syntax: Hosts/<hostIP>/username = <username>
    known.sort(); //sort by name
    //Now add these hosts to the menu
    for(int i=0; i<known.length(); i++){
      QString host = known[i].section("/",1,-1).section("/username",0,0);
      if(!CORES.contains(host)){
          qDebug() << "Connect To Host:" << host;
	  getCore(host);
	  QString user = settings->value(known[i]).toString();
	  CORES[host]->openConnection(host);
      }
    }
  }
  QTimer::singleShot(1000, this, SLOT(allowPopups()) );
}

void sysadm_tray::ClientClosed(MainUI* client){
  qDebug() << "Client Closed";
  int index = CLIENTS.indexOf(client);
  if(index >=0){ CLIENTS.takeAt(index)->deleteLater(); }
}

//Menu Actions
void sysadm_tray::OpenConnectionManager(){
  if(CMAN==0){
    CMAN = new C_Manager();
    connect(CMAN, SIGNAL(SettingsChanged()), menu, SLOT(UpdateMenu()) );
  }
  CMAN->showNormal();
}

void sysadm_tray::OpenSettings(){
  if(SDLG==0){
    SDLG = new SettingsDialog();
    connect(SDLG, SIGNAL(updateWindows()), this, SLOT(UpdateWindows()) );
  }
  SDLG->showNormal();
}

void sysadm_tray::CloseApplication(){
  //perform any cleanup
    // Disconnect any cores
  QStringList cores = CORES.keys();
  for(int i=0; i<cores.length(); i++){
    qDebug() << "Closing Connection:" << CORES[cores[i]]->currentHost();
    QTimer::singleShot(0, CORES[ cores[i] ], SLOT(closeConnection()));
  }
    // Close any clients
  if(!CLIENTS.isEmpty()){ qDebug() << "Closing open client:" << CLIENTS.length();}
  for(int i=0; i<CLIENTS.length(); i++){
    CLIENTS[i]->deleteLater();
  }
  QApplication::processEvents();
    // Delete any cores (should be disconnected by now)
  for(int i=0; i<cores.length(); i++){
    QApplication::processEvents();
    qDebug() << "Deleting Cores...";
    delete CORES.take(cores[i]);
  }
  QCoreApplication::exit(0);
}

void sysadm_tray::OpenCore(QString host, QString page){
  //See if a window for this host is already open and use that
  qDebug() << "Open Host Window:" << host;
  for(int i=0; i<CLIENTS.length(); i++){
    if(CLIENTS[i]->currentHost()==host){
       //if(CLIENTS[i]->currentCore()->isReady()){
         CLIENTS[i]->showNormal();
      //}
      return;
    }
  }
  //Split the host ID into host/bridge if necessary
  QString b_id = host.section("/",1,-1);
  if(!b_id.isEmpty()){ host = host.section("/",0,0); }
  if(getCore(host)->isConnecting()){ return; } //wait - still trying to connect
  else if(!getCore(host)->isReady()){
    if(getCore(host)->needsBaseAuth()){
      //Need to use username/password to re-connect
      QString user = settings->value("Hosts/"+host+"/username").toString(); //Have username already in settings
      QString pass = QInputDialog::getText(0, host + ": "+tr("Password Required"), QString(tr("Password for %1")).arg(user), QLineEdit::Password);
      if(!pass.isEmpty()){ getCore(host)->openConnection(user, pass, host); }
    }else{
      getCore(host)->openConnection();
    }
    return;
  }
  if(b_id.isEmpty() && getCore(host)->isBridge()){ return; }
  //Open a new window for this host
  sysadm_client *core = getCore(host);
    MainUI *tmp = new MainUI(core, page, b_id);
    if(core->isReady()){  tmp->showNormal(); }
    connect(tmp, SIGNAL(ClientClosed(MainUI*)), this, SLOT(ClientClosed(MainUI*)) );
    CLIENTS << tmp;
}

void sysadm_tray::UnlockConnections(){
  UpdateIcon();
  //Open all the cores
  updateCoreList();
  //Update the menu
  QTimer::singleShot(0, menu, SLOT(UpdateMenu()) );
  QTimer::singleShot(50, this, SLOT(trayActivated()) );
}

//Popup Notifications
void sysadm_tray::ShowMessage(HostMessage msg){
  //qDebug() << "Got Show Message";
  bool refreshlist = true;
  //Update the internal database of messages
  if(MESSAGES.contains(msg.host_id+"/"+msg.message_id) ){
    //see if this message is new or not
    HostMessage old = MESSAGES[msg.host_id+"/"+msg.message_id];
    if(old.message==msg.message /*&& old.date_time > msg.date_time*/){ refreshlist=false; } //same hidden message - don't re-show it
    else{ MESSAGES.insert(msg.host_id+"/"+msg.message_id, msg); }
  }else{
    MESSAGES.insert(msg.host_id+"/"+msg.message_id, msg);
  }
  //Now update the user-viewable menu's
  if(refreshlist){
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
  }
}

void sysadm_tray::ClearMessage(QString host, QString msg_id){
  //qDebug() << "Clear Message:" << host << msg_id;
  if(MESSAGES.contains(host+"/"+msg_id)){
    MESSAGES.remove(host+"/"+msg_id);
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
  }
}

void sysadm_tray::MessageTriggered(QAction *act){
  if(act->whatsThis()=="clearall"){
    QStringList keys = MESSAGES.keys();
    QDateTime cdt = QDateTime::currentDateTime();
    QDateTime delay = cdt.addDays(1);
    //qDebug() << "Clear all messages:" << cdt << " -to-" << delay;
    for(int i=0; i<keys.length(); i++){
      if(MESSAGES[keys[i]].date_time.secsTo(cdt)>1 ){
        HostMessage msg = MESSAGES[keys[i]];
          msg.date_time = delay;
        MESSAGES.insert(keys[i],msg);
      }
    }
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
  }else if(MESSAGES.contains(act->whatsThis())){
    //Open the designated host and hide this message
    HostMessage msg = MESSAGES[act->whatsThis()];
      //Lower the priority down to stop the tray notifications
      if(msg.priority>2){ msg.priority=2; }
      //msg.date_time = QDateTime::currentDateTime().addDays(1); //hide for one day if unresolved in the meantime;
    MESSAGES.insert(act->whatsThis(),msg);
    QTimer::singleShot(10,this, SLOT(updateMessageMenu()) );
    if(act->whatsThis().section("/",-1)=="updates"){ OpenCore(msg.host_id, "page_updates"); }
    else{ OpenCore(msg.host_id); }
  }
}

//Function to update the messageMenu
void sysadm_tray::updateMessageMenu(){
  //qDebug() << "Update Message Menu:";
  QStringList keys = MESSAGES.keys();
  QList<QAction*> acts = msgMenu->actions();
  //First update the existing actions as needed
  int num = 0; //for the final tally of messages which are visible
  QDateTime cdt = QDateTime::currentDateTime();
  //qDebug() << "Current DT/keys" << cdt << keys;
  uint cdt_t = cdt.toTime_t();
  for(int i=0; i<acts.length(); i++){
    //qDebug() << " - Check Act:" << acts[i]->whatsThis();
    if(keys.contains(acts[i]->whatsThis()) && (MESSAGES[acts[i]->whatsThis()].date_time.toTime_t() < cdt_t) ){
      //qDebug() << " - Update action" << MESSAGES[acts[i]->whatsThis()].date_time;
      acts[i]->setText( MESSAGES[acts[i]->whatsThis()].message );
      acts[i]->setIcon( QIcon(MESSAGES[acts[i]->whatsThis()].iconfile) );
      num++;
      keys.removeAll(acts[i]->whatsThis()); //already handled
    }else if( acts[i]->whatsThis()!="clearall" && !acts[i]->whatsThis().isEmpty() ) {
      //qDebug() << " - Remove Action";
      msgMenu->removeAction(acts[i]);
    }
  }
  //Now add in any new messages
  for(int i=0; i<keys.length(); i++){
    if(MESSAGES[keys[i]].date_time.secsTo(cdt)>-1){
      //qDebug() << " Add new action:" << keys[i];
      QAction *act = msgMenu->addAction( QIcon(MESSAGES[keys[i]].iconfile),MESSAGES[keys[i]].message );
	act->setWhatsThis(keys[i]);
	num++;
    }
  }
  //Now update the main menu title to account for the new number of messages
  QString title = tr("Messages");
  if(num>0){ title.prepend("("+QString::number(num)+") "); }
  msgMenu->setTitle(title);
  msgMenu->setEnabled(num>0);
  UpdateIconPriority();
}

//Icon Updates
void sysadm_tray::UpdateIconPriority(){
  int pri = 0;
  QStringList keys = MESSAGES.keys();
  QDateTime cdt = QDateTime::currentDateTime();
  //qDebug() << "Update Priority:" << cdt;
  for(int i=0; i<keys.length(); i++){
    //qDebug() << "Check Key:" << keys[i] << MESSAGES[keys[i]].priority << MESSAGES[keys[i]].date_time;
    if(MESSAGES[keys[i]].date_time.secsTo(cdt) <-1 ){ continue; } //hidden message - ignore it for priorities
    if(MESSAGES[keys[i]].priority > pri){ pri = MESSAGES[keys[i]].priority; }
  }
  cPriority = pri; //save for use
  //Update the icon right now
  if(iconTimer->isActive()){ iconTimer->stop(); }
  iconreset = false;
  UpdateIcon();
  //Now setup the automatic flashing
  if(cPriority >2 && cPriority < 9){ iconTimer->start();  }
}

void sysadm_tray::UpdateIcon(){
  //qDebug() << "Update Icon:" << cPriority << QDateTime::currentDateTime();
  QString icon = ":/icons/custom/sysadm_circle.svg";
  if(iconreset || cPriority <3){
    if(SSL_cfg.isNull()){ icon = ":/icons/custom/sysadm_circle_grey.png"; }
  }else if(cPriority < 6){  icon = ":/icons/custom/sysadm_circle_yellow.png"; }
  else if(cPriority < 9){  icon = ":/icons/custom/sysadm_circle_orange.png"; }
  else if(cPriority==9){  icon = ":/icons/custom/sysadm_circle_red.png"; }
  this->setIcon( QIcon(icon) );
  //Reset the icon flag as needed (for next run)
  iconreset = !iconreset;

}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// C++
#include <iostream>

// This class
#include "grins/grins_enums.h"
#include "grins/mesh_builder.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/mesh_modification.h"
#include "libmesh/mesh_refinement.h"
#include "libmesh/parallel_mesh.h"
#include "libmesh/parsed_function.h"
#include "libmesh/serial_mesh.h"

namespace GRINS
{

  MeshBuilder::MeshBuilder()
  {
    return;
  }

  MeshBuilder::~MeshBuilder()
  {
    return;
  }

  std::tr1::shared_ptr<libMesh::UnstructuredMesh> MeshBuilder::build
    (const GetPot& input,
     const libMesh::Parallel::Communicator &comm)
  {
    // First, read all needed variables
    std::string mesh_option = input("mesh-options/mesh_option", "NULL");
    std::string mesh_filename = input("mesh-options/mesh_filename", "NULL");

    libMesh::Real domain_x1_min = input("mesh-options/domain_x1_min", 0.0);
    libMesh::Real domain_x2_min = input("mesh-options/domain_x2_min", 0.0);
    libMesh::Real domain_x3_min = input("mesh-options/domain_x3_min", 0.0);

    libMesh::Real domain_x1_max = input("mesh-options/domain_x1_max", 1.0);
    libMesh::Real domain_x2_max = input("mesh-options/domain_x2_max", 1.0);
    libMesh::Real domain_x3_max = input("mesh-options/domain_x3_max", 1.0);

    int mesh_nx1 = input("mesh-options/mesh_nx1", -1);
    int mesh_nx2 = input("mesh-options/mesh_nx2", -1);
    int mesh_nx3 = input("mesh-options/mesh_nx3", -1);

    std::string element_type = input("mesh-options/element_type", "NULL");

    // Make sure the user told us what to do
    if(mesh_option == "NULL")
      {
	std::cerr << " MeshBuilder::read_input_options :"
		  << " mesh-options/mesh_option NOT specified "
		  << std::endl;
	libmesh_error();
      }

    // Create UnstructuredMesh object (defaults to dimension 1).
    libMesh::UnstructuredMesh* mesh;

    // Were we specifically asked to use a ParallelMesh or SerialMesh?
    std::string mesh_class = input("mesh-options/mesh_class", "default");

    if (mesh_class == "parallel")
      mesh = new libMesh::ParallelMesh(comm);
    else if (mesh_class == "serial")
      mesh = new libMesh::SerialMesh(comm);
    else if (mesh_class == "default")
      mesh = new libMesh::Mesh(comm);
    else
      {
        std::cerr << " MeshBuilder::build:"
                  << " mesh-options/mesh_class had invalid value " << mesh_class
                  << std::endl;
        libmesh_error();
      }

    if(mesh_option=="read_mesh_from_file")
      {
	// According to Roy Stogner, the only read format
	// that won't properly reset the dimension is gmsh.
	/*! \todo Need to a check a GMSH meshes */
	mesh->read(mesh_filename);
      }

    else if(mesh_option=="create_1D_mesh")
      {
	if(element_type=="NULL")
	  {
	    element_type = "EDGE3";
	  }

	GRINSEnums::ElemType element_enum_type =
	  libMesh::Utility::string_to_enum<GRINSEnums::ElemType>(element_type);

	libMesh::MeshTools::Generation::build_line(*mesh,
						   mesh_nx1,
						   domain_x1_min,
						   domain_x1_max,
						   element_enum_type);
      }

    else if(mesh_option=="create_2D_mesh")
      {
	if(element_type=="NULL")
	  {
	    element_type = "TRI6";
	  }

	// Reset mesh dimension to 2.
	mesh->set_mesh_dimension(2);

	GRINSEnums::ElemType element_enum_type =
	  libMesh::Utility::string_to_enum<GRINSEnums::ElemType>(element_type);

	libMesh::MeshTools::Generation::build_square(*mesh,
						     mesh_nx1,
						     mesh_nx2,
						     domain_x1_min,
						     domain_x1_max,
						     domain_x2_min,
						     domain_x2_max,
						     element_enum_type);
      }

    else if(mesh_option=="create_3D_mesh")
      {
	if(element_type=="NULL")
	  {
	    element_type = "TET10";
	  }

	// Reset mesh dimension to 3.
	mesh->set_mesh_dimension(3);

	GRINSEnums::ElemType element_enum_type =
	  libMesh::Utility::string_to_enum<GRINSEnums::ElemType>(element_type);

	libMesh::MeshTools::Generation::build_cube(*mesh,
						   mesh_nx1,
						   mesh_nx2,
						   mesh_nx3,
						   domain_x1_min,
						   domain_x1_max,
						   domain_x2_min,
						   domain_x2_max,
						   domain_x3_min,
						   domain_x3_max,
						   element_enum_type);
      }

    else
      {
	std::cerr << " MeshBuilder::build_mesh :"
		  << " mesh-options/mesh_option [" << mesh_option
		  << "] NOT supported " << std::endl;
	libmesh_error();
      }

    std::string redistribution_function_string =
            input("mesh-options/redistribute", std::string("0"));

    if (redistribution_function_string != "0")
      {
        libMesh::ParsedFunction<libMesh::Real>
          redistribution_function(redistribution_function_string);

        libMesh::MeshTools::Modification::redistribute
          (*mesh, redistribution_function);

        // Redistribution can create distortions *within* second-order
        // elements, which can then be magnified by refinement.  Let's
        // undistort everything by converting to first order and back
        // if necessary.

        // FIXME - this only works for meshes with uniform geometry
        // order equal to FIRST or (full-order) SECOND.

        const libMesh::Elem *elem = *mesh->elements_begin();

        if (elem->default_order() != libMesh::FIRST)
          {
            mesh->all_first_order();
            mesh->all_second_order();
          }
      }

    int uniformly_refine = input("mesh-options/uniformly_refine", 0);

    if( uniformly_refine > 0 )
      {
	libMesh::MeshRefinement(*mesh).uniformly_refine(uniformly_refine);
      }

    std::string h_refinement_function_string =
            input("mesh-options/locally_h_refine", std::string("0"));

    if (h_refinement_function_string != "0")
      {
        libMesh::ParsedFunction<libMesh::Real>
          h_refinement_function(h_refinement_function_string);

        libMesh::MeshRefinement mesh_refinement(*mesh);

        libMesh::dof_id_type found_refinements = 0;
        do {
          found_refinements = 0;

          libMesh::MeshBase::element_iterator elem_it =
                  mesh->active_local_elements_begin();
          libMesh::MeshBase::element_iterator elem_end =
                  mesh->active_local_elements_end();
          for (; elem_it != elem_end; ++elem_it)
            {
              libMesh::Elem *elem = *elem_it;

              const libMesh::Real refinement_val =
                h_refinement_function(elem->centroid());

	      const unsigned int n_refinements = refinement_val > 0 ?
                refinement_val : 0;

              if (elem->level() - uniformly_refine < n_refinements)
                {
                  elem->set_refinement_flag(libMesh::Elem::REFINE);
                  found_refinements++;
                }
            }

          if (found_refinements)
            {
	      std::cout << "Found " << found_refinements <<
                " elements to locally refine" << std::endl;
              mesh_refinement.refine_and_coarsen_elements();
            }

        } while(found_refinements);

      }

    return std::tr1::shared_ptr<libMesh::UnstructuredMesh>(mesh);
  }

} // namespace GRINS
<commit_msg>Bugfix for locally_h_refine in parallel<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// C++
#include <iostream>

// This class
#include "grins/grins_enums.h"
#include "grins/mesh_builder.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/mesh_modification.h"
#include "libmesh/mesh_refinement.h"
#include "libmesh/parallel_mesh.h"
#include "libmesh/parsed_function.h"
#include "libmesh/serial_mesh.h"

namespace GRINS
{

  MeshBuilder::MeshBuilder()
  {
    return;
  }

  MeshBuilder::~MeshBuilder()
  {
    return;
  }

  std::tr1::shared_ptr<libMesh::UnstructuredMesh> MeshBuilder::build
    (const GetPot& input,
     const libMesh::Parallel::Communicator &comm)
  {
    // First, read all needed variables
    std::string mesh_option = input("mesh-options/mesh_option", "NULL");
    std::string mesh_filename = input("mesh-options/mesh_filename", "NULL");

    libMesh::Real domain_x1_min = input("mesh-options/domain_x1_min", 0.0);
    libMesh::Real domain_x2_min = input("mesh-options/domain_x2_min", 0.0);
    libMesh::Real domain_x3_min = input("mesh-options/domain_x3_min", 0.0);

    libMesh::Real domain_x1_max = input("mesh-options/domain_x1_max", 1.0);
    libMesh::Real domain_x2_max = input("mesh-options/domain_x2_max", 1.0);
    libMesh::Real domain_x3_max = input("mesh-options/domain_x3_max", 1.0);

    int mesh_nx1 = input("mesh-options/mesh_nx1", -1);
    int mesh_nx2 = input("mesh-options/mesh_nx2", -1);
    int mesh_nx3 = input("mesh-options/mesh_nx3", -1);

    std::string element_type = input("mesh-options/element_type", "NULL");

    // Make sure the user told us what to do
    if(mesh_option == "NULL")
      {
	std::cerr << " MeshBuilder::read_input_options :"
		  << " mesh-options/mesh_option NOT specified "
		  << std::endl;
	libmesh_error();
      }

    // Create UnstructuredMesh object (defaults to dimension 1).
    libMesh::UnstructuredMesh* mesh;

    // Were we specifically asked to use a ParallelMesh or SerialMesh?
    std::string mesh_class = input("mesh-options/mesh_class", "default");

    if (mesh_class == "parallel")
      mesh = new libMesh::ParallelMesh(comm);
    else if (mesh_class == "serial")
      mesh = new libMesh::SerialMesh(comm);
    else if (mesh_class == "default")
      mesh = new libMesh::Mesh(comm);
    else
      {
        std::cerr << " MeshBuilder::build:"
                  << " mesh-options/mesh_class had invalid value " << mesh_class
                  << std::endl;
        libmesh_error();
      }

    if(mesh_option=="read_mesh_from_file")
      {
	// According to Roy Stogner, the only read format
	// that won't properly reset the dimension is gmsh.
	/*! \todo Need to a check a GMSH meshes */
	mesh->read(mesh_filename);
      }

    else if(mesh_option=="create_1D_mesh")
      {
	if(element_type=="NULL")
	  {
	    element_type = "EDGE3";
	  }

	GRINSEnums::ElemType element_enum_type =
	  libMesh::Utility::string_to_enum<GRINSEnums::ElemType>(element_type);

	libMesh::MeshTools::Generation::build_line(*mesh,
						   mesh_nx1,
						   domain_x1_min,
						   domain_x1_max,
						   element_enum_type);
      }

    else if(mesh_option=="create_2D_mesh")
      {
	if(element_type=="NULL")
	  {
	    element_type = "TRI6";
	  }

	// Reset mesh dimension to 2.
	mesh->set_mesh_dimension(2);

	GRINSEnums::ElemType element_enum_type =
	  libMesh::Utility::string_to_enum<GRINSEnums::ElemType>(element_type);

	libMesh::MeshTools::Generation::build_square(*mesh,
						     mesh_nx1,
						     mesh_nx2,
						     domain_x1_min,
						     domain_x1_max,
						     domain_x2_min,
						     domain_x2_max,
						     element_enum_type);
      }

    else if(mesh_option=="create_3D_mesh")
      {
	if(element_type=="NULL")
	  {
	    element_type = "TET10";
	  }

	// Reset mesh dimension to 3.
	mesh->set_mesh_dimension(3);

	GRINSEnums::ElemType element_enum_type =
	  libMesh::Utility::string_to_enum<GRINSEnums::ElemType>(element_type);

	libMesh::MeshTools::Generation::build_cube(*mesh,
						   mesh_nx1,
						   mesh_nx2,
						   mesh_nx3,
						   domain_x1_min,
						   domain_x1_max,
						   domain_x2_min,
						   domain_x2_max,
						   domain_x3_min,
						   domain_x3_max,
						   element_enum_type);
      }

    else
      {
	std::cerr << " MeshBuilder::build_mesh :"
		  << " mesh-options/mesh_option [" << mesh_option
		  << "] NOT supported " << std::endl;
	libmesh_error();
      }

    std::string redistribution_function_string =
            input("mesh-options/redistribute", std::string("0"));

    if (redistribution_function_string != "0")
      {
        libMesh::ParsedFunction<libMesh::Real>
          redistribution_function(redistribution_function_string);

        libMesh::MeshTools::Modification::redistribute
          (*mesh, redistribution_function);

        // Redistribution can create distortions *within* second-order
        // elements, which can then be magnified by refinement.  Let's
        // undistort everything by converting to first order and back
        // if necessary.

        // FIXME - this only works for meshes with uniform geometry
        // order equal to FIRST or (full-order) SECOND.

        const libMesh::Elem *elem = *mesh->elements_begin();

        if (elem->default_order() != libMesh::FIRST)
          {
            mesh->all_first_order();
            mesh->all_second_order();
          }
      }

    int uniformly_refine = input("mesh-options/uniformly_refine", 0);

    if( uniformly_refine > 0 )
      {
	libMesh::MeshRefinement(*mesh).uniformly_refine(uniformly_refine);
      }

    std::string h_refinement_function_string =
            input("mesh-options/locally_h_refine", std::string("0"));

    if (h_refinement_function_string != "0")
      {
        libMesh::ParsedFunction<libMesh::Real>
          h_refinement_function(h_refinement_function_string);

        libMesh::MeshRefinement mesh_refinement(*mesh);

        libMesh::dof_id_type found_refinements = 0;
        do {
          found_refinements = 0;

          libMesh::MeshBase::element_iterator elem_it =
                  mesh->active_elements_begin();
          libMesh::MeshBase::element_iterator elem_end =
                  mesh->active_elements_end();
          for (; elem_it != elem_end; ++elem_it)
            {
              libMesh::Elem *elem = *elem_it;

              const libMesh::Real refinement_val =
                h_refinement_function(elem->centroid());

	      const unsigned int n_refinements = refinement_val > 0 ?
                refinement_val : 0;

              if (elem->level() - uniformly_refine < n_refinements)
                {
                  elem->set_refinement_flag(libMesh::Elem::REFINE);
                  found_refinements++;
                }
            }

          comm.max(found_refinements);

          if (found_refinements)
            {
	      std::cout << "Found up to " << found_refinements <<
                " elements to refine on each processor" << std::endl;
              mesh_refinement.refine_and_coarsen_elements();
            }

        } while(found_refinements);

      }

    return std::tr1::shared_ptr<libMesh::UnstructuredMesh>(mesh);
  }

} // namespace GRINS
<|endoftext|>


<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "Problem.h"
#include "Factory.h"

Problem::Problem():
    _output_initial(false)
{
  unsigned int n_threads = libMesh::n_threads();

  _real_zero.resize(n_threads);
  _zero.resize(n_threads);
  _grad_zero.resize(n_threads);
  _second_zero.resize(n_threads);

  _functions.resize(n_threads);
}

Problem::~Problem()
{
  unsigned int n_threads = libMesh::n_threads();
  for (unsigned int i = 0; i < n_threads; i++)
  {
    _zero[i].release();
    _grad_zero[i].release();
    _second_zero[i].release();
  }
  _real_zero.release();
  _zero.release();
  _grad_zero.release();
  _second_zero.release();

  for (unsigned int i = 0; i < n_threads; i++)
    for (std::map<std::string, Function *>::iterator it = _functions[i].begin(); it != _functions[i].end(); ++it)
      delete it->second;
}

void
Problem::addFunction(std::string type, const std::string & name, InputParameters parameters)
{
  parameters.set<Problem *>("_problem") = this;
  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
  {
    parameters.set<THREAD_ID>("_tid") = tid;
    Function * func = static_cast<Function *>(Factory::instance()->create(type, name, parameters));
    _functions[tid][name] = func;
  }
}

Function &
Problem::getFunction(const std::string & name, THREAD_ID tid)
{
  return *_functions[tid][name];
}
<commit_msg>Problem::_real_zero was not properly initialized and caused some troubles in threaded runs<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "Problem.h"
#include "Factory.h"

Problem::Problem():
    _output_initial(false)
{
  unsigned int n_threads = libMesh::n_threads();

  _real_zero.resize(n_threads, 0.);
  _zero.resize(n_threads);
  _grad_zero.resize(n_threads);
  _second_zero.resize(n_threads);

  _functions.resize(n_threads);
}

Problem::~Problem()
{
  unsigned int n_threads = libMesh::n_threads();
  for (unsigned int i = 0; i < n_threads; i++)
  {
    _zero[i].release();
    _grad_zero[i].release();
    _second_zero[i].release();
  }
  _real_zero.release();
  _zero.release();
  _grad_zero.release();
  _second_zero.release();

  for (unsigned int i = 0; i < n_threads; i++)
    for (std::map<std::string, Function *>::iterator it = _functions[i].begin(); it != _functions[i].end(); ++it)
      delete it->second;
}

void
Problem::addFunction(std::string type, const std::string & name, InputParameters parameters)
{
  parameters.set<Problem *>("_problem") = this;
  for (THREAD_ID tid = 0; tid < libMesh::n_threads(); tid++)
  {
    parameters.set<THREAD_ID>("_tid") = tid;
    Function * func = static_cast<Function *>(Factory::instance()->create(type, name, parameters));
    _functions[tid][name] = func;
  }
}

Function &
Problem::getFunction(const std::string & name, THREAD_ID tid)
{
  return *_functions[tid][name];
}
<|endoftext|>