MiniKombajnPomiarowy3_3_rc3.7z

AVT2999 - Brak połączenia oscyloskopu z PC

Witam po przerwie. Ani przejściówka na MAX2323 ani oryginalna przejściówka na FT232RL nie działa, cały czas program nie może otworzyć portu, choć prawidłowo podaje jego nazwe ("COM5 FTDIBUS"). Próbowałem zmieniać numery portów - nic to nie daje. W załączniku umieszczam kod źródłowy aplikacji - może ktoś z Was mógłby do tego zerknąć? Program jest napisany w Qt4 o ile się nie myle.

  • MiniKombajnPomiarowy3_3_rc3.7z
    • scriptcalc.cpp
    • posix_qextserialport.o
    • analizator.cpp
    • structs.h
    • PortListener.h
    • scriptcalc.o
    • generator.o
    • mkpcom.cpp
    • generator.h
    • qtmmlwidget.o
    • qextserialenumerator_unix.o
    • sine_test.txt
    • scriptcalc.h
    • serialport.h
    • triangle_1cycle.txt
    • square.txt
    • mainwindow.o
    • triangle.txt
    • mainwindow.h
    • Array
    • serialport.cpp
    • first_test.txt
    • interface.cpp
    • main.cpp
    • oscyloskop.o
    • Makefile
    • qtmmlwidget.cpp
    • mkpcom.o
    • PortListener.o
    • ustawienia.o
    • MiniKombajnPomiarowy_V1.pro
    • analizatorlog.o
    • qextserialport.o
    • oscyloskop.cpp
    • windowsize.h
    • qtmmlwidget.h
    • Array
    • mkpcom.h
    • analizator.o
    • ustawienia.h
    • main.o
    • oscyloskop.h
    • osc_sin.txt
    • graph.o
    • graph.h
    • second_test.txt
    • .directory
    • generator.cpp
    • interface.o
    • mainwindow.cpp
    • settings.txt
    • analizatorlog.cpp
    • PortListener.cpp
    • analizator.h
    • graph.cpp
    • ustawienia.cpp
    • analizatorlog.h
    • interface.h


Pobierz plik - link do postu

MiniKombajnPomiarowy3_3_rc3.7z > scriptcalc.cpp

#include " scriptcalc.h "

Scriptcalc::Scriptcalc()
{

}


unsigned int factorial(unsigned int n)
{
unsigned int retval = 1;
for (int i = n; i & gt; 1; --i)
retval *= i;
return retval;
}

/*
void cPower(float* y, float* yj, float a, float aj, float b, float bj)
{
int n;
double Pi1,Pi2,kat,r,p,p1,p2;
double pot_pi,dod;
textcolor(16);
cprintf( " \n\rPodaj liczb%c w formacie a(+/-)bi: " ,169);
scanf( " %lg %lg %c " , & l1.re, & l1.im, & znak);
cprintf( " \nPodaj stopie%c pot%cgi: " ,228,169);
scanf( " %i " , & n);

r=sqrt(l1.re*l1.re+l1.im*l1.im); //Modul liczby zespolonej//
Pi1=atan(cos(l1.re/r));
Pi2=atan(sin(l1.im/r));
kat=atan(Pi1/Pi2);
pot_pi=kat*n;

p=pow(r,n);
p1=pow(l1.re,n);
p2=pow(l1.im,n);

cprintf( " \n\n\rPot%cga stopnia %i wynosi: " ,169,n);
cprintf( " \rPosta%c algebraiczna: " ,134);
if ((p2 & gt; 0)||(p1==0))
{
cprintf( " %0.3lg " ,p1);
cprintf( " + " );
cprintf( " %0.3lg " ,p2);
cprintf( " i " );
}
else
{
cprintf( " %0.3lg " ,p1);
cprintf( " %0.3lg " ,p2);
cprintf( " i " );
};
if (pot_pi & gt; 0)
{
cprintf( " \n\rPosta%c trygonometryczna: %0.3lg (cos %0.3lg%c + isin %0.3lg%c) " ,134,p,pot_pi,20,pot_pi,20);
}
else
{
dod=pow(pot_pi,2);
cprintf( " \n\rPosta%c trygonometryczna: " ,134);
cprintf( " %0.3lg " ,p);
cprintf( " (-cos %0.3lg%c " ,dod,20);
cprintf( " - isin %0.3lg%c) " ,dod,20);
};
cprintf( " \n\rPosta%c wyk%cadnicza: e^i*%lg " ,134,136,pot_pi);
cprintf( " \n\n\rNACISNIJ DOWOLNY KLAWISZ... " );
getch();
}*/

bool isNumber(char ch)
{
if((ch & gt; = '0' & & ch & lt; = '9') || ch == '.')
return true;
else
return false;
}

bool isNumberInf(char ch)
{
if((ch & gt; = '0' & & ch & lt; = '9'))
return true;
else
return false;
}

bool isExpr(char ch)
{
if((ch & gt; = '!' & & ch & lt; = '/' & & ch != '.') || ch == '^')
return true;
else
return false;
}

bool isOperand(char ch)
{
if(((ch & gt; = '!' & & ch & lt; = '/') || ch == '^') & & ch != ')' & & ch != '(' & & ch!= '.')
return true;
else
return false;
}

bool isFunc(char ch)
{
if(ch & gt; = 'a' & & ch & lt; 'x' & & ch != 'x' & & ch != 'e' & & ch != 'p' & & ch != 'j' & & ch != 'w')
return 1;
else
return 0;
}

bool isVariableInfix(char ch)
{
if(ch == '0' || (ch & gt; = ':' & & ch & lt; = ' & lt; '))
return 1;
else
return 0;
}


bool isFloat(char ch)
{
if((ch & gt; = '0' & & ch & lt; = '9') || ch == '-' || ch == '.')
return true;
else
return false;
}

const char* funcTab2[4] = { " ln " , " tg " , " pi " , " ch " };
const char* funcTab3[4] = { " sin " , " cos " , " log " , " abs " };

bool Scriptcalc::readFunc(char* str, char* func, int* len)
{
int i;
// if(len ==1)
// {

// }else if(len == 2)
// {

// return 0;
// }if(len == 3)
// {
for(i=0; i & lt; 4; i++)
{
bool good = 1;
int j = 3;//len;
while(j--)
if(*(str+j) != funcTab3[i][j])
good = 0;
if(good)
{
*func = i + 'e';
*len = 3;
return 1;
}
}
for(i=0; i & lt; 4; i++)
{
bool good = 1;
int j = 2;//len;
while(j--)
if(*(str+j) != funcTab2[i][j])
good = 0;
if(good)
{
*func = i + 'a';
*len = 2;
return 1;
}
}
if(*str == 'I')
{
*func = 'i';
*len = 1;
return 1;
}
return 0;
// }else
// return 0;
}

#define imag 20

void Scriptcalc::expressToInfix(QString mfunc, char* infix, float* numData)
{

int len = mfunc.length();
qDebug() & lt; & lt; " len: " & lt; & lt; len;
char func = 0;
int flen = 0;
//char data[len];
char data[1000];
int num = 0;
//int numr = 0;
int i = 0;
int j = 0;
for(i = 0; i & lt; len; i++, j++)
{
data[j] = mfunc.at(i).toAscii();
if(data[j] == ' ')j--;
}
data[j]= 0;
data[j+1] = 0;
int index = 0;
int step = 0;
bool sign = 0;
int numIndex = 1;
bool dot = 0;
int dotPos = 1;
qDebug() & lt; & lt; (char*)data;
while(index & lt; len)
{
if(isFloat(data[index]) & & (index? (isExpr(data[index-1]) & & data[index-1] != ')') : 1))
{
num = 0;
dot = 0;
dotPos = 1;
if(data[index] == '-')
{
sign = 1;
index++;
if(data[index] == 'x' || data[index] == 'e' || data[index] == 'p' || data[index] == 'j')
{
// infix[step++] = numIndex+ '0';
// numData[numIndex++] = -1;
num = 1;
}
}
while(isNumber(data[index]))
{
if(data[index] == '.')
{
dot = 1;
index++;
continue;
}
if(dot)
{
//num += (float)(data[index++] - '0')/(float)dotPos;
dotPos*=10;
}//else
//{
num *= 10;
num += data[index++] - '0';
//}
}
infix[step++] = numIndex+ '0';
numData[numIndex++] = (float)(sign? -num : num)/(float)dotPos;
sign = 0;
}else if(isExpr(data[index]))
{
infix[step++] = data[index++];
}/*else if(isFunc(data[index]))
{
if(step & gt; 0)
if((infix[step-1] & gt; = '0' & & infix[step-1] & lt; = ';') || data[index-1] == ')')
infix[step++] = '*';
num = 0;
while(isFunc(data[index]))
{
num++;
index++;
}

infix[step++] = readFunc( & data[index - num], num);
numr = num;*/
else if(readFunc( & data[index], & func, & flen))
{
infix[step++] = func;
index += flen;
}else if(data[index] == 'x' || data[index] == 'e' || data[index] == 'p' || data[index] == 'j' || (data[index] == 'w' & & data[index+1] == 't'))
{
char alias = 0;
if(data[index] == 'p')
{
alias = ';';
//index++; // 'pi' or only 'p'
}else if(data[index] == 'x')
alias = '0';
else if(data[index] == 'e')
alias = ':';
else if(data[index] == 'j')
alias = ' & lt; ';
else if(data[index] == 'w')
{
alias = '=';
index++;
}
index++;
if(step & gt; 0)
{
if((infix[step-1] & gt; = '0' & & infix[step-1] & lt; = '=') || data[index-2] == ')' || (alias == '=' & & data[index-3] == ')'))
infix[step++] = '*';
/* else if(infix[step-1] == '-')
{
step--;
infix[step++] = numIndex+ '0';
numData[numIndex++] = -1;
infix[step++] = '*';
}*/
}
infix[step++] = alias;

if(isNumber(data[index]))
{
num = 0;
dot = 0;
dotPos = 1;
while(isNumber(data[index]))
{
if(data[index] == '.')
{
dot = 1;
index++;
continue;
}
if(dot)
dotPos*=10;

num *= 10;
num += data[index++] - '0';
}
infix[step++] = '^';
infix[step++] = numIndex + '0';
numData[numIndex++] = (float)num/(float)dotPos;
}else if(data[index] == '(')
infix[step++] = '*';
}else
index++;
}
infix[step] = 0;

}



void Scriptcalc::infixToRPN(unsigned char* infix, unsigned char* RPN)
{
char stax[500];
//char output[32];
int si = -1;
int oi = 0;
int i = 0;
for(i=0; i & lt; 500; i++)
{
stax[i] = 0;
RPN[i] = 0;
}
char temp;
for(i=0; i & lt; 100 & & infix[i] != 0; i++)
{
temp = infix[i];
if(temp & gt; = '0' & & temp & lt; = '=') //number
RPN[oi++] = temp;
else if(temp & gt; = 'a' || temp == '(') //function or left bracket
stax[++si] = temp;
else if(temp == ',') //argument
{
while(stax[si] != '(')
RPN[oi++] = stax[si--];
}else if(temp == ')') //right bracket
{
while(stax[si] != '(')
RPN[oi++] = stax[si--];
si--;
if(temp & gt; = 'A')
RPN[oi++] = stax[si--];
}else if(isOperand(temp)) //operand
{
while(isFunc(stax[si])) //function
RPN[oi++] = stax[si--];
if(temp == '-' || temp == '+')
{
while(isOperand(stax[si]))
RPN[oi++] = stax[si--];
}else if(temp == '*' || temp == '/' || temp == '%')
{
while(isOperand(stax[si]) & & stax[si] != '-' & & stax[si] != '+')
RPN[oi++] = stax[si--];
}/*else if(temp == '^')
{
while(isOperand(stax[si]) & & stax[si] != '^')
RPN[oi++] = stax[si--];
}*/
stax[++si] = temp;
}
}
while(si & gt; -1)
{
RPN[oi++] = stax[si--];
}
RPN[oi] = 0;
}

float Scriptcalc::operation(float a, float b, unsigned char op)
{
if(op == '+')
return a + b;
else if(op == '-')
return a - b;
else if(op == '*')
return a * b;
else if(op == '/')
return a/b;
else if(op == '^')
return pow(a, b);
else if(op == '!')
return factorial(a);
else
return 0;
}

void Scriptcalc::operationComplex(float* y, float* yj, float a, float aj, float b, float bj, unsigned char op)
{
if(op == '+')
{
*y = a + b;
*yj = aj + bj;
}else if(op == '-')
{
*y = a - b;
*yj = aj - bj;
}else if(op == '*')
{
*y = a*b - aj*bj;
*yj = a*bj + b*aj;
}else if(op == '/')
{
*y = (a*b + aj*bj)/(b*b + bj*bj);
*yj = (aj*b - a*bj)/(b*b + bj*bj);
}else if(op == '^')
{
/*if(aj == 0 & & bj != 0)
{
*y = cos(bj*log(a));
*yj = sin(b*log(a));
*y *= pow(a, b);
}*/
_Complex float res = cpowf(a+I*aj, b+I*bj);
*y = crealf(res);
*yj = cimagf(res);
}
}

float Scriptcalc::calculateRPN(unsigned char* RPN, float* numD)
{
int si = -1;
//static float numOld;
//float out = 0;
//unsigned char stax[100];
float numData[30];
int i;
for(i=0; i & lt; 30; i++)
numData[i]= 0;//numD[i];

for(i=0; i & lt; 32 & & RPN[i] != 0; i++)
{
if((RPN[i] & gt; = '0' & & RPN[i] & lt; ='9') || RPN[i] == '=') //number
{
//stax[++si] = RPN[i];
numData[++si] = numD[RPN[i] - '0'];
numData[si + imag] = 0;
}else if(RPN[i] == ':')
{
numData[++si] = 2.71828;
numData[si + imag] = 0;
}else if(RPN[i] == ';')
{
numData[++si] = 3.14159;
numData[si + imag] = 0;
}else if(RPN[i] == ' & lt; ')
{
numData[++si] = 0;
numData[si + imag] = 1;//numD[RPN[i] - '0'];
}else if(isOperand(RPN[i])) //operand
{
//float a = numData[stax[si--] - '0'];
//float b = numData[stax[si--] - '0'];
if(RPN[i] == '!')
{
float a = numData[si--];
numData[++si] = operation(a, 0, RPN[i]);
continue;
}

float a = numData[si];
float aj = numData[imag + si--];
float b = numData[si];
float bj = numData[imag + si--];
//stax[++si] = 20;
//numData[stax[++si] - '0'] = operation(b, a, RPN[i]);
if(aj != 0 || bj != 0)
{
float y=0;
float yj=0;
operationComplex( & y, & yj, b, bj, a, aj, RPN[i]);
numData[++si] = y;
numData[si+imag] = yj;
}else
numData[++si] = operation(b, a, RPN[i]);
}else if(RPN[i] & gt; = 'a') //function
{
if(RPN[i] == 'a')
{
float a = numData[si--];
numData[++si] = log(a)*5;
}else if(RPN[i] == 'b')
{
float a = numData[si--];
numData[++si] = tan(a);
}else if(RPN[i] == 'e')
numData[si] = sin(numData[si]);
else if(RPN[i] == 'f')
numData[si] = cos(numData[si]);
else if(RPN[i] == 'g')
numData[si] = log10(numData[si]);
else if(RPN[i] == 'h')
{
//numData[si] = abs(numData[si]);
numData[si] = sqrt(numData[si]*numData[si] + numData[si+imag]*numData[si+imag]);
numData[si+imag] = 0;
}else if(RPN[i] == 'i')
{
numData[si] = numData[si] & lt; 0 ? 1 : 0;//Heaviside step function
}
}
}
//return operation(numData[0], numData[1], '+');
//return numData[stax[si] - '0'];

return numData[si];
}


bool Scriptcalc::syntaxCheck(QString mfunc)
{
int i, len = mfunc.length();
//char data[len+1];
char data[1000];
int bracket = 0;
bool operand = 0;
bool operand1 = 0;
bool number = 0;
bool rbracket = 0, lbracket = 0;
bool var = 0;
int ni = 0; //numbers amount
int j = 0;
for(i=0; i & lt; len; i++)
{
data[j] = mfunc.at(i).toAscii();
if(data[j] == ' ')
j--;
j++;
}
data[j] = 0;

if(isOperand(data[0]) & & data[0] != '-')
return 0;

for(i=0; i & lt; j; i++)
{
if(data[i] == '(')
bracket++;
else if(data[i] == ')')
bracket--;

else if(data[i] & lt; ' ' || data[i] & gt; 'z' )
return 0;

if(data[i] == '(' & & number)
return 0;

if(isNumber(data[i]) & & (rbracket || operand1))
return 0;

if(data[i] == '(' & & rbracket)
return 0;

if(data[i] == ')' & & lbracket)
return 0;

if(bracket & lt; 0)
return 0;


if(isNumber(data[i]))
{
int nlen = 0;
while(isNumber(data[i]))
{
i++;
nlen++;
}
i--;
if(nlen & gt; 21)
return 0;
number = 1;
operand1 = 0;
ni++;
}else
number = 0;

if(isFunc(data[i]) & & (var || rbracket))
return 0;

if(data[i] == ')')
rbracket = 1;
else
rbracket = 0;

if(data[i] == '(')
lbracket = 1;
else
lbracket = 0;

if(isOperand(data[i]) & & operand)
if(data[i] != '-')
return 0;

if(isOperand(data[i]) & & data[i] != '!')
{
operand = 1;
operand1 = 0;
}


if(data[i] == 'x' || data[i] == 'e' || data[i] == 'p' || data[i] == 'j' || (data[i] == 'w' & & data[i+1] == 't'))
{
var = 1;
}else
var = 0;

if(isNumber(data[i]) || data[i] == 'x' || data[i] == 'e' || data[i] == 'p' || data[i] == 'j' || (data[i] == 'w' & & data[i+1] == 't'))
{
if(operand1)
return 0;
operand = 0;
}

if(data[i] == '!')
operand1 = 1;


if(isFunc(data[i]))
{
if(operand1)
return 0;
int flen = 0;
//while(isFunc[data[i]])
/* while(data[i] & gt; = 'a' & & data[i] & lt; 'x')
{
i++;
flen++;
if(i & gt; len)
return 0;
}*/
char func=0;
if(readFunc( & data[i], & func, & flen) == 0)
return 0;
i += flen;
if(data[i] != 'x' & & data[i] != 'e' & & data[i] != 'p' & & data[i] != 'j' & & data[i] != '(' & & (data[i] != 'w' || data[i+1] != 't'))
return 0;
i--;
}
if(data[i] == 'w' & & data[i+1] == 't')
i++;
}
if(ni & gt; 10)
return 0;
if(operand)
return 0;
if(bracket == 0)
return 1;
else
return 0;
}

/*
QString Scriptcalc::presentExpress(unsigned char *expr, float* numData)
{
QString str = " & lt; math & gt; " ;
unsigned char newc, actc, oldc = 0;
int wBracket[5] = {0,0,0,0,0};
int bracket = 1, st = 0;
int wFrac[5] = {0,0,0,0,0};
int stFrac = 0;
bool fFrac[5] = {0,0,0,0,0};
int stFFrac = 0;
while(*expr)
{
newc = *(expr+1);
actc = *expr;

if(newc == '^')
str += " & lt; msup & gt; " ;
else if(newc == '/' & & actc != ')' & & oldc != '/')
str += " & lt; mfrac & gt; " ;

//if(actc == '/' & & fFrac[0] == 1)
// if(!(isVariableInfix(oldc) || isVariableInfix(newc)))
// str += " & lt; mo & gt; & middot; & lt; /mo & gt; " ;
if(oldc == '/' & & fFrac[0] == 0)
{
fFrac[0] = 1;
//if(actc != '(')
str += " & lt; mrow & gt; " ;
}


if(actc == '(')
{
bracket++;
int i = 0;
while(expr[i++] != ')');
if(expr[i] == '/' & & oldc != '/')
{
str += " & lt; mfrac & gt; & lt; mrow & gt; " ;
wFrac[++stFrac] = bracket;
}
else if(oldc == '/')
{
if(fFrac[0] == 0)
str += " & lt; mrow & gt; " ;
wFrac[++stFrac] = bracket;
}
else if(oldc == '^')
{
wBracket[++st] = bracket;
str += " & lt; mrow & gt; " ;
}//else
//str += " & lt; mo & gt; ( & lt; /mo & gt; " ;
}else if(actc == ')')
{
//if(wFrac[stFrac] != bracket)
// str += " & lt; mo & gt; ) & lt; /mo & gt; " ;
if(wFrac[stFrac] == bracket)
{
//if(fFrac[0] == 0)
if(newc != '/' || fFrac[0] == 0)
{
wFrac[stFrac--] = 0;
str += " & lt; /mrow & gt; " ;
if(newc != '/')
{
str += " & lt; /mfrac & gt; " ;
fFrac[0] = 0;
}
}
}
else if(wBracket[st] == bracket)
{
wBracket[st--] = 0;
str += " & lt; /mrow & gt; & lt; /msup & gt; " ;
}//else

bracket--;
}

if(actc == '0')
str += " & lt; mo & gt; & omega; & lt; /mo & gt; & lt; mi & gt; t & lt; /mi & gt; " ;
else if(actc == ':')
str += " & lt; mi & gt; e & lt; /mi & gt; " ;
else if(actc == ';')
str += " & lt; mo & gt; & pi; & lt; /mo & gt; " ;
else if(actc == ' & lt; ')
str += " & lt; mi & gt; j & lt; /mi & gt; " ;
else if(actc == '+')
str += " & lt; mo & gt; + & lt; /mo & gt; " ;
else if(actc == '-')
str += " & lt; mo & gt; - & lt; /mo & gt; " ;
else if(actc == '*')
{
if(!(isVariableInfix(oldc) || isVariableInfix(newc)))
str += " & lt; mo & gt; & middot; & lt; /mo & gt; " ;
}else if(actc == '(')
{

}else if((actc == ')'))
{

//bracket--;
}else if(actc & gt; '0' & & actc & lt; = '9')
str += " & lt; mn & gt; " + QString::number(numData[actc - '0'])+ " & lt; /mn & gt; " ;


if(oldc == '^' & & actc != '(')
str += " & lt; /msup & gt; " ;
else if(oldc == '/' & & actc != '(' & & newc != '/')
{
if(fFrac[0] == 1)
str += " & lt; /mrow & gt; " ;
str += " & lt; /mfrac & gt; " ;
fFrac[0] == 0;
}

oldc = actc;
expr++;
}
//str = " & lt; math & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; msup & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; msup & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; /msup & gt; & lt; /msup & gt; & lt; /math & gt; " ;
str+= " & lt; /math & gt; " ;
return str;
}
*/
#if 0

QString Scriptcalc::presentExpress(unsigned char *expr, float* numData)
{
QString str = " & lt; math & gt; " ;
unsigned char newc, actc, oldc = 0;
int wBracket[5] = {0,0,0,0,0};
int bracket = 0, st = 0;
int wFrac[5] = {-1,-1,-1,-1,-1};
int* pwFrac = wFrac;
int mFrac[5] = {-1,-1,-1,-1,-1};
int* pmFrac = mFrac;
int eFrac[5] = {-1,-1,-1,-1,-1};
int ceFrac = 0;
bool mmFrac = 0;
//bool fFrac[5] = {0,0,0,0,0};
//int stFFrac = 0;
int msup = 0;
//bool cmfrac = 0;
int i = 0;
for(i=0; expr[i]!=0; i++)
{
if(expr[i] == '/')
{
if(i == 1)
{
*pwFrac++ = 0;
*pmFrac++ = 1;
}

int j = i-1;
bracket = 0;
while(j)
{

if(expr[j] == ')')
bracket++;
if(expr[j] == '(')
bracket--;
j--;
if(bracket & lt; 0)
{
*pwFrac++ = j+1;
*pmFrac++ = i;
break;
}
if(!bracket)
{
if(expr[j] == '/')
break;
if(expr[j] != '^')
{
if(isNumberInf(expr[j+1]))
*pwFrac++ = j+1;
else
*pwFrac++ = j;
*pmFrac++ = i;
break;
}
}
if(j == 0)
{
*pwFrac++ = 0;
*pmFrac++ = i;
}
}
j = i+1;
bracket = 0;
while(expr[j])
{
if(expr[j] == '(')
bracket++;
if(expr[j] == ')')
bracket--;
j++;
if(bracket & lt; 0)
{
eFrac[ceFrac++] = j;
break;
}
if(!bracket)
{
if(expr[j-1] != '/' & & expr[j-1] != '^' & & expr[j] != '/' & & expr[j] != '^')
{
if(ceFrac)
{
if((eFrac[ceFrac-1]) != j)
eFrac[ceFrac++] = j;
}else
eFrac[ceFrac++] = j;
break;
}
}
}

}
}

bracket = 1;
i=0;
while(*expr)
{
newc = *(expr+1);
actc = *expr;

int j;
mmFrac = 0;
for(j=0; j & lt; ceFrac; j++)
{
if(wFrac[j] == i)
{
str += " & lt; mfrac & gt; & lt; mrow & gt; " ;
if(actc == '(')
{
expr++;
i++;
newc = *(expr+1);
oldc = actc;
actc = *expr;
break;
}
}
else if(mFrac[j] == i)
{
if(oldc == ')')
str = str.remove(str.length()-10, 10);
str += " & lt; /mrow & gt; & lt; mrow & gt; " ;
mmFrac = 1;
int k;
if(newc == '(')
for(k=0; k & lt; ceFrac; k++)
if(eFrac[k] & gt; i)
if(expr[eFrac[k]-1-i] ==')')
{
expr+=2;
i+=2;
newc = *(expr+1);
oldc = actc;
actc = *expr;
break;
}

}else if(eFrac[j] == i)
{
if(oldc == ')')
str = str.remove(str.length()-10, 10);
str += " & lt; /mrow & gt; & lt; /mfrac & gt; " ;
}
}
if(actc == '/' & & mmFrac == 0)
if(!(isVariableInfix(oldc) || isVariableInfix(newc)))
str += " & lt; mo & gt; & middot; & lt; /mo & gt; " ;

if(newc == '^')
{
str += " & lt; msup & gt; & lt; mrow & gt; " ;
msup++;
}

if(actc == '=')
str += " & lt; mrow & gt; & lt; mo & gt; & omega; & lt; /mo & gt; & lt; mi & gt; t & lt; /mi & gt; & lt; /mrow & gt; " ;
if(actc == '0')
str += " & lt; mi & gt; x & lt; /mi & gt; " ;
else if(actc == ':')
str += " & lt; mi & gt; e & lt; /mi & gt; " ;
else if(actc == ';')
str += " & lt; mo & gt; & pi; & lt; /mo & gt; " ;
else if(actc == ' & lt; ')
str += " & lt; mi & gt; j & lt; /mi & gt; " ;
else if(actc == '+')
str += " & lt; mo & gt; + & lt; /mo & gt; " ;
else if(actc == '-')
str += " & lt; mo & gt; - & lt; /mo & gt; " ;
else if(actc == '^')
str += " & lt; /mrow & gt; & lt; mrow & gt; " ;
else if(actc == 'a')
str += " & lt; mo & gt; ln & lt; /mo & gt; " ;
else if(actc == 'b')
str += " & lt; mo & gt; tg & lt; /mo & gt; " ;
else if(actc == 'e')
str += " & lt; mo & gt; sin & lt; /mo & gt; " ;
else if(actc == 'f')
str += " & lt; mo & gt; cos & lt; /mo & gt; " ;
else if(actc == '*')
{
if(!(isVariableInfix(oldc) || isVariableInfix(newc)))
str += " & lt; mo & gt; & middot; & lt; /mo & gt; " ;
}else if(actc == '(')
{
bracket++;
if(oldc == '^')
{
wBracket[++st] = bracket;
//str += " & lt; mrow & gt; " ;
}
//if(oldc != '/')
str += " & lt; mo & gt; ( & lt; /mo & gt; " ;
}else if((actc == ')'))
{
//if(newc != '/')
str += " & lt; mo & gt; ) & lt; /mo & gt; " ;
if(wBracket[st] == bracket)
{
wBracket[st--] = 0;
if(newc == '^')
msup++;
else
while(msup)
{
str += " & lt; /mrow & gt; & lt; /msup & gt; " ;
msup--;
}
}
bracket--;
}else if(actc & gt; '0' & & actc & lt; = '9')
str += " & lt; mn & gt; " + QString::number(numData[actc - '0'])+ " & lt; /mn & gt; " ;


if(oldc == '^' & & newc == '^')
msup++;
else if(oldc == '^' & & actc != '(')
while(msup)
{
msup--;
str += " & lt; /mrow & gt; & lt; /msup & gt; " ;
}
/*else if(oldc == '/' & & actc != '(' & & newc != '/')
{
if(fFrac[0] == 1)
str += " & lt; /mrow & gt; " ;
str += " & lt; /mfrac & gt; " ;
fFrac[0] == 0;
}*/

oldc = actc;
expr++;
i++;
}
int j;
for(j=0; j & lt; ceFrac; j++)
{
if(eFrac[j] == i)
{
if(oldc == ')')
str = str.remove(str.length()-10, 10);
str += " & lt; /mrow & gt; & lt; /mfrac & gt; " ;
}
}
//str = " & lt; math & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; msup & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; msup & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; mi & gt; x & lt; /mi & gt; & lt; /msup & gt; & lt; /msup & gt; & lt; /math & gt; " ;
str+= " & lt; /math & gt; " ;
return str;
}
#endif

QString Scriptcalc::createMML(QString expr)
{
QString str;
int i;
char oldc = 0;
char actc;
char newc;
int frac = 0;

for(i=0; i & lt; expr.length(); i++)
{
actc = expr.at(i).toAscii();
if(i & gt; 0)
oldc = expr.at(i-1).toAscii();
if(i & lt; expr.length()-1)
newc = expr.at(i+1).toAscii();
else
newc = 0;

if(newc == '^')
str += " & lt; msup & gt; & lt; mrow & gt; " ;


if(actc == '/')
{
if(frac & gt; 1)
actc = '*';
else
str += " & lt; /mrow & gt; & lt; mrow & gt; " ;
}

if(newc == '/')
{
if(frac == 0)
str += " & lt; mfrac & gt; & lt; mrow & gt; " ;
frac++;
}

if(actc == '=')
str += " & lt; mrow & gt; & lt; mo & gt; & omega; & lt; /mo & gt; & lt; mi & gt; t & lt; /mi & gt; & lt; /mrow & gt; " ;
else if(actc == '^')
str += " & lt; /mrow & gt; & lt; mrow & gt; " ;
else if(actc == '0')
str += " & lt; mi & gt; x & lt; /mi & gt; " ;
else if(actc == ':')
str += " & lt; mi & gt; e & lt; /mi & gt; " ;
else if(actc == ';')
str += " & lt; mo & gt; & pi; & lt; /mo & gt; " ;
else if(actc == ' & lt; ')
str += " & lt; mi & gt; j & lt; /mi & gt; " ;
else if(actc == '+')
str += " & lt; mo & gt; + & lt; /mo & gt; " ;
else if(actc == '-')
str += " & lt; mo & gt; - & lt; /mo & gt; " ;
else if(actc == '^')
str += " & lt; /mrow & gt; & lt; mrow & gt; " ;
else if(actc == 'a')
str += " & lt; mo & gt; ln & lt; /mo & gt; " ;
else if(actc == 'b')
str += " & lt; mo & gt; tg & lt; /mo & gt; " ;
else if(actc == 'e')
str += " & lt; mo & gt; sin & lt; /mo & gt; " ;
else if(actc == 'f')
str += " & lt; mo & gt; cos & lt; /mo & gt; " ;
else if(actc == 'g')
str += " & lt; mo & gt; log & lt; /mo & gt; " ;
else if(actc == 'h')
str += " & lt; mo & gt; abs & lt; /mo & gt; " ;
else if(actc == 'i')
str += " & lt; mo & gt; & wp; & lt; /mo & gt; " ;
else if(actc == '!')
str += " & lt; mo & gt; ! & lt; /mo & gt; " ;
else if(actc == '*')
{
if(!(isVariableInfix(oldc) || isVariableInfix(newc)))
str += " & lt; mo & gt; & middot; & lt; /mo & gt; " ;
}else if(actc == '(')
str += " & lt; mo & gt; ( & lt; /mo & gt; " ;
else if(actc == ')')
str += " & lt; mo & gt; ) & lt; /mo & gt; " ;
else if(actc & gt; '0' & & actc & lt; = '9')
{
str += " & lt; mn & gt; " ;
str += actc;
str += " & lt; /mn & gt; " ;
}else if(actc & gt; = 'A' & & actc & lt; ='Z')
str += actc;

if(oldc == '^')
str += " & lt; /mrow & gt; & lt; /msup & gt; " ;

if(oldc == '/' & & newc != '/')
str += " & lt; /mrow & gt; & lt; /mfrac & gt; " ;
}
return str;
}

QString Scriptcalc::presentExpress(char *expr, float* numData)
{
QString str = " & lt; math & gt; " ;
QString bufexpr[20];
QString exprs;// = new QString((const char)expr);

int i;
for(i=0; expr[i]; i++)
exprs.append(expr[i]);

bool change = 1;
uint ptr = 0;
while(change)
{
change = 0;
int openb = exprs.lastIndexOf('(');
int closeb = 0;
if(openb & gt; -1)
{
closeb = exprs.indexOf(')', openb);
if(openb & gt; 0)
if(exprs.at(openb-1) & gt; = 'a' & & exprs.at(openb-1) & lt; = 'k')
openb--;
bufexpr[ptr] = exprs.mid(openb, closeb-openb+1);
exprs = exprs.remove(openb, closeb-openb+1);
exprs.insert(openb, ((char)ptr+'A'));
int tptr = ptr;
ptr++;
change = 1;

while(change)
{
change = 0;
int openb = bufexpr[tptr].lastIndexOf('^');
if(openb & gt; -1)
{
bufexpr[ptr] = bufexpr[tptr].mid(openb-1, 3);
bufexpr[tptr] = bufexpr[tptr].remove(openb-1, 3);
bufexpr[tptr].insert(openb-1, ((char)ptr+'A'));
ptr++;
change = 1;
}
if(ptr & gt; 19)return " " ;
}
change = 1;
}
if(ptr & gt; 19)return " " ;
}

change = 1;
while(change)
{
change = 0;
int openb = exprs.lastIndexOf('^');
if(openb & gt; -1)
{
bufexpr[ptr] = exprs.mid(openb-1, 3);
exprs = exprs.remove(openb-1, 3);
exprs.insert(openb-1, ((char)ptr+'A'));
ptr++;
change = 1;
}
if(ptr & gt; 19)return " " ;
}


str += createMML(exprs);
//QRegExp rexpr = new QRegExp( " [k-z] " );

change = 1;
while(change)
{
change = 0;
int openb = str.indexOf(QRegExp( " [A-Z] " ), 0);
if(openb & gt; -1)
{
uint ptr = str.at(openb).toAscii() - 'A';
str = str.remove(openb, 1);
QString tmpexpr = createMML(bufexpr[ptr]);
str = str.insert(openb, tmpexpr);

if(str.at(openb+4) == '(')
{
if(openb - 11 & gt; 0)
{
if(str.at(openb - 11) == 'f') //frac and '('
{
str = str.remove(openb+4, 1);
str = str.remove(openb-7 + tmpexpr.length(), 1);
}
}
if(openb + tmpexpr.length() & lt; str.length())
{
if(str.at(openb + tmpexpr.length() + 10) == 'f')
{
str = str.remove(openb + tmpexpr.length() - 6, 1);
str = str.remove(openb + 4, 1);
}
}
}

change = 1;
}
}
while((i = str.indexOf(QRegExp( " [1-9] " ), i)) & gt; -1)
{
int num = str.at(i).toAscii() - '0';
str = str.remove(i, 1);
str = str.insert(i, QString::number(numData[num]));
i += QString::number(numData[num]).length()+1;
}

str += " & lt; /math & gt; " ;
return str;
}


MiniKombajnPomiarowy3_3_rc3.7z > analizator.cpp

#include " analizator.h "

static int buff[1024];

Analizator::Analizator(QWidget* parent)
{
Analizator::parent = parent;

QStringList tlist;
tlist & lt; & lt; " 10Hz/dz " & lt; & lt; " 25Hz/dz " & lt; & lt; " 50Hz/dz " & lt; & lt; " 100Hz/dz " & lt; & lt; " 250Hz/dz " & lt; & lt; " 500Hz/dz " & lt; & lt; " 1kHz/dz " & lt; & lt; " 2.5kHz/dz " & lt; & lt; " 5kHz/dz "
& lt; & lt; " 10kHz/dz " & lt; & lt; " 25kHz/dz " & lt; & lt; " 50kHz/dz " & lt; & lt; " 62.5kHz/dz " ;
tSpin = new QComboBox(parent);
tSpin- & gt; setGeometry(100, 580, 110, 20);
tSpin- & gt; addItems(tlist);
tSpin- & gt; setCurrentIndex(7);
tSpin- & gt; setDisabled(1);
tSpin- & gt; hide();
QObject::connect(tSpin, SIGNAL(activated(int)), this, SLOT(taSlot()));

QStringList vlist;
vlist & lt; & lt; " 500mV " & lt; & lt; " 250mV " & lt; & lt; " 125mV " & lt; & lt; " 62.5mV " & lt; & lt; " 31mV " & lt; & lt; " 15.6mV " & lt; & lt; " 7.8mV " ;
vSpin = new QComboBox(parent);
vSpin- & gt; setGeometry(250, 580, 110, 20);
vSpin- & gt; addItems(vlist);
vSpin- & gt; setDisabled(1);
vSpin- & gt; hide();
QObject::connect(vSpin, SIGNAL(activated(int)), this, SLOT(vaSlot()));

xScroll = new QScrollBar(Qt::Horizontal, parent);
xScroll- & gt; setGeometry(0, Ysize+y_s+10, Xsize+x_s*2, 20);
xScroll- & gt; setMinimum(-192);
xScroll- & gt; setMaximum(192);
xScroll- & gt; setDisabled(1);
QObject::connect(xScroll, SIGNAL(valueChanged(int)), this, SLOT(xPosSlot()));

labeldaB = new QLabel( " Power: 0daB " , parent);
labeldaB- & gt; setGeometry(Xpanel, 100, XsizePanel, 20);
labeldaB- & gt; setDisabled(1);
labeldaB- & gt; hide();

labelTHDN = new QLabel( " THD+N: 0daB " , parent);
labelTHDN- & gt; setGeometry(Xpanel, 120, XsizePanel, 20);
labelTHDN- & gt; setDisabled(1);
labelTHDN- & gt; hide();

maxHoldBox = new QCheckBox( " Max hold " , parent);
maxHoldBox- & gt; setGeometry(400, 580, 100, 20);
maxHoldBox- & gt; setDisabled(1);
maxHoldBox- & gt; hide();
QObject::connect(maxHoldBox, SIGNAL(stateChanged(int)), this, SLOT(maxHoldSlot()));

timeBase = 7;
gain1 = 0;
xPos = 0;
int i;
for(i=0; i & lt; 1280; i++)
sinTab[i] = sin(i*2*3.14159/1024.0);
for(i=0; i & lt; 1024; i++)
buff[i] = 0;
}

void Analizator::show()
{
vSpin- & gt; show();
tSpin- & gt; show();
xScroll- & gt; show();
//labeldaB- & gt; show();
labelTHDN- & gt; show();
maxHoldBox- & gt; show();
}

void Analizator::hide()
{
vSpin- & gt; hide();
tSpin- & gt; hide();
xScroll- & gt; hide();
labeldaB- & gt; hide();
labelTHDN- & gt; hide();
maxHoldBox- & gt; hide();
}

void Analizator::enable()
{
vSpin- & gt; setEnabled(1);
tSpin- & gt; setEnabled(1);
xScroll- & gt; setEnabled(1);
labeldaB- & gt; setEnabled(1);
labelTHDN- & gt; setEnabled(1);
maxHoldBox- & gt; setEnabled(1);
}

void Analizator::start()
{
comPort- & gt; osc1chStart();
comPort- & gt; setGain1(gain1);
comPort- & gt; setTimeBase(timeBase);
}

void Analizator::adjustGraph(int *buf, double *in, int xPos)
{
int i;
if(xPos & lt; -128)xPos=-128;
if(xPos & gt; 0)xPos=0;
for(i = 0; i & lt; 512; i++)
{
buf[i] = in[i - xPos]*26 - 2148;
if(buf[i] & lt; -1024)buf[i]=-1024;
}
}

double decabel(double in)
{
return log10(in)*10;
}

double thdn(double* in, int N, double power)
{
double max = -100000;
double thd_n = 0.0;
int index=-1;
int i;
for(i = 0; i & lt; 2; i++)
in[i] = 0.0;
for(i = 0; i & lt; N; i++)
{
if(in[i] & gt; max)
{
max = in[i];
index = i;
}
}
if(index == -1)return -1;
for(i = -3; i & lt; 3; i++)
{
if(i + index & gt; = 0)
in[i+index] = 0.0;
}
for(i = 0; i & lt; N; i++)
{
thd_n += in[i];
}
return exp((decabel(thd_n) - power)/20)*100;
}

void Analizator::drawGraph(Buffer *bufIn)
{
Graph graph(parent);
if(bufIn- & gt; length & gt; 2047)
graph.convBufToInt16(bufIn, buff);
graph.svWindow();
int i;
for(i=0; i & lt; 1024; i++)
bufx[i] = buff[i];


double power = fft(bufx, bufy, 10, sinTab, 1024);
double thd_n = thdn(bufx, 512, power);
adjustGraph(lcdBuf, bufy, xPos);
graph.signal(lcdBuf, QColor(20,30,240));

if(maxHoldBox- & gt; checkState() == Qt::Checked)
{
for(i=0; i & lt; 512; i++)
if(lcdBuf[i] & gt; lcdBufMax[i])
lcdBufMax[i] = lcdBuf[i];
graph.signal(lcdBufMax, QColor(200, 30, 20));
}


labeldaB- & gt; setText( " Power: " + QString::number(power, 'f', 1) + " daB " );
labelTHDN- & gt; setText( " THD+N: " + QString::number(thd_n, 'f', 2) + " % " );
}

//------------FFT----------------------------------------------------------
int reverse(int n, int v)
// Odwrócenie kolejności v najmłodszych bitów liczby n - funkcja pomocnicza
{
int bit, r = 0;
for (bit=0; bit & lt; v; bit++) {
r = (r & lt; & lt; 1) | (n & 1);
n & gt; & gt; = 1;
}
return r;
}


double Analizator::fft(double *x, double *y, int v, double *SinTab, int M)

/*
Parametry wejściowe:
x - N próbek rzeczywistego sygnału znormalizowanego i oknowanego
v - log2(N)
SinTab - tablica wartości funkcji sin(ß) dla ß z przedziału [0,2pi)
M - liczba próbek funkcji sinus w okresie (rozmiar tablicy SinTab)
Parametry wyjsciowe:
y - N próbek logarytmicznego widma FFT sygnału wyrażonego w [daB],
dla częstotliwości znormalizowanych fT z przedziału [0,1)
Zwracana wartość:
moc sygnału x wyrażona w [daB] (liczona z twierdzenia Parsevala)
*/

{
int p, q, r, grp, bfy;
register int lc1, lc2, lc3;
double Sin, Cos, xp, yp, xq, yq;
double sum;

/* Wyznaczenie liczby punktów FFT */

#define N (1 & lt; & lt; v)

/* Wyzerowanie części urojonej (y) */

for (lc1=0; lc1 & lt; N; lc1++)
{
x[lc1] = x[lc1]*(0.54-0.46*SinTab[lc1 +M/4]);
y[lc1] = 0.0;
}

/* Szybkie przekształcenie Fouriera wg Cooley'a i Tukey'a
(obliczenia z podstawieniem, próbki widma w odwróconym porządku bitów),
por. [Oppenheim, Schafer], wzór (6.16) i rys.6-12 */

grp = 1;
bfy = N/2;
for (lc1=0; lc1 & lt; v; lc1++) { /* kolejne przebiegi obliczeń z podstawianiem */
p = 0;
q = bfy;
r = 0;
for (lc2=0; lc2 & lt; grp; lc2++) { /* grupy motylków w ramach danego przebiegu */
Sin = SinTab[r];
Cos = SinTab[r+M/4];
r = reverse(reverse(r,v-1)+1,v-1);
for (lc3=0; lc3 & lt; bfy; lc3++) { /* motylki w ramach danej grupy */
xq = x[q];
yq = y[q];
xp = x[p] + xq*Cos + yq*Sin; x[q] = 2*x[p] - xp; x[p] = xp;
yp = y[p] + yq*Cos - xq*Sin; y[q] = 2*y[p] - yp; y[p] = yp;
p++;
q++;
}
p += bfy;
q += bfy;
}
grp *= 2;
bfy /= 2;
}

/* Wyznaczenie kwadratu widma amplitudowego */

for (lc1=0; lc1 & lt; N; lc1++)
x[lc1] = x[lc1]*x[lc1] + y[lc1]*y[lc1];

/* Tasowanie próbek widma przywracające ich naturalne uporządkowanie */

for (lc1=0; lc1 & lt; N; lc1++)
y[reverse(lc1,v)] = x[lc1];

for (lc1=0; lc1 & lt; N; lc1++)
x[lc1] = y[lc1];

/* Logarytmowanie widma [daB] */

for (lc1=0; lc1 & lt; N; lc1++)
y[lc1] = decabel(y[lc1]);

/* Obliczenie logarytmu mocy [daB] na podstawie twierdzenia Parsevala */

sum = 0.0;
for (lc1=0; lc1 & lt; N/2; lc1++)
sum += x[lc1];

return decabel(sum);
}

//-------SLOTS------------------------
void Analizator::taSlot()
{
timeBase = 14 - tSpin- & gt; currentIndex();
comPort- & gt; setTimeBase(timeBase);
}

void Analizator::vaSlot()
{
gain1 = vSpin- & gt; currentIndex();
comPort- & gt; setGain1(gain1);
}

void Analizator::xPosSlot()
{
xPos = xScroll- & gt; value();
if(xPos & lt; -128)xPos=-128;
if(xPos & gt; 0)xPos=0;
}

void Analizator::maxHoldSlot()
{
if(maxHoldBox- & gt; checkState() == Qt::Checked)
{
int i;
for(i=0; i & lt; 512; i++)
lcdBufMax[i] = -1024;
}
}


MiniKombajnPomiarowy3_3_rc3.7z > structs.h

#ifndef STRUCTS_H
#define STRUCTS_H


struct Buffer
{
unsigned char at [32768];
int length;
int recLen;
};

union BitField
{
bool bit[8];
unsigned char byte;

};

struct Trigger
{
unsigned char edge;
unsigned char level;
unsigned char state;
};

#endif // STRUCTS_H


MiniKombajnPomiarowy3_3_rc3.7z > PortListener.h

#ifndef PORTLISTENER_H_
#define PORTLISTENER_H_

#include & lt; QObject & gt;

#ifdef _TTY_WIN_
#include " qext_win/qextserialport.h "
#else
#include " qext_posix/qextserialport.h "
#endif

class PortListener : public QObject
{
Q_OBJECT
public:
PortListener(const QString & portName);

private:
QextSerialPort *port;

private slots:
void onReadyRead();
void onDsrChanged(bool status);

};


#endif /*PORTLISTENER_H_*/


MiniKombajnPomiarowy3_3_rc3.7z > mkpcom.cpp

#include " mkpcom.h "
#include " interface.h "

extern bool bufReady;

QString sts;

MKPCom::MKPCom()
{

}

MKPCom::~MKPCom()
{
if(rsPort- & gt; open(QIODevice::ReadWrite) == true)
rsPort- & gt; close();
}

bool MKPCom::Open(QString portName, BaudRateType baud, Buffer* bufIn)
{
rsPort = new QextSerialPort(portName, QextSerialPort::EventDriven);
if(rsPort- & gt; open(QIODevice::ReadWrite) == true)
//if(1)
{
sts = " opened " ;
rsPort- & gt; setBaudRate(baud);
rsPort- & gt; setFlowControl(FLOW_OFF);
rsPort- & gt; setParity(PAR_NONE);
rsPort- & gt; setDataBits(DATA_8);
rsPort- & gt; setStopBits(STOP_1);
thr = new Thread(rsPort, bufIn, this);
#ifdef _TTY_POSIX_
QObject::connect(rsPort, SIGNAL(readyRead()), thr, SLOT(onReadyRead()), Qt::QueuedConnection);
#endif
return true;
}else
{
return false;
}
}

bool MKPCom::Close()
{
thr- & gt; terminate();
thr- & gt; wait();
delete thr;

//if(rsPort- & gt; open(QIODevice::ReadWrite) == true)
rsPort- & gt; close();

sts = " closed " ;
return true;
}

bool MKPCom::Start()
{
thr- & gt; start();
return true;
}


bool MKPCom::osc1chStart()
{
rsPort- & gt; write( " CA " );
return true;
}

bool MKPCom::osc2chStart()
{
rsPort- & gt; write( " EA " );
return true;
}

bool MKPCom::genStart()
{
rsPort- & gt; write( " G " );
return true;
}

void MKPCom::setParam1(char par, int val)
{
char buf[3];
buf[0] = par;
buf[1] = val*2 + '0';
buf[2] = 0;
rsPort- & gt; write(buf);
}

bool MKPCom::setGain1(int gain)
{
setParam1('U', gain);
rsPort- & gt; write( " A " );
return true;
}

bool MKPCom::setGain2(int gain)
{
setParam1('W', gain);
rsPort- & gt; write( " A " );
return true;
}

bool MKPCom::setTimeBase(int t)
{
setParam1('S', t);
rsPort- & gt; write( " A " );
return true;
}

bool MKPCom::enable2channel()
{
rsPort- & gt; write( " EA " );
return true;
}

bool MKPCom::disable2channel()
{
rsPort- & gt; write( " CA " );
return true;
}

bool MKPCom::sendGenChannel(int* pout)
{
unsigned short int buf[513];
for(int i=0; i & lt; 512; i++)
{
buf[i] = (pout[i]+2048);
buf[i] = (((buf[i] & 0xf80) & lt; & lt; 1) | (buf[i] & 0x7f)) & lt; & lt; 1;
}
char* cp = (char*)buf;
cp[1024] = 0;
rsPort- & gt; write( " K " );
rsPort- & gt; write(cp, 1024);
return true;
}

bool MKPCom::setFreq(int per, int tab)
{
char tTab[8];
tTab[0] = 'M';
tTab[1] = '0' + (per & gt; & gt; 11 & 0x1e);
tTab[2] = '0' + (per & gt; & gt; 7 & 0x1e);
tTab[3] = '0' + (per & gt; & gt; 3 & 0x1e);
tTab[4] = '0' + (per & lt; & lt; 1 & 0x1e);
tTab[5] = '0' + (tab & gt; & gt; 7 & 0x1e);
tTab[6] = '0' + (tab & gt; & gt; 3 & 0x1e);
tTab[7] = '0' + (tab & lt; & lt; 1 & 0x1e);
tTab[8] = 0;
rsPort- & gt; write(tTab);
return true;
}

bool MKPCom::laStart()
{
rsPort- & gt; write( " I " );
return true;
}

bool MKPCom::setLAstart()
{
rsPort- & gt; write( " O " );
return true;
}

bool MKPCom::setLAtrig(Trigger trig)
{
char tTab[7];
tTab[0] = '[';
tTab[1] = '0' + (trig.edge & gt; & gt; 3 & 0x1e);
tTab[2] = '0' + (trig.edge & lt; & lt; 1 & 0x1e);
tTab[3] = '0' + (trig.level & gt; & gt; 3 & 0x1e);
tTab[4] = '0' + (trig.level & lt; & lt; 1 & 0x1e);
tTab[5] = '0' + (trig.state & gt; & gt; 3 & 0x1e);
tTab[6] = '0' + (trig.state & lt; & lt; 1 & 0x1e);
tTab[7] = 0;
rsPort- & gt; write(tTab);
return true;
}

bool MKPCom::setLAtimebase(int timebase)
{
setParam1('Y', timebase);
return true;
}

bool MKPCom::setLAforceTrig()
{
rsPort- & gt; write( " Q " );
return true;
}

//-------Thread-------------------

Thread::Thread(QextSerialPort* portrs, Buffer* bufIn, MKPCom* parent)
// :QThread(parent)
{
port = portrs;
this- & gt; parent = parent;
bytes.clear();
this- & gt; bufIn = bufIn;

}

void Thread::run()
{
while(1)
{

#ifdef _TTY_WIN_
msleep(10);
onReadyRead();
#else
msleep(100);
#endif
}
}

void Thread::onReadyRead()
{
msleep(10);
bytes.append(port- & gt; readAll());
int inds = bytes.indexOf('s',0);
int inde = 0;
if(inds & gt; -1)
{
inde = bytes.indexOf('e', inds);
//qDebug() & lt; & lt; " len " & lt; & lt; bytes.length();
if(inde & gt; inds)
{
//*bufIn = bytes.mid(inds+1, inde-inds-1); //get one oscilloscope record
int i;
for(i=0; i & lt; inde-inds-1; i++)
{
bufIn- & gt; at[i] = bytes.at(inds+i+1);
}
bufIn- & gt; length = i;
bufIn- & gt; recLen = 2048;
bytes = bytes.remove(0, inde); //remove record from buffer
bufReady = 1;
}
}
}


MiniKombajnPomiarowy3_3_rc3.7z > generator.h

#ifndef GENERATOR_H
#define GENERATOR_H

#include & lt; QtGui/QMainWindow & gt;
#include & lt; QTextCodec & gt;
#include & lt; QtGui & gt;
#include " windowsize.h "
#include " mkpcom.h "
#include " math.h "
#include " graph.h "
#include " scriptcalc.h "
#include " qtmmlwidget.h "


class Generator: public QMainWindow
{
Q_OBJECT

public:
Generator(QMainWindow* parent, int* b);
void show();
void hide();
void enable();
void start();
void drawGraph(int xPos, int yPos);
void adjustGraph(int* buf, int length, int* out, int xPos, int yPos, int zoom);
void getPortHandle(MKPCom* cp)
{
comPort = cp;
}
int getFreq()
{
return freq;
}

void drawArb(QMouseEvent* e);
void drawFunc();
void drawArbRelease();
private:
QMainWindow* parent;
MKPCom* comPort;
Scriptcalc* Script;
QSpinBox* fSpin;
QSpinBox* fMulSpin;
QSpinBox* gSpin;
//QListWidget* tList;
QComboBox* tList;
QSpinBox* dSpin;
QSpinBox* oSpin;

QPushButton* openBut;
QPushButton* saveBut;

QLabel* labelFreq;
//QLabel* labelGain;
QLabel* labelFunc;
QLabel* labelXRange;

QPlainTextEdit* mathFuncText;
QPushButton* mathFuncButton;
QDoubleSpinBox * xFuncSpin;
QDoubleSpinBox * xFuncSpin2;

QtMmlWidget *mmlWidget;
QScrollArea *mmlScroll;

void bufChange(int tab, int type, int gain, int duty, int dc_shift);
void refreshBuff(void);
void calculateRealOut(int* bufin, int* bufout, int size, int period);
int freq;
int* buff;
int Tab;
int Per;
int Type;
int Duty;
int Gain;
int DcShift;
int recentArbPointX;
int recentArbPointY;
unsigned char RPN[500];
float numData[100];
int realOut[512];
int buffBase[512];

private slots:
void fMulSlot();
void fSlot();
void typeSlot();
void gSlot();
void dSlot();
void oSlot();
void mathFuncSlot();
void mathFuncTextSlot();
void xFuncSlot();
void openSlot();
void saveSlot();

};

#endif // GENERATOR_H


MiniKombajnPomiarowy3_3_rc3.7z > sine_test.txt

2047
2046
2046
2045
2044
2043
2041
2039
2037
2034
2031
2028
2024
2020
2016
2012
2007
2002
1997
1991
1985
1979
1972
1965
1958
1951
1943
1935
1927
1918
1909
1900
1891
1881
1871
1861
1850
1839
1828
1816
1805
1793
1781
1768
1755
1742
1729
1715
1701
1687
1673
1659
1644
1629
1613
1598
1582
1566
1549
1533
1516
1499
1482
1465
1447
1429
1411
1393
1374
1355
1337
1317
1298
1279
1259
1239
1219
1199
1178
1157
1137
1116
1095
1073
1052
1030
1008
987
964
942
920
897
875
852
829
806
783
760
736
713
689
665
642
618
594
570
545
521
497
472
448
423
399
374
349
325
300
275
250
225
200
175
150
125
100
75
50
25
0
-25
-50
-75
-100
-125
-150
-175
-200
-225
-250
-275
-300
-325
-349
-374
-399
-423
-448
-472
-497
-521
-545
-570
-594
-618
-642
-665
-689
-713
-736
-760
-783
-806
-829
-852
-875
-897
-920
-942
-964
-987
-1008
-1030
-1052
-1073
-1095
-1116
-1137
-1157
-1178
-1199
-1219
-1239
-1259
-1279
-1298
-1317
-1337
-1355
-1374
-1393
-1411
-1429
-1447
-1465
-1482
-1499
-1516
-1533
-1549
-1566
-1582
-1598
-1613
-1629
-1644
-1659
-1673
-1687
-1701
-1715
-1729
-1742
-1755
-1768
-1781
-1793
-1805
-1816
-1828
-1839
-1850
-1861
-1871
-1881
-1891
-1900
-1909
-1918
-1927
-1935
-1943
-1951
-1958
-1965
-1972
-1979
-1985
-1991
-1997
-2002
-2007
-2012
-2016
-2020
-2024
-2028
-2031
-2034
-2037
-2039
-2041
-2043
-2044
-2045
-2046
-2046
-2046
-2046
-2046
-2045
-2044
-2043
-2041
-2039
-2037
-2034
-2031
-2028
-2024
-2020
-2016
-2012
-2007
-2002
-1997
-1991
-1985
-1979
-1972
-1965
-1958
-1951
-1943
-1935
-1927
-1918
-1909
-1900
-1891
-1881
-1871
-1861
-1850
-1839
-1828
-1816
-1805
-1793
-1781
-1768
-1755
-1742
-1729
-1715
-1701
-1687
-1673
-1659
-1644
-1629
-1613
-1598
-1582
-1566
-1549
-1533
-1516
-1499
-1482
-1465
-1447
-1429
-1411
-1393
-1374
-1355
-1337
-1317
-1298
-1279
-1259
-1239
-1219
-1199
-1178
-1157
-1137
-1116
-1095
-1073
-1052
-1030
-1008
-987
-964
-942
-920
-897
-875
-852
-829
-806
-783
-760
-736
-713
-689
-665
-642
-618
-594
-570
-545
-521
-497
-472
-448
-423
-399
-374
-349
-325
-300
-275
-250
-225
-200
-175
-150
-125
-100
-75
-50
-25
0
25
50
75
100
125
150
175
200
225
250
275
300
325
349
374
399
423
448
472
497
521
545
570
594
618
642
665
689
713
736
760
783
806
829
852
875
897
920
942
964
987
1008
1030
1052
1073
1095
1116
1137
1157
1178
1199
1219
1239
1259
1279
1298
1317
1337
1355
1374
1393
1411
1429
1447
1465
1482
1499
1516
1533
1549
1566
1582
1598
1613
1629
1644
1658
1673
1687
1701
1715
1729
1742
1755
1768
1781
1793
1805
1816
1828
1839
1850
1861
1871
1881
1891
1900
1909
1918
1927
1935
1943
1951
1958
1965
1972
1979
1985
1991
1997
2002
2007
2012
2016
2020
2024
2028
2031
2034
2037
2039
2041
2043
2044
2045
2046
2046
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0


MiniKombajnPomiarowy3_3_rc3.7z > scriptcalc.h

#ifndef SCRIPTCALC_H
#define SCRIPTCALC_H

#include & lt; QtGui & gt;
#include & lt; math.h & gt;
#include & lt; complex.h & gt;

class Scriptcalc
{
public:
Scriptcalc();
bool syntaxCheck(QString);
void expressToInfix(QString, char*, float*);
void infixToRPN(unsigned char*, unsigned char*);
float calculateRPN(unsigned char*, float*);
QString presentExpress(char *expr, float* numData);
private:
float operation(float, float, unsigned char);
void operationComplex(float* y, float* yj, float a, float aj, float b, float bj, unsigned char op);
bool readFunc(char* str, char *func, int* len);
QString createMML(QString expr);
};

#endif // SCRIPTCALC_H


MiniKombajnPomiarowy3_3_rc3.7z > serialport.h

#ifndef SERIALPORT_H
#define SERIALPORT_H

#include & lt; stdio.h & gt; /* Standard input/output definitions */
#include & lt; string.h & gt; /* String function definitions */
#include & lt; unistd.h & gt; /* UNIX standard function definitions */
#include & lt; fcntl.h & gt; /* File control definitions */
#include & lt; errno.h & gt; /* Error number definitions */
#include & lt; termios.h & gt; /* POSIX terminal control definitions */
#include & lt; cstdlib & gt;
#include & lt; iostream & gt;

using namespace std;

class SerialPort
{
public:
SerialPort();
bool Open(const char* name);
void Set(int baud);
bool Write(char* str, int bytes)
{
if(write(fd, str, bytes) & lt; 0)
return false;
return true;
}
void Close(void)
{
close(fd);
}
int Read(char* str, int bytes)
{
return read(fd, str, bytes);
}

private:
int fd; //File descriptor for the port
};

#endif // SERIALPORT_H


MiniKombajnPomiarowy3_3_rc3.7z > triangle_1cycle.txt

-692
-692
-692
-692
-675
-675
-675
-662
-662
-662
-652
-652
-652
-635
-635
-635
-615
-615
-615
-615
-602
-602
-602
-577
-577
-577
-570
-570
-570
-540
-540
-540
-525
-525
-525
-510
-510
-510
-510
-497
-497
-497
-485
-485
-485
-465
-465
-465
-447
-447
-447
-427
-427
-427
-427
-417
-417
-417
-392
-392
-392
-380
-380
-380
-362
-362
-362
-342
-342
-342
-330
-330
-330
-330
-317
-317
-317
-295
-295
-295
-272
-272
-272
-265
-265
-265
-242
-242
-242
-242
-227
-227
-227
-205
-205
-205
-185
-185
-185
-172
-172
-172
-145
-145
-145
-130
-130
-130
-130
-115
-115
-115
-97
-97
-97
-82
-82
-82
-65
-65
-65
-50
-50
-50
-50
-30
-30
-30
-10
-10
-10
7
7
7
25
25
25
42
42
42
55
55
55
55
75
75
75
90
90
90
110
110
110
122
122
122
145
145
145
145
150
150
150
172
172
172
180
180
180
202
202
202
220
220
220
242
242
242
242
252
252
252
275
275
275
292
292
292
310
310
310
327
327
327
342
342
342
342
352
352
352
377
377
377
390
390
390
415
415
415
430
430
430
430
442
442
442
462
462
462
482
482
482
495
495
495
510
510
510
545
545
545
545
555
555
555
565
565
565
587
587
587
595
595
595
625
625
625
625
630
630
630
655
655
655
675
675
675
657
657
657
675
675
675
655
655
655
655
630
630
630
615
615
615
595
595
595
582
582
582
570
570
570
570
545
545
545
535
535
535
515
515
515
502
502
502
470
470
470
457
457
457
457
440
440
440
425
425
425
402
402
402
392
392
392
375
375
375
375
360
360
360
340
340
340
322
322
322
305
305
305
282
282
282
270
270
270
270
250
250
250
235
235
235
217
217
217
197
197
197
180
180
180
160
160
160
160
160
160
160
140
140
140
130
130
130
110
110
110
90
90
90
90
72
72
72
52
52
52
40
40
40
20
20
20
0
0
0
-2
-2
-2
-2
-35
-35
-35
-42
-42
-42
-70
-70
-70
-82
-82
-82
-100
-100
-100
-100
-117
-117
-117
-132
-132
-132
-160
-160
-160
-167
-167
-167
-190
-190
-190
-210
-210
-210
-210
-230
-230
-230
-240
-240
-240
-265
-265
-265
-277
-277
-277
-297
-297
-297
-297
-315
-315
-315
-332
-332
-332
-350
-350
-350
-362
-362
-362
-377
-377
-377
-392
-392
-392
-392
-417
-417
-417
-435
-435
-435
-452
-452
-452
-460
-460
-460
-487
-487
-487
-487
-500
-500
-500
-515
-515
-515
-535
-535
-535
-545
-545
-545
-562
-562
-562
-585
-585
-585
-585
-605
-605
-605
-620
-620
-620
-635
-635
-635
-650
-650
-650
-665
-665
-665


MiniKombajnPomiarowy3_3_rc3.7z > square.txt

-282
-278
-278
-280
-284
-280
-278
-288
-282
-276
-288
-284
-286
-282
-282
-284
-280
-284
-280
-286
-284
-282
-280
-288
-282
-216
-56
136
232
274
264
268
260
260
264
258
260
268
260
260
266
272
262
264
264
266
258
262
260
266
260
262
262
264
256
266
262
270
260
264
264
264
262
262
264
268
260
260
266
268
262
264
268
268
262
264
262
264
262
256
262
266
260
264
266
272
260
264
260
264
264
264
264
268
260
260
260
268
264
258
262
268
260
264
268
262
204
50
-122
-272
-286
-292
-290
-282
-284
-284
-282
-282
-282
-286
-286
-280
-278
-280
-284
-274
-280
-280
-284
-280
-280
-280
-282
-282
-284
-282
-278
-284
-284
-284
-288
-280
-280
-282
-284
-278
-278
-282
-280
-280
-278
-282
-280
-280
-282
-282
-282
-280
-284
-284
-288
-284
-280
-284
-282
-282
-280
-282
-282
-282
-284
-284
-284
-276
-282
-280
-284
-282
-284
-284
-284
-282
-280
-286
-276
-280
-282
-236
-72
232
262
274
270
268
264
262
264
264
266
266
264
268
260
266
264
264
256
262
260
266
264
260
262
268
262
264
264
268
260
262
266
268
266
264
264
272
260
264
260
268
264
262
262
266
262
264
264
268
262
260
264
268
268
260
266
266
260
258
260
266
266
264
264
266
258
260
262
268
262
258
264
266
264
260
264
268
262
262
218
-98
-216
-268
-284
-296
-294
-290
-286
-276
-276
-282
-278
-278
-284
-282
-280
-278
-280
-288
-282
-284
-280
-292
-286
-282
-286
-278
-284
-280
-280
-284
-282
-276
-280
-280
-282
-278
-278
-280
-284
-276
-284
-284
-284
-280
-284
-284
-284
-280
-280
-284
-288
-276
-282
-284
-282
-278
-282
-282
-284
-278
-282
-282
-282
-280
-284
-280
-280
-278
-282
-290
-280
-280
-280
-282
-280
-286
-282
-282
-280
-92
88
214
268
272
264
256
256
266
260
262
268
266
262
260
262
264
262
264
264
264
264
258
266
268
268
258
266
266
262
258
260
264
264
268
268
266
260
258
260
266
262
262
262
264
256
262
262
266
262
262
264
268
266
264
266
266
264
262
264
264
264
262
264
268
264
268
266
268
262
258
264
264
262
260
264
266
254
282
268
226
96
-80
-214
-282
-298
-298
-288
-288
-278
-286
-280
-278
-280
-284
-278
-278
-284
-280
-282
-284
-284
-280
-280
-280
-282
-284
-278
-284
-280
-282
-284
-284
-286
-286
-280
-278
-284
-284
-284
-280
-280
-284
-282
-280
-282
-286
-284
-278
-280
-288
-278
-276
-282
-284
-282
-280
-280
-280
-280
-280
-284
-284
-284
-276
-282
-284
-284
-276
-284
-284
-280
-280
-280
-288
-280
-280
-282
-292
-280
-278
-256
-128
74
266
266
266
266
268
260
260
264
266
264
258
264
268
264
258
260
268
258
258
264
264
266
262
264
264
260
264
258
262
262
264
264
268
262
262
268
268
256
264
264
268
266
260
266
266
260
266
262
268
262
264
266
268
264
264
264
268
266
264
264
272
262
264
264
270
256
262
264
266
260
258
266
272
264
268
260
266
260
238
118
-190
-288
-288
-292
-296
-288
-292
-288
-280
-284
-282
-286
-282
-278
-284
-282
-278
-282
-284
-282
-282
-288
-284
-286
-280
-284
-288
-288
-278
-282
-286
-284
-276
-280
-288
-278
-282
-284
-284
-290
-280
-286
-282
-284
-276
-280
-286
-276
-284
-280
-288
-280
-284
-284
-276
-276
-280
-280
-284
-284
-286
-284
-284
-284
-284
-284
-284
-282
-278
-290
-280
-282
-282
-282
-284
-284
-284
-284
-290
-266
192
192
252
274
270
264
260
262
266
262
260
266
268
262
262
264
266
260
268
264
264
266
262
266
268
258
258
266
266
260
264
260
268
262
260
260
268
262
260
260
264
266
264
264
268
264
268
264
268
266
262
264
268
260
260
266
270
260
256
262
268
260
262
266
268
258
260
266
268
260
260
266
272
262
262
260
268
260
262
262
142
-40
-188
-256
-292
-296
-296
-288
-282
-280
-284
-278
-282
-280
-284
-288
-280
-278
-284
-274
-278
-278
-290
-278
-282
-282
-282
-282
-278
-278
-280
-280
-282
-286
-278
-282
-280
-278
-282
-286
-282
-280
-282
-282
-278
-274
-284
-280
-278
-284
-284
-282
-284
-284
-284
-280
-278
-280
-284
-284
-280
-284
-280
-288
-278
-286
-282
-284
-278
-282
-276
-288
-278
-286
-284
-280
-276
-282
-282
-288
-264
-164
20
184
276
270
266
262
264
262
258
260
262
264
264
264
268
256
264
262
268
258
262
266
268
264
264
268
266
262
264
270
268
264
260
266
268
264
258
264
268
264
262
264
272
256
268
262
264
260
268
268
268
262
262
264
268
264
260
260
268
264
266
266
270
266
260
262
266
266
260
268
264
262
264
260
254
254
262
262
268
246
154
-12
-254
-286
-298
-294
-290
-292
-292
-286
-280
-280
-286
-280
-276
-280
-286
-278
-274
-276
-284
-282
-280
-280
-286
-280
-284
-284
-284
-280
-278
-284
-286
-282
-280
-280
-290
-278
-278
-278
-286
-284
-278
-288
-280
-284
-278
-282
-282
-280
-280
-282
-284
-286
-276
-286
-284
-282
-282
-288
-288
-282
-276
-282
-284
-280
-280
-282
-282
-288
-282
-280
-284
-280
-280
-282
-282
-284
-278
-284
-276
-180
164
242
268
272
266
256
262
264
270
262
264
266
272
264
260
260
260
262
264
264
268
260
264
264
272
262
262


MiniKombajnPomiarowy3_3_rc3.7z > triangle.txt

140
140
132
120
120
122
120
115
115
110
92
92
92
87
72
70
70
65
55
52
52
52
52
47
47
42
25
27
27
25
17
5
5
5
0
-5
-5
-15
-20
-30
-30
-32
-35
-42
-42
-45
-55
-55
-55
-72
-60
-80
-80
-82
-95
-100
-100
-105
-107
-122
-122
-110
-130
-142
-142
-130
-150
-145
-145
-157
-165
-172
-172
-172
-170
-185
-185
-200
-200
-205
-205
-215
-212
-222
-222
-225
-237
-240
-240
-232
-232
-230
-230
-225
-215
-210
-210
-195
-202
-187
-187
-172
-180
-170
-170
-175
-165
-155
-155
-150
-137
-137
-137
-132
-110
-115
-115
-117
-110
-105
-105
-97
-87
-72
-72
-70
-65
-55
-55
-50
-57
-57
-40
-37
-32
-32
-25
-25
-15
-15
-15
-10
-2
-2
5
10
25
25
15
32
40
40
40
50
52
52
55
62
72
72
75
82
85
85
87
100
112
112
115
120
117
117
125
127
142
142
137
137
145
145
160
165
165
165
177
175
177
177
190
190
202
202
205
212
212
212
217
215
210
210
202
195
185
185
192
187
175
175
172
175
160
160
150
142
145
145
142
127
127
127
127
120
125
125
105
100
97
97
95
82
77
77
72
62
65
65
57
45
52
52
40
32
30
30
20
10
15
15
-2
2
0
0
-12
-15
-25
-25
-32
-32
-32
-40
-47
-55
-55
-50
-72
-70
-70
-82
-85
-90
-90
-92
-105
-112
-112
-115
-110
-122
-122
-130
-137
-145
-145
-142
-162
-145
-145
-167
-175
-192
-192
-185
-197
-197
-197
-200
-210
-215
-215
-220
-232
-230
-230
-237
-240
-235
-235
-225
-222
-210
-210
-210
-200
-195
-195
-185
-190
-177
-177
-175
-170
-160
-160
-160
-145
-152
-152
-132
-127
-125
-125
-115
-117
-107
-107
-100
-95
-90
-90
-77
-82
-70
-70
-60
-62
-55
-55
-47
-35
-35
-35
-30
-20
-22
-22
-12
2
2
2
7
15
20
20
25
30
37
37
42
47
52
52
55
60
62
62
72
75
82
82
92
100
115
115
110
122
122
122
132
130
130
135
140
147
147
150
155
160
160
177
175
175
175
187
185
197
197
207
200
207
207
215
210
220
220
215
202
192
192
200
195
182
182
175
170
167
167
160
145
150
150
142
145
132
132
130
125
122
122
112
100
102
102
95
82
85
85
80
70
62
62
60
60
55
55
42
45
42
42
30
20
12
12
10
0
-2
-2
5
-15
-10
-10
-30
-30
-32
-32
-40
-52
-55
-55
-55
-67
-65
-65
-80
-85
-90
-90
-100
-105
-112
-112
-122
-122
-125
-125
-137
-132
-155
-155
-152
-147
-160
-160
-170
-175
-180
-180
-190
-192
-200
-200
-205
-215


MiniKombajnPomiarowy3_3_rc3.7z > mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include & lt; QtGui/QMainWindow & gt;
#include & lt; QTextCodec & gt;
#include & lt; QGridLayout & gt;
#include & lt; QtGui & gt;
#include & lt; QTime & gt;
#include & lt; QMouseEvent & gt;
#include " mkpcom.h "
#include " oscyloskop.h "
#include " generator.h "
#include " analizator.h "
#include " ustawienia.h "
#include " analizatorlog.h "
#include " windowsize.h "

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();
void text(QString txt);
QMainWindow* getPointer(void);
private:
void paintEvent(QPaintEvent *);
void timerEvent(QTimerEvent *);
void mouseMoveEvent(QMouseEvent *);
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void setTextPos(QMouseEvent *e);
void closeRecentDevice();
void openNewDevice();
QGridLayout *layout;
QWidget *tab;
QTabWidget *tabs;
QLabel *label;

QLabel *timeLabel;
QLabel *voltLabel;
QPushButton *openPort;



Oscyloskop* osc;
Generator* gen;
Analizator* ana;
AnalizatorLog* anaLog;
Ustawienia* ust;


MKPCom* comPort;

int device;
bool portOpened;
int gain1;
int gain2;
int timeBase;
private slots:
void tabSlot();
void comSlot();


};

#endif // MAINWINDOW_H


MiniKombajnPomiarowy3_3_rc3.7z > qextserialenumerator.cpp

/**
* @file qextserialenumerator.cpp
* @author Michał Policht
* @see QextSerialEnumerator
*/

#include " qextserialenumerator.h "

#include & lt; objbase.h & gt;
#include & lt; initguid.h & gt;


#ifdef _TTY_WIN_
//this is serial port GUID
#ifndef GUID_CLASS_COMPORT
DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);
#endif

/* Gordon Schumacher's macros for TCHAR - & gt; QString conversions and vice versa */
#ifdef UNICODE
#define QStringToTCHAR(x) (wchar_t*) x.utf16()
#define PQStringToTCHAR(x) (wchar_t*) x- & gt; utf16()
#define TCHARToQString(x) QString::fromUtf16((ushort*)(x))
#define TCHARToQStringN(x,y) QString::fromUtf16((ushort*)(x),(y))
#else
#define QStringToTCHAR(x) x.local8Bit().constData()
#define PQStringToTCHAR(x) x- & gt; local8Bit().constData()
#define TCHARToQString(x) QString::fromLocal8Bit((x))
#define TCHARToQStringN(x,y) QString::fromLocal8Bit((x),(y))
#endif /*UNICODE*/


//static
QString QextSerialEnumerator::getRegKeyValue(HKEY key, LPCTSTR property)
{
DWORD size = 0;
RegQueryValueEx(key, property, NULL, NULL, NULL, & size);
BYTE * buff = new BYTE[size];
if (RegQueryValueEx(key, property, NULL, NULL, buff, & size) == ERROR_SUCCESS) {
return TCHARToQStringN(buff, size);
delete [] buff;
} else {
qWarning( " QextSerialEnumerator::getRegKeyValue: can not obtain value from registry " );
delete [] buff;
return QString();
}
}

//static
QString QextSerialEnumerator::getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property)
{
DWORD buffSize = 0;
SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, NULL, 0, & buffSize);
BYTE * buff = new BYTE[buffSize];
if (!SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, buff, buffSize, NULL))
qCritical( " Can not obtain property: %ld from registry " , property);
QString result = TCHARToQString(buff);
delete [] buff;
return result;
}

//static
void QextSerialEnumerator::setupAPIScan(QList & lt; QextPortInfo & gt; & infoList)
{
HDEVINFO devInfo = INVALID_HANDLE_VALUE;
GUID * guidDev = (GUID *) & GUID_CLASS_COMPORT;

devInfo = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if(devInfo == INVALID_HANDLE_VALUE) {
qCritical( " SetupDiGetClassDevs failed. Error code: %ld " , GetLastError());
return;
}

//enumerate the devices
bool ok = true;
SP_DEVICE_INTERFACE_DATA ifcData;
ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL;
DWORD detDataSize = 0;
DWORD oldDetDataSize = 0;

for (DWORD i = 0; ok; i++) {
ok = SetupDiEnumDeviceInterfaces(devInfo, NULL, guidDev, i, & ifcData);
if (ok) {
SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)};
//check for required detData size
SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, NULL, 0, & detDataSize, & devData);
//if larger than old detData size then reallocate the buffer
if (detDataSize & gt; oldDetDataSize) {
delete [] detData;
detData = (SP_DEVICE_INTERFACE_DETAIL_DATA *) new char[detDataSize];
detData- & gt; cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
oldDetDataSize = detDataSize;
}
//check the details
if (SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, detData, detDataSize,
NULL, & devData)) {
// Got a device. Get the details.
QextPortInfo info;
info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME);
info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME);
//anyway, to get the port name we must still open registry directly :( ???
//Eh...
HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0,
DIREG_DEV, KEY_READ);
info.portName = getRegKeyValue(devKey, TEXT( " PortName " ));
RegCloseKey(devKey);
infoList.append(info);
} else {
qCritical( " SetupDiGetDeviceInterfaceDetail failed. Error code: %ld " , GetLastError());
delete [] detData;
return;
}
} else {
if (GetLastError() != ERROR_NO_MORE_ITEMS) {
delete [] detData;
qCritical( " SetupDiEnumDeviceInterfaces failed. Error code: %ld " , GetLastError());
return;
}
}
}
delete [] detData;
}

#endif /*_TTY_WIN_*/


//static
QList & lt; QextPortInfo & gt; QextSerialEnumerator::getPorts()
{
QList & lt; QextPortInfo & gt; ports;

#ifdef _TTY_WIN_
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!::GetVersionEx( & vi)) {
qCritical( " Could not get OS version. " );
return ports;
}
// Handle windows 9x and NT4 specially
if (vi.dwMajorVersion & lt; 5) {
qCritical( " Enumeration for this version of Windows is not implemented yet " );
/* if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
EnumPortsWNt4(ports);
else
EnumPortsW9x(ports);*/
} else //w2k or later
setupAPIScan(ports);
#endif /*_TTY_WIN_*/
#ifdef _TTY_POSIX_
qCritical( " Enumeration for POSIX systems is not implemented yet. " );
#endif /*_TTY_POSIX_*/

return ports;
}


MiniKombajnPomiarowy3_3_rc3.7z > qextserialport.cpp

/*!
\class QextSerialPort
\author Stefan Sander
\author Michal Policht

A cross-platform serial port class.
This class encapsulates a serial port on both POSIX and Windows systems. The user will be
notified of errors and possible portability conflicts at run-time by default - this behavior can
be turned off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn
off portability warnings) in the project.

You may choose from polling or event driven API. For details check setQueryMode() documentation.

\note
On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may
select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
make no guarantees as to the quality of POSIX support under NT/2000 however.

*/

#include & lt; stdio.h & gt;
#include " qextserialport.h "

/*!
Default constructor. Note that the naming convention used by a QextSerialPort constructed with
this constructor will be determined by #defined constants, or lack thereof - the default behavior
is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are:

\verbatim

Constant Used By Naming Convention
---------- ------------- ------------------------
_TTY_WIN_ Windows COM1, COM2
_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
& lt; none & gt; Linux /dev/ttyS0, /dev/ttyS1
\endverbatim

The object will be associated with the first port in the system, e.g. COM1 on Windows systems.
See the other constructors if you need to use a port other than the first.
*/
QextSerialPort::QextSerialPort()
: QextBaseType()
{}

/*!
Constructs a serial port attached to the port specified by name.
name is the name of the device, which is windowsystem-specific,
e.g. " COM1 " or " /dev/ttyS0 " .

\see setQueryMode().
*/
QextSerialPort::QextSerialPort(const QString & name, QueryMode mode)
: QextBaseType(name, mode)
{
}

/*!
Constructs a port with default name and settings specified by the settings parameter.

\see setQueryMode().
*/
QextSerialPort::QextSerialPort(PortSettings const & settings, QueryMode mode)
: QextBaseType(settings, mode)
{}

/*!
Constructs a port with the name and settings specified.

\see setQueryMode().
*/
QextSerialPort::QextSerialPort(const QString & name, PortSettings const & settings, QueryMode mode)
: QextBaseType(name, settings, mode)
{}

/*!
Copy constructor.

\deprecated
*/
QextSerialPort::QextSerialPort(const QextSerialPort & s)
: QextBaseType(s)
{}

/*!
\fn QextSerialPort & QextSerialPort::operator=(const QextSerialPort & s)
Overrides the = operator.

\deprecated
*/
QextSerialPort & QextSerialPort::operator=(const QextSerialPort & s)
{
return (QextSerialPort & )QextBaseType::operator=(s);
}

/*!
\fn QextSerialPort::~QextSerialPort()
Standard destructor.
*/
QextSerialPort::~QextSerialPort()
{}


MiniKombajnPomiarowy3_3_rc3.7z > qextserialbase.cpp

#include " qextserialbase.h "

/*!
\fn QextSerialBase::QextSerialBase()
Default constructor.
*/
QextSerialBase::QextSerialBase()
: QIODevice()
{

#ifdef _TTY_WIN_
setPortName( " COM1 " );

#elif defined(_TTY_IRIX_)
setPortName( " /dev/ttyf1 " );

#elif defined(_TTY_HPUX_)
setPortName( " /dev/tty1p0 " );

#elif defined(_TTY_SUN_)
setPortName( " /dev/ttya " );

#elif defined(_TTY_DIGITAL_)
setPortName( " /dev/tty01 " );

#elif defined(_TTY_FREEBSD_)
setPortName( " /dev/ttyd1 " );

#else
setPortName( " /dev/ttyS0 " );
#endif

construct();
}

/*!
\fn QextSerialBase::QextSerialBase(const QString & name)
Construct a port and assign it to the device specified by the name parameter.
*/
QextSerialBase::QextSerialBase(const QString & name)
: QIODevice()
{
setPortName(name);
construct();
}

/*!
\fn QextSerialBase::~QextSerialBase()
Standard destructor.
*/
QextSerialBase::~QextSerialBase()
{
delete mutex;
}

/*!
\fn void QextSerialBase::construct()
Common constructor function for setting up default port settings.
(115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 0 ms timeout).
*/
void QextSerialBase::construct()
{
Settings.BaudRate=BAUD115200;
Settings.DataBits=DATA_8;
Settings.Parity=PAR_NONE;
Settings.StopBits=STOP_1;
Settings.FlowControl=FLOW_HARDWARE;
Settings.Timeout_Millisec=500;
mutex = new QMutex( QMutex::Recursive );
setOpenMode(QIODevice::NotOpen);
}

void QextSerialBase::setQueryMode(QueryMode mechanism)
{
_queryMode = mechanism;
}

/*!
\fn void QextSerialBase::setPortName(const QString & name)
Sets the name of the device associated with the object, e.g. " COM1 " , or " /dev/ttyS0 " .
*/
void QextSerialBase::setPortName(const QString & name)
{
port = name;
}

/*!
\fn QString QextSerialBase::portName() const
Returns the name set by setPortName().
*/
QString QextSerialBase::portName() const
{
return port;
}

/*!
\fn BaudRateType QextSerialBase::baudRate(void) const
Returns the baud rate of the serial port. For a list of possible return values see
the definition of the enum BaudRateType.
*/
BaudRateType QextSerialBase::baudRate(void) const
{
return Settings.BaudRate;
}

/*!
\fn DataBitsType QextSerialBase::dataBits() const
Returns the number of data bits used by the port. For a list of possible values returned by
this function, see the definition of the enum DataBitsType.
*/
DataBitsType QextSerialBase::dataBits() const
{
return Settings.DataBits;
}

/*!
\fn ParityType QextSerialBase::parity() const
Returns the type of parity used by the port. For a list of possible values returned by
this function, see the definition of the enum ParityType.
*/
ParityType QextSerialBase::parity() const
{
return Settings.Parity;
}

/*!
\fn StopBitsType QextSerialBase::stopBits() const
Returns the number of stop bits used by the port. For a list of possible return values, see
the definition of the enum StopBitsType.
*/
StopBitsType QextSerialBase::stopBits() const
{
return Settings.StopBits;
}

/*!
\fn FlowType QextSerialBase::flowControl() const
Returns the type of flow control used by the port. For a list of possible values returned
by this function, see the definition of the enum FlowType.
*/
FlowType QextSerialBase::flowControl() const
{
return Settings.FlowControl;
}

/*!
\fn bool QextSerialBase::isSequential() const
Returns true if device is sequential, otherwise returns false. Serial port is sequential device
so this function always returns true. Check QIODevice::isSequential() documentation for more
information.
*/
bool QextSerialBase::isSequential() const
{
return true;
}

/*!
\fn bool QextSerialBase::atEnd() const
This function will return true if the input buffer is empty (or on error), and false otherwise.
Call QextSerialBase::lastError() for error information.
*/
bool QextSerialBase::atEnd() const
{
if (size()) {
return true;
}
return false;
}

/*!
\fn qint64 QextSerialBase::readLine(char * data, qint64 maxSize)
This function will read a line of buffered input from the port, stopping when either maxSize bytes
have been read, the port has no more data available, or a newline is encountered.
The value returned is the length of the string that was read.
*/
qint64 QextSerialBase::readLine(char * data, qint64 maxSize)
{
qint64 numBytes = bytesAvailable();
char* pData = data;

if (maxSize & lt; 2) //maxSize must be larger than 1
return -1;

/*read a byte at a time for MIN(bytesAvail, maxSize - 1) iterations, or until a newline*/
while (pData & lt; (data+numBytes) & & --maxSize) {
readData(pData, 1);
if (*pData++ == '\n') {
break;
}
}
*pData='\0';

/*return size of data read*/
return (pData-data);
}

/*!
\fn ulong QextSerialBase::lastError() const
Returns the code for the last error encountered by the port, or E_NO_ERROR if the last port
operation was successful. Possible error codes are:

\verbatim
Error Explanation
--------------------------- -------------------------------------------------------------
E_NO_ERROR No Error has occured
E_INVALID_FD Invalid file descriptor (port was not opened correctly)
E_NO_MEMORY Unable to allocate memory tables (POSIX)
E_CAUGHT_NON_BLOCKED_SIGNAL Caught a non-blocked signal (POSIX)
E_PORT_TIMEOUT Operation timed out (POSIX)
E_INVALID_DEVICE The file opened by the port is not a character device (POSIX)
E_BREAK_CONDITION The port detected a break condition
E_FRAMING_ERROR The port detected a framing error
(usually caused by incorrect baud rate settings)
E_IO_ERROR There was an I/O error while communicating with the port
E_BUFFER_OVERRUN Character buffer overrun
E_RECEIVE_OVERFLOW Receive buffer overflow
E_RECEIVE_PARITY_ERROR The port detected a parity error in the received data
E_TRANSMIT_OVERFLOW Transmit buffer overflow
E_READ_FAILED General read operation failure
E_WRITE_FAILED General write operation failure
\endverbatim
*/
ulong QextSerialBase::lastError() const
{
return lastErr;
}


MiniKombajnPomiarowy3_3_rc3.7z > qextserialport.h

#ifndef _QEXTSERIALPORT_H_
#define _QEXTSERIALPORT_H_

/*POSIX CODE*/
#ifdef _TTY_POSIX_
#include " posix_qextserialport.h "
#define QextBaseType Posix_QextSerialPort

/*MS WINDOWS CODE*/
#else
#include " win_qextserialport.h "
#define QextBaseType Win_QextSerialPort
#endif

class QextSerialPort: public QextBaseType
{
Q_OBJECT

public:
typedef QextSerialBase::QueryMode QueryMode;

QextSerialPort();
QextSerialPort(const QString & name, QueryMode mode = QextSerialPort::Polling);
QextSerialPort(PortSettings const & s, QueryMode mode = QextSerialPort::Polling);
QextSerialPort(const QString & name, PortSettings const & s, QueryMode mode = QextSerialPort::Polling);
QextSerialPort(const QextSerialPort & s);
QextSerialPort & operator=(const QextSerialPort & );
virtual ~QextSerialPort();

};

#endif


MiniKombajnPomiarowy3_3_rc3.7z > qextserialbase.h

#ifndef _QEXTSERIALBASE_H_
#define _QEXTSERIALBASE_H_

#include & lt; QIODevice & gt;
#include & lt; QFile & gt;
#include & lt; QThread & gt;
#include & lt; QMutex & gt;

/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
#ifdef _TTY_NOWARN_
#define _TTY_NOWARN_PORT_
#endif

/*macros for thread support*/
#define LOCK_MUTEX() mutex- & gt; lock()
#define UNLOCK_MUTEX() mutex- & gt; unlock()

/*macros for warning and debug messages*/
#ifdef _TTY_NOWARN_PORT_
#define TTY_PORTABILITY_WARNING(s)
#else
#define TTY_PORTABILITY_WARNING(s) qWarning(s)
#endif /*_TTY_NOWARN_PORT_*/
#ifdef _TTY_NOWARN_
#define TTY_WARNING(s)
#else
#define TTY_WARNING(s) qWarning(s)
#endif /*_TTY_NOWARN_*/


/*line status constants*/
#define LS_CTS 0x01
#define LS_DSR 0x02
#define LS_DCD 0x04
#define LS_RI 0x08
#define LS_RTS 0x10
#define LS_DTR 0x20
#define LS_ST 0x40
#define LS_SR 0x80

/*error constants*/
#define E_NO_ERROR 0
#define E_INVALID_FD 1
#define E_NO_MEMORY 2
#define E_CAUGHT_NON_BLOCKED_SIGNAL 3
#define E_PORT_TIMEOUT 4
#define E_INVALID_DEVICE 5
#define E_BREAK_CONDITION 6
#define E_FRAMING_ERROR 7
#define E_IO_ERROR 8
#define E_BUFFER_OVERRUN 9
#define E_RECEIVE_OVERFLOW 10
#define E_RECEIVE_PARITY_ERROR 11
#define E_TRANSMIT_OVERFLOW 12
#define E_READ_FAILED 13
#define E_WRITE_FAILED 14

/*!
* Enums for port settings.
*/
enum NamingConvention
{
WIN_NAMES,
IRIX_NAMES,
HPUX_NAMES,
SUN_NAMES,
DIGITAL_NAMES,
FREEBSD_NAMES,
LINUX_NAMES
};

enum BaudRateType
{
BAUD50, //POSIX ONLY
BAUD75, //POSIX ONLY
BAUD110,
BAUD134, //POSIX ONLY
BAUD150, //POSIX ONLY
BAUD200, //POSIX ONLY
BAUD300,
BAUD600,
BAUD1200,
BAUD1800, //POSIX ONLY
BAUD2400,
BAUD4800,
BAUD9600,
BAUD14400, //WINDOWS ONLY
BAUD19200,
BAUD38400,
BAUD56000, //WINDOWS ONLY
BAUD57600,
BAUD76800, //POSIX ONLY
BAUD115200,
BAUD128000, //WINDOWS ONLY
BAUD230400,
BAUD256000, //WINDOWS ONLY
BAUD460800,
BAUD921600
};

enum DataBitsType
{
DATA_5,
DATA_6,
DATA_7,
DATA_8
};

enum ParityType
{
PAR_NONE,
PAR_ODD,
PAR_EVEN,
PAR_MARK, //WINDOWS ONLY
PAR_SPACE
};

enum StopBitsType
{
STOP_1,
STOP_1_5, //WINDOWS ONLY
STOP_2
};

enum FlowType
{
FLOW_OFF,
FLOW_HARDWARE,
FLOW_XONXOFF
};

/**
* structure to contain port settings
*/
struct PortSettings
{
BaudRateType BaudRate;
DataBitsType DataBits;
ParityType Parity;
StopBitsType StopBits;
FlowType FlowControl;
long Timeout_Millisec;
};

/*!
* \author Stefan Sander
* \author Michal Policht
*
* A common base class for Win_QextSerialBase, Posix_QextSerialBase and QextSerialPort.
*/
class QextSerialBase : public QIODevice
{
Q_OBJECT

public:
enum QueryMode {
Polling,
EventDriven
};

protected:
QMutex* mutex;
QString port;
PortSettings Settings;
ulong lastErr;
QextSerialBase::QueryMode _queryMode;

virtual qint64 readData(char * data, qint64 maxSize)=0;
virtual qint64 writeData(const char * data, qint64 maxSize)=0;

public:
QextSerialBase();
QextSerialBase(const QString & name);
virtual ~QextSerialBase();
virtual void construct();
virtual void setPortName(const QString & name);
virtual QString portName() const;

/**!
* Get query mode.
* \return query mode.
*/
inline QextSerialBase::QueryMode queryMode() const { return _queryMode; };

/*!
* Set desired serial communication handling style. You may choose from polling
* or event driven approach. This function does nothing when port is open; to
* apply changes port must be reopened.
*
* In event driven approach read() and write() functions are acting
* asynchronously. They return immediately and the operation is performed in
* the background, so they doesn't freeze the calling thread.
* To determine when operation is finished, QextSerialPort runs separate thread
* and monitors serial port events. Whenever the event occurs, adequate signal
* is emitted.
*
* When polling is set, read() and write() are acting synchronously. Signals are
* not working in this mode and some functions may not be available. The advantage
* of polling is that it generates less overhead due to lack of signals emissions
* and it doesn't start separate thread to monitor events.
*
* Generally event driven approach is more capable and friendly, although some
* applications may need as low overhead as possible and then polling comes.
*
* \param mode query mode.
*/
virtual void setQueryMode(QueryMode mode);

// virtual void setBlockingRead(bool block) = 0; /// & lt; @todo implement.

virtual void setBaudRate(BaudRateType)=0;
virtual BaudRateType baudRate() const;
virtual void setDataBits(DataBitsType)=0;
virtual DataBitsType dataBits() const;
virtual void setParity(ParityType)=0;
virtual ParityType parity() const;
virtual void setStopBits(StopBitsType)=0;
virtual StopBitsType stopBits() const;
virtual void setFlowControl(FlowType)=0;
virtual FlowType flowControl() const;
virtual void setTimeout(long)=0;

virtual bool open(OpenMode mode)=0;
virtual bool isSequential() const;
virtual void close()=0;
virtual void flush()=0;

virtual qint64 size() const=0;
virtual qint64 bytesAvailable()=0;
virtual bool atEnd() const;

virtual void ungetChar(char c)=0;
virtual qint64 readLine(char * data, qint64 maxSize);

virtual ulong lastError() const;
virtual void translateError(ulong error)=0;

virtual void setDtr(bool set=true)=0;
virtual void setRts(bool set=true)=0;
virtual ulong lineStatus()=0;

signals:
/**
* This signal is emitted whenever port settings are updated.
* \param valid \p true if settings are valid, \p false otherwise.
*
* @todo implement.
*/
// void validSettings(bool valid);

/*!
* This signal is emitted whenever dsr line has changed its state. You may
* use this signal to check if device is connected.
* \param status \p true when DSR signal is on, \p false otherwise.
*
* \see lineStatus().
*/
void dsrChanged(bool status);
};

#endif


MiniKombajnPomiarowy3_3_rc3.7z > win_qextserialport.cpp

//#include & lt; stdio.h & gt;
//#include & lt; Process.h & gt;
//#include & lt; QCoreApplication & gt;
//#include & lt; QEvent & gt;
#include & lt; QReadWriteLock & gt;
#include " win_qextserialport.h "


/*!
\fn Win_QextSerialPort::Win_QextSerialPort()
Default constructor. Note that the name of the device used by a Win_QextSerialPort constructed
with this constructor will be determined by #defined constants, or lack thereof - the default
behavior is the same as _TTY_LINUX_. Possible naming conventions and their associated constants
are:

\verbatim

Constant Used By Naming Convention
---------- ------------- ------------------------
_TTY_WIN_ Windows COM1, COM2
_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
& lt; none & gt; Linux /dev/ttyS0, /dev/ttyS1
\endverbatim

This constructor associates the object with the first port on the system, e.g. COM1 for Windows
platforms. See the other constructor if you need a port other than the first.
*/
Win_QextSerialPort::Win_QextSerialPort():
QextSerialBase()
{
Win_Handle=INVALID_HANDLE_VALUE;
init();
}

/*!Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort & )
Copy constructor.
*/
Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort & s):
QextSerialBase(s.port)
{
Win_Handle=INVALID_HANDLE_VALUE;
_queryMode = s._queryMode;
_bytesToWrite = s._bytesToWrite;
bytesToWriteLock = new QReadWriteLock;
overlapThread = new Win_QextSerialThread(this);
memcpy( & overlap, & s.overlap, sizeof(OVERLAPPED));
memcpy( & overlapWrite, & s.overlapWrite, sizeof(OVERLAPPED));
setOpenMode(s.openMode());
lastErr=s.lastErr;
port = s.port;
Settings.FlowControl=s.Settings.FlowControl;
Settings.Parity=s.Settings.Parity;
Settings.DataBits=s.Settings.DataBits;
Settings.StopBits=s.Settings.StopBits;
Settings.BaudRate=s.Settings.BaudRate;
Win_Handle=s.Win_Handle;
memcpy( & Win_CommConfig, & s.Win_CommConfig, sizeof(COMMCONFIG));
memcpy( & Win_CommTimeouts, & s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
if (s.overlapThread- & gt; isRunning())
overlapThread- & gt; start();
}

/*!
\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name)
Constructs a serial port attached to the port specified by devName.
devName is the name of the device, which is windowsystem-specific,
e.g. " COM2 " or " /dev/ttyS0 " .
*/
Win_QextSerialPort::Win_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode):
QextSerialBase(name)
{
Win_Handle=INVALID_HANDLE_VALUE;
setQueryMode(mode);
init();
}

/*!
\fn Win_QextSerialPort::Win_QextSerialPort(const PortSettings & settings)
Constructs a port with default name and specified settings.
*/
Win_QextSerialPort::Win_QextSerialPort(const PortSettings & settings, QextSerialBase::QueryMode mode) {
Win_Handle=INVALID_HANDLE_VALUE;
setBaudRate(settings.BaudRate);
setDataBits(settings.DataBits);
setStopBits(settings.StopBits);
setParity(settings.Parity);
setFlowControl(settings.FlowControl);
setTimeout(settings.Timeout_Millisec);
setQueryMode(mode);
init();
}

/*!
\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings & settings)
Constructs a port with specified name and settings.
*/
Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings & settings, QextSerialBase::QueryMode mode) {
Win_Handle=INVALID_HANDLE_VALUE;
setPortName(name);
setBaudRate(settings.BaudRate);
setDataBits(settings.DataBits);
setStopBits(settings.StopBits);
setParity(settings.Parity);
setFlowControl(settings.FlowControl);
setTimeout(settings.Timeout_Millisec);
setQueryMode(mode);
init();
}

void Win_QextSerialPort::init()
{
_bytesToWrite = 0;
overlap.Internal = 0;
overlap.InternalHigh = 0;
overlap.Offset = 0;
overlap.OffsetHigh = 0;
overlap.hEvent = CreateEvent(NULL, true, false, NULL);
overlapThread = new Win_QextSerialThread(this);
bytesToWriteLock = new QReadWriteLock;
}

/*!
\fn Win_QextSerialPort::~Win_QextSerialPort()
Standard destructor.
*/
Win_QextSerialPort::~Win_QextSerialPort() {
if (isOpen()) {
close();
}
CloseHandle(overlap.hEvent);
delete overlapThread;
delete bytesToWriteLock;
}

/*!
\fn Win_QextSerialPort & Win_QextSerialPort::operator=(const Win_QextSerialPort & s)
overrides the = operator
*/
Win_QextSerialPort & Win_QextSerialPort::operator=(const Win_QextSerialPort & s) {
setOpenMode(s.openMode());
_queryMode = s._queryMode;
_bytesToWrite = s._bytesToWrite;
bytesToWriteLock = new QReadWriteLock;
overlapThread = new Win_QextSerialThread(this);
memcpy( & overlap, & s.overlap, sizeof(OVERLAPPED));
memcpy( & overlapWrite, & s.overlapWrite, sizeof(OVERLAPPED));
lastErr=s.lastErr;
port = s.port;
Settings.FlowControl=s.Settings.FlowControl;
Settings.Parity=s.Settings.Parity;
Settings.DataBits=s.Settings.DataBits;
Settings.StopBits=s.Settings.StopBits;
Settings.BaudRate=s.Settings.BaudRate;
Win_Handle=s.Win_Handle;
memcpy( & Win_CommConfig, & s.Win_CommConfig, sizeof(COMMCONFIG));
memcpy( & Win_CommTimeouts, & s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
if (s.overlapThread- & gt; isRunning())
overlapThread- & gt; start();
return *this;
}


/*!
\fn bool Win_QextSerialPort::open(OpenMode mode)
Opens a serial port. Note that this function does not specify which device to open. If you need
to open a device by name, see Win_QextSerialPort::open(const char*). This function has no effect
if the port associated with the class is already open. The port is also configured to the current
settings, as stored in the Settings structure.
*/
bool Win_QextSerialPort::open(OpenMode mode) {
unsigned long confSize = sizeof(COMMCONFIG);
Win_CommConfig.dwSize = confSize;
DWORD dwFlagsAndAttributes = 0;
if (queryMode() == QextSerialBase::EventDriven)
dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;

LOCK_MUTEX();
if (mode == QIODevice::NotOpen)
return isOpen();
if (!isOpen()) {
/*open the port*/
Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
if (Win_Handle!=INVALID_HANDLE_VALUE) {
/*configure port settings*/
GetCommConfig(Win_Handle, & Win_CommConfig, & confSize);
GetCommState(Win_Handle, & (Win_CommConfig.dcb));

/*set up parameters*/
Win_CommConfig.dcb.fBinary=TRUE;
Win_CommConfig.dcb.fInX=FALSE;
Win_CommConfig.dcb.fOutX=FALSE;
Win_CommConfig.dcb.fAbortOnError=FALSE;
Win_CommConfig.dcb.fNull=FALSE;
setBaudRate(Settings.BaudRate);
setDataBits(Settings.DataBits);
setStopBits(Settings.StopBits);
setParity(Settings.Parity);
setFlowControl(Settings.FlowControl);
setTimeout(Settings.Timeout_Millisec);
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));

//init event driven approach
if (queryMode() == QextSerialBase::EventDriven) {
Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(Win_Handle, & Win_CommTimeouts);
if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
qWarning( " Failed to set Comm Mask. Error code: %ld " , GetLastError());
UNLOCK_MUTEX();
return false;
}
overlapThread- & gt; start();
}
QIODevice::open(mode);
}
} else {
UNLOCK_MUTEX();
return false;
}
UNLOCK_MUTEX();
return isOpen();
}

/*!
\fn void Win_QextSerialPort::close()
Closes a serial port. This function has no effect if the serial port associated with the class
is not currently open.
*/
void Win_QextSerialPort::close()
{
LOCK_MUTEX();

if (isOpen()) {
flush();
if (overlapThread- & gt; isRunning()) {
overlapThread- & gt; stop();
if (QThread::currentThread() != overlapThread)
overlapThread- & gt; wait();
}
if (CloseHandle(Win_Handle))
Win_Handle = INVALID_HANDLE_VALUE;
_bytesToWrite = 0;
QIODevice::close();
}

UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::flush()
Flushes all pending I/O to the serial port. This function has no effect if the serial port
associated with the class is not currently open.
*/
void Win_QextSerialPort::flush() {
LOCK_MUTEX();
if (isOpen()) {
FlushFileBuffers(Win_Handle);
}
UNLOCK_MUTEX();
}

/*!
\fn qint64 Win_QextSerialPort::size() const
This function will return the number of bytes waiting in the receive queue of the serial port.
It is included primarily to provide a complete QIODevice interface, and will not record errors
in the lastErr member (because it is const). This function is also not thread-safe - in
multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
*/
qint64 Win_QextSerialPort::size() const {
int availBytes;
COMSTAT Win_ComStat;
DWORD Win_ErrorMask=0;
ClearCommError(Win_Handle, & Win_ErrorMask, & Win_ComStat);
availBytes = Win_ComStat.cbInQue;
return (qint64)availBytes;
}

/*!
\fn qint64 Win_QextSerialPort::bytesAvailable()
Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
the port is not currently open, or -1 on error. Error information can be retrieved by calling
Win_QextSerialPort::getLastError().
*/
qint64 Win_QextSerialPort::bytesAvailable() {
LOCK_MUTEX();
if (isOpen()) {
DWORD Errors;
COMSTAT Status;
bool success=ClearCommError(Win_Handle, & Errors, & Status);
translateError(Errors);
if (success) {
lastErr=E_NO_ERROR;
UNLOCK_MUTEX();
return Status.cbInQue + QIODevice::bytesAvailable();
}
UNLOCK_MUTEX();
return (unsigned int)-1;
}
UNLOCK_MUTEX();
return 0;
}

/*!
\fn void Win_QextSerialPort::translateError(ulong error)
Translates a system-specific error code to a QextSerialPort error code. Used internally.
*/
void Win_QextSerialPort::translateError(ulong error) {
if (error & CE_BREAK) {
lastErr=E_BREAK_CONDITION;
}
else if (error & CE_FRAME) {
lastErr=E_FRAMING_ERROR;
}
else if (error & CE_IOE) {
lastErr=E_IO_ERROR;
}
else if (error & CE_MODE) {
lastErr=E_INVALID_FD;
}
else if (error & CE_OVERRUN) {
lastErr=E_BUFFER_OVERRUN;
}
else if (error & CE_RXPARITY) {
lastErr=E_RECEIVE_PARITY_ERROR;
}
else if (error & CE_RXOVER) {
lastErr=E_RECEIVE_OVERFLOW;
}
else if (error & CE_TXFULL) {
lastErr=E_TRANSMIT_OVERFLOW;
}
}

/*!
\fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
Reads a block of data from the serial port. This function will read at most maxlen bytes from
the serial port and place them in the buffer pointed to by data. Return value is the number of
bytes actually read, or -1 on error.

\warning before calling this function ensure that serial port associated with this class
is currently open (use isOpen() function to check if port is open).
*/
qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
{
DWORD retVal;

LOCK_MUTEX();

retVal = 0;
if (queryMode() == QextSerialBase::EventDriven) {
OVERLAPPED overlapRead;
overlapRead.Internal = 0;
overlapRead.InternalHigh = 0;
overlapRead.Offset = 0;
overlapRead.OffsetHigh = 0;
overlapRead.hEvent = CreateEvent(NULL, true, false, NULL);
if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapRead)) {
if (GetLastError() == ERROR_IO_PENDING)
GetOverlappedResult(Win_Handle, & overlapRead, & retVal, true);
else {
lastErr = E_READ_FAILED;
retVal = (DWORD)-1;
}
}
CloseHandle(overlapRead.hEvent);
} else if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) {
lastErr = E_READ_FAILED;
retVal = (DWORD)-1;
}

UNLOCK_MUTEX();

return (qint64)retVal;
}

/*!
\fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
Writes a block of data to the serial port. This function will write len bytes
from the buffer pointed to by data to the serial port. Return value is the number
of bytes actually written, or -1 on error.

\warning before calling this function ensure that serial port associated with this class
is currently open (use isOpen() function to check if port is open).
*/
qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
{
DWORD retVal;

LOCK_MUTEX();

retVal = 0;
if (queryMode() == QextSerialBase::EventDriven) {
bytesToWriteLock- & gt; lockForWrite();
_bytesToWrite += maxSize;
bytesToWriteLock- & gt; unlock();
overlapWrite.Internal = 0;
overlapWrite.InternalHigh = 0;
overlapWrite.Offset = 0;
overlapWrite.OffsetHigh = 0;
overlapWrite.hEvent = CreateEvent(NULL, true, false, NULL);
if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapWrite)) {
lastErr = E_WRITE_FAILED;
retVal = (DWORD)-1;
} else
retVal = maxSize;
} else if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) {
lastErr = E_WRITE_FAILED;
retVal = (DWORD)-1;
}

UNLOCK_MUTEX();

return (qint64)retVal;
}

/*!
\fn void Win_QextSerialPort::ungetChar(char c)
This function is included to implement the full QIODevice interface, and currently has no
purpose within this class. This function is meaningless on an unbuffered device and currently
only prints a warning message to that effect.
*/
void Win_QextSerialPort::ungetChar(char) {

/*meaningless on unbuffered sequential device - return error and print a warning*/
TTY_WARNING( " Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless " );
}

/*!
\fn void Win_QextSerialPort::setFlowControl(FlowType flow)
Sets the flow control used by the port. Possible values of flow are:
\verbatim
FLOW_OFF No flow control
FLOW_HARDWARE Hardware (RTS/CTS) flow control
FLOW_XONXOFF Software (XON/XOFF) flow control
\endverbatim
*/
void Win_QextSerialPort::setFlowControl(FlowType flow) {
LOCK_MUTEX();
if (Settings.FlowControl!=flow) {
Settings.FlowControl=flow;
}
if (isOpen()) {
switch(flow) {

/*no flow control*/
case FLOW_OFF:
Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
Win_CommConfig.dcb.fInX=FALSE;
Win_CommConfig.dcb.fOutX=FALSE;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
break;

/*software (XON/XOFF) flow control*/
case FLOW_XONXOFF:
Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
Win_CommConfig.dcb.fInX=TRUE;
Win_CommConfig.dcb.fOutX=TRUE;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
break;

case FLOW_HARDWARE:
Win_CommConfig.dcb.fOutxCtsFlow=TRUE;
Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
Win_CommConfig.dcb.fInX=FALSE;
Win_CommConfig.dcb.fOutX=FALSE;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
break;
}
}
UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::setParity(ParityType parity)
Sets the parity associated with the serial port. The possible values of parity are:
\verbatim
PAR_SPACE Space Parity
PAR_MARK Mark Parity
PAR_NONE No Parity
PAR_EVEN Even Parity
PAR_ODD Odd Parity
\endverbatim
*/
void Win_QextSerialPort::setParity(ParityType parity) {
LOCK_MUTEX();
if (Settings.Parity!=parity) {
Settings.Parity=parity;
}
if (isOpen()) {
Win_CommConfig.dcb.Parity=(unsigned char)parity;
switch (parity) {

/*space parity*/
case PAR_SPACE:
if (Settings.DataBits==DATA_8) {
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems. " );
}
Win_CommConfig.dcb.fParity=TRUE;
break;

/*mark parity - WINDOWS ONLY*/
case PAR_MARK:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: Mark parity is not supported by POSIX systems " );
Win_CommConfig.dcb.fParity=TRUE;
break;

/*no parity*/
case PAR_NONE:
Win_CommConfig.dcb.fParity=FALSE;
break;

/*even parity*/
case PAR_EVEN:
Win_CommConfig.dcb.fParity=TRUE;
break;

/*odd parity*/
case PAR_ODD:
Win_CommConfig.dcb.fParity=TRUE;
break;
}
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits)
Sets the number of data bits used by the serial port. Possible values of dataBits are:
\verbatim
DATA_5 5 data bits
DATA_6 6 data bits
DATA_7 7 data bits
DATA_8 8 data bits
\endverbatim

\note
This function is subject to the following restrictions:
\par
5 data bits cannot be used with 2 stop bits.
\par
1.5 stop bits can only be used with 5 data bits.
\par
8 data bits cannot be used with space parity on POSIX systems.

*/
void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {
LOCK_MUTEX();
if (Settings.DataBits!=dataBits) {
if ((Settings.StopBits==STOP_2 & & dataBits==DATA_5) ||
(Settings.StopBits==STOP_1_5 & & dataBits!=DATA_5)) {
}
else {
Settings.DataBits=dataBits;
}
}
if (isOpen()) {
switch(dataBits) {

/*5 data bits*/
case DATA_5:
if (Settings.StopBits==STOP_2) {
TTY_WARNING( " Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits. " );
}
else {
Win_CommConfig.dcb.ByteSize=5;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
break;

/*6 data bits*/
case DATA_6:
if (Settings.StopBits==STOP_1_5) {
TTY_WARNING( " Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits. " );
}
else {
Win_CommConfig.dcb.ByteSize=6;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
break;

/*7 data bits*/
case DATA_7:
if (Settings.StopBits==STOP_1_5) {
TTY_WARNING( " Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits. " );
}
else {
Win_CommConfig.dcb.ByteSize=7;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
break;

/*8 data bits*/
case DATA_8:
if (Settings.StopBits==STOP_1_5) {
TTY_WARNING( " Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits. " );
}
else {
Win_CommConfig.dcb.ByteSize=8;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
break;
}
}
UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits)
Sets the number of stop bits used by the serial port. Possible values of stopBits are:
\verbatim
STOP_1 1 stop bit
STOP_1_5 1.5 stop bits
STOP_2 2 stop bits
\endverbatim

\note
This function is subject to the following restrictions:
\par
2 stop bits cannot be used with 5 data bits.
\par
1.5 stop bits cannot be used with 6 or more data bits.
\par
POSIX does not support 1.5 stop bits.
*/
void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {
LOCK_MUTEX();
if (Settings.StopBits!=stopBits) {
if ((Settings.DataBits==DATA_5 & & stopBits==STOP_2) ||
(stopBits==STOP_1_5 & & Settings.DataBits!=DATA_5)) {
}
else {
Settings.StopBits=stopBits;
}
}
if (isOpen()) {
switch (stopBits) {

/*one stop bit*/
case STOP_1:
Win_CommConfig.dcb.StopBits=ONESTOPBIT;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
break;

/*1.5 stop bits*/
case STOP_1_5:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX. " );
if (Settings.DataBits!=DATA_5) {
TTY_WARNING( " Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits " );
}
else {
Win_CommConfig.dcb.StopBits=ONE5STOPBITS;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
break;

/*two stop bits*/
case STOP_2:
if (Settings.DataBits==DATA_5) {
TTY_WARNING( " Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits " );
}
else {
Win_CommConfig.dcb.StopBits=TWOSTOPBITS;
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
break;
}
}
UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate)
Sets the baud rate of the serial port. Note that not all rates are applicable on
all platforms. The following table shows translations of the various baud rate
constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
are speeds that are usable on both Windows and POSIX.
\verbatim

RATE Windows Speed POSIX Speed
----------- ------------- -----------
BAUD50 110 50
BAUD75 110 75
*BAUD110 110 110
BAUD134 110 134.5
BAUD150 110 150
BAUD200 110 200
*BAUD300 300 300
*BAUD600 600 600
*BAUD1200 1200 1200
BAUD1800 1200 1800
*BAUD2400 2400 2400
*BAUD4800 4800 4800
*BAUD9600 9600 9600
BAUD14400 14400 9600
*BAUD19200 19200 19200
*BAUD38400 38400 38400
BAUD56000 56000 38400
*BAUD57600 57600 57600
BAUD76800 57600 76800
*BAUD115200 115200 115200
BAUD128000 128000 115200
BAUD256000 256000 115200
\endverbatim
*/
void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {
LOCK_MUTEX();
if (Settings.BaudRate!=baudRate) {
switch (baudRate) {
case BAUD50:
case BAUD75:
case BAUD134:
case BAUD150:
case BAUD200:
Settings.BaudRate=BAUD110;
break;

case BAUD1800:
Settings.BaudRate=BAUD1200;
break;

case BAUD76800:
Settings.BaudRate=BAUD57600;
break;

default:
Settings.BaudRate=baudRate;
break;
}
}
if (isOpen()) {
switch (baudRate) {

/*50 baud*/
case BAUD50:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 50 baud operation. Switching to 110 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_110;
break;

/*75 baud*/
case BAUD75:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 75 baud operation. Switching to 110 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_110;
break;

/*110 baud*/
case BAUD110:
Win_CommConfig.dcb.BaudRate=CBR_110;
break;

/*134.5 baud*/
case BAUD134:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 134.5 baud operation. Switching to 110 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_110;
break;

/*150 baud*/
case BAUD150:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 150 baud operation. Switching to 110 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_110;
break;

/*200 baud*/
case BAUD200:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 200 baud operation. Switching to 110 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_110;
break;

/*300 baud*/
case BAUD300:
Win_CommConfig.dcb.BaudRate=CBR_300;
break;

/*600 baud*/
case BAUD600:
Win_CommConfig.dcb.BaudRate=CBR_600;
break;

/*1200 baud*/
case BAUD1200:
Win_CommConfig.dcb.BaudRate=CBR_1200;
break;

/*1800 baud*/
case BAUD1800:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 1800 baud operation. Switching to 1200 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_1200;
break;

/*2400 baud*/
case BAUD2400:
Win_CommConfig.dcb.BaudRate=CBR_2400;
break;

/*4800 baud*/
case BAUD4800:
Win_CommConfig.dcb.BaudRate=CBR_4800;
break;

/*9600 baud*/
case BAUD9600:
Win_CommConfig.dcb.BaudRate=CBR_9600;
break;

/*14400 baud*/
case BAUD14400:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation. " );
Win_CommConfig.dcb.BaudRate=CBR_14400;
break;

/*19200 baud*/
case BAUD19200:
Win_CommConfig.dcb.BaudRate=CBR_19200;
break;

/*38400 baud*/
case BAUD38400:
Win_CommConfig.dcb.BaudRate=CBR_38400;
break;

/*56000 baud*/
case BAUD56000:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation. " );
Win_CommConfig.dcb.BaudRate=CBR_56000;
break;

/*57600 baud*/
case BAUD57600:
Win_CommConfig.dcb.BaudRate=CBR_57600;
break;

/*76800 baud*/
case BAUD76800:
TTY_WARNING( " Win_QextSerialPort: Windows does not support 76800 baud operation. Switching to 57600 baud. " );
Win_CommConfig.dcb.BaudRate=CBR_57600;
break;

/*115200 baud*/
case BAUD115200:
Win_CommConfig.dcb.BaudRate=CBR_115200;
break;

/*128000 baud*/
case BAUD128000:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation. " );
Win_CommConfig.dcb.BaudRate=CBR_128000;
break;

/*230400 baud*/
case BAUD230400:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation. " );
Win_CommConfig.dcb.BaudRate= 230400;
break;

/*256000 baud*/
case BAUD256000:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation. " );
Win_CommConfig.dcb.BaudRate=CBR_256000;
break;

/*460800 baud*/
case BAUD460800:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation. " );
Win_CommConfig.dcb.BaudRate=460800;
break;

/*921600 baud*/
case BAUD921600:
TTY_PORTABILITY_WARNING( " Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation. " );
Win_CommConfig.dcb.BaudRate=921600;
break;
}
SetCommConfig(Win_Handle, & Win_CommConfig, sizeof(COMMCONFIG));
}
UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::setDtr(bool set)
Sets DTR line to the requested state (high by default). This function will have no effect if
the port associated with the class is not currently open.
*/
void Win_QextSerialPort::setDtr(bool set) {
LOCK_MUTEX();
if (isOpen()) {
if (set) {
EscapeCommFunction(Win_Handle, SETDTR);
}
else {
EscapeCommFunction(Win_Handle, CLRDTR);
}
}
UNLOCK_MUTEX();
}

/*!
\fn void Win_QextSerialPort::setRts(bool set)
Sets RTS line to the requested state (high by default). This function will have no effect if
the port associated with the class is not currently open.
*/
void Win_QextSerialPort::setRts(bool set) {
LOCK_MUTEX();
if (isOpen()) {
if (set) {
EscapeCommFunction(Win_Handle, SETRTS);
}
else {
EscapeCommFunction(Win_Handle, CLRRTS);
}
}
UNLOCK_MUTEX();
}

/*!
\fn ulong Win_QextSerialPort::lineStatus(void)
returns the line status as stored by the port function. This function will retrieve the states
of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
long with specific bits indicating which lines are high. The following constants should be used
to examine the states of individual lines:

\verbatim
Mask Line
------ ----
LS_CTS CTS
LS_DSR DSR
LS_DCD DCD
LS_RI RI
\endverbatim

This function will return 0 if the port associated with the class is not currently open.
*/
ulong Win_QextSerialPort::lineStatus(void) {
unsigned long Status=0, Temp=0;
LOCK_MUTEX();
if (isOpen()) {
GetCommModemStatus(Win_Handle, & Temp);
if (Temp & MS_CTS_ON) {
Status|=LS_CTS;
}
if (Temp & MS_DSR_ON) {
Status|=LS_DSR;
}
if (Temp & MS_RING_ON) {
Status|=LS_RI;
}
if (Temp & MS_RLSD_ON) {
Status|=LS_DCD;
}
}
UNLOCK_MUTEX();
return Status;
}

bool Win_QextSerialPort::waitForReadyRead(int)
{
//@todo implement
return false;
}

qint64 Win_QextSerialPort::bytesToWrite() const
{
return _bytesToWrite;
}

void Win_QextSerialPort::monitorCommEvent()
{
DWORD eventMask = 0;

ResetEvent(overlap.hEvent);
if (!WaitCommEvent(Win_Handle, & eventMask, & overlap))
if (GetLastError() != ERROR_IO_PENDING)
qCritical( " WaitCommEvent error %ld\n " , GetLastError());

if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0) {
//overlap event occured
DWORD undefined;
if (!GetOverlappedResult(Win_Handle, & overlap, & undefined, false)) {
qWarning( " Comm event overlapped error %ld " , GetLastError());
return;
}
if (eventMask & EV_RXCHAR) {
if (sender() != this)
emit readyRead();
}
if (eventMask & EV_TXEMPTY) {
DWORD numBytes;
GetOverlappedResult(Win_Handle, & overlapWrite, & numBytes, true);
bytesToWriteLock- & gt; lockForWrite();
if (sender() != this)
emit bytesWritten(bytesToWrite());
_bytesToWrite = 0;
bytesToWriteLock- & gt; unlock();
}
if (eventMask & EV_DSR)
if (lineStatus() & LS_DSR)
emit dsrChanged(true);
else
emit dsrChanged(false);
}
}

void Win_QextSerialPort::terminateCommWait()
{
SetCommMask(Win_Handle, 0);
}


/*!
\fn void Win_QextSerialPort::setTimeout(ulong millisec);
Sets the read and write timeouts for the port to millisec milliseconds.
Setting 0 for both sec and millisec indicates that timeouts are not used for read nor
write operations. Setting -1 indicates that read and write should return immediately.

\note this function does nothing in event driven mode.
*/
void Win_QextSerialPort::setTimeout(long millisec) {
LOCK_MUTEX();
Settings.Timeout_Millisec = millisec;

if (millisec == -1) {
Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
} else {
Win_CommTimeouts.ReadIntervalTimeout = millisec;
Win_CommTimeouts.ReadTotalTimeoutConstant = millisec;
}
Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
Win_CommTimeouts.WriteTotalTimeoutMultiplier = millisec;
Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
if (queryMode() != QextSerialBase::EventDriven)
SetCommTimeouts(Win_Handle, & Win_CommTimeouts);

UNLOCK_MUTEX();
}


Win_QextSerialThread::Win_QextSerialThread(Win_QextSerialPort * qesp):
QThread()
{
this- & gt; qesp = qesp;
terminate = false;
}

void Win_QextSerialThread::stop()
{
terminate = true;
qesp- & gt; terminateCommWait();
}

void Win_QextSerialThread::run()
{
while (!terminate)
qesp- & gt; monitorCommEvent();
terminate = false;
}


MiniKombajnPomiarowy3_3_rc3.7z > qextserialenumerator.h

/*!
* \file qextserialenumerator.h
* \author Michal Policht
* \see QextSerialEnumerator
*/

#ifndef _QEXTSERIALENUMERATOR_H_
#define _QEXTSERIALENUMERATOR_H_

#include & lt; QString & gt;
#include & lt; QList & gt;

#ifdef _TTY_WIN_
#include & lt; windows.h & gt;
#include & lt; setupapi.h & gt;
#endif /*_TTY_WIN_*/


/*!
* Structure containing port information.
*/
struct QextPortInfo {
QString portName; /// & lt; Port name.
QString physName; /// & lt; Physical name.
QString friendName; /// & lt; Friendly name.
QString enumName; /// & lt; Enumerator name.
};


/*!
* Serial port enumerator. This class provides list of ports available in the system.
*
* Windows implementation is based on Zach Gorman's work from
* & lt; a href= " http://www.codeproject.com " & gt; The Code Project & lt; /a & gt; (http://www.codeproject.com/system/setupdi.asp).
*/
class QextSerialEnumerator
{
private:
#ifdef _TTY_WIN_
/*!
* Get value of specified property from the registry.
* \param key handle to an open key.
* \param property property name.
* \return property value.
*/
static QString getRegKeyValue(HKEY key, LPCTSTR property);

/*!
* Get specific property from registry.
* \param devInfo pointer to the device information set that contains the interface
* and its underlying device. Returned by SetupDiGetClassDevs() function.
* \param devData pointer to an SP_DEVINFO_DATA structure that defines the device instance.
* this is returned by SetupDiGetDeviceInterfaceDetail() function.
* \param property registry property. One of defined SPDRP_* constants.
* \return property string.
*/
static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property);

/*!
* Search for serial ports using setupapi.
* \param infoList list with result.
*/
static void setupAPIScan(QList & lt; QextPortInfo & gt; & infoList);
#endif /*_TTY_WIN_*/

public:
/*!
* Get list of ports.
* \return list of ports currently available in the system.
*/
static QList & lt; QextPortInfo & gt; getPorts();
};

#endif /*_QEXTSERIALENUMERATOR_H_*/


MiniKombajnPomiarowy3_3_rc3.7z > win_qextserialport.h

#ifndef _WIN_QEXTSERIALPORT_H_
#define _WIN_QEXTSERIALPORT_H_

#include " qextserialbase.h "
#include & lt; windows.h & gt;
#include & lt; QThread & gt;


/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
#ifdef _TTY_NOWARN_
#define _TTY_NOWARN_PORT_
#endif

class QReadWriteLock;
class Win_QextSerialThread;


/*!
\author Stefan Sander
\author Michal Policht

A cross-platform serial port class.
This class encapsulates the Windows portion of QextSerialPort. The user will be notified of
errors and possible portability conflicts at run-time by default - this behavior can be turned
off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off
portability warnings) in the project. Note that defining _TTY_NOWARN_ also defines
_TTY_NOWARN_PORT_.

\note
On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may
select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
make no guarantees as to the quality of POSIX support under NT/2000 however.

\todo remove copy constructor and assign operator.
*/
class Win_QextSerialPort: public QextSerialBase
{
Q_OBJECT
friend class Win_QextSerialThread;

private:
/*!
* This method is a part of constructor.
*/
void init();

protected:
HANDLE Win_Handle;
HANDLE threadStartEvent;
HANDLE threadTerminateEvent;
OVERLAPPED overlap;
OVERLAPPED overlapWrite;
COMMCONFIG Win_CommConfig;
COMMTIMEOUTS Win_CommTimeouts;
QReadWriteLock * bytesToWriteLock; /// & lt; @todo maybe move to QextSerialBase.
qint64 _bytesToWrite; /// & lt; @todo maybe move to QextSerialBase (and implement in POSIX).
Win_QextSerialThread * overlapThread; /// & lt; @todo maybe move to QextSerialBase (and implement in POSIX).

void monitorCommEvent();
void terminateCommWait();
virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize);

public:
Win_QextSerialPort();
Win_QextSerialPort(Win_QextSerialPort const & s);
Win_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
Win_QextSerialPort(const PortSettings & settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
Win_QextSerialPort(const QString & name, const PortSettings & settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
Win_QextSerialPort & operator=(const Win_QextSerialPort & s);
virtual ~Win_QextSerialPort();
virtual bool open(OpenMode mode);
virtual void close();
virtual void flush();
virtual qint64 size() const;
virtual void ungetChar(char c);
virtual void setFlowControl(FlowType);
virtual void setParity(ParityType);
virtual void setDataBits(DataBitsType);
virtual void setStopBits(StopBitsType);
virtual void setBaudRate(BaudRateType);
virtual void setDtr(bool set=true);
virtual void setRts(bool set=true);
virtual ulong lineStatus(void);
virtual qint64 bytesAvailable();
virtual void translateError(ulong);
virtual void setTimeout(long);

/*!
* Return number of bytes waiting in the buffer. Currently this shows number
* of bytes queued within write() and before the TX_EMPTY event occured. TX_EMPTY
* event is created whenever last character in the system buffer was sent.
*
* \return number of bytes queued within write(), before the first TX_EMPTY
* event occur.
*
* \warning this function may not give you expected results since TX_EMPTY may occur
* while writing data to the buffer. Eventually some TX_EMPTY events may not be
* catched.
*
* \note this function always returns 0 in polling mode.
*
* \see flush().
*/
virtual qint64 bytesToWrite() const;

virtual bool waitForReadyRead(int msecs); /// & lt; @todo implement.
};

/*!
* This thread monitors communication events.
*/
class Win_QextSerialThread: public QThread
{
Win_QextSerialPort * qesp;
bool terminate;

public:
/*!
* Constructor.
*
* \param qesp valid serial port object.
*/
Win_QextSerialThread(Win_QextSerialPort * qesp);

/*!
* Stop the thread.
*/
void stop();

protected:
//overriden
virtual void run();

};

#endif


MiniKombajnPomiarowy3_3_rc3.7z > serialport.cpp

#include " serialport.h "

SerialPort::SerialPort()
{
}

bool SerialPort::Open(const char* name)
{
fd = open(name, O_RDWR | O_NOCTTY | O_NDELAY);
//fcntl(fd, F_SETFL, 0);
if (fd == -1)
{
//Could not open the port.
//perror( " open_port: Unable to open /dev/ttyS0 - " );
return false;
}else
{
fcntl(fd, F_SETFL, 0);
return true;
}
//return (fd);
}

void SerialPort::Set(int baud) //trzeba uzupełnić niektóre flagi
{
speed_t speed = B115200;
if(baud == 19200)speed = B19200;
else if(baud == 38400)speed = B38400;
else if(baud == 57600)speed = B57600;
else if(baud == 115200)speed = B115200;
else if(baud == 230400)speed = B230400;
else if(baud == 460800)speed = B460800;
else if(baud == 921600)speed = B921600;
else if(baud == 1152000)speed = B1152000;
else if(baud == 1500000)speed = B1500000;
else if(baud == 2500000)speed = B2500000;
struct termios options;
//Get the current options for the port...
tcgetattr(fd, & options);
//Set the baud rates to 115200...
cfsetispeed( & options, speed);
cfsetospeed( & options, speed);
//cfsetispeed( & options, B230400);
//cfsetospeed( & options, B230400);
//cfsetispeed( & options, B921600);
//cfsetospeed( & options, B921600);
//Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
// No parity (8N1):
options.c_cflag & = ~PARENB;
options.c_cflag & = ~CSTOPB;
options.c_cflag & = ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
options.c_lflag & = ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag & = ~OPOST;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
//Set the new options for the port...
tcsetattr(fd, TCSANOW, & options);
}


MiniKombajnPomiarowy3_3_rc3.7z > first_test.txt

Hello ssk


MiniKombajnPomiarowy3_3_rc3.7z > interface.cpp

#include " interface.h "

Interface::Interface(QMainWindow* w)
{
window = w;
}

/*void Interface::text(char *txt)
{
//window- & gt; label- & gt; setText( " RS232 " );
//window- & gt; labelSendText( " aa " );
}*/


MiniKombajnPomiarowy3_3_rc3.7z > main.cpp

#include & lt; QtGui/QApplication & gt;
#include " mainwindow.h "

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.update();
return a.exec();
}


MiniKombajnPomiarowy3_3_rc3.7z > qtmmlwidget.cpp

/****************************************************************************
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of a Qt Solutions component.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** Please note Third Party Software included with Qt Solutions may impose
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
**
****************************************************************************/

#include & lt; QtGui/QApplication & gt;
#include & lt; QtCore/QString & gt;
#include & lt; QtCore/QMap & gt;
#include & lt; QtGui/QDesktopWidget & gt;
#include & lt; QtGui/QPainter & gt;
#include & lt; QtGui/QPaintEvent & gt;

#include " qtmmlwidget.h "

// *******************************************************************
// Declarations
// *******************************************************************

#define ROUND(a) (int)((a)+.5)

static bool g_draw_frames = false;
static const double g_mfrac_spacing = 0.1;
static const double g_mroot_base_margin = 0.1;
static const double g_script_size_multiplier = 0.7071; // sqrt(1/2)
static const int g_min_font_point_size = 8;
static const QChar g_radical_char = QChar(0x1A, 0x22);
static const unsigned g_oper_spec_rows = 9;

struct Mml
{
enum NodeType {
NoNode = 0, MiNode, MnNode, MfracNode, MrowNode, MsqrtNode,
MrootNode, MsupNode, MsubNode, MsubsupNode, MoNode,
MstyleNode, TextNode, MphantomNode, MfencedNode,
MtableNode, MtrNode, MtdNode, MoverNode, MunderNode,
MunderoverNode, MerrorNode, MtextNode, MpaddedNode,
MspaceNode, MalignMarkNode, UnknownNode
};

enum MathVariant {
NormalMV = 0x0000,
BoldMV = 0x0001,
ItalicMV = 0x0002,
DoubleStruckMV = 0x0004,
ScriptMV = 0x0008,
FrakturMV = 0x0010,
SansSerifMV = 0x0020,
MonospaceMV = 0x0040
};

enum FormType { PrefixForm, InfixForm, PostfixForm };
enum ColAlign { ColAlignLeft, ColAlignCenter, ColAlignRight };
enum RowAlign { RowAlignTop, RowAlignCenter, RowAlignBottom,
RowAlignAxis, RowAlignBaseline };
enum FrameType { FrameNone, FrameSolid, FrameDashed };

struct FrameSpacing {
FrameSpacing(int hor = 0, int ver = 0)
: m_hor(hor), m_ver(ver) {}
int m_hor, m_ver;
};
};

struct OperSpec {
enum StretchDir { NoStretch, HStretch, VStretch, HVStretch };

const char *name;
Mml::FormType form;
const char *attributes[g_oper_spec_rows];
StretchDir stretch_dir;
};

struct NodeSpec
{
Mml::NodeType type;
const char *tag;
const char *type_str;
int child_spec;
const char *child_types;
const char *attributes;

enum ChildSpec {
ChildAny = -1, // any number of children allowed
ChildIgnore = -2, // do not build subexpression of children
ImplicitMrow = -3 // if more than one child, build mrow
};
};

struct EntitySpec
{
const char *name;
const char *value;
};

typedef QMap & lt; QString, QString & gt; MmlAttributeMap;
class MmlNode;

class MmlDocument : public Mml
{
public:
MmlDocument();
~MmlDocument();
void clear();

bool setContent(QString text, QString *errorMsg = 0,
int *errorLine = 0, int *errorColumn = 0);
void paint(QPainter *p, const QPoint & pos) const;
void dump() const;
QSize size() const;
void layout();

QString fontName(QtMmlWidget::MmlFont type) const;
void setFontName(QtMmlWidget::MmlFont type, const QString & name);

int baseFontPointSize() const
{ return m_base_font_point_size; }
void setBaseFontPointSize(int size)
{ m_base_font_point_size = size; }
QColor foregroundColor() const
{ return m_foreground_color; }
void setForegroundColor(const QColor & color)
{ m_foreground_color = color; }
QColor backgroundColor() const
{ return m_background_color; }
void setBackgroundColor(const QColor & color)
{ m_background_color = color; }

private:
void _dump(const MmlNode *node, QString & indent) const;
bool insertChild(MmlNode *parent, MmlNode *new_node, QString *errorMsg);

MmlNode *domToMml(const QDomNode & dom_node, bool *ok, QString *errorMsg);
MmlNode *createNode(NodeType type, const MmlAttributeMap & mml_attr,
const QString & mml_value, QString *errorMsg);
MmlNode *createImplicitMrowNode(const QDomNode & dom_node, bool *ok,
QString *errorMsg);

void insertOperator(MmlNode *node, const QString & text);

MmlNode *m_root_node;

QString m_normal_font_name;
QString m_fraktur_font_name;
QString m_sans_serif_font_name;
QString m_script_font_name;
QString m_monospace_font_name;
QString m_doublestruck_font_name;
int m_base_font_point_size;
QColor m_foreground_color;
QColor m_background_color;
};

class MmlNode : public Mml
{
friend class MmlDocument;

public:
MmlNode(NodeType type, MmlDocument *document, const MmlAttributeMap & attribute_map);
virtual ~MmlNode();

// Mml stuff
NodeType nodeType() const
{ return m_node_type; }

virtual QString toStr() const;

void setRelOrigin(const QPoint & rel_origin);
QPoint relOrigin() const
{ return m_rel_origin; }
void stretchTo(const QRect & rect);
bool isStretched() const
{ return m_stretched; }
QPoint devicePoint(const QPoint & p) const;

QRect myRect() const
{ return m_my_rect; }
QRect parentRect() const;
virtual QRect deviceRect() const;
void updateMyRect();
virtual void setMyRect(const QRect & rect)
{ m_my_rect = rect; }

virtual void stretch();
virtual void layout();
virtual void paint(QPainter *p);

int basePos() const;
int overlinePos() const;
int underlinePos() const;
int em() const;
int ex() const;

QString explicitAttribute(const QString & name, const QString & def = QString::null) const;
QString inheritAttributeFromMrow(const QString & name, const QString & def = QString::null) const;

virtual QFont font() const;
virtual QColor color() const;
virtual QColor background() const;
virtual int scriptlevel(const MmlNode *child = 0) const;


// Node stuff
MmlDocument *document() const
{ return m_document; }
MmlNode *parent() const
{ return m_parent; }
MmlNode *firstChild() const
{ return m_first_child; }
MmlNode *nextSibling() const
{ return m_next_sibling; }
MmlNode *previousSibling() const
{ return m_previous_sibling; }
MmlNode *lastSibling() const;
MmlNode *firstSibling() const;
bool isLastSibling() const
{ return m_next_sibling == 0; }
bool isFirstSibling() const
{ return m_previous_sibling == 0; }
bool hasChildNodes() const
{ return m_first_child != 0; }

protected:
virtual void layoutSymbol();
virtual void paintSymbol(QPainter *p) const;
virtual QRect symbolRect() const
{ return QRect(0, 0, 0, 0); }

MmlNode *parentWithExplicitAttribute(const QString & name, NodeType type = NoNode);
int interpretSpacing(const QString & value, bool *ok) const;

private:
MmlAttributeMap m_attribute_map;
bool m_stretched;
QRect m_my_rect, m_parent_rect;
QPoint m_rel_origin;

NodeType m_node_type;
MmlDocument *m_document;

MmlNode *m_parent,
*m_first_child,
*m_next_sibling,
*m_previous_sibling;
};

class MmlTokenNode : public MmlNode
{
public:
MmlTokenNode(NodeType type, MmlDocument *document,
const MmlAttributeMap & attribute_map)
: MmlNode(type, document, attribute_map) {}

QString text() const;
};

class MmlMphantomNode : public MmlNode
{
public:
MmlMphantomNode(MmlDocument *document,
const MmlAttributeMap & attribute_map)
: MmlNode(MphantomNode, document, attribute_map) {}

virtual void paint(QPainter *) {}
};

class MmlUnknownNode : public MmlNode
{
public:
MmlUnknownNode(MmlDocument *document,
const MmlAttributeMap & attribute_map)
: MmlNode(UnknownNode, document, attribute_map) {}
};

class MmlMfencedNode : public MmlNode
{
public:
MmlMfencedNode(MmlDocument *document,
const MmlAttributeMap & attribute_map)
: MmlNode(MfencedNode, document, attribute_map) {}
};

class MmlMalignMarkNode : public MmlNode
{
public:
MmlMalignMarkNode(MmlDocument *document)
: MmlNode(MalignMarkNode, document, MmlAttributeMap()) {}
};

class MmlMfracNode : public MmlNode
{
public:
MmlMfracNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MfracNode, document, attribute_map) {}

MmlNode *numerator() const;
MmlNode *denominator() const;

protected:
virtual void layoutSymbol();
virtual void paintSymbol(QPainter *p) const;
virtual QRect symbolRect() const;
};

class MmlMrowNode : public MmlNode
{
public:
MmlMrowNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MrowNode, document, attribute_map) {}
};

class MmlRootBaseNode : public MmlNode
{
public:
MmlRootBaseNode(NodeType type, MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(type, document, attribute_map) {}

MmlNode *base() const;
MmlNode *index() const;

virtual int scriptlevel(const MmlNode *child = 0) const;

protected:
virtual void layoutSymbol();
virtual void paintSymbol(QPainter *p) const;
virtual QRect symbolRect() const;
int tailWidth() const;
};

class MmlMrootNode : public MmlRootBaseNode
{
public:
MmlMrootNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlRootBaseNode(MrootNode, document, attribute_map) {}
};

class MmlMsqrtNode : public MmlRootBaseNode
{
public:
MmlMsqrtNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlRootBaseNode(MsqrtNode, document, attribute_map) {}

};


class MmlTextNode : public MmlNode
{
public:
MmlTextNode(const QString & text, MmlDocument *document);

virtual QString toStr() const;
QString text() const
{ return m_text; }

// TextNodes are not xml elements, so they can't have attributes of
// their own. Everything is taken from the parent.
virtual QFont font() const
{ return parent()- & gt; font(); }
virtual int scriptlevel(const MmlNode* = 0) const
{ return parent()- & gt; scriptlevel(this); }
virtual QColor color() const
{ return parent()- & gt; color(); }
virtual QColor background() const
{ return parent()- & gt; background(); }

protected:
virtual void paintSymbol(QPainter *p) const;
virtual QRect symbolRect() const;

QString m_text;
};

class MmlMiNode : public MmlTokenNode
{
public:
MmlMiNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlTokenNode(MiNode, document, attribute_map) {}
};

class MmlMnNode : public MmlTokenNode
{
public:
MmlMnNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlTokenNode(MnNode, document, attribute_map) {}
};

class MmlSubsupBaseNode : public MmlNode
{
public:
MmlSubsupBaseNode(NodeType type, MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(type, document, attribute_map) {}

MmlNode *base() const;
MmlNode *sscript() const;

virtual int scriptlevel(const MmlNode *child = 0) const;
};

class MmlMsupNode : public MmlSubsupBaseNode
{
public:
MmlMsupNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlSubsupBaseNode(MsupNode, document, attribute_map) {}

protected:
virtual void layoutSymbol();
};

class MmlMsubNode : public MmlSubsupBaseNode
{
public:
MmlMsubNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlSubsupBaseNode(MsubNode, document, attribute_map) {}

protected:
virtual void layoutSymbol();
};

class MmlMsubsupNode : public MmlNode
{
public:
MmlMsubsupNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MsubsupNode, document, attribute_map) {}

MmlNode *base() const;
MmlNode *superscript() const;
MmlNode *subscript() const;

virtual int scriptlevel(const MmlNode *child = 0) const;

protected:
virtual void layoutSymbol();
};

class MmlMoNode : public MmlTokenNode
{
public:
MmlMoNode(MmlDocument *document, const MmlAttributeMap & attribute_map);

QString dictionaryAttribute(const QString & name) const;
virtual void stretch();
virtual int lspace() const;
virtual int rspace() const;

virtual QString toStr() const;

protected:
virtual void layoutSymbol();
virtual QRect symbolRect() const;

virtual FormType form() const;

private:
const OperSpec *m_oper_spec;
};

class MmlMstyleNode : public MmlNode
{
public:
MmlMstyleNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MstyleNode, document, attribute_map) {}
};

class MmlTableBaseNode : public MmlNode
{
public:
MmlTableBaseNode(NodeType type, MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(type, document, attribute_map) {}
};

class MmlMtableNode : public MmlTableBaseNode
{
public:
MmlMtableNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlTableBaseNode(MtableNode, document, attribute_map) {}

int rowspacing() const;
int columnspacing() const;
int framespacing_hor() const;
int framespacing_ver() const;
FrameType frame() const;
FrameType columnlines(int idx) const;
FrameType rowlines(int idx) const;

protected:
virtual void layoutSymbol();
virtual QRect symbolRect() const;
virtual void paintSymbol(QPainter *p) const;

private:
struct CellSizeData
{
void init(const MmlNode *first_row);
QList & lt; int & gt; col_widths, row_heights;
int numCols() const { return col_widths.count(); }
int numRows() const { return row_heights.count(); }
uint colWidthSum() const;
uint rowHeightSum() const;
};

CellSizeData m_cell_size_data;
int m_content_width, m_content_height;
};

class MmlMtrNode : public MmlTableBaseNode
{
public:
MmlMtrNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlTableBaseNode(MtrNode, document, attribute_map) {}
void layoutCells(const QList & lt; int & gt; & col_widths, int col_spc);
};

class MmlMtdNode : public MmlTableBaseNode
{
public:
MmlMtdNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlTableBaseNode(MtdNode, document, attribute_map)
{ m_scriptlevel_adjust = 0; }
virtual void setMyRect(const QRect & rect);

ColAlign columnalign();
RowAlign rowalign();
uint colNum();
uint rowNum();
virtual int scriptlevel(const MmlNode *child = 0) const;

private:
int m_scriptlevel_adjust; // added or subtracted to scriptlevel to
// make contents fit the cell
};

class MmlMoverNode : public MmlNode
{
public:
MmlMoverNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MoverNode, document, attribute_map) {}
virtual int scriptlevel(const MmlNode *node = 0) const;

protected:
virtual void layoutSymbol();
};

class MmlMunderNode : public MmlNode
{
public:
MmlMunderNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MunderNode, document, attribute_map) {}
virtual int scriptlevel(const MmlNode *node = 0) const;

protected:
virtual void layoutSymbol();
};

class MmlMunderoverNode : public MmlNode
{
public:
MmlMunderoverNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MunderoverNode, document, attribute_map) {}
virtual int scriptlevel(const MmlNode *node = 0) const;

protected:
virtual void layoutSymbol();
};

class MmlMerrorNode : public MmlNode
{
public:
MmlMerrorNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MerrorNode, document, attribute_map) {}
};

class MmlMtextNode : public MmlNode
{
public:
MmlMtextNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MtextNode, document, attribute_map) {}
};

class MmlMpaddedNode : public MmlNode
{
public:
MmlMpaddedNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MpaddedNode, document, attribute_map) {}

public:
int lspace() const;
int width() const;
int height() const;
int depth() const;

protected:
int interpretSpacing(QString value, int base_value, bool *ok) const;
virtual void layoutSymbol();
virtual QRect symbolRect() const;
};

class MmlMspaceNode : public MmlNode
{
public:
MmlMspaceNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlNode(MspaceNode, document, attribute_map) {}
};

static const NodeSpec *mmlFindNodeSpec(Mml::NodeType type);
static const NodeSpec *mmlFindNodeSpec(const QString & tag);
static bool mmlCheckChildType(Mml::NodeType parent_type,
Mml::NodeType child_type, QString *error_str);
static bool mmlCheckAttributes(Mml::NodeType child_type,
const MmlAttributeMap & attr, QString *error_str);
static QString mmlDictAttribute(const QString & name, const OperSpec *spec);
static const OperSpec *mmlFindOperSpec(const QString & name, Mml::FormType form);
static int interpretSpacing(QString name, int em, int ex, bool *ok);
static int interpretPercentSpacing(QString value, int base, bool *ok);
static uint interpretMathVariant(const QString & value, bool *ok);
static Mml::FormType interpretForm(const QString & value, bool *ok);
static Mml::FrameType interpretFrameType(const QString & value_list, uint idx, bool *ok);
static Mml::FrameSpacing interpretFrameSpacing(const QString & value_list, int em, int ex, bool *ok);
static Mml::ColAlign interpretColAlign(const QString & value_list, uint colnum, bool *ok);
static Mml::RowAlign interpretRowAlign(const QString & value_list, uint rownum, bool *ok);
static Mml::FrameType interpretFrameType(const QString & value_list, uint idx, bool *ok);
static QFont interpretDepreciatedFontAttr(const MmlAttributeMap & font_attr, QFont & fn, int em, int ex);
static QFont interpretMathSize(QString value, QFont & fn, int em, int ex, bool *ok);
static QString interpretListAttr(const QString & value_list, int idx, const QString & def);
static QString rectToStr(const QRect & rect);
static QString entityDeclarations();


#define MML_ATT_COMMON " class style id xref actiontype "
#define MML_ATT_FONTSIZE " fontsize fontweight fontstyle fontfamily color "
#define MML_ATT_MATHVARIANT " mathvariant mathsize mathcolor mathbackground "
#define MML_ATT_FONTINFO MML_ATT_FONTSIZE MML_ATT_MATHVARIANT
#define MML_ATT_OPINFO " form fence separator lspace rspace stretchy symmetric " \
" maxsize minsize largeop movablelimits accent "
#define MML_ATT_SIZEINFO " width height depth "
#define MML_ATT_TABLEINFO " align rowalign columnalign columnwidth groupalign " \
" alignmentscope side rowspacing columnspacing rowlines " \
" columnlines width frame framespacing equalrows " \
" equalcolumns displaystyle "
#define MML_ATT_MFRAC " bevelled numalign denomalign linethickness "
#define MML_ATT_MSTYLE MML_ATT_FONTINFO MML_ATT_OPINFO \
" scriptlevel lquote rquote linethickness displaystyle " \
" scriptsizemultiplier scriptminsize background " \
" veryverythinmathspace verythinmathspace thinmathspace " \
" mediummathspace thickmathspace verythickmathspace " \
" veryverythickmathspace open close separators " \
" subscriptshift superscriptshift accentunder tableinfo " \
" rowspan columnspan edge selection bevelled "
#define MML_ATT_MTABLE " align rowalign columnalign groupalign alignmentscope " \
" columnwidth width rowspacing columnspacing rowlines columnlines " \
" frame framespacing equalrows equalcolumns displaystyle side " \
" minlabelspacing "

static const NodeSpec g_node_spec_data[] = {

// type tag type_str child_spec child_types attributes " " =none, 0=any
// ----------------------- --------------- ------------------- ----------------------- ------------------------ ------------------------------------
{ Mml::MiNode, " mi " , " MiNode " , NodeSpec::ChildAny, " TextNode MalignMark " , MML_ATT_COMMON MML_ATT_FONTINFO },
{ Mml::MnNode, " mn " , " MnNode " , NodeSpec::ChildAny, " TextNode MalignMark " , MML_ATT_COMMON MML_ATT_FONTINFO },
{ Mml::MfracNode, " mfrac " , " MfracNode " , 2, 0, MML_ATT_COMMON MML_ATT_MFRAC },
{ Mml::MrowNode, " mrow " , " MrowNode " , NodeSpec::ChildAny, 0, MML_ATT_COMMON " display mode " },
{ Mml::MsqrtNode, " msqrt " , " MsqrtNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
{ Mml::MrootNode, " mroot " , " MrootNode " , 2, 0, MML_ATT_COMMON },
{ Mml::MsupNode, " msup " , " MsupNode " , 2, 0, MML_ATT_COMMON " subscriptshift " },
{ Mml::MsubNode, " msub " , " MsubNode " , 2, 0, MML_ATT_COMMON " superscriptshift " },
{ Mml::MsubsupNode, " msubsup " , " MsubsupNode " , 3, 0, MML_ATT_COMMON " subscriptshift superscriptshift " },
{ Mml::MoNode, " mo " , " MoNode " , NodeSpec::ChildAny, " TextNode MalignMark " , MML_ATT_COMMON MML_ATT_FONTINFO MML_ATT_OPINFO },
{ Mml::MstyleNode, " mstyle " , " MstyleNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON MML_ATT_MSTYLE },
{ Mml::MphantomNode, " mphantom " , " MphantomNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
{ Mml::MalignMarkNode, " malignmark " , " MalignMarkNode " , 0, 0, " " },
{ Mml::MfencedNode, " mfenced " , " MfencedNode " , NodeSpec::ChildAny, 0, MML_ATT_COMMON " open close separators " },
{ Mml::MtableNode, " mtable " , " MtableNode " , NodeSpec::ChildAny, " MtrNode " , MML_ATT_COMMON MML_ATT_MTABLE },
{ Mml::MtrNode, " mtr " , " MtrNode " , NodeSpec::ChildAny, " MtdNode " , MML_ATT_COMMON " rowalign columnalign groupalign " },
{ Mml::MtdNode, " mtd " , " MtdNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " rowspan columnspan rowalign columnalign groupalign " },
{ Mml::MoverNode, " mover " , " MoverNode " , 2, 0, MML_ATT_COMMON " accent " },
{ Mml::MunderNode, " munder " , " MunderNode " , 2, 0, MML_ATT_COMMON " accentunder " },
{ Mml::MunderoverNode, " munderover " , " MunderoverNode " , 3, 0, MML_ATT_COMMON " accentunder accent " },
{ Mml::MerrorNode, " merror " , " MerrorNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON },
{ Mml::MtextNode, " mtext " , " MtextNode " , 1, " TextNode " , MML_ATT_COMMON " width height depth linebreak " },
{ Mml::MpaddedNode, " mpadded " , " MpaddedNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth lspace " },
{ Mml::MspaceNode, " mspace " , " MspaceNode " , NodeSpec::ImplicitMrow, 0, MML_ATT_COMMON " width height depth linebreak " },
{ Mml::TextNode, 0, " TextNode " , NodeSpec::ChildIgnore, 0, " " },
{ Mml::UnknownNode, 0, " UnknownNode " , NodeSpec::ChildAny, 0, 0 },
{ Mml::NoNode, 0, 0, 0, 0, 0 }
};

static const char *g_oper_spec_names[g_oper_spec_rows] = { " accent " , " fence " , " largeop " , " lspace " , " minsize " , " movablelimits " , " rspace " , " separator " , " stretchy " /* stretchdir */ };
static const OperSpec g_oper_spec_data[] = {

{ " !! " , Mml::PostfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " !! "
{ " ! " , Mml::PostfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " ! "
{ " != " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " != "
{ " & And; " , Mml::InfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " mediummathspace " , 0, " true " }, OperSpec::VStretch }, // " & And; "
{ " & ApplyFunction; " , Mml::InfixForm, { 0, 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & ApplyFunction; "
{ " & Assign; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Assign; "
{ " & Backslash; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & Backslash; "
{ " & Because; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Because; "
{ " & Breve; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & Breve; "
{ " & Cap; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Cap; "
{ " & CapitalDifferentialD; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // & CapitalDifferentialD; "
{ " & Cedilla; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & Cedilla; "
{ " & CenterDot; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & CenterDot; "
{ " & CircleDot; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & CircleDot; "
{ " & CircleMinus; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & CircleMinus; "
{ " & CirclePlus; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & CirclePlus; "
{ " & CircleTimes; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & CircleTimes; "
{ " & ClockwiseContourIntegral; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // & ClockwiseContourIntegral; "
{ " & CloseCurlyDoubleQuote; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // & CloseCurlyDoubleQuote; "
{ " & CloseCurlyQuote; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & CloseCurlyQuote; "
{ " & Colon; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Colon; "
{ " & Congruent; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Congruent; "
{ " & ContourIntegral; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & ContourIntegral; "
{ " & Coproduct; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Coproduct; "
{ " & CounterClockwiseContourIntegral; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // & CounterClockwiseContourInteg
{ " & Cross; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Cross; "
{ " & Cup; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Cup; "
{ " & CupCap; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & CupCap; "
{ " & Del; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Del; "
{ " & DiacriticalAcute; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & DiacriticalAcute; "
{ " & DiacriticalDot; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & DiacriticalDot; "
{ " & DiacriticalDoubleAcute; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // & DiacriticalDoubleAcute; "
{ " & DiacriticalGrave; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & DiacriticalGrave; "
{ " & DiacriticalLeftArrow; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & DiacriticalLeftArrow; "
{ " & DiacriticalLeftRightArrow; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & DiacriticalLeftRightArrow; "
{ " & DiacriticalLeftRightVector; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & DiacriticalLeftRightVector; "
{ " & DiacriticalLeftVector; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & DiacriticalLeftVector; "
{ " & DiacriticalRightArrow; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & DiacriticalRightArrow; "
{ " & DiacriticalRightVector; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & DiacriticalRightVector; "
{ " & DiacriticalTilde; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::NoStretch }, // " & DiacriticalTilde; "
{ " & Diamond; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Diamond; "
{ " & DifferentialD; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & DifferentialD; "
{ " & DotEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & DotEqual; "
{ " & DoubleContourIntegral; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // & DoubleContourIntegral; "
{ " & DoubleDot; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & DoubleDot; "
{ " & DoubleDownArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DoubleDownArrow; "
{ " & DoubleLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & DoubleLeftArrow; "
{ " & DoubleLeftRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // & DoubleLeftRightArrow; "
{ " & DoubleLeftTee; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & DoubleLeftTee; "
{ " & DoubleLongLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // " & DoubleLongLeftArrow; "
{ " & DoubleLongLeftRightArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // & DoubleLongLeftRightArrow; "
{ " & DoubleLongRightArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // & DoubleLongRightArrow; "
{ " & DoubleRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & DoubleRightArrow; "
{ " & DoubleRightTee; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & DoubleRightTee; "
{ " & DoubleUpArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DoubleUpArrow; "
{ " & DoubleUpDownArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DoubleUpDownArrow; "
{ " & DoubleVerticalBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & DoubleVerticalBar; "
{ " & DownArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DownArrow; "
{ " & DownArrowBar; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DownArrowBar; "
{ " & DownArrowUpArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DownArrowUpArrow; "
{ " & DownBreve; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & DownBreve; "
{ " & DownLeftRightVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownLeftRightVector; "
{ " & DownLeftTeeVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownLeftTeeVector; "
{ " & DownLeftVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownLeftVector; "
{ " & DownLeftVectorBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownLeftVectorBar; "
{ " & DownRightTeeVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownRightTeeVector; "
{ " & DownRightVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownRightVector; "
{ " & DownRightVectorBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & DownRightVectorBar; "
{ " & DownTee; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & DownTee; "
{ " & DownTeeArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & DownTeeArrow; "
{ " & Element; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Element; "
{ " & Equal; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Equal; "
{ " & EqualTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & EqualTilde; "
{ " & Equilibrium; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & Equilibrium; "
{ " & Exists; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Exists; "
{ " & ForAll; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & ForAll; "
{ " & GreaterEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterEqual; "
{ " & GreaterEqualLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterEqualLess; "
{ " & GreaterFullEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterFullEqual; "
{ " & GreaterGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterGreater; "
{ " & GreaterLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterLess; "
{ " & GreaterSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterSlantEqual; "
{ " & GreaterTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & GreaterTilde; "
{ " & Hacek; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::NoStretch }, // " & Hacek; "
{ " & Hat; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & Hat; "
{ " & HorizontalLine; " , Mml::InfixForm, { 0, 0, 0, " 0em " , " 0 " , 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & HorizontalLine; "
{ " & HumpDownHump; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & HumpDownHump; "
{ " & HumpEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & HumpEqual; "
{ " & Implies; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & Implies; "
{ " & Integral; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & Integral; "
{ " & Intersection; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, " true " , " thinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & Intersection; "
{ " & InvisibleComma; " , Mml::InfixForm, { 0, 0, 0, " 0em " , 0, 0, " 0em " , " true " , 0 }, OperSpec::NoStretch }, // " & InvisibleComma; "
{ " & InvisibleTimes; " , Mml::InfixForm, { 0, 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & InvisibleTimes; "
{ " & LeftAngleBracket; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & LeftAngleBracket; "
{ " & LeftArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftArrow; "
{ " & LeftArrowBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftArrowBar; "
{ " & LeftArrowRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftArrowRightArrow; "
{ " & LeftBracketingBar; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & LeftBracketingBar; "
{ " & LeftCeiling; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & LeftCeiling; "
{ " & LeftDoubleBracket; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & LeftDoubleBracket; "
{ " & LeftDoubleBracketingBar; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & LeftDoubleBracketingBar; "
{ " & LeftDownTeeVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftDownTeeVector; "
{ " & LeftDownVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftDownVector; "
{ " & LeftDownVectorBar; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftDownVectorBar; "
{ " & LeftFloor; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & LeftFloor; "
{ " & LeftRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftRightArrow; "
{ " & LeftRightVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftRightVector; "
{ " & LeftSkeleton; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & LeftSkeleton; "
{ " & LeftTee; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LeftTee; "
{ " & LeftTeeArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftTeeArrow; "
{ " & LeftTeeVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftTeeVector; "
{ " & LeftTriangle; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LeftTriangle; "
{ " & LeftTriangleBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LeftTriangleBar; "
{ " & LeftTriangleEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LeftTriangleEqual; "
{ " & LeftUpDownVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftUpDownVector; "
{ " & LeftUpTeeVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftUpTeeVector; "
{ " & LeftUpVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftUpVector; "
{ " & LeftUpVectorBar; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LeftUpVectorBar; "
{ " & LeftVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LeftVector; "
{ " & LeftVectorBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::VStretch }, // " & LeftVectorBar; "
{ " & LessEqualGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LessEqualGreater; "
{ " & LessFullEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LessFullEqual; "
{ " & LessGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LessGreater; "
{ " & LessLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LessLess; "
{ " & LessSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LessSlantEqual; "
{ " & LessTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & LessTilde; "
{ " & LongLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LongLeftArrow; "
{ " & LongLeftRightArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LongLeftRightArrow; "
{ " & LongRightArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // " & LongRightArrow; "
{ " & LowerLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LowerLeftArrow; "
{ " & LowerRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & LowerRightArrow; "
{ " & MinusPlus; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " veryverythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & MinusPlus; "
{ " & NestedGreaterGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NestedGreaterGreater; "
{ " & NestedLessLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NestedLessLess; "
{ " & Not; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Not; "
{ " & NotCongruent; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotCongruent; "
{ " & NotCupCap; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotCupCap; "
{ " & NotDoubleVerticalBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotDoubleVerticalBar; "
{ " & NotElement; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotElement; "
{ " & NotEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotEqual; "
{ " & NotEqualTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotEqualTilde; "
{ " & NotExists; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotExists; "
{ " & NotGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotGreater; "
{ " & NotGreaterEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotGreaterEqual; "
{ " & NotGreaterFullEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotGreaterFullEqual; "
{ " & NotGreaterGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotGreaterGreater; "
{ " & NotGreaterLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotGreaterLess; "
{ " & NotGreaterSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotGreaterSlantEqual; "
{ " & NotGreaterTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotGreaterTilde; "
{ " & NotHumpDownHump; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotHumpDownHump; "
{ " & NotHumpEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotHumpEqual; "
{ " & NotLeftTriangle; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLeftTriangle; "
{ " & NotLeftTriangleBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLeftTriangleBar; "
{ " & NotLeftTriangleEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotLeftTriangleEqual; "
{ " & NotLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLess; "
{ " & NotLessEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLessEqual; "
{ " & NotLessFullEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLessFullEqual; "
{ " & NotLessGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLessGreater; "
{ " & NotLessLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLessLess; "
{ " & NotLessSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLessSlantEqual; "
{ " & NotLessTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotLessTilde; "
{ " & NotNestedGreaterGreater; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotNestedGreaterGreater; "
{ " & NotNestedLessLess; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotNestedLessLess; "
{ " & NotPrecedes; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotPrecedes; "
{ " & NotPrecedesEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotPrecedesEqual; "
{ " & NotPrecedesSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotPrecedesSlantEqual; "
{ " & NotPrecedesTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotPrecedesTilde; "
{ " & NotReverseElement; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotReverseElement; "
{ " & NotRightTriangle; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotRightTriangle; "
{ " & NotRightTriangleBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotRightTriangleBar; "
{ " & NotRightTriangleEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotRightTriangleEqual; "
{ " & NotSquareSubset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSquareSubset; "
{ " & NotSquareSubsetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotSquareSubsetEqual; "
{ " & NotSquareSuperset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSquareSuperset; "
{ " & NotSquareSupersetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotSquareSupersetEqual; "
{ " & NotSubset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSubset; "
{ " & NotSubsetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSubsetEqual; "
{ " & NotSucceeds; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSucceeds; "
{ " & NotSucceedsEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSucceedsEqual; "
{ " & NotSucceedsSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // & NotSucceedsSlantEqual; "
{ " & NotSucceedsTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSucceedsTilde; "
{ " & NotSuperset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSuperset; "
{ " & NotSupersetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotSupersetEqual; "
{ " & NotTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotTilde; "
{ " & NotTildeEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotTildeEqual; "
{ " & NotTildeFullEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotTildeFullEqual; "
{ " & NotTildeTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotTildeTilde; "
{ " & NotVerticalBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & NotVerticalBar; "
{ " & OpenCurlyDoubleQuote; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // & OpenCurlyDoubleQuote; "
{ " & OpenCurlyQuote; " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & OpenCurlyQuote; "
{ " & Or; " , Mml::InfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " mediummathspace " , 0, " true " }, OperSpec::VStretch }, // " & Or; "
{ " & OverBar; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & OverBar; "
{ " & OverBrace; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & OverBrace; "
{ " & OverBracket; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & OverBracket; "
{ " & OverParenthesis; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & OverParenthesis; "
{ " & PartialD; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & PartialD; "
{ " & PlusMinus; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " veryverythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & PlusMinus; "
{ " & Precedes; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Precedes; "
{ " & PrecedesEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & PrecedesEqual; "
{ " & PrecedesSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & PrecedesSlantEqual; "
{ " & PrecedesTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & PrecedesTilde; "
{ " & Product; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, " true " , " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Product; "
{ " & Proportion; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Proportion; "
{ " & Proportional; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Proportional; "
{ " & ReverseElement; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & ReverseElement; "
{ " & ReverseEquilibrium; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & ReverseEquilibrium; "
{ " & ReverseUpEquilibrium; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HStretch }, // & ReverseUpEquilibrium; "
{ " & RightAngleBracket; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & RightAngleBracket; "
{ " & RightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightArrow; "
{ " & RightArrowBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightArrowBar; "
{ " & RightArrowLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightArrowLeftArrow; "
{ " & RightBracketingBar; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & RightBracketingBar; "
{ " & RightCeiling; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & RightCeiling; "
{ " & RightDoubleBracket; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & RightDoubleBracket; "
{ " & RightDoubleBracketingBar; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // & RightDoubleBracketingBar; "
{ " & RightDownTeeVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & RightDownTeeVector; "
{ " & RightDownVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & RightDownVector; "
{ " & RightDownVectorBar; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & RightDownVectorBar; "
{ " & RightFloor; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & RightFloor; "
{ " & RightSkeleton; " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & RightSkeleton; "
{ " & RightTee; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & RightTee; "
{ " & RightTeeArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightTeeArrow; "
{ " & RightTeeVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightTeeVector; "
{ " & RightTriangle; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & RightTriangle; "
{ " & RightTriangleBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & RightTriangleBar; "
{ " & RightTriangleEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & RightTriangleEqual; "
{ " & RightUpDownVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & RightUpDownVector; "
{ " & RightUpTeeVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & RightUpTeeVector; "
{ " & RightUpVector; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & RightUpVector; "
{ " & RightUpVectorBar; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & RightUpVectorBar; "
{ " & RightVector; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightVector; "
{ " & RightVectorBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HStretch }, // " & RightVectorBar; "
{ " & RoundImplies; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & RoundImplies; "
{ " & ShortDownArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & ShortDownArrow; "
{ " & ShortLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::HStretch }, // " & ShortLeftArrow; "
{ " & ShortRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::HStretch }, // " & ShortRightArrow; "
{ " & ShortUpArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::VStretch }, // " & ShortUpArrow; "
{ " & SmallCircle; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SmallCircle; "
{ " & Sqrt; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & Sqrt; "
{ " & Square; " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Square; "
{ " & SquareIntersection; " , Mml::InfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " mediummathspace " , 0, " true " }, OperSpec::HVStretch }, // " & SquareIntersection; "
{ " & SquareSubset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SquareSubset; "
{ " & SquareSubsetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SquareSubsetEqual; "
{ " & SquareSuperset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SquareSuperset; "
{ " & SquareSupersetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SquareSupersetEqual; "
{ " & SquareUnion; " , Mml::InfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " mediummathspace " , 0, " true " }, OperSpec::HVStretch }, // " & SquareUnion; "
{ " & Star; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Star; "
{ " & Subset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Subset; "
{ " & SubsetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SubsetEqual; "
{ " & Succeeds; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Succeeds; "
{ " & SucceedsEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SucceedsEqual; "
{ " & SucceedsSlantEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SucceedsSlantEqual; "
{ " & SucceedsTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SucceedsTilde; "
{ " & SuchThat; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SuchThat; "
{ " & Sum; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, " true " , " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Sum; "
{ " & Superset; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Superset; "
{ " & SupersetEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & SupersetEqual; "
{ " & Therefore; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Therefore; "
{ " & Tilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Tilde; "
{ " & TildeEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & TildeEqual; "
{ " & TildeFullEqual; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & TildeFullEqual; "
{ " & TildeTilde; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & TildeTilde; "
{ " & TripleDot; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " & TripleDot; "
{ " & UnderBar; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & UnderBar; "
{ " & UnderBrace; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & UnderBrace; "
{ " & UnderBracket; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & UnderBracket; "
{ " & UnderParenthesis; " , Mml::PostfixForm, { " true " , 0, 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::HStretch }, // " & UnderParenthesis; "
{ " & Union; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, " true " , " thinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & Union; "
{ " & UnionPlus; " , Mml::PrefixForm, { 0, 0, " true " , " 0em " , 0, " true " , " thinmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & UnionPlus; "
{ " & UpArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & UpArrow; "
{ " & UpArrowBar; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & UpArrowBar; "
{ " & UpArrowDownArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & UpArrowDownArrow; "
{ " & UpDownArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & UpDownArrow; "
{ " & UpEquilibrium; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & UpEquilibrium; "
{ " & UpTee; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & UpTee; "
{ " & UpTeeArrow; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, " true " }, OperSpec::VStretch }, // " & UpTeeArrow; "
{ " & UpperLeftArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & UpperLeftArrow; "
{ " & UpperRightArrow; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::HVStretch }, // " & UpperRightArrow; "
{ " & Vee; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Vee; "
{ " & VerticalBar; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & VerticalBar; "
{ " & VerticalLine; " , Mml::InfixForm, { 0, 0, 0, " 0em " , " 0 " , 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " & VerticalLine; "
{ " & VerticalSeparator; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::VStretch }, // " & VerticalSeparator; "
{ " & VerticalTilde; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & VerticalTilde; "
{ " & Wedge; " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & Wedge; "
{ " & amp; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & amp; "
{ " & amp; & amp; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & amp; & amp; "
{ " & le; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & le; "
{ " & lt; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & lt; "
{ " & lt;= " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & lt;= "
{ " & lt; & gt; " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & lt; & gt; "
{ " ' " , Mml::PostfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " ' "
{ " ( " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " ( "
{ " ) " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " ) "
{ " * " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " * "
{ " ** " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " ** "
{ " *= " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " *= "
{ " + " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " + "
{ " + " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " veryverythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " + "
{ " ++ " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " ++ "
{ " += " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " += "
{ " , " , Mml::InfixForm, { 0, 0, 0, " 0em " , 0, 0, " verythickmathspace " , " true " , 0 }, OperSpec::NoStretch }, // " , "
{ " - " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " - "
{ " - " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " veryverythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " - "
{ " -- " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " -- "
{ " -= " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " -= "
{ " - & gt; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " - & gt; "
{ " . " , Mml::InfixForm, { 0, 0, 0, " 0em " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " . "
{ " .. " , Mml::PostfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " .. "
{ " ... " , Mml::PostfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " 0em " , 0, 0 }, OperSpec::NoStretch }, // " ... "
{ " / " , Mml::InfixForm, { 0, 0, 0, " thinmathspace " , 0, 0, " thinmathspace " , 0, " true " }, OperSpec::VStretch }, // " / "
{ " // " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " // "
{ " /= " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " /= "
{ " : " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " : "
{ " := " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " := "
{ " ; " , Mml::InfixForm, { 0, 0, 0, " 0em " , 0, 0, " verythickmathspace " , " true " , 0 }, OperSpec::NoStretch }, // " ; "
{ " ; " , Mml::PostfixForm, { 0, 0, 0, " 0em " , 0, 0, " 0em " , " true " , 0 }, OperSpec::NoStretch }, // " ; "
{ " = " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " = "
{ " == " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " == "
{ " & gt; " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & gt; "
{ " & gt; = " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, 0 }, OperSpec::NoStretch }, // " & gt; = "
{ " ? " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " ? "
{ " @ " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " @ "
{ " [ " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " [ "
{ " ] " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " ] "
{ " ^ " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " ^ "
{ " _ " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " _ "
{ " lim " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, " true " , " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " lim "
{ " max " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, " true " , " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " max "
{ " min " , Mml::PrefixForm, { 0, 0, 0, " 0em " , 0, " true " , " thinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " min "
{ " { " , Mml::PrefixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " { "
{ " | " , Mml::InfixForm, { 0, 0, 0, " thickmathspace " , 0, 0, " thickmathspace " , 0, " true " }, OperSpec::VStretch }, // " | "
{ " || " , Mml::InfixForm, { 0, 0, 0, " mediummathspace " , 0, 0, " mediummathspace " , 0, 0 }, OperSpec::NoStretch }, // " || "
{ " } " , Mml::PostfixForm, { 0, " true " , 0, " 0em " , 0, 0, " 0em " , 0, " true " }, OperSpec::VStretch }, // " } "
{ " ~ " , Mml::InfixForm, { 0, 0, 0, " verythinmathspace " , 0, 0, " verythinmathspace " , 0, 0 }, OperSpec::NoStretch }, // " ~ "

{ 0 , Mml::InfixForm, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, OperSpec::NoStretch }
};

static const OperSpec g_oper_spec_defaults =
{ 0 , Mml::InfixForm, { " false " , " false " , " false " , " thickmathspace " , " 1 " , " false " , " thickmathspace " , " false " , " false " }, OperSpec::NoStretch };

static const uint g_oper_spec_count = sizeof(g_oper_spec_data)/sizeof(OperSpec) - 1;

static const EntitySpec g_xml_entity_data[] = {
{ " angzarr " , " & #x0237C; " },
{ " cirmid " , " & #x02AEF; " },
{ " cudarrl " , " & #x02938; " },
{ " cudarrr " , " & #x02935; " },
{ " cularr " , " & #x021B6; " },
{ " cularrp " , " & #x0293D; " },
{ " curarr " , " & #x021B7; " },
{ " curarrm " , " & #x0293C; " },
{ " Darr " , " & #x021A1; " },
{ " dArr " , " & #x021D3; " },
{ " ddarr " , " & #x021CA; " },
{ " DDotrahd " , " & #x02911; " },
{ " dfisht " , " & #x0297F; " },
{ " dHar " , " & #x02965; " },
{ " dharl " , " & #x021C3; " },
{ " dharr " , " & #x021C2; " },
{ " duarr " , " & #x021F5; " },
{ " duhar " , " & #x0296F; " },
{ " dzigrarr " , " & #x027FF; " },
{ " erarr " , " & #x02971; " },
{ " hArr " , " & #x021D4; " },
{ " harr " , " & #x02194; " },
{ " harrcir " , " & #x02948; " },
{ " harrw " , " & #x021AD; " },
{ " hoarr " , " & #x021FF; " },
{ " imof " , " & #x022B7; " },
{ " lAarr " , " & #x021DA; " },
{ " Larr " , " & #x0219E; " },
{ " larrbfs " , " & #x0291F; " },
{ " larrfs " , " & #x0291D; " },
{ " larrhk " , " & #x021A9; " },
{ " larrlp " , " & #x021AB; " },
{ " larrpl " , " & #x02939; " },
{ " larrsim " , " & #x02973; " },
{ " larrtl " , " & #x021A2; " },
{ " lAtail " , " & #x0291B; " },
{ " latail " , " & #x02919; " },
{ " lBarr " , " & #x0290E; " },
{ " lbarr " , " & #x0290C; " },
{ " ldca " , " & #x02936; " },
{ " ldrdhar " , " & #x02967; " },
{ " ldrushar " , " & #x0294B; " },
{ " ldsh " , " & #x021B2; " },
{ " lfisht " , " & #x0297C; " },
{ " lHar " , " & #x02962; " },
{ " lhard " , " & #x021BD; " },
{ " lharu " , " & #x021BC; " },
{ " lharul " , " & #x0296A; " },
{ " llarr " , " & #x021C7; " },
{ " llhard " , " & #x0296B; " },
{ " loarr " , " & #x021FD; " },
{ " lrarr " , " & #x021C6; " },
{ " lrhar " , " & #x021CB; " },
{ " lrhard " , " & #x0296D; " },
{ " lsh " , " & #x021B0; " },
{ " lurdshar " , " & #x0294A; " },
{ " luruhar " , " & #x02966; " },
{ " Map " , " & #x02905; " },
{ " map " , " & #x021A6; " },
{ " midcir " , " & #x02AF0; " },
{ " mumap " , " & #x022B8; " },
{ " nearhk " , " & #x02924; " },
{ " neArr " , " & #x021D7; " },
{ " nearr " , " & #x02197; " },
{ " nesear " , " & #x02928; " },
{ " nhArr " , " & #x021CE; " },
{ " nharr " , " & #x021AE; " },
{ " nlArr " , " & #x021CD; " },
{ " nlarr " , " & #x0219A; " },
{ " nrArr " , " & #x021CF; " },
{ " nrarr " , " & #x0219B; " },
{ " nrarrc " , " & #x02933; & #x00338; " },
{ " nrarrw " , " & #x0219D; & #x00338; " },
{ " nvHarr " , " & #x02904; " },
{ " nvlArr " , " & #x02902; " },
{ " nvrArr " , " & #x02903; " },
{ " nwarhk " , " & #x02923; " },
{ " nwArr " , " & #x021D6; " },
{ " nwarr " , " & #x02196; " },
{ " nwnear " , " & #x02927; " },
{ " olarr " , " & #x021BA; " },
{ " orarr " , " & #x021BB; " },
{ " origof " , " & #x022B6; " },
{ " rAarr " , " & #x021DB; " },
{ " Rarr " , " & #x021A0; " },
{ " rarrap " , " & #x02975; " },
{ " rarrbfs " , " & #x02920; " },
{ " rarrc " , " & #x02933; " },
{ " rarrfs " , " & #x0291E; " },
{ " rarrhk " , " & #x021AA; " },
{ " rarrlp " , " & #x021AC; " },
{ " rarrpl " , " & #x02945; " },
{ " rarrsim " , " & #x02974; " },
{ " Rarrtl " , " & #x02916; " },
{ " rarrtl " , " & #x021A3; " },
{ " rarrw " , " & #x0219D; " },
{ " rAtail " , " & #x0291C; " },
{ " ratail " , " & #x0291A; " },
{ " RBarr " , " & #x02910; " },
{ " rBarr " , " & #x0290F; " },
{ " rbarr " , " & #x0290D; " },
{ " rdca " , " & #x02937; " },
{ " rdldhar " , " & #x02969; " },
{ " rdsh " , " & #x021B3; " },
{ " rfisht " , " & #x0297D; " },
{ " rHar " , " & #x02964; " },
{ " rhard " , " & #x021C1; " },
{ " rharu " , " & #x021C0; " },
{ " rharul " , " & #x0296C; " },
{ " rlarr " , " & #x021C4; " },
{ " rlhar " , " & #x021CC; " },
{ " roarr " , " & #x021FE; " },
{ " rrarr " , " & #x021C9; " },
{ " rsh " , " & #x021B1; " },
{ " ruluhar " , " & #x02968; " },
{ " searhk " , " & #x02925; " },
{ " seArr " , " & #x021D8; " },
{ " searr " , " & #x02198; " },
{ " seswar " , " & #x02929; " },
{ " simrarr " , " & #x02972; " },
{ " slarr " , " & #x02190; " },
{ " srarr " , " & #x02192; " },
{ " swarhk " , " & #x02926; " },
{ " swArr " , " & #x021D9; " },
{ " swarr " , " & #x02199; " },
{ " swnwar " , " & #x0292A; " },
{ " Uarr " , " & #x0219F; " },
{ " uArr " , " & #x021D1; " },
{ " Uarrocir " , " & #x02949; " },
{ " udarr " , " & #x021C5; " },
{ " udhar " , " & #x0296E; " },
{ " ufisht " , " & #x0297E; " },
{ " uHar " , " & #x02963; " },
{ " uharl " , " & #x021BF; " },
{ " uharr " , " & #x021BE; " },
{ " uuarr " , " & #x021C8; " },
{ " vArr " , " & #x021D5; " },
{ " varr " , " & #x02195; " },
{ " xhArr " , " & #x027FA; " },
{ " xharr " , " & #x027F7; " },
{ " xlArr " , " & #x027F8; " },
{ " xlarr " , " & #x027F5; " },
{ " xmap " , " & #x027FC; " },
{ " xrArr " , " & #x027F9; " },
{ " xrarr " , " & #x027F6; " },
{ " zigrarr " , " & #x021DD; " },
{ " ac " , " & #x0223E; " },
{ " acE " , " & #x0223E; & #x00333; " },
{ " amalg " , " & #x02A3F; " },
{ " barvee " , " & #x022BD; " },
{ " Barwed " , " & #x02306; " },
{ " barwed " , " & #x02305; " },
{ " bsolb " , " & #x029C5; " },
{ " Cap " , " & #x022D2; " },
{ " capand " , " & #x02A44; " },
{ " capbrcup " , " & #x02A49; " },
{ " capcap " , " & #x02A4B; " },
{ " capcup " , " & #x02A47; " },
{ " capdot " , " & #x02A40; " },
{ " caps " , " & #x02229; & #x0FE00; " },
{ " ccaps " , " & #x02A4D; " },
{ " ccups " , " & #x02A4C; " },
{ " ccupssm " , " & #x02A50; " },
{ " coprod " , " & #x02210; " },
{ " Cup " , " & #x022D3; " },
{ " cupbrcap " , " & #x02A48; " },
{ " cupcap " , " & #x02A46; " },
{ " cupcup " , " & #x02A4A; " },
{ " cupdot " , " & #x0228D; " },
{ " cupor " , " & #x02A45; " },
{ " cups " , " & #x0222A; & #x0FE00; " },
{ " cuvee " , " & #x022CE; " },
{ " cuwed " , " & #x022CF; " },
{ " Dagger " , " & #x02021; " },
{ " dagger " , " & #x02020; " },
{ " diam " , " & #x022C4; " },
{ " divonx " , " & #x022C7; " },
{ " eplus " , " & #x02A71; " },
{ " hercon " , " & #x022B9; " },
{ " intcal " , " & #x022BA; " },
{ " iprod " , " & #x02A3C; " },
{ " loplus " , " & #x02A2D; " },
{ " lotimes " , " & #x02A34; " },
{ " lthree " , " & #x022CB; " },
{ " ltimes " , " & #x022C9; " },
{ " midast " , " & #x0002A; " },
{ " minusb " , " & #x0229F; " },
{ " minusd " , " & #x02238; " },
{ " minusdu " , " & #x02A2A; " },
{ " ncap " , " & #x02A43; " },
{ " ncup " , " & #x02A42; " },
{ " oast " , " & #x0229B; " },
{ " ocir " , " & #x0229A; " },
{ " odash " , " & #x0229D; " },
{ " odiv " , " & #x02A38; " },
{ " odot " , " & #x02299; " },
{ " odsold " , " & #x029BC; " },
{ " ofcir " , " & #x029BF; " },
{ " ogt " , " & #x029C1; " },
{ " ohbar " , " & #x029B5; " },
{ " olcir " , " & #x029BE; " },
{ " olt " , " & #x029C0; " },
{ " omid " , " & #x029B6; " },
{ " ominus " , " & #x02296; " },
{ " opar " , " & #x029B7; " },
{ " operp " , " & #x029B9; " },
{ " oplus " , " & #x02295; " },
{ " osol " , " & #x02298; " },
{ " Otimes " , " & #x02A37; " },
{ " otimes " , " & #x02297; " },
{ " otimesas " , " & #x02A36; " },
{ " ovbar " , " & #x0233D; " },
{ " plusacir " , " & #x02A23; " },
{ " plusb " , " & #x0229E; " },
{ " pluscir " , " & #x02A22; " },
{ " plusdo " , " & #x02214; " },
{ " plusdu " , " & #x02A25; " },
{ " pluse " , " & #x02A72; " },
{ " plussim " , " & #x02A26; " },
{ " plustwo " , " & #x02A27; " },
{ " prod " , " & #x0220F; " },
{ " race " , " & #x029DA; " },
{ " roplus " , " & #x02A2E; " },
{ " rotimes " , " & #x02A35; " },
{ " rthree " , " & #x022CC; " },
{ " rtimes " , " & #x022CA; " },
{ " sdot " , " & #x022C5; " },
{ " sdotb " , " & #x022A1; " },
{ " setmn " , " & #x02216; " },
{ " simplus " , " & #x02A24; " },
{ " smashp " , " & #x02A33; " },
{ " solb " , " & #x029C4; " },
{ " sqcap " , " & #x02293; " },
{ " sqcaps " , " & #x02293; & #x0FE00; " },
{ " sqcup " , " & #x02294; " },
{ " sqcups " , " & #x02294; & #x0FE00; " },
{ " ssetmn " , " & #x02216; " },
{ " sstarf " , " & #x022C6; " },
{ " subdot " , " & #x02ABD; " },
{ " sum " , " & #x02211; " },
{ " supdot " , " & #x02ABE; " },
{ " timesb " , " & #x022A0; " },
{ " timesbar " , " & #x02A31; " },
{ " timesd " , " & #x02A30; " },
{ " tridot " , " & #x025EC; " },
{ " triminus " , " & #x02A3A; " },
{ " triplus " , " & #x02A39; " },
{ " trisb " , " & #x029CD; " },
{ " tritime " , " & #x02A3B; " },
{ " uplus " , " & #x0228E; " },
{ " veebar " , " & #x022BB; " },
{ " wedbar " , " & #x02A5F; " },
{ " wreath " , " & #x02240; " },
{ " xcap " , " & #x022C2; " },
{ " xcirc " , " & #x025EF; " },
{ " xcup " , " & #x022C3; " },
{ " xdtri " , " & #x025BD; " },
{ " xodot " , " & #x02A00; " },
{ " xoplus " , " & #x02A01; " },
{ " xotime " , " & #x02A02; " },
{ " xsqcup " , " & #x02A06; " },
{ " xuplus " , " & #x02A04; " },
{ " xutri " , " & #x025B3; " },
{ " xvee " , " & #x022C1; " },
{ " xwedge " , " & #x022C0; " },
{ " dlcorn " , " & #x0231E; " },
{ " drcorn " , " & #x0231F; " },
{ " gtlPar " , " & #x02995; " },
{ " langd " , " & #x02991; " },
{ " lbrke " , " & #x0298B; " },
{ " lbrksld " , " & #x0298F; " },
{ " lbrkslu " , " & #x0298D; " },
{ " lceil " , " & #x02308; " },
{ " lfloor " , " & #x0230A; " },
{ " lmoust " , " & #x023B0; " },
{ " lparlt " , " & #x02993; " },
{ " ltrPar " , " & #x02996; " },
{ " rangd " , " & #x02992; " },
{ " rbrke " , " & #x0298C; " },
{ " rbrksld " , " & #x0298E; " },
{ " rbrkslu " , " & #x02990; " },
{ " rceil " , " & #x02309; " },
{ " rfloor " , " & #x0230B; " },
{ " rmoust " , " & #x023B1; " },
{ " rpargt " , " & #x02994; " },
{ " ulcorn " , " & #x0231C; " },
{ " urcorn " , " & #x0231D; " },
{ " gnap " , " & #x02A8A; " },
{ " gnE " , " & #x02269; " },
{ " gne " , " & #x02A88; " },
{ " gnsim " , " & #x022E7; " },
{ " gvnE " , " & #x02269; & #x0FE00; " },
{ " lnap " , " & #x02A89; " },
{ " lnE " , " & #x02268; " },
{ " lne " , " & #x02A87; " },
{ " lnsim " , " & #x022E6; " },
{ " lvnE " , " & #x02268; & #x0FE00; " },
{ " nap " , " & #x02249; " },
{ " napE " , " & #x02A70; & #x00338; " },
{ " napid " , " & #x0224B; & #x00338; " },
{ " ncong " , " & #x02247; " },
{ " ncongdot " , " & #x02A6D; & #x00338; " },
{ " nequiv " , " & #x02262; " },
{ " ngE " , " & #x02267; & #x00338; " },
{ " nge " , " & #x02271; " },
{ " nges " , " & #x02A7E; & #x00338; " },
{ " nGg " , " & #x022D9; & #x00338; " },
{ " ngsim " , " & #x02275; " },
{ " nGt " , " & #x0226B; & #x020D2; " },
{ " ngt " , " & #x0226F; " },
{ " nGtv " , " & #x0226B; & #x00338; " },
{ " nlE " , " & #x02266; & #x00338; " },
{ " nle " , " & #x02270; " },
{ " nles " , " & #x02A7D; & #x00338; " },
{ " nLl " , " & #x022D8; & #x00338; " },
{ " nlsim " , " & #x02274; " },
{ " nLt " , " & #x0226A; & #x020D2; " },
{ " nlt " , " & #x0226E; " },
{ " nltri " , " & #x022EA; " },
{ " nltrie " , " & #x022EC; " },
{ " nLtv " , " & #x0226A; & #x00338; " },
{ " nmid " , " & #x02224; " },
{ " npar " , " & #x02226; " },
{ " npr " , " & #x02280; " },
{ " nprcue " , " & #x022E0; " },
{ " npre " , " & #x02AAF; & #x00338; " },
{ " nrtri " , " & #x022EB; " },
{ " nrtrie " , " & #x022ED; " },
{ " nsc " , " & #x02281; " },
{ " nsccue " , " & #x022E1; " },
{ " nsce " , " & #x02AB0; & #x00338; " },
{ " nsim " , " & #x02241; " },
{ " nsime " , " & #x02244; " },
{ " nsmid " , " & #x02224; " },
{ " nspar " , " & #x02226; " },
{ " nsqsube " , " & #x022E2; " },
{ " nsqsupe " , " & #x022E3; " },
{ " nsub " , " & #x02284; " },
{ " nsubE " , " & #x02AC5; & #x0338; " },
{ " nsube " , " & #x02288; " },
{ " nsup " , " & #x02285; " },
{ " nsupE " , " & #x02AC6; & #x0338; " },
{ " nsupe " , " & #x02289; " },
{ " ntgl " , " & #x02279; " },
{ " ntlg " , " & #x02278; " },
{ " nvap " , " & #x0224D; & #x020D2; " },
{ " nVDash " , " & #x022AF; " },
{ " nVdash " , " & #x022AE; " },
{ " nvDash " , " & #x022AD; " },
{ " nvdash " , " & #x022AC; " },
{ " nvge " , " & #x02265; & #x020D2; " },
{ " nvgt " , " & #x0003E; & #x020D2; " },
{ " nvle " , " & #x02264; & #x020D2; " },
{ " nvlt " , " & #x0003C; & #x020D2; " },
{ " nvltrie " , " & #x022B4; & #x020D2; " },
{ " nvrtrie " , " & #x022B5; & #x020D2; " },
{ " nvsim " , " & #x0223C; & #x020D2; " },
{ " parsim " , " & #x02AF3; " },
{ " prnap " , " & #x02AB9; " },
{ " prnE " , " & #x02AB5; " },
{ " prnsim " , " & #x022E8; " },
{ " rnmid " , " & #x02AEE; " },
{ " scnap " , " & #x02ABA; " },
{ " scnE " , " & #x02AB6; " },
{ " scnsim " , " & #x022E9; " },
{ " simne " , " & #x02246; " },
{ " solbar " , " & #x0233F; " },
{ " subnE " , " & #x02ACB; " },
{ " subne " , " & #x0228A; " },
{ " supnE " , " & #x02ACC; " },
{ " supne " , " & #x0228B; " },
{ " vnsub " , " & #x02282; & #x020D2; " },
{ " vnsup " , " & #x02283; & #x020D2; " },
{ " vsubnE " , " & #x02ACB; & #x0FE00; " },
{ " vsubne " , " & #x0228A; & #x0FE00; " },
{ " vsupnE " , " & #x02ACC; & #x0FE00; " },
{ " vsupne " , " & #x0228B; & #x0FE00; " },
{ " ang " , " & #x02220; " },
{ " ange " , " & #x029A4; " },
{ " angmsd " , " & #x02221; " },
{ " angmsdaa " , " & #x029A8; " },
{ " angmsdab " , " & #x029A9; " },
{ " angmsdac " , " & #x029AA; " },
{ " angmsdad " , " & #x029AB; " },
{ " angmsdae " , " & #x029AC; " },
{ " angmsdaf " , " & #x029AD; " },
{ " angmsdag " , " & #x029AE; " },
{ " angmsdah " , " & #x029AF; " },
{ " angrtvb " , " & #x022BE; " },
{ " angrtvbd " , " & #x0299D; " },
{ " bbrk " , " & #x023B5; " },
{ " bemptyv " , " & #x029B0; " },
{ " beth " , " & #x02136; " },
{ " boxbox " , " & #x029C9; " },
{ " bprime " , " & #x02035; " },
{ " bsemi " , " & #x0204F; " },
{ " cemptyv " , " & #x029B2; " },
{ " cirE " , " & #x029C3; " },
{ " cirscir " , " & #x029C2; " },
{ " comp " , " & #x02201; " },
{ " daleth " , " & #x02138; " },
{ " demptyv " , " & #x029B1; " },
{ " ell " , " & #x02113; " },
{ " empty " , " & #x02205; " },
{ " emptyv " , " & #x02205; " },
{ " gimel " , " & #x02137; " },
{ " iiota " , " & #x02129; " },
{ " image " , " & #x02111; " },
{ " imath " , " & #x00131; " },
{ " jmath " , " & #x0006A; " },
{ " laemptyv " , " & #x029B4; " },
{ " lltri " , " & #x025FA; " },
{ " lrtri " , " & #x022BF; " },
{ " mho " , " & #x02127; " },
{ " nang " , " & #x02220; & #x020D2; " },
{ " nexist " , " & #x02204; " },
{ " oS " , " & #x024C8; " },
{ " planck " , " & #x0210F; " },
{ " plankv " , " & #x0210F; " },
{ " raemptyv " , " & #x029B3; " },
{ " range " , " & #x029A5; " },
{ " real " , " & #x0211C; " },
{ " tbrk " , " & #x023B4; " },
{ " ultri " , " & #x025F8; " },
{ " urtri " , " & #x025F9; " },
{ " vzigzag " , " & #x0299A; " },
{ " weierp " , " & #x02118; " },
{ " apE " , " & #x02A70; " },
{ " ape " , " & #x0224A; " },
{ " apid " , " & #x0224B; " },
{ " asymp " , " & #x02248; " },
{ " Barv " , " & #x02AE7; " },
{ " bcong " , " & #x0224C; " },
{ " bepsi " , " & #x003F6; " },
{ " bowtie " , " & #x022C8; " },
{ " bsim " , " & #x0223D; " },
{ " bsime " , " & #x022CD; " },
{ " bsolhsub " , " & #x0005C; & #x02282; " },
{ " bump " , " & #x0224E; " },
{ " bumpE " , " & #x02AAE; " },
{ " bumpe " , " & #x0224F; " },
{ " cire " , " & #x02257; " },
{ " Colon " , " & #x02237; " },
{ " Colone " , " & #x02A74; " },
{ " colone " , " & #x02254; " },
{ " congdot " , " & #x02A6D; " },
{ " csub " , " & #x02ACF; " },
{ " csube " , " & #x02AD1; " },
{ " csup " , " & #x02AD0; " },
{ " csupe " , " & #x02AD2; " },
{ " cuepr " , " & #x022DE; " },
{ " cuesc " , " & #x022DF; " },
{ " Dashv " , " & #x02AE4; " },
{ " dashv " , " & #x022A3; " },
{ " easter " , " & #x02A6E; " },
{ " ecir " , " & #x02256; " },
{ " ecolon " , " & #x02255; " },
{ " eDDot " , " & #x02A77; " },
{ " eDot " , " & #x02251; " },
{ " efDot " , " & #x02252; " },
{ " eg " , " & #x02A9A; " },
{ " egs " , " & #x02A96; " },
{ " egsdot " , " & #x02A98; " },
{ " el " , " & #x02A99; " },
{ " els " , " & #x02A95; " },
{ " elsdot " , " & #x02A97; " },
{ " equest " , " & #x0225F; " },
{ " equivDD " , " & #x02A78; " },
{ " erDot " , " & #x02253; " },
{ " esdot " , " & #x02250; " },
{ " Esim " , " & #x02A73; " },
{ " esim " , " & #x02242; " },
{ " fork " , " & #x022D4; " },
{ " forkv " , " & #x02AD9; " },
{ " frown " , " & #x02322; " },
{ " gap " , " & #x02A86; " },
{ " gE " , " & #x02267; " },
{ " gEl " , " & #x02A8C; " },
{ " gel " , " & #x022DB; " },
{ " ges " , " & #x02A7E; " },
{ " gescc " , " & #x02AA9; " },
{ " gesdot " , " & #x02A80; " },
{ " gesdoto " , " & #x02A82; " },
{ " gesdotol " , " & #x02A84; " },
{ " gesl " , " & #x022DB; & #x0FE00; " },
{ " gesles " , " & #x02A94; " },
{ " Gg " , " & #x022D9; " },
{ " gl " , " & #x02277; " },
{ " gla " , " & #x02AA5; " },
{ " glE " , " & #x02A92; " },
{ " glj " , " & #x02AA4; " },
{ " gsim " , " & #x02273; " },
{ " gsime " , " & #x02A8E; " },
{ " gsiml " , " & #x02A90; " },
{ " Gt " , " & #x0226B; " },
{ " gtcc " , " & #x02AA7; " },
{ " gtcir " , " & #x02A7A; " },
{ " gtdot " , " & #x022D7; " },
{ " gtquest " , " & #x02A7C; " },
{ " gtrarr " , " & #x02978; " },
{ " homtht " , " & #x0223B; " },
{ " lap " , " & #x02A85; " },
{ " lat " , " & #x02AAB; " },
{ " late " , " & #x02AAD; " },
{ " lates " , " & #x02AAD; & #x0FE00; " },
{ " lE " , " & #x02266; " },
{ " lEg " , " & #x02A8B; " },
{ " leg " , " & #x022DA; " },
{ " les " , " & #x02A7D; " },
{ " lescc " , " & #x02AA8; " },
{ " lesdot " , " & #x02A7F; " },
{ " lesdoto " , " & #x02A81; " },
{ " lesdotor " , " & #x02A83; " },
{ " lesg " , " & #x022DA; & #x0FE00; " },
{ " lesges " , " & #x02A93; " },
{ " lg " , " & #x02276; " },
{ " lgE " , " & #x02A91; " },
{ " Ll " , " & #x022D8; " },
{ " lsim " , " & #x02272; " },
{ " lsime " , " & #x02A8D; " },
{ " lsimg " , " & #x02A8F; " },
{ " Lt " , " & #x0226A; " },
{ " ltcc " , " & #x02AA6; " },
{ " ltcir " , " & #x02A79; " },
{ " ltdot " , " & #x022D6; " },
{ " ltlarr " , " & #x02976; " },
{ " ltquest " , " & #x02A7B; " },
{ " ltrie " , " & #x022B4; " },
{ " mcomma " , " & #x02A29; " },
{ " mDDot " , " & #x0223A; " },
{ " mid " , " & #x02223; " },
{ " mlcp " , " & #x02ADB; " },
{ " models " , " & #x022A7; " },
{ " mstpos " , " & #x0223E; " },
{ " Pr " , " & #x02ABB; " },
{ " pr " , " & #x0227A; " },
{ " prap " , " & #x02AB7; " },
{ " prcue " , " & #x0227C; " },
{ " prE " , " & #x02AB3; " },
{ " pre " , " & #x02AAF; " },
{ " prsim " , " & #x0227E; " },
{ " prurel " , " & #x022B0; " },
{ " ratio " , " & #x02236; " },
{ " rtrie " , " & #x022B5; " },
{ " rtriltri " , " & #x029CE; " },
{ " Sc " , " & #x02ABC; " },
{ " sc " , " & #x0227B; " },
{ " scap " , " & #x02AB8; " },
{ " sccue " , " & #x0227D; " },
{ " scE " , " & #x02AB4; " },
{ " sce " , " & #x02AB0; " },
{ " scsim " , " & #x0227F; " },
{ " sdote " , " & #x02A66; " },
{ " simg " , " & #x02A9E; " },
{ " simgE " , " & #x02AA0; " },
{ " siml " , " & #x02A9D; " },
{ " simlE " , " & #x02A9F; " },
{ " smid " , " & #x02223; " },
{ " smile " , " & #x02323; " },
{ " smt " , " & #x02AAA; " },
{ " smte " , " & #x02AAC; " },
{ " smtes " , " & #x02AAC; & #x0FE00; " },
{ " spar " , " & #x02225; " },
{ " sqsub " , " & #x0228F; " },
{ " sqsube " , " & #x02291; " },
{ " sqsup " , " & #x02290; " },
{ " sqsupe " , " & #x02292; " },
{ " Sub " , " & #x022D0; " },
{ " subE " , " & #x02AC5; " },
{ " subedot " , " & #x02AC3; " },
{ " submult " , " & #x02AC1; " },
{ " subplus " , " & #x02ABF; " },
{ " subrarr " , " & #x02979; " },
{ " subsim " , " & #x02AC7; " },
{ " subsub " , " & #x02AD5; " },
{ " subsup " , " & #x02AD3; " },
{ " Sup " , " & #x022D1; " },
{ " supdsub " , " & #x02AD8; " },
{ " supE " , " & #x02AC6; " },
{ " supedot " , " & #x02AC4; " },
{ " suphsol " , " & #x02283; & #x00338; " },
{ " suphsub " , " & #x02AD7; " },
{ " suplarr " , " & #x0297B; " },
{ " supmult " , " & #x02AC2; " },
{ " supplus " , " & #x02AC0; " },
{ " supsim " , " & #x02AC8; " },
{ " supsub " , " & #x02AD4; " },
{ " supsup " , " & #x02AD6; " },
{ " thkap " , " & #x02248; " },
{ " topfork " , " & #x02ADA; " },
{ " trie " , " & #x0225C; " },
{ " twixt " , " & #x0226C; " },
{ " Vbar " , " & #x02AEB; " },
{ " vBar " , " & #x02AE8; " },
{ " vBarv " , " & #x02AE9; " },
{ " VDash " , " & #x022AB; " },
{ " Vdash " , " & #x022A9; " },
{ " vDash " , " & #x022A8; " },
{ " vdash " , " & #x022A2; " },
{ " Vdashl " , " & #x02AE6; " },
{ " vltri " , " & #x022B2; " },
{ " vprop " , " & #x0221D; " },
{ " vrtri " , " & #x022B3; " },
{ " Vvdash " , " & #x022AA; " },
{ " alpha " , " & #x003B1; " },
{ " beta " , " & #x003B2; " },
{ " chi " , " & #x003C7; " },
{ " Delta " , " & #x00394; " },
{ " delta " , " & #x003B4; " },
{ " epsi " , " & #x003B5; " },
{ " epsiv " , " & #x0025B; " },
{ " eta " , " & #x003B7; " },
{ " Gamma " , " & #x00393; " },
{ " gamma " , " & #x003B3; " },
{ " Gammad " , " & #x003DC; " },
{ " gammad " , " & #x003DD; " },
{ " iota " , " & #x003B9; " },
{ " kappa " , " & #x003BA; " },
{ " kappav " , " & #x003F0; " },
{ " Lambda " , " & #x0039B; " },
{ " lambda " , " & #x003BB; " },
{ " mu " , " & #x003BC; " },
{ " nu " , " & #x003BD; " },
{ " Omega " , " & #x003A9; " },
{ " omega " , " & #x003C9; " },
{ " Phi " , " & #x003A6; " },
{ " phi " , " & #x003D5; " },
{ " phiv " , " & #x003C6; " },
{ " Pi " , " & #x003A0; " },
{ " pi " , " & #x003C0; " },
{ " piv " , " & #x003D6; " },
{ " Psi " , " & #x003A8; " },
{ " psi " , " & #x003C8; " },
{ " rho " , " & #x003C1; " },
{ " rhov " , " & #x003F1; " },
{ " Sigma " , " & #x003A3; " },
{ " sigma " , " & #x003C3; " },
{ " sigmav " , " & #x003C2; " },
{ " tau " , " & #x003C4; " },
{ " Theta " , " & #x00398; " },
{ " theta " , " & #x003B8; " },
{ " thetav " , " & #x003D1; " },
{ " Upsi " , " & #x003D2; " },
{ " upsi " , " & #x003C5; " },
{ " Xi " , " & #x0039E; " },
{ " xi " , " & #x003BE; " },
{ " zeta " , " & #x003B6; " },
{ " Cfr " , " & #x0212D; " },
{ " Hfr " , " & #x0210C; " },
{ " Ifr " , " & #x02111; " },
{ " Rfr " , " & #x0211C; " },
{ " Zfr " , " & #x02128; " },
{ " Copf " , " & #x02102; " },
{ " Hopf " , " & #x0210D; " },
{ " Nopf " , " & #x02115; " },
{ " Popf " , " & #x02119; " },
{ " Qopf " , " & #x0211A; " },
{ " Ropf " , " & #x0211D; " },
{ " Zopf " , " & #x02124; " },
{ " Bscr " , " & #x0212C; " },
{ " Escr " , " & #x02130; " },
{ " escr " , " & #x0212F; " },
{ " Fscr " , " & #x02131; " },
{ " gscr " , " & #x0210A; " },
{ " Hscr " , " & #x0210B; " },
{ " Iscr " , " & #x02110; " },
{ " Lscr " , " & #x02112; " },
{ " Mscr " , " & #x02133; " },
{ " oscr " , " & #x02134; " },
{ " pscr " , " & #x1D4C5; " },
{ " Rscr " , " & #x0211B; " },
{ " acd " , " & #x0223F; " },
{ " aleph " , " & #x02135; " },
{ " And " , " & #x02A53; " },
{ " and " , " & #x02227; " },
{ " andand " , " & #x02A55; " },
{ " andd " , " & #x02A5C; " },
{ " andslope " , " & #x02A58; " },
{ " andv " , " & #x02A5A; " },
{ " angrt " , " & #x0221F; " },
{ " angsph " , " & #x02222; " },
{ " angst " , " & #x0212B; " },
{ " ap " , " & #x02248; " },
{ " apacir " , " & #x02A6F; " },
{ " awconint " , " & #x02233; " },
{ " awint " , " & #x02A11; " },
{ " becaus " , " & #x02235; " },
{ " bernou " , " & #x0212C; " },
{ " bne " , " & #x0003D; & #x020E5; " },
{ " bnequiv " , " & #x02261; & #x020E5; " },
{ " bNot " , " & #x02AED; " },
{ " bnot " , " & #x02310; " },
{ " bottom " , " & #x022A5; " },
{ " cap " , " & #x02229; " },
{ " Cconint " , " & #x02230; " },
{ " cirfnint " , " & #x02A10; " },
{ " compfn " , " & #x02218; " },
{ " cong " , " & #x02245; " },
{ " Conint " , " & #x0222F; " },
{ " conint " , " & #x0222E; " },
{ " ctdot " , " & #x022EF; " },
{ " cup " , " & #x0222A; " },
{ " cwconint " , " & #x02232; " },
{ " cwint " , " & #x02231; " },
{ " cylcty " , " & #x0232D; " },
{ " disin " , " & #x022F2; " },
{ " Dot " , " & #x000A8; " },
{ " DotDot " , " & #x020DC; " },
{ " dsol " , " & #x029F6; " },
{ " dtdot " , " & #x022F1; " },
{ " dwangle " , " & #x029A6; " },
{ " epar " , " & #x022D5; " },
{ " eparsl " , " & #x029E3; " },
{ " equiv " , " & #x02261; " },
{ " eqvparsl " , " & #x029E5; " },
{ " exist " , " & #x02203; " },
{ " fnof " , " & #x00192; " },
{ " forall " , " & #x02200; " },
{ " fpartint " , " & #x02A0D; " },
{ " ge " , " & #x02265; " },
{ " hamilt " , " & #x0210B; " },
{ " iff " , " & #x021D4; " },
{ " iinfin " , " & #x029DC; " },
{ " infin " , " & #x0221E; " },
{ " Int " , " & #x0222C; " },
{ " int " , " & #x0222B; " },
{ " intlarhk " , " & #x02A17; " },
{ " isin " , " & #x02208; " },
{ " isindot " , " & #x022F5; " },
{ " isinE " , " & #x022F9; " },
{ " isins " , " & #x022F4; " },
{ " isinsv " , " & #x022F3; " },
{ " isinv " , " & #x02208; " },
{ " lagran " , " & #x02112; " },
{ " Lang " , " & #x0300A; " },
{ " lang " , " & #x02329; " },
{ " lArr " , " & #x021D0; " },
{ " lbbrk " , " & #x03014; " },
{ " le " , " & #x02264; " },
{ " loang " , " & #x03018; " },
{ " lobrk " , " & #x0301A; " },
{ " lopar " , " & #x02985; " },
{ " lowast " , " & #x02217; " },
{ " minus " , " & #x02212; " },
{ " mnplus " , " & #x02213; " },
{ " nabla " , " & #x02207; " },
{ " ne " , " & #x02260; " },
{ " nedot " , " & #x02250; & #x00338; " },
{ " nhpar " , " & #x02AF2; " },
{ " ni " , " & #x0220B; " },
{ " nis " , " & #x022FC; " },
{ " nisd " , " & #x022FA; " },
{ " niv " , " & #x0220B; " },
{ " Not " , " & #x02AEC; " },
{ " notin " , " & #x02209; " },
{ " notindot " , " & #x022F5; & #x00338; " },
{ " notinva " , " & #x02209; " },
{ " notinvb " , " & #x022F7; " },
{ " notinvc " , " & #x022F6; " },
{ " notni " , " & #x0220C; " },
{ " notniva " , " & #x0220C; " },
{ " notnivb " , " & #x022FE; " },
{ " notnivc " , " & #x022FD; " },
{ " nparsl " , " & #x02AFD; & #x020E5; " },
{ " npart " , " & #x02202; & #x00338; " },
{ " npolint " , " & #x02A14; " },
{ " nvinfin " , " & #x029DE; " },
{ " olcross " , " & #x029BB; " },
{ " Or " , " & #x02A54; " },
{ " or " , " & #x02228; " },
{ " ord " , " & #x02A5D; " },
{ " order " , " & #x02134; " },
{ " oror " , " & #x02A56; " },
{ " orslope " , " & #x02A57; " },
{ " orv " , " & #x02A5B; " },
{ " par " , " & #x02225; " },
{ " parsl " , " & #x02AFD; " },
{ " part " , " & #x02202; " },
{ " permil " , " & #x02030; " },
{ " perp " , " & #x022A5; " },
{ " pertenk " , " & #x02031; " },
{ " phmmat " , " & #x02133; " },
{ " pointint " , " & #x02A15; " },
{ " Prime " , " & #x02033; " },
{ " prime " , " & #x02032; " },
{ " profalar " , " & #x0232E; " },
{ " profline " , " & #x02312; " },
{ " profsurf " , " & #x02313; " },
{ " prop " , " & #x0221D; " },
{ " qint " , " & #x02A0C; " },
{ " qprime " , " & #x02057; " },
{ " quatint " , " & #x02A16; " },
{ " radic " , " & #x0221A; " },
{ " Rang " , " & #x0300B; " },
{ " rang " , " & #x0232A; " },
{ " rArr " , " & #x021D2; " },
{ " rbbrk " , " & #x03015; " },
{ " roang " , " & #x03019; " },
{ " robrk " , " & #x0301B; " },
{ " ropar " , " & #x02986; " },
{ " rppolint " , " & #x02A12; " },
{ " scpolint " , " & #x02A13; " },
{ " sim " , " & #x0223C; " },
{ " simdot " , " & #x02A6A; " },
{ " sime " , " & #x02243; " },
{ " smeparsl " , " & #x029E4; " },
{ " square " , " & #x025A1; " },
{ " squarf " , " & #x025AA; " },
{ " sub " , " & #x02282; " },
{ " sube " , " & #x02286; " },
{ " sup " , " & #x02283; " },
{ " supe " , " & #x02287; " },
{ " tdot " , " & #x020DB; " },
{ " there4 " , " & #x02234; " },
{ " tint " , " & #x0222D; " },
{ " top " , " & #x022A4; " },
{ " topbot " , " & #x02336; " },
{ " topcir " , " & #x02AF1; " },
{ " tprime " , " & #x02034; " },
{ " utdot " , " & #x022F0; " },
{ " uwangle " , " & #x029A7; " },
{ " vangrt " , " & #x0299C; " },
{ " veeeq " , " & #x0225A; " },
{ " Verbar " , " & #x02016; " },
{ " wedgeq " , " & #x02259; " },
{ " xnis " , " & #x022FB; " },
{ " boxDL " , " & #x02557; " },
{ " boxDl " , " & #x02556; " },
{ " boxdL " , " & #x02555; " },
{ " boxdl " , " & #x02510; " },
{ " boxDR " , " & #x02554; " },
{ " boxDr " , " & #x02553; " },
{ " boxdR " , " & #x02552; " },
{ " boxdr " , " & #x0250C; " },
{ " boxH " , " & #x02550; " },
{ " boxh " , " & #x02500; " },
{ " boxHD " , " & #x02566; " },
{ " boxHd " , " & #x02564; " },
{ " boxhD " , " & #x02565; " },
{ " boxhd " , " & #x0252C; " },
{ " boxHU " , " & #x02569; " },
{ " boxHu " , " & #x02567; " },
{ " boxhU " , " & #x02568; " },
{ " boxhu " , " & #x02534; " },
{ " boxUL " , " & #x0255D; " },
{ " boxUl " , " & #x0255C; " },
{ " boxuL " , " & #x0255B; " },
{ " boxul " , " & #x02518; " },
{ " boxUR " , " & #x0255A; " },
{ " boxUr " , " & #x02559; " },
{ " boxuR " , " & #x02558; " },
{ " boxur " , " & #x02514; " },
{ " boxV " , " & #x02551; " },
{ " boxv " , " & #x02502; " },
{ " boxVH " , " & #x0256C; " },
{ " boxVh " , " & #x0256B; " },
{ " boxvH " , " & #x0256A; " },
{ " boxvh " , " & #x0253C; " },
{ " boxVL " , " & #x02563; " },
{ " boxVl " , " & #x02562; " },
{ " boxvL " , " & #x02561; " },
{ " boxvl " , " & #x02524; " },
{ " boxVR " , " & #x02560; " },
{ " boxVr " , " & #x0255F; " },
{ " boxvR " , " & #x0255E; " },
{ " boxvr " , " & #x0251C; " },
{ " Acy " , " & #x00410; " },
{ " acy " , " & #x00430; " },
{ " Bcy " , " & #x00411; " },
{ " bcy " , " & #x00431; " },
{ " CHcy " , " & #x00427; " },
{ " chcy " , " & #x00447; " },
{ " Dcy " , " & #x00414; " },
{ " dcy " , " & #x00434; " },
{ " Ecy " , " & #x0042D; " },
{ " ecy " , " & #x0044D; " },
{ " Fcy " , " & #x00424; " },
{ " fcy " , " & #x00444; " },
{ " Gcy " , " & #x00413; " },
{ " gcy " , " & #x00433; " },
{ " HARDcy " , " & #x0042A; " },
{ " hardcy " , " & #x0044A; " },
{ " Icy " , " & #x00418; " },
{ " icy " , " & #x00438; " },
{ " IEcy " , " & #x00415; " },
{ " iecy " , " & #x00435; " },
{ " IOcy " , " & #x00401; " },
{ " iocy " , " & #x00451; " },
{ " Jcy " , " & #x00419; " },
{ " jcy " , " & #x00439; " },
{ " Kcy " , " & #x0041A; " },
{ " kcy " , " & #x0043A; " },
{ " KHcy " , " & #x00425; " },
{ " khcy " , " & #x00445; " },
{ " Lcy " , " & #x0041B; " },
{ " lcy " , " & #x0043B; " },
{ " Mcy " , " & #x0041C; " },
{ " mcy " , " & #x0043C; " },
{ " Ncy " , " & #x0041D; " },
{ " ncy " , " & #x0043D; " },
{ " numero " , " & #x02116; " },
{ " Ocy " , " & #x0041E; " },
{ " ocy " , " & #x0043E; " },
{ " Pcy " , " & #x0041F; " },
{ " pcy " , " & #x0043F; " },
{ " Rcy " , " & #x00420; " },
{ " rcy " , " & #x00440; " },
{ " Scy " , " & #x00421; " },
{ " scy " , " & #x00441; " },
{ " SHCHcy " , " & #x00429; " },
{ " shchcy " , " & #x00449; " },
{ " SHcy " , " & #x00428; " },
{ " shcy " , " & #x00448; " },
{ " SOFTcy " , " & #x0042C; " },
{ " softcy " , " & #x0044C; " },
{ " Tcy " , " & #x00422; " },
{ " tcy " , " & #x00442; " },
{ " TScy " , " & #x00426; " },
{ " tscy " , " & #x00446; " },
{ " Ucy " , " & #x00423; " },
{ " ucy " , " & #x00443; " },
{ " Vcy " , " & #x00412; " },
{ " vcy " , " & #x00432; " },
{ " YAcy " , " & #x0042F; " },
{ " yacy " , " & #x0044F; " },
{ " Ycy " , " & #x0042B; " },
{ " ycy " , " & #x0044B; " },
{ " YUcy " , " & #x0042E; " },
{ " yucy " , " & #x0044E; " },
{ " Zcy " , " & #x00417; " },
{ " zcy " , " & #x00437; " },
{ " ZHcy " , " & #x00416; " },
{ " zhcy " , " & #x00436; " },
{ " DJcy " , " & #x00402; " },
{ " djcy " , " & #x00452; " },
{ " DScy " , " & #x00405; " },
{ " dscy " , " & #x00455; " },
{ " DZcy " , " & #x0040F; " },
{ " dzcy " , " & #x0045F; " },
{ " GJcy " , " & #x00403; " },
{ " gjcy " , " & #x00453; " },
{ " Iukcy " , " & #x00406; " },
{ " iukcy " , " & #x00456; " },
{ " Jsercy " , " & #x00408; " },
{ " jsercy " , " & #x00458; " },
{ " Jukcy " , " & #x00404; " },
{ " jukcy " , " & #x00454; " },
{ " KJcy " , " & #x0040C; " },
{ " kjcy " , " & #x0045C; " },
{ " LJcy " , " & #x00409; " },
{ " ljcy " , " & #x00459; " },
{ " NJcy " , " & #x0040A; " },
{ " njcy " , " & #x0045A; " },
{ " TSHcy " , " & #x0040B; " },
{ " tshcy " , " & #x0045B; " },
{ " Ubrcy " , " & #x0040E; " },
{ " ubrcy " , " & #x0045E; " },
{ " YIcy " , " & #x00407; " },
{ " yicy " , " & #x00457; " },
{ " acute " , " & #x000B4; " },
{ " breve " , " & #x002D8; " },
{ " caron " , " & #x002C7; " },
{ " cedil " , " & #x000B8; " },
{ " circ " , " & #x002C6; " },
{ " dblac " , " & #x002DD; " },
{ " die " , " & #x000A8; " },
{ " dot " , " & #x002D9; " },
{ " grave " , " & #x00060; " },
{ " macr " , " & #x000AF; " },
{ " ogon " , " & #x002DB; " },
{ " ring " , " & #x002DA; " },
{ " tilde " , " & #x002DC; " },
{ " uml " , " & #x000A8; " },
{ " Aacute " , " & #x000C1; " },
{ " aacute " , " & #x000E1; " },
{ " Acirc " , " & #x000C2; " },
{ " acirc " , " & #x000E2; " },
{ " AElig " , " & #x000C6; " },
{ " aelig " , " & #x000E6; " },
{ " Agrave " , " & #x000C0; " },
{ " agrave " , " & #x000E0; " },
{ " Aring " , " & #x000C5; " },
{ " aring " , " & #x000E5; " },
{ " Atilde " , " & #x000C3; " },
{ " atilde " , " & #x000E3; " },
{ " Auml " , " & #x000C4; " },
{ " auml " , " & #x000E4; " },
{ " Ccedil " , " & #x000C7; " },
{ " ccedil " , " & #x000E7; " },
{ " Eacute " , " & #x000C9; " },
{ " eacute " , " & #x000E9; " },
{ " Ecirc " , " & #x000CA; " },
{ " ecirc " , " & #x000EA; " },
{ " Egrave " , " & #x000C8; " },
{ " egrave " , " & #x000E8; " },
{ " ETH " , " & #x000D0; " },
{ " eth " , " & #x000F0; " },
{ " Euml " , " & #x000CB; " },
{ " euml " , " & #x000EB; " },
{ " Iacute " , " & #x000CD; " },
{ " iacute " , " & #x000ED; " },
{ " Icirc " , " & #x000CE; " },
{ " icirc " , " & #x000EE; " },
{ " Igrave " , " & #x000CC; " },
{ " igrave " , " & #x000EC; " },
{ " Iuml " , " & #x000CF; " },
{ " iuml " , " & #x000EF; " },
{ " Ntilde " , " & #x000D1; " },
{ " ntilde " , " & #x000F1; " },
{ " Oacute " , " & #x000D3; " },
{ " oacute " , " & #x000F3; " },
{ " Ocirc " , " & #x000D4; " },
{ " ocirc " , " & #x000F4; " },
{ " Ograve " , " & #x000D2; " },
{ " ograve " , " & #x000F2; " },
{ " Oslash " , " & #x000D8; " },
{ " oslash " , " & #x000F8; " },
{ " Otilde " , " & #x000D5; " },
{ " otilde " , " & #x000F5; " },
{ " Ouml " , " & #x000D6; " },
{ " ouml " , " & #x000F6; " },
{ " szlig " , " & #x000DF; " },
{ " THORN " , " & #x000DE; " },
{ " thorn " , " & #x000FE; " },
{ " Uacute " , " & #x000DA; " },
{ " uacute " , " & #x000FA; " },
{ " Ucirc " , " & #x000DB; " },
{ " ucirc " , " & #x000FB; " },
{ " Ugrave " , " & #x000D9; " },
{ " ugrave " , " & #x000F9; " },
{ " Uuml " , " & #x000DC; " },
{ " uuml " , " & #x000FC; " },
{ " Yacute " , " & #x000DD; " },
{ " yacute " , " & #x000FD; " },
{ " yuml " , " & #x000FF; " },
{ " Abreve " , " & #x00102; " },
{ " abreve " , " & #x00103; " },
{ " Amacr " , " & #x00100; " },
{ " amacr " , " & #x00101; " },
{ " Aogon " , " & #x00104; " },
{ " aogon " , " & #x00105; " },
{ " Cacute " , " & #x00106; " },
{ " cacute " , " & #x00107; " },
{ " Ccaron " , " & #x0010C; " },
{ " ccaron " , " & #x0010D; " },
{ " Ccirc " , " & #x00108; " },
{ " ccirc " , " & #x00109; " },
{ " Cdot " , " & #x0010A; " },
{ " cdot " , " & #x0010B; " },
{ " Dcaron " , " & #x0010E; " },
{ " dcaron " , " & #x0010F; " },
{ " Dstrok " , " & #x00110; " },
{ " dstrok " , " & #x00111; " },
{ " Ecaron " , " & #x0011A; " },
{ " ecaron " , " & #x0011B; " },
{ " Edot " , " & #x00116; " },
{ " edot " , " & #x00117; " },
{ " Emacr " , " & #x00112; " },
{ " emacr " , " & #x00113; " },
{ " ENG " , " & #x0014A; " },
{ " eng " , " & #x0014B; " },
{ " Eogon " , " & #x00118; " },
{ " eogon " , " & #x00119; " },
{ " gacute " , " & #x001F5; " },
{ " Gbreve " , " & #x0011E; " },
{ " gbreve " , " & #x0011F; " },
{ " Gcedil " , " & #x00122; " },
{ " Gcirc " , " & #x0011C; " },
{ " gcirc " , " & #x0011D; " },
{ " Gdot " , " & #x00120; " },
{ " gdot " , " & #x00121; " },
{ " Hcirc " , " & #x00124; " },
{ " hcirc " , " & #x00125; " },
{ " Hstrok " , " & #x00126; " },
{ " hstrok " , " & #x00127; " },
{ " Idot " , " & #x00130; " },
{ " IJlig " , " & #x00132; " },
{ " ijlig " , " & #x00133; " },
{ " Imacr " , " & #x0012A; " },
{ " imacr " , " & #x0012B; " },
{ " inodot " , " & #x00131; " },
{ " Iogon " , " & #x0012E; " },
{ " iogon " , " & #x0012F; " },
{ " Itilde " , " & #x00128; " },
{ " itilde " , " & #x00129; " },
{ " Jcirc " , " & #x00134; " },
{ " jcirc " , " & #x00135; " },
{ " Kcedil " , " & #x00136; " },
{ " kcedil " , " & #x00137; " },
{ " kgreen " , " & #x00138; " },
{ " Lacute " , " & #x00139; " },
{ " lacute " , " & #x0013A; " },
{ " Lcaron " , " & #x0013D; " },
{ " lcaron " , " & #x0013E; " },
{ " Lcedil " , " & #x0013B; " },
{ " lcedil " , " & #x0013C; " },
{ " Lmidot " , " & #x0013F; " },
{ " lmidot " , " & #x00140; " },
{ " Lstrok " , " & #x00141; " },
{ " lstrok " , " & #x00142; " },
{ " Nacute " , " & #x00143; " },
{ " nacute " , " & #x00144; " },
{ " napos " , " & #x00149; " },
{ " Ncaron " , " & #x00147; " },
{ " ncaron " , " & #x00148; " },
{ " Ncedil " , " & #x00145; " },
{ " ncedil " , " & #x00146; " },
{ " Odblac " , " & #x00150; " },
{ " odblac " , " & #x00151; " },
{ " OElig " , " & #x00152; " },
{ " oelig " , " & #x00153; " },
{ " Omacr " , " & #x0014C; " },
{ " omacr " , " & #x0014D; " },
{ " Racute " , " & #x00154; " },
{ " racute " , " & #x00155; " },
{ " Rcaron " , " & #x00158; " },
{ " rcaron " , " & #x00159; " },
{ " Rcedil " , " & #x00156; " },
{ " rcedil " , " & #x00157; " },
{ " Sacute " , " & #x0015A; " },
{ " sacute " , " & #x0015B; " },
{ " Scaron " , " & #x00160; " },
{ " scaron " , " & #x00161; " },
{ " Scedil " , " & #x0015E; " },
{ " scedil " , " & #x0015F; " },
{ " Scirc " , " & #x0015C; " },
{ " scirc " , " & #x0015D; " },
{ " Tcaron " , " & #x00164; " },
{ " tcaron " , " & #x00165; " },
{ " Tcedil " , " & #x00162; " },
{ " tcedil " , " & #x00163; " },
{ " Tstrok " , " & #x00166; " },
{ " tstrok " , " & #x00167; " },
{ " Ubreve " , " & #x0016C; " },
{ " ubreve " , " & #x0016D; " },
{ " Udblac " , " & #x00170; " },
{ " udblac " , " & #x00171; " },
{ " Umacr " , " & #x0016A; " },
{ " umacr " , " & #x0016B; " },
{ " Uogon " , " & #x00172; " },
{ " uogon " , " & #x00173; " },
{ " Uring " , " & #x0016E; " },
{ " uring " , " & #x0016F; " },
{ " Utilde " , " & #x00168; " },
{ " utilde " , " & #x00169; " },
{ " Wcirc " , " & #x00174; " },
{ " wcirc " , " & #x00175; " },
{ " Ycirc " , " & #x00176; " },
{ " ycirc " , " & #x00177; " },
{ " Yuml " , " & #x00178; " },
{ " Zacute " , " & #x00179; " },
{ " zacute " , " & #x0017A; " },
{ " Zcaron " , " & #x0017D; " },
{ " zcaron " , " & #x0017E; " },
{ " Zdot " , " & #x0017B; " },
{ " zdot " , " & #x0017C; " },
{ " apos " , " & #x00027; " },
{ " ast " , " & #x0002A; " },
{ " brvbar " , " & #x000A6; " },
{ " bsol " , " & #x0005C; " },
{ " cent " , " & #x000A2; " },
{ " colon " , " & #x0003A; " },
{ " comma " , " & #x0002C; " },
{ " commat " , " & #x00040; " },
{ " copy " , " & #x000A9; " },
{ " curren " , " & #x000A4; " },
{ " darr " , " & #x02193; " },
{ " deg " , " & #x000B0; " },
{ " divide " , " & #x000F7; " },
{ " dollar " , " & #x00024; " },
{ " equals " , " & #x0003D; " },
{ " excl " , " & #x00021; " },
{ " frac12 " , " & #x000BD; " },
{ " frac14 " , " & #x000BC; " },
{ " frac18 " , " & #x0215B; " },
{ " frac34 " , " & #x000BE; " },
{ " frac38 " , " & #x0215C; " },
{ " frac58 " , " & #x0215D; " },
{ " frac78 " , " & #x0215E; " },
{ " gt " , " & #x0003E; " },
{ " half " , " & #x000BD; " },
{ " horbar " , " & #x02015; " },
{ " hyphen " , " & #x02010; " },
{ " iexcl " , " & #x000A1; " },
{ " iquest " , " & #x000BF; " },
{ " laquo " , " & #x000AB; " },
{ " larr " , " & #x02190; " },
{ " lcub " , " & #x0007B; " },
{ " ldquo " , " & #x0201C; " },
{ " lowbar " , " & #x0005F; " },
{ " lpar " , " & #x00028; " },
{ " lsqb " , " & #x0005B; " },
{ " lsquo " , " & #x02018; " },
{ " lt " , " & #x0003C; " },
{ " micro " , " & #x000B5; " },
{ " middot " , " & #x000B7; " },
{ " nbsp " , " & #x000A0; " },
{ " not " , " & #x000AC; " },
{ " num " , " & #x00023; " },
{ " ohm " , " & #x02126; " },
{ " ordf " , " & #x000AA; " },
{ " ordm " , " & #x000BA; " },
{ " para " , " & #x000B6; " },
{ " percnt " , " & #x00025; " },
{ " period " , " & #x0002E; " },
{ " plus " , " & #x0002B; " },
{ " plusmn " , " & #x000B1; " },
{ " pound " , " & #x000A3; " },
{ " quest " , " & #x0003F; " },
{ " quot " , " & #x00022; " },
{ " raquo " , " & #x000BB; " },
{ " rarr " , " & #x02192; " },
{ " rcub " , " & #x0007D; " },
{ " rdquo " , " & #x0201D; " },
{ " reg " , " & #x000AE; " },
{ " rpar " , " & #x00029; " },
{ " rsqb " , " & #x0005D; " },
{ " rsquo " , " & #x02019; " },
{ " sect " , " & #x000A7; " },
{ " semi " , " & #x0003B; " },
{ " shy " , " & #x000AD; " },
{ " sol " , " & #x0002F; " },
{ " sung " , " & #x0266A; " },
{ " sup1 " , " & #x000B9; " },
{ " sup2 " , " & #x000B2; " },
{ " sup3 " , " & #x000B3; " },
{ " times " , " & #x000D7; " },
{ " trade " , " & #x02122; " },
{ " uarr " , " & #x02191; " },
{ " verbar " , " & #x0007C; " },
{ " yen " , " & #x000A5; " },
{ " blank " , " & #x02423; " },
{ " blk12 " , " & #x02592; " },
{ " blk14 " , " & #x02591; " },
{ " blk34 " , " & #x02593; " },
{ " block " , " & #x02588; " },
{ " bull " , " & #x02022; " },
{ " caret " , " & #x02041; " },
{ " check " , " & #x02713; " },
{ " cir " , " & #x025CB; " },
{ " clubs " , " & #x02663; " },
{ " copysr " , " & #x02117; " },
{ " cross " , " & #x02717; " },
{ " Dagger " , " & #x02021; " },
{ " dagger " , " & #x02020; " },
{ " dash " , " & #x02010; " },
{ " diams " , " & #x02666; " },
{ " dlcrop " , " & #x0230D; " },
{ " drcrop " , " & #x0230C; " },
{ " dtri " , " & #x025BF; " },
{ " dtrif " , " & #x025BE; " },
{ " emsp " , " & #x02003; " },
{ " emsp13 " , " & #x02004; " },
{ " emsp14 " , " & #x02005; " },
{ " ensp " , " & #x02002; " },
{ " female " , " & #x02640; " },
{ " ffilig " , " & #x0FB03; " },
{ " fflig " , " & #x0FB00; " },
{ " ffllig " , " & #x0FB04; " },
{ " filig " , " & #x0FB01; " },
{ " flat " , " & #x0266D; " },
{ " fllig " , " & #x0FB02; " },
{ " frac13 " , " & #x02153; " },
{ " frac15 " , " & #x02155; " },
{ " frac16 " , " & #x02159; " },
{ " frac23 " , " & #x02154; " },
{ " frac25 " , " & #x02156; " },
{ " frac35 " , " & #x02157; " },
{ " frac45 " , " & #x02158; " },
{ " frac56 " , " & #x0215A; " },
{ " hairsp " , " & #x0200A; " },
{ " hearts " , " & #x02665; " },
{ " hellip " , " & #x02026; " },
{ " hybull " , " & #x02043; " },
{ " incare " , " & #x02105; " },
{ " ldquor " , " & #x0201E; " },
{ " lhblk " , " & #x02584; " },
{ " loz " , " & #x025CA; " },
{ " lozf " , " & #x029EB; " },
{ " lsquor " , " & #x0201A; " },
{ " ltri " , " & #x025C3; " },
{ " ltrif " , " & #x025C2; " },
{ " male " , " & #x02642; " },
{ " malt " , " & #x02720; " },
{ " marker " , " & #x025AE; " },
{ " mdash " , " & #x02014; " },
{ " mldr " , " & #x02026; " },
{ " natur " , " & #x0266E; " },
{ " ndash " , " & #x02013; " },
{ " nldr " , " & #x02025; " },
{ " numsp " , " & #x02007; " },
{ " phone " , " & #x0260E; " },
{ " puncsp " , " & #x02008; " },
{ " rdquor " , " & #x0201D; " },
{ " rect " , " & #x025AD; " },
{ " rsquor " , " & #x02019; " },
{ " rtri " , " & #x025B9; " },
{ " rtrif " , " & #x025B8; " },
{ " rx " , " & #x0211E; " },
{ " sext " , " & #x02736; " },
{ " sharp " , " & #x0266F; " },
{ " spades " , " & #x02660; " },
{ " squ " , " & #x025A1; " },
{ " squf " , " & #x025AA; " },
{ " star " , " & #x02606; " },
{ " starf " , " & #x02605; " },
{ " target " , " & #x02316; " },
{ " telrec " , " & #x02315; " },
{ " thinsp " , " & #x02009; " },
{ " uhblk " , " & #x02580; " },
{ " ulcrop " , " & #x0230F; " },
{ " urcrop " , " & #x0230E; " },
{ " utri " , " & #x025B5; " },
{ " utrif " , " & #x025B4; " },
{ " vellip " , " & #x022EE; " },
{ " af " , " & #x02061; " },
{ " asympeq " , " & #x0224D; " },
{ " Cross " , " & #x02A2F; " },
{ " DD " , " & #x02145; " },
{ " dd " , " & #x02146; " },
{ " DownArrowBar " , " & #x02913; " },
{ " DownBreve " , " & #x00311; " },
{ " DownLeftRightVector " , " & #x02950; " },
{ " DownLeftTeeVector " , " & #x0295E; " },
{ " DownLeftVectorBar " , " & #x02956; " },
{ " DownRightTeeVector " , " & #x0295F; " },
{ " DownRightVectorBar " , " & #x02957; " },
{ " ee " , " & #x02147; " },
{ " EmptySmallSquare " , " & #x025FB; " },
{ " EmptyVerySmallSquare " , " & #x025AB; " },
{ " Equal " , " & #x02A75; " },
{ " FilledSmallSquare " , " & #x025FC; " },
{ " FilledVerySmallSquare " , " & #x025AA; " },
{ " GreaterGreater " , " & #x02AA2; " },
{ " Hat " , " & #x0005E; " },
{ " HorizontalLine " , " & #x02500; " },
{ " ic " , " & #x02063; " },
{ " ii " , " & #x02148; " },
{ " it " , " & #x02062; " },
{ " larrb " , " & #x021E4; " },
{ " LeftDownTeeVector " , " & #x02961; " },
{ " LeftDownVectorBar " , " & #x02959; " },
{ " LeftRightVector " , " & #x0294E; " },
{ " LeftTeeVector " , " & #x0295A; " },
{ " LeftTriangleBar " , " & #x029CF; " },
{ " LeftUpDownVector " , " & #x02951; " },
{ " LeftUpTeeVector " , " & #x02960; " },
{ " LeftUpVectorBar " , " & #x02958; " },
{ " LeftVectorBar " , " & #x02952; " },
{ " LessLess " , " & #x02AA1; " },
{ " mapstodown " , " & #x021A7; " },
{ " mapstoleft " , " & #x021A4; " },
{ " mapstoup " , " & #x021A5; " },
{ " MediumSpace " , " & #x0205F; " },
{ " nbump " , " & #x0224E; & #x00338; " },
{ " nbumpe " , " & #x0224F; & #x00338; " },
{ " nesim " , " & #x02242; & #x00338; " },
{ " NewLine " , " & #x0000A; " },
{ " NoBreak " , " & #x02060; " },
{ " NotCupCap " , " & #x0226D; " },
{ " NotHumpEqual " , " & #x0224F; & #x00338; " },
{ " NotLeftTriangleBar " , " & #x029CF; & #x00338; " },
{ " NotNestedGreaterGreater " , " & #x02AA2; & #x00338; " },
{ " NotNestedLessLess " , " & #x02AA1; & #x00338; " },
{ " NotRightTriangleBar " , " & #x029D0; & #x00338; " },
{ " NotSquareSubset " , " & #x0228F; & #x00338; " },
{ " NotSquareSuperset " , " & #x02290; & #x00338; " },
{ " NotSucceedsTilde " , " & #x0227F; & #x00338; " },
{ " OverBar " , " & #x000AF; " },
{ " OverBrace " , " & #x0FE37; " },
{ " OverBracket " , " & #x023B4; " },
{ " OverParenthesis " , " & #x0FE35; " },
{ " planckh " , " & #x0210E; " },
{ " Product " , " & #x0220F; " },
{ " rarrb " , " & #x021E5; " },
{ " RightDownTeeVector " , " & #x0295D; " },
{ " RightDownVectorBar " , " & #x02955; " },
{ " RightTeeVector " , " & #x0295B; " },
{ " RightTriangleBar " , " & #x029D0; " },
{ " RightUpDownVector " , " & #x0294F; " },
{ " RightUpTeeVector " , " & #x0295C; " },
{ " RightUpVectorBar " , " & #x02954; " },
{ " RightVectorBar " , " & #x02953; " },
{ " RoundImplies " , " & #x02970; " },
{ " RuleDelayed " , " & #x029F4; " },
{ " Tab " , " & #x00009; " },
{ " ThickSpace " , " & #x02009; & #x0200A; & #x0200A; " },
{ " UnderBar " , " & #x00332; " },
{ " UnderBrace " , " & #x0FE38; " },
{ " UnderBracket " , " & #x023B5; " },
{ " UnderParenthesis " , " & #x0FE36; " },
{ " UpArrowBar " , " & #x02912; " },
{ " Upsilon " , " & #x003A5; " },
{ " VerticalLine " , " & #x0007C; " },
{ " VerticalSeparator " , " & #x02758; " },
{ " ZeroWidthSpace " , " & #x0200B; " },
{ " angle " , " & #x02220; " },
{ " ApplyFunction " , " & #x02061; " },
{ " approx " , " & #x02248; " },
{ " approxeq " , " & #x0224A; " },
{ " Assign " , " & #x02254; " },
{ " backcong " , " & #x0224C; " },
{ " backepsilon " , " & #x003F6; " },
{ " backprime " , " & #x02035; " },
{ " backsim " , " & #x0223D; " },
{ " backsimeq " , " & #x022CD; " },
{ " Backslash " , " & #x02216; " },
{ " barwedge " , " & #x02305; " },
{ " Because " , " & #x02235; " },
{ " because " , " & #x02235; " },
{ " Bernoullis " , " & #x0212C; " },
{ " between " , " & #x0226C; " },
{ " bigcap " , " & #x022C2; " },
{ " bigcirc " , " & #x025EF; " },
{ " bigcup " , " & #x022C3; " },
{ " bigodot " , " & #x02A00; " },
{ " bigoplus " , " & #x02A01; " },
{ " bigotimes " , " & #x02A02; " },
{ " bigsqcup " , " & #x02A06; " },
{ " bigstar " , " & #x02605; " },
{ " bigtriangledown " , " & #x025BD; " },
{ " bigtriangleup " , " & #x025B3; " },
{ " biguplus " , " & #x02A04; " },
{ " bigvee " , " & #x022C1; " },
{ " bigwedge " , " & #x022C0; " },
{ " bkarow " , " & #x0290D; " },
{ " blacklozenge " , " & #x029EB; " },
{ " blacksquare " , " & #x025AA; " },
{ " blacktriangle " , " & #x025B4; " },
{ " blacktriangledown " , " & #x025BE; " },
{ " blacktriangleleft " , " & #x025C2; " },
{ " blacktriangleright " , " & #x025B8; " },
{ " bot " , " & #x022A5; " },
{ " boxminus " , " & #x0229F; " },
{ " boxplus " , " & #x0229E; " },
{ " boxtimes " , " & #x022A0; " },
{ " Breve " , " & #x002D8; " },
{ " bullet " , " & #x02022; " },
{ " Bumpeq " , " & #x0224E; " },
{ " bumpeq " , " & #x0224F; " },
{ " CapitalDifferentialD " , " & #x02145; " },
{ " Cayleys " , " & #x0212D; " },
{ " Cedilla " , " & #x000B8; " },
{ " CenterDot " , " & #x000B7; " },
{ " centerdot " , " & #x000B7; " },
{ " checkmark " , " & #x02713; " },
{ " circeq " , " & #x02257; " },
{ " circlearrowleft " , " & #x021BA; " },
{ " circlearrowright " , " & #x021BB; " },
{ " circledast " , " & #x0229B; " },
{ " circledcirc " , " & #x0229A; " },
{ " circleddash " , " & #x0229D; " },
{ " CircleDot " , " & #x02299; " },
{ " circledR " , " & #x000AE; " },
{ " circledS " , " & #x024C8; " },
{ " CircleMinus " , " & #x02296; " },
{ " CirclePlus " , " & #x02295; " },
{ " CircleTimes " , " & #x02297; " },
{ " ClockwiseContourIntegral " , " & #x02232; " },
{ " CloseCurlyDoubleQuote " , " & #x0201D; " },
{ " CloseCurlyQuote " , " & #x02019; " },
{ " clubsuit " , " & #x02663; " },
{ " coloneq " , " & #x02254; " },
{ " complement " , " & #x02201; " },
{ " complexes " , " & #x02102; " },
{ " Congruent " , " & #x02261; " },
{ " ContourIntegral " , " & #x0222E; " },
{ " Coproduct " , " & #x02210; " },
{ " CounterClockwiseContourIntegral " , " & #x02233; " },
{ " CupCap " , " & #x0224D; " },
{ " curlyeqprec " , " & #x022DE; " },
{ " curlyeqsucc " , " & #x022DF; " },
{ " curlyvee " , " & #x022CE; " },
{ " curlywedge " , " & #x022CF; " },
{ " curvearrowleft " , " & #x021B6; " },
{ " curvearrowright " , " & #x021B7; " },
{ " dbkarow " , " & #x0290F; " },
{ " ddagger " , " & #x02021; " },
{ " ddotseq " , " & #x02A77; " },
{ " Del " , " & #x02207; " },
{ " DiacriticalAcute " , " & #x000B4; " },
{ " DiacriticalDot " , " & #x002D9; " },
{ " DiacriticalDoubleAcute " , " & #x002DD; " },
{ " DiacriticalGrave " , " & #x00060; " },
{ " DiacriticalTilde " , " & #x002DC; " },
{ " Diamond " , " & #x022C4; " },
{ " diamond " , " & #x022C4; " },
{ " diamondsuit " , " & #x02666; " },
{ " DifferentialD " , " & #x02146; " },
{ " digamma " , " & #x003DD; " },
{ " div " , " & #x000F7; " },
{ " divideontimes " , " & #x022C7; " },
{ " doteq " , " & #x02250; " },
{ " doteqdot " , " & #x02251; " },
{ " DotEqual " , " & #x02250; " },
{ " dotminus " , " & #x02238; " },
{ " dotplus " , " & #x02214; " },
{ " dotsquare " , " & #x022A1; " },
{ " doublebarwedge " , " & #x02306; " },
{ " DoubleContourIntegral " , " & #x0222F; " },
{ " DoubleDot " , " & #x000A8; " },
{ " DoubleDownArrow " , " & #x021D3; " },
{ " DoubleLeftArrow " , " & #x021D0; " },
{ " DoubleLeftRightArrow " , " & #x021D4; " },
{ " DoubleLeftTee " , " & #x02AE4; " },
{ " DoubleLongLeftArrow " , " & #x027F8; " },
{ " DoubleLongLeftRightArrow " , " & #x027FA; " },
{ " DoubleLongRightArrow " , " & #x027F9; " },
{ " DoubleRightArrow " , " & #x021D2; " },
{ " DoubleRightTee " , " & #x022A8; " },
{ " DoubleUpArrow " , " & #x021D1; " },
{ " DoubleUpDownArrow " , " & #x021D5; " },
{ " DoubleVerticalBar " , " & #x02225; " },
{ " DownArrow " , " & #x02193; " },
{ " Downarrow " , " & #x021D3; " },
{ " downarrow " , " & #x02193; " },
{ " DownArrowUpArrow " , " & #x021F5; " },
{ " downdownarrows " , " & #x021CA; " },
{ " downharpoonleft " , " & #x021C3; " },
{ " downharpoonright " , " & #x021C2; " },
{ " DownLeftVector " , " & #x021BD; " },
{ " DownRightVector " , " & #x021C1; " },
{ " DownTee " , " & #x022A4; " },
{ " DownTeeArrow " , " & #x021A7; " },
{ " drbkarow " , " & #x02910; " },
{ " Element " , " & #x02208; " },
{ " emptyset " , " & #x02205; " },
{ " eqcirc " , " & #x02256; " },
{ " eqcolon " , " & #x02255; " },
{ " eqsim " , " & #x02242; " },
{ " eqslantgtr " , " & #x02A96; " },
{ " eqslantless " , " & #x02A95; " },
{ " EqualTilde " , " & #x02242; " },
{ " Equilibrium " , " & #x021CC; " },
{ " Exists " , " & #x02203; " },
{ " expectation " , " & #x02130; " },
{ " ExponentialE " , " & #x02147; " },
{ " exponentiale " , " & #x02147; " },
{ " fallingdotseq " , " & #x02252; " },
{ " ForAll " , " & #x02200; " },
{ " Fouriertrf " , " & #x02131; " },
{ " geq " , " & #x02265; " },
{ " geqq " , " & #x02267; " },
{ " geqslant " , " & #x02A7E; " },
{ " gg " , " & #x0226B; " },
{ " ggg " , " & #x022D9; " },
{ " gnapprox " , " & #x02A8A; " },
{ " gneq " , " & #x02A88; " },
{ " gneqq " , " & #x02269; " },
{ " GreaterEqual " , " & #x02265; " },
{ " GreaterEqualLess " , " & #x022DB; " },
{ " GreaterFullEqual " , " & #x02267; " },
{ " GreaterLess " , " & #x02277; " },
{ " GreaterSlantEqual " , " & #x02A7E; " },
{ " GreaterTilde " , " & #x02273; " },
{ " gtrapprox " , " & #x02A86; " },
{ " gtrdot " , " & #x022D7; " },
{ " gtreqless " , " & #x022DB; " },
{ " gtreqqless " , " & #x02A8C; " },
{ " gtrless " , " & #x02277; " },
{ " gtrsim " , " & #x02273; " },
{ " gvertneqq " , " & #x02269; & #x0FE00; " },
{ " Hacek " , " & #x002C7; " },
{ " hbar " , " & #x0210F; " },
{ " heartsuit " , " & #x02665; " },
{ " HilbertSpace " , " & #x0210B; " },
{ " hksearow " , " & #x02925; " },
{ " hkswarow " , " & #x02926; " },
{ " hookleftarrow " , " & #x021A9; " },
{ " hookrightarrow " , " & #x021AA; " },
{ " hslash " , " & #x0210F; " },
{ " HumpDownHump " , " & #x0224E; " },
{ " HumpEqual " , " & #x0224F; " },
{ " iiiint " , " & #x02A0C; " },
{ " iiint " , " & #x0222D; " },
{ " Im " , " & #x02111; " },
{ " ImaginaryI " , " & #x02148; " },
{ " imagline " , " & #x02110; " },
{ " imagpart " , " & #x02111; " },
{ " Implies " , " & #x021D2; " },
{ " in " , " & #x02208; " },
{ " integers " , " & #x02124; " },
{ " Integral " , " & #x0222B; " },
{ " intercal " , " & #x022BA; " },
{ " Intersection " , " & #x022C2; " },
{ " intprod " , " & #x02A3C; " },
{ " InvisibleComma " , " & #x02063; " },
{ " InvisibleTimes " , " & #x02062; " },
{ " langle " , " & #x02329; " },
{ " Laplacetrf " , " & #x02112; " },
{ " lbrace " , " & #x0007B; " },
{ " lbrack " , " & #x0005B; " },
{ " LeftAngleBracket " , " & #x02329; " },
{ " LeftArrow " , " & #x02190; " },
{ " Leftarrow " , " & #x021D0; " },
{ " leftarrow " , " & #x02190; " },
{ " LeftArrowBar " , " & #x021E4; " },
{ " LeftArrowRightArrow " , " & #x021C6; " },
{ " leftarrowtail " , " & #x021A2; " },
{ " LeftCeiling " , " & #x02308; " },
{ " LeftDoubleBracket " , " & #x0301A; " },
{ " LeftDownVector " , " & #x021C3; " },
{ " LeftFloor " , " & #x0230A; " },
{ " leftharpoondown " , " & #x021BD; " },
{ " leftharpoonup " , " & #x021BC; " },
{ " leftleftarrows " , " & #x021C7; " },
{ " LeftRightArrow " , " & #x02194; " },
{ " Leftrightarrow " , " & #x021D4; " },
{ " leftrightarrow " , " & #x02194; " },
{ " leftrightarrows " , " & #x021C6; " },
{ " leftrightharpoons " , " & #x021CB; " },
{ " leftrightsquigarrow " , " & #x021AD; " },
{ " LeftTee " , " & #x022A3; " },
{ " LeftTeeArrow " , " & #x021A4; " },
{ " leftthreetimes " , " & #x022CB; " },
{ " LeftTriangle " , " & #x022B2; " },
{ " LeftTriangleEqual " , " & #x022B4; " },
{ " LeftUpVector " , " & #x021BF; " },
{ " LeftVector " , " & #x021BC; " },
{ " leq " , " & #x02264; " },
{ " leqq " , " & #x02266; " },
{ " leqslant " , " & #x02A7D; " },
{ " lessapprox " , " & #x02A85; " },
{ " lessdot " , " & #x022D6; " },
{ " lesseqgtr " , " & #x022DA; " },
{ " lesseqqgtr " , " & #x02A8B; " },
{ " LessEqualGreater " , " & #x022DA; " },
{ " LessFullEqual " , " & #x02266; " },
{ " LessGreater " , " & #x02276; " },
{ " lessgtr " , " & #x02276; " },
{ " lesssim " , " & #x02272; " },
{ " LessSlantEqual " , " & #x02A7D; " },
{ " LessTilde " , " & #x02272; " },
{ " ll " , " & #x0226A; " },
{ " llcorner " , " & #x0231E; " },
{ " Lleftarrow " , " & #x021DA; " },
{ " lmoustache " , " & #x023B0; " },
{ " lnapprox " , " & #x02A89; " },
{ " lneq " , " & #x02A87; " },
{ " lneqq " , " & #x02268; " },
{ " LongLeftArrow " , " & #x027F5; " },
{ " Longleftarrow " , " & #x027F8; " },
{ " longleftarrow " , " & #x027F5; " },
{ " LongLeftRightArrow " , " & #x027F7; " },
{ " Longleftrightarrow " , " & #x027FA; " },
{ " longleftrightarrow " , " & #x027F7; " },
{ " longmapsto " , " & #x027FC; " },
{ " LongRightArrow " , " & #x027F6; " },
{ " Longrightarrow " , " & #x027F9; " },
{ " longrightarrow " , " & #x027F6; " },
{ " looparrowleft " , " & #x021AB; " },
{ " looparrowright " , " & #x021AC; " },
{ " LowerLeftArrow " , " & #x02199; " },
{ " LowerRightArrow " , " & #x02198; " },
{ " lozenge " , " & #x025CA; " },
{ " lrcorner " , " & #x0231F; " },
{ " Lsh " , " & #x021B0; " },
{ " lvertneqq " , " & #x02268; & #x0FE00; " },
{ " maltese " , " & #x02720; " },
{ " mapsto " , " & #x021A6; " },
{ " measuredangle " , " & #x02221; " },
{ " Mellintrf " , " & #x02133; " },
{ " MinusPlus " , " & #x02213; " },
{ " mp " , " & #x02213; " },
{ " multimap " , " & #x022B8; " },
{ " napprox " , " & #x02249; " },
{ " natural " , " & #x0266E; " },
{ " naturals " , " & #x02115; " },
{ " nearrow " , " & #x02197; " },
{ " NegativeMediumSpace " , " & #x0200B; " },
{ " NegativeThickSpace " , " & #x0200B; " },
{ " NegativeThinSpace " , " & #x0200B; " },
{ " NegativeVeryThinSpace " , " & #x0200B; " },
{ " NestedGreaterGreater " , " & #x0226B; " },
{ " NestedLessLess " , " & #x0226A; " },
{ " nexists " , " & #x02204; " },
{ " ngeq " , " & #x02271; " },
{ " ngeqq " , " & #x02267; & #x00338; " },
{ " ngeqslant " , " & #x02A7E; & #x00338; " },
{ " ngtr " , " & #x0226F; " },
{ " nLeftarrow " , " & #x021CD; " },
{ " nleftarrow " , " & #x0219A; " },
{ " nLeftrightarrow " , " & #x021CE; " },
{ " nleftrightarrow " , " & #x021AE; " },
{ " nleq " , " & #x02270; " },
{ " nleqq " , " & #x02266; & #x00338; " },
{ " nleqslant " , " & #x02A7D; & #x00338; " },
{ " nless " , " & #x0226E; " },
{ " NonBreakingSpace " , " & #x000A0; " },
{ " NotCongruent " , " & #x02262; " },
{ " NotDoubleVerticalBar " , " & #x02226; " },
{ " NotElement " , " & #x02209; " },
{ " NotEqual " , " & #x02260; " },
{ " NotEqualTilde " , " & #x02242; & #x00338; " },
{ " NotExists " , " & #x02204; " },
{ " NotGreater " , " & #x0226F; " },
{ " NotGreaterEqual " , " & #x02271; " },
{ " NotGreaterFullEqual " , " & #x02266; & #x00338; " },
{ " NotGreaterGreater " , " & #x0226B; & #x00338; " },
{ " NotGreaterLess " , " & #x02279; " },
{ " NotGreaterSlantEqual " , " & #x02A7E; & #x00338; " },
{ " NotGreaterTilde " , " & #x02275; " },
{ " NotHumpDownHump " , " & #x0224E; & #x00338; " },
{ " NotLeftTriangle " , " & #x022EA; " },
{ " NotLeftTriangleEqual " , " & #x022EC; " },
{ " NotLess " , " & #x0226E; " },
{ " NotLessEqual " , " & #x02270; " },
{ " NotLessGreater " , " & #x02278; " },
{ " NotLessLess " , " & #x0226A; & #x00338; " },
{ " NotLessSlantEqual " , " & #x02A7D; & #x00338; " },
{ " NotLessTilde " , " & #x02274; " },
{ " NotPrecedes " , " & #x02280; " },
{ " NotPrecedesEqual " , " & #x02AAF; & #x00338; " },
{ " NotPrecedesSlantEqual " , " & #x022E0; " },
{ " NotReverseElement " , " & #x0220C; " },
{ " NotRightTriangle " , " & #x022EB; " },
{ " NotRightTriangleEqual " , " & #x022ED; " },
{ " NotSquareSubsetEqual " , " & #x022E2; " },
{ " NotSquareSupersetEqual " , " & #x022E3; " },
{ " NotSubset " , " & #x02282; & #x020D2; " },
{ " NotSubsetEqual " , " & #x02288; " },
{ " NotSucceeds " , " & #x02281; " },
{ " NotSucceedsEqual " , " & #x02AB0; & #x00338; " },
{ " NotSucceedsSlantEqual " , " & #x022E1; " },
{ " NotSuperset " , " & #x02283; & #x020D2; " },
{ " NotSupersetEqual " , " & #x02289; " },
{ " NotTilde " , " & #x02241; " },
{ " NotTildeEqual " , " & #x02244; " },
{ " NotTildeFullEqual " , " & #x02247; " },
{ " NotTildeTilde " , " & #x02249; " },
{ " NotVerticalBar " , " & #x02224; " },
{ " nparallel " , " & #x02226; " },
{ " nprec " , " & #x02280; " },
{ " npreceq " , " & #x02AAF; & #x00338; " },
{ " nRightarrow " , " & #x021CF; " },
{ " nrightarrow " , " & #x0219B; " },
{ " nshortmid " , " & #x02224; " },
{ " nshortparallel " , " & #x02226; " },
{ " nsimeq " , " & #x02244; " },
{ " nsubset " , " & #x02282; & #x020D2; " },
{ " nsubseteq " , " & #x02288; " },
{ " nsubseteqq " , " & #x02AC5; & #x0338; " },
{ " nsucc " , " & #x02281; " },
{ " nsucceq " , " & #x02AB0; & #x00338; " },
{ " nsupset " , " & #x02283; & #x020D2; " },
{ " nsupseteq " , " & #x02289; " },
{ " nsupseteqq " , " & #x02AC6; & #x0338; " },
{ " ntriangleleft " , " & #x022EA; " },
{ " ntrianglelefteq " , " & #x022EC; " },
{ " ntriangleright " , " & #x022EB; " },
{ " ntrianglerighteq " , " & #x022ED; " },
{ " nwarrow " , " & #x02196; " },
{ " oint " , " & #x0222E; " },
{ " OpenCurlyDoubleQuote " , " & #x0201C; " },
{ " OpenCurlyQuote " , " & #x02018; " },
{ " orderof " , " & #x02134; " },
{ " parallel " , " & #x02225; " },
{ " PartialD " , " & #x02202; " },
{ " pitchfork " , " & #x022D4; " },
{ " PlusMinus " , " & #x000B1; " },
{ " pm " , " & #x000B1; " },
{ " Poincareplane " , " & #x0210C; " },
{ " prec " , " & #x0227A; " },
{ " precapprox " , " & #x02AB7; " },
{ " preccurlyeq " , " & #x0227C; " },
{ " Precedes " , " & #x0227A; " },
{ " PrecedesEqual " , " & #x02AAF; " },
{ " PrecedesSlantEqual " , " & #x0227C; " },
{ " PrecedesTilde " , " & #x0227E; " },
{ " preceq " , " & #x02AAF; " },
{ " precnapprox " , " & #x02AB9; " },
{ " precneqq " , " & #x02AB5; " },
{ " precnsim " , " & #x022E8; " },
{ " precsim " , " & #x0227E; " },
{ " primes " , " & #x02119; " },
{ " Proportion " , " & #x02237; " },
{ " Proportional " , " & #x0221D; " },
{ " propto " , " & #x0221D; " },
{ " quaternions " , " & #x0210D; " },
{ " questeq " , " & #x0225F; " },
{ " rangle " , " & #x0232A; " },
{ " rationals " , " & #x0211A; " },
{ " rbrace " , " & #x0007D; " },
{ " rbrack " , " & #x0005D; " },
{ " Re " , " & #x0211C; " },
{ " realine " , " & #x0211B; " },
{ " realpart " , " & #x0211C; " },
{ " reals " , " & #x0211D; " },
{ " ReverseElement " , " & #x0220B; " },
{ " ReverseEquilibrium " , " & #x021CB; " },
{ " ReverseUpEquilibrium " , " & #x0296F; " },
{ " RightAngleBracket " , " & #x0232A; " },
{ " RightArrow " , " & #x02192; " },
{ " Rightarrow " , " & #x021D2; " },
{ " rightarrow " , " & #x02192; " },
{ " RightArrowBar " , " & #x021E5; " },
{ " RightArrowLeftArrow " , " & #x021C4; " },
{ " rightarrowtail " , " & #x021A3; " },
{ " RightCeiling " , " & #x02309; " },
{ " RightDoubleBracket " , " & #x0301B; " },
{ " RightDownVector " , " & #x021C2; " },
{ " RightFloor " , " & #x0230B; " },
{ " rightharpoondown " , " & #x021C1; " },
{ " rightharpoonup " , " & #x021C0; " },
{ " rightleftarrows " , " & #x021C4; " },
{ " rightleftharpoons " , " & #x021CC; " },
{ " rightrightarrows " , " & #x021C9; " },
{ " rightsquigarrow " , " & #x0219D; " },
{ " RightTee " , " & #x022A2; " },
{ " RightTeeArrow " , " & #x021A6; " },
{ " rightthreetimes " , " & #x022CC; " },
{ " RightTriangle " , " & #x022B3; " },
{ " RightTriangleEqual " , " & #x022B5; " },
{ " RightUpVector " , " & #x021BE; " },
{ " RightVector " , " & #x021C0; " },
{ " risingdotseq " , " & #x02253; " },
{ " rmoustache " , " & #x023B1; " },
{ " Rrightarrow " , " & #x021DB; " },
{ " Rsh " , " & #x021B1; " },
{ " searrow " , " & #x02198; " },
{ " setminus " , " & #x02216; " },
{ " ShortDownArrow " , " & #x02193; " },
{ " ShortLeftArrow " , " & #x02190; " },
{ " shortmid " , " & #x02223; " },
{ " shortparallel " , " & #x02225; " },
{ " ShortRightArrow " , " & #x02192; " },
{ " ShortUpArrow " , " & #x02191; " },
{ " simeq " , " & #x02243; " },
{ " SmallCircle " , " & #x02218; " },
{ " smallsetminus " , " & #x02216; " },
{ " spadesuit " , " & #x02660; " },
{ " Sqrt " , " & #x0221A; " },
{ " sqsubset " , " & #x0228F; " },
{ " sqsubseteq " , " & #x02291; " },
{ " sqsupset " , " & #x02290; " },
{ " sqsupseteq " , " & #x02292; " },
{ " Square " , " & #x025A1; " },
{ " SquareIntersection " , " & #x02293; " },
{ " SquareSubset " , " & #x0228F; " },
{ " SquareSubsetEqual " , " & #x02291; " },
{ " SquareSuperset " , " & #x02290; " },
{ " SquareSupersetEqual " , " & #x02292; " },
{ " SquareUnion " , " & #x02294; " },
{ " Star " , " & #x022C6; " },
{ " straightepsilon " , " & #x003B5; " },
{ " straightphi " , " & #x003D5; " },
{ " Subset " , " & #x022D0; " },
{ " subset " , " & #x02282; " },
{ " subseteq " , " & #x02286; " },
{ " subseteqq " , " & #x02AC5; " },
{ " SubsetEqual " , " & #x02286; " },
{ " subsetneq " , " & #x0228A; " },
{ " subsetneqq " , " & #x02ACB; " },
{ " succ " , " & #x0227B; " },
{ " succapprox " , " & #x02AB8; " },
{ " succcurlyeq " , " & #x0227D; " },
{ " Succeeds " , " & #x0227B; " },
{ " SucceedsEqual " , " & #x02AB0; " },
{ " SucceedsSlantEqual " , " & #x0227D; " },
{ " SucceedsTilde " , " & #x0227F; " },
{ " succeq " , " & #x02AB0; " },
{ " succnapprox " , " & #x02ABA; " },
{ " succneqq " , " & #x02AB6; " },
{ " succnsim " , " & #x022E9; " },
{ " succsim " , " & #x0227F; " },
{ " SuchThat " , " & #x0220B; " },
{ " Sum " , " & #x02211; " },
{ " Superset " , " & #x02283; " },
{ " SupersetEqual " , " & #x02287; " },
{ " Supset " , " & #x022D1; " },
{ " supset " , " & #x02283; " },
{ " supseteq " , " & #x02287; " },
{ " supseteqq " , " & #x02AC6; " },
{ " supsetneq " , " & #x0228B; " },
{ " supsetneqq " , " & #x02ACC; " },
{ " swarrow " , " & #x02199; " },
{ " Therefore " , " & #x02234; " },
{ " therefore " , " & #x02234; " },
{ " thickapprox " , " & #x02248; " },
{ " thicksim " , " & #x0223C; " },
{ " ThinSpace " , " & #x02009; " },
{ " Tilde " , " & #x0223C; " },
{ " TildeEqual " , " & #x02243; " },
{ " TildeFullEqual " , " & #x02245; " },
{ " TildeTilde " , " & #x02248; " },
{ " toea " , " & #x02928; " },
{ " tosa " , " & #x02929; " },
{ " triangle " , " & #x025B5; " },
{ " triangledown " , " & #x025BF; " },
{ " triangleleft " , " & #x025C3; " },
{ " trianglelefteq " , " & #x022B4; " },
{ " triangleq " , " & #x0225C; " },
{ " triangleright " , " & #x025B9; " },
{ " trianglerighteq " , " & #x022B5; " },
{ " TripleDot " , " & #x020DB; " },
{ " twoheadleftarrow " , " & #x0219E; " },
{ " twoheadrightarrow " , " & #x021A0; " },
{ " ulcorner " , " & #x0231C; " },
{ " Union " , " & #x022C3; " },
{ " UnionPlus " , " & #x0228E; " },
{ " UpArrow " , " & #x02191; " },
{ " Uparrow " , " & #x021D1; " },
{ " uparrow " , " & #x02191; " },
{ " UpArrowDownArrow " , " & #x021C5; " },
{ " UpDownArrow " , " & #x02195; " },
{ " Updownarrow " , " & #x021D5; " },
{ " updownarrow " , " & #x02195; " },
{ " UpEquilibrium " , " & #x0296E; " },
{ " upharpoonleft " , " & #x021BF; " },
{ " upharpoonright " , " & #x021BE; " },
{ " UpperLeftArrow " , " & #x02196; " },
{ " UpperRightArrow " , " & #x02197; " },
{ " upsilon " , " & #x003C5; " },
{ " UpTee " , " & #x022A5; " },
{ " UpTeeArrow " , " & #x021A5; " },
{ " upuparrows " , " & #x021C8; " },
{ " urcorner " , " & #x0231D; " },
{ " varepsilon " , " & #x0025B; " },
{ " varkappa " , " & #x003F0; " },
{ " varnothing " , " & #x02205; " },
{ " varphi " , " & #x003C6; " },
{ " varpi " , " & #x003D6; " },
{ " varpropto " , " & #x0221D; " },
{ " varrho " , " & #x003F1; " },
{ " varsigma " , " & #x003C2; " },
{ " varsubsetneq " , " & #x0228A; & #x0FE00; " },
{ " varsubsetneqq " , " & #x02ACB; & #x0FE00; " },
{ " varsupsetneq " , " & #x0228B; & #x0FE00; " },
{ " varsupsetneqq " , " & #x02ACC; & #x0FE00; " },
{ " vartheta " , " & #x003D1; " },
{ " vartriangleleft " , " & #x022B2; " },
{ " vartriangleright " , " & #x022B3; " },
{ " Vee " , " & #x022C1; " },
{ " vee " , " & #x02228; " },
{ " Vert " , " & #x02016; " },
{ " vert " , " & #x0007C; " },
{ " VerticalBar " , " & #x02223; " },
{ " VerticalTilde " , " & #x02240; " },
{ " VeryThinSpace " , " & #x0200A; " },
{ " Wedge " , " & #x022C0; " },
{ " wedge " , " & #x02227; " },
{ " wp " , " & #x02118; " },
{ " wr " , " & #x02240; " },
{ " zeetrf " , " & #x02128; " },
{ 0, 0 }
};

// *******************************************************************
// MmlDocument
// *******************************************************************

QString MmlDocument::fontName(QtMmlWidget::MmlFont type) const
{
switch (type) {
case QtMmlWidget::NormalFont:
return m_normal_font_name;
case QtMmlWidget::FrakturFont:
return m_fraktur_font_name;
case QtMmlWidget::SansSerifFont:
return m_sans_serif_font_name;
case QtMmlWidget::ScriptFont:
return m_script_font_name;
case QtMmlWidget::MonospaceFont:
return m_monospace_font_name;
case QtMmlWidget::DoublestruckFont:
return m_doublestruck_font_name;
};

return QString::null;
}

void MmlDocument::setFontName(QtMmlWidget::MmlFont type, const QString & name)
{
switch (type) {
case QtMmlWidget::NormalFont:
m_normal_font_name = name;
break;
case QtMmlWidget::FrakturFont:
m_fraktur_font_name = name;
break;
case QtMmlWidget::SansSerifFont:
m_sans_serif_font_name = name;
break;
case QtMmlWidget::ScriptFont:
m_script_font_name = name;
break;
case QtMmlWidget::MonospaceFont:
m_monospace_font_name = name;
break;
case QtMmlWidget::DoublestruckFont:
m_doublestruck_font_name = name;
break;
};
}

Mml::NodeType domToMmlNodeType(const QDomNode & dom_node)
{
Mml::NodeType mml_type = Mml::NoNode;

switch (dom_node.nodeType()) {
case QDomNode::ElementNode: {
QString tag = dom_node.nodeName();
const NodeSpec *spec = mmlFindNodeSpec(tag);

// treat urecognised tags as mrow
if (spec == 0)
mml_type = Mml::UnknownNode;
else
mml_type = spec- & gt; type;

break;
}
case QDomNode::TextNode:
mml_type = Mml::TextNode;
break;

case QDomNode::DocumentNode:
mml_type = Mml::MrowNode;
break;

case QDomNode::EntityReferenceNode:
// qWarning( " EntityReferenceNode: name=\ " " + dom_node.nodeName() + " \ " value=\ " " + dom_node.nodeValue() + " \ " " );
break;

case QDomNode::AttributeNode:
case QDomNode::CDATASectionNode:
case QDomNode::EntityNode:
case QDomNode::ProcessingInstructionNode:
case QDomNode::CommentNode:
case QDomNode::DocumentTypeNode:
case QDomNode::DocumentFragmentNode:
case QDomNode::NotationNode:
case QDomNode::BaseNode:
case QDomNode::CharacterDataNode:
break;
}

return mml_type;
}


MmlDocument::MmlDocument()
{
m_root_node = 0;

// Some defaults which happen to work on my computer,
// but probably won't work on other's
#if defined(Q_WS_WIN)
m_normal_font_name = " Times New Roman " ;
#else
m_normal_font_name = " Century Schoolbook L " ;
#endif
m_fraktur_font_name = " Fraktur " ;
m_sans_serif_font_name = " Luxi Sans " ;
m_script_font_name = " Urw Chancery L " ;
m_monospace_font_name = " Luxi Mono " ;
m_doublestruck_font_name = " Doublestruck " ;
m_base_font_point_size = 16;
m_foreground_color = Qt::black;
m_background_color = Qt::white;
}

MmlDocument::~MmlDocument()
{
clear();
}

void MmlDocument::clear()
{
delete m_root_node;
m_root_node = 0;
}

void MmlDocument::dump() const
{
if (m_root_node == 0)
return;

QString indent;
_dump(m_root_node, indent);
}

void MmlDocument::_dump(const MmlNode *node, QString & indent) const
{
if (node == 0) return;

qWarning((indent + node- & gt; toStr()).toLatin1().data());

indent += " " ;
const MmlNode *child = node- & gt; firstChild();
for (; child != 0; child = child- & gt; nextSibling())
_dump(child, indent);
indent.truncate(indent.length() - 2);
}

bool MmlDocument::setContent(QString text, QString *errorMsg,
int *errorLine, int *errorColumn)
{
clear();

QString prefix = " & lt; ?xml version=\ " 2.0\ " ? & gt; \n " ;
prefix.append(entityDeclarations());

uint prefix_lines = 0;
for (int i = 0; i & lt; prefix.length(); ++i) {
if (prefix.at(i) == '\n')
++prefix_lines;
}

QDomDocument dom;
if (!dom.setContent(prefix + text, false, errorMsg, errorLine, errorColumn)) {
if (errorLine != 0)
*errorLine -= prefix_lines;
return false;
}

// we don't have access to line info from now on
if (errorLine != 0) *errorLine = -1;
if (errorColumn != 0) *errorColumn = -1;

bool ok;
MmlNode *root_node = domToMml(dom, & ok, errorMsg);
if (!ok)
return false;

if (root_node == 0) {
if (errorMsg != 0)
*errorMsg = " empty document " ;
return false;
}

insertChild(0, root_node, 0);
layout();

/* QFile of( " /tmp/dump.xml " );
of.open(IO_WriteOnly);
QTextStream os( & of);
os.setEncoding(QTextStream::UnicodeUTF8);
os & lt; & lt; dom.toString(); */

return true;
}

void MmlDocument::layout()
{
if (m_root_node == 0)
return;

m_root_node- & gt; layout();
m_root_node- & gt; stretch();
// dump();
}

bool MmlDocument::insertChild(MmlNode *parent, MmlNode *new_node,
QString *errorMsg)
{
if (new_node == 0)
return true;

Q_ASSERT(new_node- & gt; parent() == 0
& & new_node- & gt; nextSibling() == 0
& & new_node- & gt; previousSibling() == 0);

if (parent != 0) {
if (!mmlCheckChildType(parent- & gt; nodeType(), new_node- & gt; nodeType(), errorMsg))
return false;
}

if (parent == 0) {
if (m_root_node == 0)
m_root_node = new_node;
else {
MmlNode *n = m_root_node- & gt; lastSibling();
n- & gt; m_next_sibling = new_node;
new_node- & gt; m_previous_sibling = n;
}
}
else {
new_node- & gt; m_parent = parent;
if (parent- & gt; hasChildNodes()) {
MmlNode *n = parent- & gt; firstChild()- & gt; lastSibling();
n- & gt; m_next_sibling = new_node;
new_node- & gt; m_previous_sibling = n;
}
else parent- & gt; m_first_child = new_node;
}

return true;
}

MmlNode *MmlDocument::createNode(NodeType type,
const MmlAttributeMap & mml_attr,
const QString & mml_value,
QString *errorMsg)
{
Q_ASSERT(type != NoNode);

MmlNode *mml_node = 0;

if (!mmlCheckAttributes(type, mml_attr, errorMsg))
return 0;

switch (type) {
case MiNode:
mml_node = new MmlMiNode(this, mml_attr);
break;
case MnNode:
mml_node = new MmlMnNode(this, mml_attr);
break;
case MfracNode:
mml_node = new MmlMfracNode(this, mml_attr);
break;
case MrowNode:
mml_node = new MmlMrowNode(this, mml_attr);
break;
case MsqrtNode:
mml_node = new MmlMsqrtNode(this, mml_attr);
break;
case MrootNode:
mml_node = new MmlMrootNode(this, mml_attr);
break;
case MsupNode:
mml_node = new MmlMsupNode(this, mml_attr);
break;
case MsubNode:
mml_node = new MmlMsubNode(this, mml_attr);
break;
case MsubsupNode:
mml_node = new MmlMsubsupNode(this, mml_attr);
break;
case MoNode:
mml_node = new MmlMoNode(this, mml_attr);
break;
case MstyleNode:
mml_node = new MmlMstyleNode(this, mml_attr);
break;
case TextNode:
mml_node = new MmlTextNode(mml_value, this);
break;
case MphantomNode:
mml_node = new MmlMphantomNode(this, mml_attr);
break;
case MfencedNode:
mml_node = new MmlMfencedNode(this, mml_attr);
break;
case MtableNode:
mml_node = new MmlMtableNode(this, mml_attr);
break;
case MtrNode:
mml_node = new MmlMtrNode(this, mml_attr);
break;
case MtdNode:
mml_node = new MmlMtdNode(this, mml_attr);
break;
case MoverNode:
mml_node = new MmlMoverNode(this, mml_attr);
break;
case MunderNode:
mml_node = new MmlMunderNode(this, mml_attr);
break;
case MunderoverNode:
mml_node = new MmlMunderoverNode(this, mml_attr);
break;
case MalignMarkNode:
mml_node = new MmlMalignMarkNode(this);
break;
case MerrorNode:
mml_node = new MmlMerrorNode(this, mml_attr);
break;
case MtextNode:
mml_node = new MmlMtextNode(this, mml_attr);
break;
case MpaddedNode:
mml_node = new MmlMpaddedNode(this, mml_attr);
break;
case MspaceNode:
mml_node = new MmlMspaceNode(this, mml_attr);
break;
case UnknownNode:
mml_node = new MmlUnknownNode(this, mml_attr);
break;
case NoNode:
mml_node = 0;
break;
}

return mml_node;
}

void MmlDocument::insertOperator(MmlNode *node, const QString & text)
{
MmlNode *text_node = createNode(TextNode, MmlAttributeMap(), text, 0);
MmlNode *mo_node = createNode(MoNode, MmlAttributeMap(), QString::null, 0);

bool ok = insertChild(node, mo_node, 0);
Q_ASSERT( ok );
ok = insertChild(mo_node, text_node, 0);
Q_ASSERT( ok );
}

MmlNode *MmlDocument::domToMml(const QDomNode & dom_node, bool *ok, QString *errorMsg)
{
// create the node

Q_ASSERT(ok != 0);

NodeType mml_type = domToMmlNodeType(dom_node);

if (mml_type == NoNode) {
*ok = true;
return 0;
}

QDomNamedNodeMap dom_attr = dom_node.attributes();
MmlAttributeMap mml_attr;
for (unsigned i = 0; i & lt; dom_attr.length(); ++i) {
QDomNode attr_node = dom_attr.item(i);
Q_ASSERT(!attr_node.nodeName().isNull());
Q_ASSERT(!attr_node.nodeValue().isNull());
mml_attr[attr_node.nodeName()] = attr_node.nodeValue();
}

QString mml_value;
if (mml_type == TextNode)
mml_value = dom_node.nodeValue();
MmlNode *mml_node = createNode(mml_type, mml_attr, mml_value, errorMsg);
if (mml_node == 0) {
*ok = false;
return 0;
}

// create the node's children according to the child_spec

const NodeSpec *spec = mmlFindNodeSpec(mml_type);
QDomNodeList dom_child_list = dom_node.childNodes();
int child_cnt = dom_child_list.count();
MmlNode *mml_child = 0;

QString separator_list;
if (mml_type == MfencedNode)
separator_list = mml_node- & gt; explicitAttribute( " separators " , " , " );

switch (spec- & gt; child_spec) {
case NodeSpec::ChildIgnore:
break;

case NodeSpec::ImplicitMrow:

if (child_cnt & gt; 0) {
mml_child = createImplicitMrowNode(dom_node, ok, errorMsg);
if (!*ok) {
delete mml_node;
return 0;
}

if (!insertChild(mml_node, mml_child, errorMsg)) {
delete mml_node;
delete mml_child;
*ok = false;
return 0;
}
}

break;

default:
// exact ammount of children specified - check...
if (spec- & gt; child_spec != child_cnt) {
if (errorMsg != 0)
*errorMsg = QString( " element " )
+ spec- & gt; tag
+ " requires exactly "
+ QString::number(spec- & gt; child_spec)
+ " arguments, got "
+ QString::number(child_cnt);
delete mml_node;
*ok = false;
return 0;
}

// ...and continue just as in ChildAny

case NodeSpec::ChildAny:
if (mml_type == MfencedNode)
insertOperator(mml_node, mml_node- & gt; explicitAttribute( " open " , " ( " ));

for (int i = 0; i & lt; child_cnt; ++i) {
QDomNode dom_child = dom_child_list.item(i);

MmlNode *mml_child = domToMml(dom_child, ok, errorMsg);
if (!*ok) {
delete mml_node;
return 0;
}

if (mml_type == MtableNode & & mml_child- & gt; nodeType() != MtrNode) {
MmlNode *mtr_node = createNode(MtrNode, MmlAttributeMap(), QString::null, 0);
insertChild(mml_node, mtr_node, 0);
if (!insertChild(mtr_node, mml_child, errorMsg)) {
delete mml_node;
delete mml_child;
*ok = false;
return 0;
}
}
else if (mml_type == MtrNode & & mml_child- & gt; nodeType() != MtdNode) {
MmlNode *mtd_node = createNode(MtdNode, MmlAttributeMap(), QString::null, 0);
insertChild(mml_node, mtd_node, 0);
if (!insertChild(mtd_node, mml_child, errorMsg)) {
delete mml_node;
delete mml_child;
*ok = false;
return 0;
}
}
else {
if (!insertChild(mml_node, mml_child, errorMsg)) {
delete mml_node;
delete mml_child;
*ok = false;
return 0;
}
}

if (i & lt; child_cnt - 1 & & mml_type == MfencedNode & & !separator_list.isEmpty()) {
QChar separator;
if (i & gt; = (int)separator_list.length())
separator = separator_list.at(separator_list.length() - 1);
else
separator = separator_list[i];
insertOperator(mml_node, QString(separator));
}
}

if (mml_type == MfencedNode)
insertOperator(mml_node, mml_node- & gt; explicitAttribute( " close " , " ) " ));

break;
}

*ok = true;
return mml_node;
}

MmlNode *MmlDocument::createImplicitMrowNode(const QDomNode & dom_node, bool *ok,
QString *errorMsg)
{
QDomNodeList dom_child_list = dom_node.childNodes();
int child_cnt = dom_child_list.count();

if (child_cnt == 0) {
*ok = true;
return 0;
}

if (child_cnt == 1)
return domToMml(dom_child_list.item(0), ok, errorMsg);

MmlNode *mml_node = createNode(MrowNode, MmlAttributeMap(),
QString::null, errorMsg);
Q_ASSERT(mml_node != 0); // there is no reason in heaven or hell for this to fail

for (int i = 0; i & lt; child_cnt; ++i) {
QDomNode dom_child = dom_child_list.item(i);

MmlNode *mml_child = domToMml(dom_child, ok, errorMsg);
if (!*ok) {
delete mml_node;
return 0;
}

if (!insertChild(mml_node, mml_child, errorMsg)) {
delete mml_node;
delete mml_child;
*ok = false;
return 0;
}
}

return mml_node;
}

void MmlDocument::paint(QPainter *p, const QPoint & pos) const
{
if (m_root_node == 0)
return;

/* p- & gt; save();
p- & gt; setPen(Qt::blue);
p- & gt; drawLine(pos.x() - 5, pos.y(), pos.x() + 5, pos.y());
p- & gt; drawLine(pos.x(), pos.y() - 5, pos.x(), pos.y() + 5);
p- & gt; restore(); */

QRect mr = m_root_node- & gt; myRect();
m_root_node- & gt; setRelOrigin(pos - mr.topLeft());
m_root_node- & gt; paint(p);
}

QSize MmlDocument::size() const
{
if (m_root_node == 0)
return QSize(0, 0);
return m_root_node- & gt; deviceRect().size();
}




// *******************************************************************
// MmlNode
// *******************************************************************


MmlNode::MmlNode(NodeType type, MmlDocument *document, const MmlAttributeMap & attribute_map)
{
m_parent = 0;
m_first_child = 0;
m_next_sibling = 0;
m_previous_sibling = 0;

m_node_type = type;
m_document = document;
m_attribute_map = attribute_map;

m_my_rect = m_parent_rect = QRect(0, 0, 0, 0);
m_rel_origin = QPoint(0, 0);
m_stretched = false;
}

MmlNode::~MmlNode()
{
MmlNode *n = firstChild();
while (n != 0) {
MmlNode *tmp = n- & gt; nextSibling();
delete n;
n = tmp;
}
}

static QString rectToStr(const QRect & rect)
{
return QString( " [(%1, %2), %3x%4] " )
.arg(rect.x())
.arg(rect.y())
.arg(rect.width())
.arg(rect.height());
}

QString MmlNode::toStr() const
{
const NodeSpec *spec = mmlFindNodeSpec(nodeType());
Q_ASSERT(spec != 0);

return QString( " %1 %2 mr=%3 pr=%4 dr=%5 ro=(%7, %8) str=%9 " )
.arg(spec- & gt; type_str)
.arg((unsigned long)this, 0, 16)
.arg(rectToStr(myRect()))
.arg(rectToStr(parentRect()))
.arg(rectToStr(deviceRect()))
.arg(m_rel_origin.x())
.arg(m_rel_origin.y())
.arg((int)isStretched());
}

int MmlNode::interpretSpacing(const QString & value, bool *ok) const
{
return ::interpretSpacing(value, em(), ex(), ok);
}

int MmlNode::basePos() const
{
QFontMetrics fm(font());
return fm.strikeOutPos();
}

int MmlNode::underlinePos() const
{
QFontMetrics fm(font());
return basePos() + fm.underlinePos();
}
int MmlNode::overlinePos() const
{
QFontMetrics fm(font());
return basePos() - fm.overlinePos();
}

MmlNode *MmlNode::lastSibling() const
{
const MmlNode *n = this;
while (!n- & gt; isLastSibling())
n = n- & gt; nextSibling();
return const_cast & lt; MmlNode* & gt; (n);
}

MmlNode *MmlNode::firstSibling() const
{
const MmlNode *n = this;
while (!n- & gt; isFirstSibling())
n = n- & gt; previousSibling();
return const_cast & lt; MmlNode* & gt; (n);
}

int MmlNode::em() const
{
return QFontMetrics(font()).boundingRect('m').width();
}

int MmlNode::ex() const
{
return QFontMetrics(font()).boundingRect('x').height();
}

int MmlNode::scriptlevel(const MmlNode *) const
{
int parent_sl;
const MmlNode *p = parent();
if (p == 0)
parent_sl = 0;
else
parent_sl = p- & gt; scriptlevel(this);

QString expl_sl_str = explicitAttribute( " scriptlevel " );
if (expl_sl_str.isNull())
return parent_sl;

if (expl_sl_str.startsWith( " + " ) || expl_sl_str.startsWith( " - " )) {
bool ok;
int expl_sl = expl_sl_str.toInt( & ok);
if (ok) {
return parent_sl + expl_sl;
}
else {
qWarning(( " MmlNode::scriptlevel(): bad value " + expl_sl_str).toLatin1().data());
return parent_sl;
}
}

bool ok;
int expl_sl = expl_sl_str.toInt( & ok);
if (ok)
return expl_sl;


if (expl_sl_str == " + " )
return parent_sl + 1;
else if (expl_sl_str == " - " )
return parent_sl - 1;
else {
qWarning(( " MmlNode::scriptlevel(): could not parse value: \ " " + expl_sl_str + " \ " " ).toLatin1().data());
return parent_sl;
}
}

QPoint MmlNode::devicePoint(const QPoint & p) const
{
QRect mr = myRect();
QRect dr = deviceRect();

if (isStretched())
return dr.topLeft() + QPoint((p.x() - mr.left())*dr.width()/mr.width(),
(p.y() - mr.top())*dr.height()/mr.height());
else
return dr.topLeft() + p - mr.topLeft();
}

QString MmlNode::inheritAttributeFromMrow(const QString & name,
const QString & def) const
{
const MmlNode *p = this;
for (; p != 0; p = p- & gt; parent()) {
if (p == this || p- & gt; nodeType() == MstyleNode) {
QString value = p- & gt; explicitAttribute(name);
if (!value.isNull())
return value;
}
}

return def;
}

QColor MmlNode::color() const
{
// If we are child of & lt; merror & gt; return red
const MmlNode *p = this;
for (; p != 0; p = p- & gt; parent()) {
if (p- & gt; nodeType() == MerrorNode)
return QColor( " red " );
}

QString value_str = inheritAttributeFromMrow( " mathcolor " );
if (value_str.isNull())
value_str = inheritAttributeFromMrow( " color " );
if (value_str.isNull())
return QColor();

return QColor(value_str);
}

QColor MmlNode::background() const
{
QString value_str = inheritAttributeFromMrow( " mathbackground " );
if (value_str.isNull())
value_str = inheritAttributeFromMrow( " background " );
if (value_str.isNull())
return QColor();

return QColor(value_str);
}

static void updateFontAttr(MmlAttributeMap & font_attr, const MmlNode *n,
const QString & name, const QString & preferred_name = QString::null)
{
if (font_attr.contains(preferred_name) || font_attr.contains(name))
return;
QString value = n- & gt; explicitAttribute(name);
if (!value.isNull())
font_attr[name] = value;
}

static MmlAttributeMap collectFontAttributes(const MmlNode *node)
{
MmlAttributeMap font_attr;

for (const MmlNode *n = node; n != 0; n = n- & gt; parent()) {
if (n == node || n- & gt; nodeType() == Mml::MstyleNode) {
updateFontAttr(font_attr, n, " mathvariant " );
updateFontAttr(font_attr, n, " mathsize " );

// depreciated attributes
updateFontAttr(font_attr, n, " fontsize " , " mathsize " );
updateFontAttr(font_attr, n, " fontweight " , " mathvariant " );
updateFontAttr(font_attr, n, " fontstyle " , " mathvariant " );
updateFontAttr(font_attr, n, " fontfamily " , " mathvariant " );
}
}

return font_attr;
}

QFont MmlNode::font() const
{
QFont fn(document()- & gt; fontName(QtMmlWidget::NormalFont),
document()- & gt; baseFontPointSize());

int ps = fn.pointSize();
int sl = scriptlevel();
if (sl & gt; = 0) {
for (int i = 0; i & lt; sl; ++i)
ps = (int)(ps*g_script_size_multiplier);
}
else {
for (int i = 0; i & gt; sl; --i)
ps = (int)(ps/g_script_size_multiplier);
}
if (ps & lt; g_min_font_point_size)
ps = g_min_font_point_size;
fn.setPointSize(ps);

int em = QFontMetrics(fn).boundingRect('m').width();
int ex = QFontMetrics(fn).boundingRect('x').height();

MmlAttributeMap font_attr = collectFontAttributes(this);

if (font_attr.contains( " mathvariant " )) {
QString value = font_attr[ " mathvariant " ];

bool ok;
uint mv = interpretMathVariant(value, & ok);

if (ok) {
if (mv & ScriptMV)
fn.setFamily(document()- & gt; fontName(QtMmlWidget::ScriptFont));

if (mv & FrakturMV)
fn.setFamily(document()- & gt; fontName(QtMmlWidget::FrakturFont));

if (mv & SansSerifMV)
fn.setFamily(document()- & gt; fontName(QtMmlWidget::SansSerifFont));

if (mv & MonospaceMV)
fn.setFamily(document()- & gt; fontName(QtMmlWidget::MonospaceFont));

if (mv & DoubleStruckMV)
fn.setFamily(document()- & gt; fontName(QtMmlWidget::DoublestruckFont));

if (mv & BoldMV)
fn.setBold(true);

if (mv & ItalicMV)
fn.setItalic(true);
}
}

if (font_attr.contains( " mathsize " )) {
QString value = font_attr[ " mathsize " ];
fn = interpretMathSize(value, fn, em, ex, 0);
}

fn = interpretDepreciatedFontAttr(font_attr, fn, em, ex);

if (nodeType() == MiNode
& & !font_attr.contains( " mathvariant " )
& & !font_attr.contains( " fontstyle " )) {
const MmlMiNode *mi_node = (const MmlMiNode*) this;
if (mi_node- & gt; text().length() == 1)
fn.setItalic(true);
}

if (nodeType() == MoNode) {
fn.setItalic(false);
fn.setBold(false);
}

return fn;
}

QString MmlNode::explicitAttribute(const QString & name, const QString & def) const
{
MmlAttributeMap::const_iterator it = m_attribute_map.find(name);
if (it != m_attribute_map.end())
return *it;
return def;
}


QRect MmlNode::parentRect() const
{
if (isStretched())
return m_parent_rect;

QRect mr = myRect();
QPoint ro = relOrigin();

return QRect(ro + mr.topLeft(), mr.size());
}


void MmlNode::stretchTo(const QRect & rect)
{
m_parent_rect = rect;
m_stretched = true;
}

void MmlNode::setRelOrigin(const QPoint & rel_origin)
{
m_rel_origin = rel_origin + QPoint(-myRect().left(), 0);
m_stretched = false;
}

void MmlNode::updateMyRect()
{
m_my_rect = symbolRect();
MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling())
m_my_rect |= child- & gt; parentRect();
}

void MmlNode::layout()
{
m_parent_rect = QRect(0, 0, 0, 0);
m_stretched = false;
m_rel_origin = QPoint(0, 0);

MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling())
child- & gt; layout();

layoutSymbol();

updateMyRect();

if (parent() == 0)
m_rel_origin = QPoint(0, 0);
}


QRect MmlNode::deviceRect() const
{
if (parent() == 0)
return QRect(relOrigin() + myRect().topLeft(), myRect().size());

/* if (!isStretched()) {
QRect pdr = parent()- & gt; deviceRect();
QRect pmr = parent()- & gt; myRect();
QRect pr = parentRect();
QRect mr = myRect();
return QRect(pdr.left() + pr.left() - pmr.left(),
pdr.top() + pr.top() - pmr.top(),
mr.width(), mr.height());
}
*/
QRect pdr = parent()- & gt; deviceRect();
QRect pr = parentRect();
QRect pmr = parent()- & gt; myRect();

float scale_w = 0;
if (pmr.width() != 0)
scale_w = (float)pdr.width()/pmr.width();
float scale_h = 0;
if (pmr.height() != 0)
scale_h = (float)pdr.height()/pmr.height();

return QRect(pdr.left() + ROUND((pr.left() - pmr.left())*scale_w),
pdr.top() + ROUND((pr.top() - pmr.top())*scale_h),
ROUND((pr.width()*scale_w)),
ROUND((pr.height()*scale_h)));
}

void MmlNode::layoutSymbol()
{
// default behaves like an mrow

// now lay them out in a neat row, aligning their origins to my origin
int w = 0;
MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling()) {
child- & gt; setRelOrigin(QPoint(w, 0));
w += child- & gt; parentRect().width() + 1;
}
}

void MmlNode::paint(QPainter *p)
{
if (!myRect().isValid())
return;
p- & gt; save();
p- & gt; setViewport(deviceRect());
p- & gt; setWindow(myRect());


QColor fg = color();
QColor bg = background();
if (bg.isValid())
p- & gt; fillRect(myRect(), bg);
if (fg.isValid())
p- & gt; setPen(color());

MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling())
child- & gt; paint(p);

paintSymbol(p);

p- & gt; restore();
}

void MmlNode::paintSymbol(QPainter *p) const
{
if (g_draw_frames & & myRect().isValid()) {
p- & gt; save();
p- & gt; setPen(Qt::red);
p- & gt; drawRect(m_my_rect);
QPen pen = p- & gt; pen();
pen.setStyle(Qt::DotLine);
p- & gt; setPen(pen);
p- & gt; drawLine(myRect().left(), 0, myRect().right(), 0);
p- & gt; restore();
}
}

void MmlNode::stretch()
{
MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling())
child- & gt; stretch();
}

QString MmlTokenNode::text() const
{
QString result;

const MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling()) {
if (child- & gt; nodeType() != TextNode) continue;
if (!result.isEmpty())
result += ' ';
result += ((MmlTextNode*)child)- & gt; text();
}

return result;
}

MmlNode *MmlMfracNode::numerator() const
{
MmlNode *node = firstChild();
Q_ASSERT(node != 0);
return node;
}

MmlNode *MmlMfracNode::denominator() const
{
MmlNode *node = numerator()- & gt; nextSibling();
Q_ASSERT(node != 0);
return node;
}

QRect MmlMfracNode::symbolRect() const
{
int num_width = numerator()- & gt; myRect().width();
int denom_width = denominator()- & gt; myRect().width();
int my_width = qMax(num_width, denom_width) + 4;

return QRect(-my_width/2, 0, my_width, 1);
}

void MmlMfracNode::layoutSymbol()
{
MmlNode *num = numerator();
MmlNode *denom = denominator();

QRect num_rect = num- & gt; myRect();
QRect denom_rect = denom- & gt; myRect();

int spacing = (int)(g_mfrac_spacing*(num_rect.height() + denom_rect.height()));

num- & gt; setRelOrigin(QPoint(-num_rect.width()/2, - spacing - num_rect.bottom()));
denom- & gt; setRelOrigin(QPoint(-denom_rect.width()/2, spacing - denom_rect.top()));
}

static bool zeroLineThickness(const QString & s)
{
if (s.length() == 0 || !s[0].isDigit())
return false;

for (int i = 0; i & lt; s.length(); ++i) {
QChar c = s.at(i);
if (c.isDigit() & & c != '0')
return false;
}
return true;
}

void MmlMfracNode::paintSymbol(QPainter *p) const
{
QString linethickness_str = inheritAttributeFromMrow( " linethickness " , " 1 " );

/* InterpretSpacing returns an int, which might be 0 even if the thickness
is & gt; 0, though very very small. That's ok, because the painter then paints
a line of thickness 1. However, we have to run this check if the line
thickness really is zero */
if (!zeroLineThickness(linethickness_str)) {
bool ok;
int linethickness = interpretSpacing(linethickness_str, & ok);
if (!ok)
linethickness = 1;

p- & gt; save();
QPen pen = p- & gt; pen();
pen.setWidth(linethickness);
p- & gt; setPen(pen);
QSize s = myRect().size();
p- & gt; drawLine(-s.width()/2, 0, s.width()/2, 0);
p- & gt; restore();
}
}

MmlNode *MmlRootBaseNode::base() const
{
MmlNode *node = firstChild();
// Q_ASSERT(node != 0);
return node;
}

MmlNode *MmlRootBaseNode::index() const
{
MmlNode *b = base();
if (b == 0)
return 0;
return b- & gt; nextSibling();
}

int MmlRootBaseNode::scriptlevel(const MmlNode *child) const
{
int sl = MmlNode::scriptlevel();

MmlNode *i = index();
if (child != 0 & & child == i)
return sl + 1;
else
return sl;
}


QRect MmlRootBaseNode::symbolRect() const
{
MmlNode *b = base();
QRect base_rect;
if (b == 0)
base_rect = QRect(0, 0, 1, 1);
else
base_rect = base()- & gt; myRect();

int margin = (int)(g_mroot_base_margin*base_rect.height());
int tw = tailWidth();

return QRect(-tw, base_rect.top() - margin, tw,
base_rect.height() + 2*margin);
}

int MmlRootBaseNode::tailWidth() const
{
QFontMetrics fm(font());
return fm.boundingRect(g_radical_char).width();
}

void MmlRootBaseNode::layoutSymbol()
{
MmlNode *b = base();
QSize base_size;
if (b != 0) {
b- & gt; setRelOrigin(QPoint(0, 0));
base_size = base()- & gt; myRect().size();
} else
base_size = QSize(1, 1);

MmlNode *i = index();
if (i != 0) {
int tw = tailWidth();

QRect i_rect = i- & gt; myRect();
i- & gt; setRelOrigin(QPoint(-tw/2 - i_rect.width(),
-i_rect.bottom() - 4));
}
}

void MmlRootBaseNode::paintSymbol(QPainter *p) const
{
QFont fn = font();

p- & gt; save();

QRect sr = symbolRect();

QRect r = sr;
r.moveTopLeft(devicePoint(sr.topLeft()));
p- & gt; setViewport(r);
p- & gt; setWindow(QFontMetrics(fn).boundingRect(g_radical_char));
p- & gt; setFont(font());
p- & gt; drawText(0, 0, QString(g_radical_char));

p- & gt; restore();

p- & gt; drawLine(sr.right(), sr.top(), myRect().right(), sr.top());
}

MmlTextNode::MmlTextNode(const QString & text, MmlDocument *document)
: MmlNode(TextNode, document, MmlAttributeMap())
{
m_text = text;
// Trim whitespace from ends, but keep nbsp and thinsp
m_text.remove(QRegExp( " ^[^\\S\\x00a0\\x2009]+ " ));
m_text.remove(QRegExp( " [^\\S\\x00a0\\x2009]+$ " ));

if (m_text == QString(QChar(0x62, 0x20)) // & InvisibleTimes;
|| m_text == QString(QChar(0x63, 0x20)) // & InvisibleComma;
|| m_text == QString(QChar(0x61, 0x20))) // & ApplyFunction;
m_text = " " ;
}

QString MmlTextNode::toStr() const
{
return MmlNode::toStr() + " , text=\ " " + m_text + " \ " " ;
}

void MmlTextNode::paintSymbol(QPainter *p) const
{
MmlNode::paintSymbol(p);

QFont fn = font();

QFontInfo fi(fn);
// qWarning( " MmlTextNode::paintSymbol(): requested: %s, used: %s, size=%d, italic=%d, bold=%d, text=\ " %s\ " sl=%d " ,
// fn.family().latin1(), fi.family().latin1(), fi.pointSize(), (int)fi.italic(), (int)fi.bold(), m_text.latin1(), scriptlevel());

QFontMetrics fm(fn);

p- & gt; save();
p- & gt; setFont(fn);

p- & gt; drawText(0, fm.strikeOutPos(), m_text);
p- & gt; restore();
}

QRect MmlTextNode::symbolRect() const
{
QFontMetrics fm(font());

QRect br = fm.tightBoundingRect(m_text);
br.translate(0, fm.strikeOutPos());

return br;
}

MmlNode *MmlSubsupBaseNode::base() const
{
MmlNode *b = firstChild();
Q_ASSERT(b != 0);
return b;
}

MmlNode *MmlSubsupBaseNode::sscript() const
{
MmlNode *s = base()- & gt; nextSibling();
Q_ASSERT(s != 0);
return s;
}

int MmlSubsupBaseNode::scriptlevel(const MmlNode *child) const
{
int sl = MmlNode::scriptlevel();

MmlNode *s = sscript();
if (child != 0 & & child == s)
return sl + 1;
else
return sl;
}

void MmlMsupNode::layoutSymbol()
{
MmlNode *b = base();
MmlNode *s = sscript();

b- & gt; setRelOrigin(QPoint(-b- & gt; myRect().width(), 0));
s- & gt; setRelOrigin(QPoint(0, b- & gt; myRect().top()));
}

void MmlMsubNode::layoutSymbol()
{
MmlNode *b = base();
MmlNode *s = sscript();

b- & gt; setRelOrigin(QPoint(-b- & gt; myRect().width(), 0));
s- & gt; setRelOrigin(QPoint(0, b- & gt; myRect().bottom()));
}

MmlNode *MmlMsubsupNode::base() const
{
MmlNode *b = firstChild();
Q_ASSERT(b != 0);
return b;
}

MmlNode *MmlMsubsupNode::subscript() const
{
MmlNode *sub = base()- & gt; nextSibling();
Q_ASSERT(sub != 0);
return sub;
}

MmlNode *MmlMsubsupNode::superscript() const
{
MmlNode *sup = subscript()- & gt; nextSibling();
Q_ASSERT(sup != 0);
return sup;
}

void MmlMsubsupNode::layoutSymbol()
{
MmlNode *b = base();
MmlNode *sub = subscript();
MmlNode *sup = superscript();

b- & gt; setRelOrigin(QPoint(-b- & gt; myRect().width(), 0));
sub- & gt; setRelOrigin(QPoint(0, b- & gt; myRect().bottom()));
sup- & gt; setRelOrigin(QPoint(0, b- & gt; myRect().top()));
}

int MmlMsubsupNode::scriptlevel(const MmlNode *child) const
{
int sl = MmlNode::scriptlevel();

MmlNode *sub = subscript();
MmlNode *sup = superscript();

if (child != 0 & & (child == sup || child == sub))
return sl + 1;
else
return sl;
}

QString MmlMoNode::toStr() const
{
return MmlNode::toStr() + QString( " form=%1 " ).arg((int)form());
}

void MmlMoNode::layoutSymbol()
{
MmlNode *child = firstChild();
if (child == 0)
return;

child- & gt; setRelOrigin(QPoint(0, 0));

if (m_oper_spec == 0)
m_oper_spec = mmlFindOperSpec(text(), form());
}

MmlMoNode::MmlMoNode(MmlDocument *document, const MmlAttributeMap & attribute_map)
: MmlTokenNode(MoNode, document, attribute_map)
{
m_oper_spec = 0;
}

QString MmlMoNode::dictionaryAttribute(const QString & name) const
{
const MmlNode *p = this;
for (; p != 0; p = p- & gt; parent()) {
if (p == this || p- & gt; nodeType() == MstyleNode) {
QString expl_attr = p- & gt; explicitAttribute(name);
if (!expl_attr.isNull())
return expl_attr;
}
}

return mmlDictAttribute(name, m_oper_spec);
}

Mml::FormType MmlMoNode::form() const
{
QString value_str = inheritAttributeFromMrow( " form " );
if (!value_str.isNull()) {
bool ok;
FormType value = interpretForm(value_str, & ok);
if (ok)
return value;
else
qWarning( " Could not convert %s to form " , value_str.toLatin1().data());

}

// Default heuristic.
if (firstSibling() == (MmlNode*)this & & lastSibling() != (MmlNode*)this)
return PrefixForm;
else if (lastSibling() == (MmlNode*)this & & firstSibling() != (MmlNode*)this)
return PostfixForm;
else return InfixForm;

}

void MmlMoNode::stretch()
{
if (parent() == 0)
return;

if (m_oper_spec == 0)
return;

if (m_oper_spec- & gt; stretch_dir == OperSpec::HStretch
& & parent()- & gt; nodeType() == MrowNode
& & (nextSibling() != 0 || previousSibling() != 0))
return;

QRect pmr = parent()- & gt; myRect();
QRect pr = parentRect();

switch (m_oper_spec- & gt; stretch_dir) {
case OperSpec::VStretch:
stretchTo(QRect(pr.left(), pmr.top(), pr.width(), pmr.height()));
break;
case OperSpec::HStretch:
stretchTo(QRect(pmr.left(), pr.top(), pmr.width(), pr.height()));
break;
case OperSpec::HVStretch:
stretchTo(pmr);
break;
case OperSpec::NoStretch:
break;
}
}

int MmlMoNode::lspace() const
{
Q_ASSERT(m_oper_spec != 0);
if (parent() == 0
|| (parent()- & gt; nodeType() != MrowNode
& & parent()- & gt; nodeType() != MfencedNode
& & parent()- & gt; nodeType() != UnknownNode)
|| (previousSibling() == 0 & & nextSibling() == 0))
return 0;
else
return interpretSpacing(dictionaryAttribute( " lspace " ), 0);
}

int MmlMoNode::rspace() const
{
Q_ASSERT(m_oper_spec != 0);
if (parent() == 0
|| (parent()- & gt; nodeType() != MrowNode
& & parent()- & gt; nodeType() != MfencedNode
& & parent()- & gt; nodeType() != UnknownNode)
|| (previousSibling() == 0 & & nextSibling() == 0))
return 0;
else
return interpretSpacing(dictionaryAttribute( " rspace " ), 0);
}

QRect MmlMoNode::symbolRect() const
{
const MmlNode *child = firstChild();

if (child == 0)
return QRect(0, 0, 0, 0);

QRect cmr = child- & gt; myRect();

return QRect(-lspace(), cmr.top(),
cmr.width() + lspace() + rspace(), cmr.height());
}

int MmlMtableNode::rowspacing() const
{
QString value = explicitAttribute( " rowspacing " );
if (value.isNull())
return ex();
bool ok;
int r = interpretSpacing(value, & ok);

if (ok)
return r;
else
return ex();
}

int MmlMtableNode::columnspacing() const
{
QString value = explicitAttribute( " columnspacing " );
if (value.isNull())
return (int)(0.8*em());
bool ok;
int r = interpretSpacing(value, & ok);

if (ok)
return r;
else
return (int)(0.8*em());
}

uint MmlMtableNode::CellSizeData::colWidthSum() const
{
uint w = 0;
for (int i = 0; i & lt; col_widths.count(); ++i)
w += col_widths[i];
return w;
}

uint MmlMtableNode::CellSizeData::rowHeightSum() const
{
uint h = 0;
for (int i = 0; i & lt; row_heights.count(); ++i)
h += row_heights[i];
return h;
}

void MmlMtableNode::CellSizeData::init(const MmlNode *first_row)
{
col_widths.clear();
row_heights.clear();

const MmlNode *mtr = first_row;
for (; mtr != 0; mtr = mtr- & gt; nextSibling()) {

Q_ASSERT(mtr- & gt; nodeType() == MtrNode);

int col_cnt = 0;
const MmlNode *mtd = mtr- & gt; firstChild();
for (; mtd != 0; mtd = mtd- & gt; nextSibling(), ++col_cnt) {

Q_ASSERT(mtd- & gt; nodeType() == MtdNode);

QRect mtdmr = mtd- & gt; myRect();

if (col_cnt == col_widths.count())
col_widths.append(mtdmr.width());
else
col_widths[col_cnt] = qMax(col_widths[col_cnt], mtdmr.width());
}

row_heights.append(mtr- & gt; myRect().height());
}
}

void MmlMtableNode::layoutSymbol()
{
// Obtain natural widths of columns
m_cell_size_data.init(firstChild());

int col_spc = columnspacing();
int row_spc = rowspacing();
int frame_spc_hor = framespacing_hor();
QString columnwidth_attr = explicitAttribute( " columnwidth " , " auto " );

// Is table width set by user? If so, set col_width_sum and never ever change it.
int col_width_sum = m_cell_size_data.colWidthSum();
bool width_set_by_user = false;
QString width_str = explicitAttribute( " width " , " auto " );
if (width_str != " auto " ) {
bool ok;

int w = interpretSpacing(width_str, & ok);
if (ok) {
col_width_sum = w
- col_spc*(m_cell_size_data.numCols() - 1)
- frame_spc_hor*2;
width_set_by_user = true;
}
}

// Find out what kind of columns we are dealing with and set the widths of
// statically sized columns.
int fixed_width_sum = 0; // sum of widths of statically sized set columns
int auto_width_sum = 0; // sum of natural widths of auto sized columns
int relative_width_sum = 0; // sum of natural widths of relatively sized columns
double relative_fraction_sum = 0; // total fraction of width taken by relatively
// sized columns
int i;
for (i = 0; i & lt; m_cell_size_data.numCols(); ++i) {
QString value = interpretListAttr(columnwidth_attr, i, " auto " );

// Is it an auto sized column?
if (value == " auto " || value == " fit " ) {
auto_width_sum += m_cell_size_data.col_widths[i];
continue;
}

// Is it a statically sized column?
bool ok;
int w = interpretSpacing(value, & ok);
if (ok) {
// Yup, sets its width to the user specified value
m_cell_size_data.col_widths[i] = w;
fixed_width_sum += w;
continue;
}

// Is it a relatively sized column?
if (value.endsWith( " % " )) {
value.truncate(value.length() - 1);
double factor = value.toFloat( & ok);
if (ok & & !value.isEmpty()) {
factor /= 100.0;
relative_width_sum += m_cell_size_data.col_widths[i];
relative_fraction_sum += factor;
if (!width_set_by_user) {
// If the table width was not set by the user, we are free to increase
// it so that the width of this column will be & gt; = than its natural width
int min_col_width_sum = ROUND(m_cell_size_data.col_widths[i]/factor);
if (min_col_width_sum & gt; col_width_sum)
col_width_sum = min_col_width_sum;
}
continue;
}
else
qWarning( " MmlMtableNode::layoutSymbol(): could not parse value %s%% " , value.toLatin1().data());
}

// Relatively sized column, but we failed to parse the factor. Treat is like an auto
// column.
auto_width_sum += m_cell_size_data.col_widths[i];
}

// Work out how much space remains for the auto olumns, after allocating
// the statically sized and the relatively sized columns.
int required_auto_width_sum = col_width_sum
- ROUND(relative_fraction_sum*col_width_sum)
- fixed_width_sum;

if (!width_set_by_user & & required_auto_width_sum & lt; auto_width_sum) {
if (relative_fraction_sum & lt; 1)
col_width_sum = ROUND((fixed_width_sum + auto_width_sum)/(1 - relative_fraction_sum));
else
col_width_sum = fixed_width_sum + auto_width_sum + relative_width_sum;
required_auto_width_sum = auto_width_sum;
}

// Ratio by which we have to shring/grow all auto sized columns to make it all fit
double auto_width_scale = 1;
if (auto_width_sum & gt; 0)
auto_width_scale = (float)required_auto_width_sum/auto_width_sum;

// Set correct sizes for the auto sized and the relatively sized columns.
for (i = 0; i & lt; m_cell_size_data.numCols(); ++i) {
QString value = interpretListAttr(columnwidth_attr, i, " auto " );

// Is it a relatively sized column?
if (value.endsWith( " % " )) {
bool ok;
int w = interpretPercentSpacing(value, col_width_sum, & ok);
if (ok)
m_cell_size_data.col_widths[i] = w;
else
// We're treating parsing errors here as auto sized columns
m_cell_size_data.col_widths[i]
= ROUND(auto_width_scale*m_cell_size_data.col_widths[i]);
}
// Is it an auto sized column?
else if (value == " auto " ) {
m_cell_size_data.col_widths[i]
= ROUND(auto_width_scale*m_cell_size_data.col_widths[i]);
}
}

QString s;
QList & lt; int & gt; & col_widths = m_cell_size_data.col_widths;
for (i = 0; i & lt; col_widths.count(); ++i) {
s += QString( " [w=%1 %2%%] " )
.arg(col_widths[i])
.arg(100*col_widths[i]/m_cell_size_data.colWidthSum());
}
// qWarning(s);

m_content_width = m_cell_size_data.colWidthSum()
+ col_spc*(m_cell_size_data.numCols() - 1);
m_content_height = m_cell_size_data.rowHeightSum()
+ row_spc*(m_cell_size_data.numRows() - 1);

int bottom = -m_content_height/2;
MmlNode *child = firstChild();
for (; child != 0; child = child- & gt; nextSibling()) {
Q_ASSERT(child- & gt; nodeType() == MtrNode);
MmlMtrNode *row = (MmlMtrNode*) child;

row- & gt; layoutCells(m_cell_size_data.col_widths, col_spc);
QRect rmr = row- & gt; myRect();
row- & gt; setRelOrigin(QPoint(0, bottom - rmr.top()));
bottom += rmr.height() + row_spc;
}
}

QRect MmlMtableNode::symbolRect() const
{
int frame_spc_hor = framespacing_hor();
int frame_spc_ver = framespacing_ver();

return QRect(-frame_spc_hor,
-m_content_height/2 - frame_spc_ver,
m_content_width + 2*frame_spc_hor,
m_content_height + 2*frame_spc_ver);
}

Mml::FrameType MmlMtableNode::frame() const
{
QString value = explicitAttribute( " frame " , " none " );
return interpretFrameType(value, 0, 0);
}

Mml::FrameType MmlMtableNode::columnlines(int idx) const
{
QString value = explicitAttribute( " columnlines " , " none " );
return interpretFrameType(value, idx, 0);
}

Mml::FrameType MmlMtableNode::rowlines(int idx) const
{
QString value = explicitAttribute( " rowlines " , " none " );
return interpretFrameType(value, idx, 0);
}

void MmlMtableNode::paintSymbol(QPainter *p) const
{
FrameType f = frame();
if (f != FrameNone) {
p- & gt; save();

QPen pen = p- & gt; pen();
if (f == FrameDashed)
pen.setStyle(Qt::DashLine);
else
pen.setStyle(Qt::SolidLine);
p- & gt; setPen(pen);
p- & gt; drawRect(myRect());

p- & gt; restore();
}

p- & gt; save();

int col_spc = columnspacing();
int row_spc = rowspacing();

QPen pen = p- & gt; pen();
int col_offset = 0;
int i;
for (i = 0; i & lt; m_cell_size_data.numCols() - 1; ++i) {
FrameType f = columnlines(i);
col_offset += m_cell_size_data.col_widths[i];

if (f != FrameNone) {
if (f == FrameDashed)
pen.setStyle(Qt::DashLine);
else if (f == FrameSolid)
pen.setStyle(Qt::SolidLine);

p- & gt; setPen(pen);
int x = col_offset + col_spc/2;
p- & gt; drawLine(x, -m_content_height/2, x, m_content_height/2 );
}
col_offset += col_spc;
}

int row_offset = 0;
for (i = 0; i & lt; m_cell_size_data.numRows() - 1; ++i) {
FrameType f = rowlines(i);
row_offset += m_cell_size_data.row_heights[i];

if (f != FrameNone) {
if (f == FrameDashed)
pen.setStyle(Qt::DashLine);
else if (f == FrameSolid)
pen.setStyle(Qt::SolidLine);

p- & gt; setPen(pen);
int y = row_offset + row_spc/2 - m_content_height/2;
p- & gt; drawLine(0, y, m_content_width, y);
}
row_offset += row_spc;
}

p- & gt; restore();
}

int MmlMtableNode::framespacing_ver() const
{
if (frame() == FrameNone)
return (int)(0.2*em());

QString value = explicitAttribute( " framespacing " , " 0.4em 0.5ex " );

bool ok;
FrameSpacing fs = interpretFrameSpacing(value, em(), ex(), & ok);
if (ok)
return fs.m_ver;
else
return (int)(0.5*ex());
}

int MmlMtableNode::framespacing_hor() const
{
if (frame() == FrameNone)
return (int)(0.2*em());

QString value = explicitAttribute( " framespacing " , " 0.4em 0.5ex " );

bool ok;
FrameSpacing fs = interpretFrameSpacing(value, em(), ex(), & ok);
if (ok)
return fs.m_hor;
else
return (int)(0.4*em());
}

void MmlMtrNode::layoutCells(const QList & lt; int & gt; & col_widths,
int col_spc)
{
QRect mr = myRect();

MmlNode *child = firstChild();
int col_offset = 0;
uint colnum = 0;
for (; child != 0; child = child- & gt; nextSibling(), ++colnum) {
Q_ASSERT(child- & gt; nodeType() == MtdNode);
MmlMtdNode *mtd = (MmlMtdNode*) child;

QRect r = QRect(0, mr.top(), col_widths[colnum], mr.height());
mtd- & gt; setMyRect(r);
mtd- & gt; setRelOrigin(QPoint(col_offset, 0));
col_offset += col_widths[colnum] + col_spc;
}

updateMyRect();
}

int MmlMtdNode::scriptlevel(const MmlNode *child) const
{
int sl = MmlNode::scriptlevel();
if (child != 0 & & child == firstChild())
return sl + m_scriptlevel_adjust;
else
return sl;
}

void MmlMtdNode::setMyRect(const QRect & rect)
{
MmlNode::setMyRect(rect);
MmlNode *child = firstChild();
if (child == 0)
return;

if (rect.width() & lt; child- & gt; myRect().width()) {
while (rect.width() & lt; child- & gt; myRect().width()
& & child- & gt; font().pointSize() & gt; g_min_font_point_size) {

// qWarning( " MmlMtdNode::setMyRect(): rect.width()=%d, child()- & gt; myRect().width=%d sl=%d " ,
// rect.width(), child- & gt; myRect().width(), m_scriptlevel_adjust);

++m_scriptlevel_adjust;
child- & gt; layout();
}

// qWarning( " MmlMtdNode::setMyRect(): rect.width()=%d, child()- & gt; myRect().width=%d sl=%d " ,
// rect.width(), child- & gt; myRect().width(), m_scriptlevel_adjust);
}

QRect mr = myRect();
QRect cmr = child- & gt; myRect();

QPoint child_rel_origin;

switch (columnalign()) {
case ColAlignLeft:
child_rel_origin.setX(0);
break;
case ColAlignCenter:
child_rel_origin.setX(mr.left() + (mr.width() - cmr.width())/2);
break;
case ColAlignRight:
child_rel_origin.setX(mr.right() - cmr.width());
break;
}

switch (rowalign()) {
case RowAlignTop:
child_rel_origin.setY(mr.top() - cmr.top());
break;
case RowAlignCenter:
case RowAlignBaseline:
child_rel_origin.setY(mr.top() -cmr.top() + (mr.height() - cmr.height())/2);
break;
case RowAlignBottom:
child_rel_origin.setY(mr.bottom() - cmr.bottom());
break;
case RowAlignAxis:
child_rel_origin.setY(0);
break;
}

child- & gt; setRelOrigin(child_rel_origin);
}

uint MmlMtdNode::colNum()
{
MmlNode *syb = previousSibling();

uint i = 0;
for (; syb != 0; syb = syb- & gt; previousSibling())
++i;

return i;
}

uint MmlMtdNode::rowNum()
{
MmlNode *row = parent()- & gt; previousSibling();

uint i = 0;
for (; row != 0; row = row- & gt; previousSibling())
++i;

return i;
}

MmlMtdNode::ColAlign MmlMtdNode::columnalign()
{
QString val = explicitAttribute( " columnalign " );
if (!val.isNull())
return interpretColAlign(val, 0, 0);

MmlNode *node = parent(); // & lt; mtr & gt;
if (node == 0)
return ColAlignCenter;

uint colnum = colNum();
val = node- & gt; explicitAttribute( " columnalign " );
if (!val.isNull())
return interpretColAlign(val, colnum, 0);

node = node- & gt; parent(); // & lt; mtable & gt;
if (node == 0)
return ColAlignCenter;

val = node- & gt; explicitAttribute( " columnalign " );
if (!val.isNull())
return interpretColAlign(val, colnum, 0);

return ColAlignCenter;
}

MmlMtdNode::RowAlign MmlMtdNode::rowalign()
{
QString val = explicitAttribute( " rowalign " );
if (!val.isNull())
return interpretRowAlign(val, 0, 0);

MmlNode *node = parent(); // & lt; mtr & gt;
if (node == 0)
return RowAlignAxis;

uint rownum = rowNum();
val = node- & gt; explicitAttribute( " rowalign " );
if (!val.isNull())
return interpretRowAlign(val, rownum, 0);

node = node- & gt; parent(); // & lt; mtable & gt;
if (node == 0)
return RowAlignAxis;

val = node- & gt; explicitAttribute( " rowalign " );
if (!val.isNull())
return interpretRowAlign(val, rownum, 0);

return RowAlignAxis;
}

void MmlMoverNode::layoutSymbol()
{
MmlNode *base = firstChild();
Q_ASSERT(base != 0);
MmlNode *over = base- & gt; nextSibling();
Q_ASSERT(over != 0);

QRect base_rect = base- & gt; myRect();
QRect over_rect = over- & gt; myRect();

int spacing = (int)(g_mfrac_spacing*(over_rect.height()
+ base_rect.height()));

base- & gt; setRelOrigin(QPoint(-base_rect.width()/2, 0));
over- & gt; setRelOrigin(QPoint(-over_rect.width()/2,
base_rect.top() - spacing - over_rect.bottom()));
}

int MmlMoverNode::scriptlevel(const MmlNode *node) const
{
MmlNode *base = firstChild();
Q_ASSERT(base != 0);
MmlNode *over = base- & gt; nextSibling();
Q_ASSERT(over != 0);

int sl = MmlNode::scriptlevel();
if (node != 0 & & node == over)
return sl + 1;
else
return sl;
}

void MmlMunderNode::layoutSymbol()
{
MmlNode *base = firstChild();
Q_ASSERT(base != 0);
MmlNode *under = base- & gt; nextSibling();
Q_ASSERT(under != 0);

QRect base_rect = base- & gt; myRect();
QRect under_rect = under- & gt; myRect();

int spacing = (int)(g_mfrac_spacing*(under_rect.height() + base_rect.height()));

base- & gt; setRelOrigin(QPoint(-base_rect.width()/2, 0));
under- & gt; setRelOrigin(QPoint(-under_rect.width()/2, base_rect.bottom() + spacing - under_rect.top()));
}

int MmlMunderNode::scriptlevel(const MmlNode *node) const
{
MmlNode *base = firstChild();
Q_ASSERT(base != 0);
MmlNode *under = base- & gt; nextSibling();
Q_ASSERT(under != 0);

int sl = MmlNode::scriptlevel();
if (node != 0 & & node == under)
return sl + 1;
else
return sl;
}

void MmlMunderoverNode::layoutSymbol()
{
MmlNode *base = firstChild();
Q_ASSERT(base != 0);
MmlNode *under = base- & gt; nextSibling();
Q_ASSERT(under != 0);
MmlNode *over = under- & gt; nextSibling();
Q_ASSERT(over != 0);

QRect base_rect = base- & gt; myRect();
QRect under_rect = under- & gt; myRect();
QRect over_rect = over- & gt; myRect();

int spacing = (int)(g_mfrac_spacing*( base_rect.height()
+ under_rect.height()
+ over_rect.height()) );

base- & gt; setRelOrigin(QPoint(-base_rect.width()/2, 0));
under- & gt; setRelOrigin(QPoint(-under_rect.width()/2, base_rect.bottom() + spacing - under_rect.top()));
over- & gt; setRelOrigin(QPoint(-over_rect.width()/2, base_rect.top() - spacing - under_rect.bottom()));
}

int MmlMunderoverNode::scriptlevel(const MmlNode *node) const
{
MmlNode *base = firstChild();
Q_ASSERT(base != 0);
MmlNode *under = base- & gt; nextSibling();
Q_ASSERT(under != 0);
MmlNode *over = under- & gt; nextSibling();
Q_ASSERT(over != 0);

int sl = MmlNode::scriptlevel();
if (node != 0 & & (node == under || node == over))
return sl + 1;
else
return sl;
}

int MmlMpaddedNode::interpretSpacing(QString value, int base_value, bool *ok) const
{
if (ok != 0)
*ok = false;

value.replace(' ', " " );

QString sign, factor_str, pseudo_unit;
bool percent = false;

// extract the sign
int idx = 0;
if (idx & lt; value.length() & & (value.at(idx) == '+' || value.at(idx) == '-'))
sign = value.at(idx++);

// extract the factor
while (idx & lt; value.length() & & (value.at(idx).isDigit() || value.at(idx) == '.'))
factor_str.append(value.at(idx++));

// extract the % sign
if (idx & lt; value.length() & & value.at(idx) == '%') {
percent = true;
++idx;
}

// extract the pseudo-unit
pseudo_unit = value.mid(idx);

bool float_ok;
double factor = factor_str.toFloat( & float_ok);
if (!float_ok || factor & lt; 0) {
qWarning( " MmlMpaddedNode::interpretSpacing(): could not parse \ " %s\ " " , value.toLatin1().data());
return 0;
}

if (percent)
factor /= 100.0;

QRect cr;
if (firstChild() == 0)
cr = QRect(0, 0, 0, 0);
else
cr = firstChild()- & gt; myRect();

int unit_size;

if (pseudo_unit.isEmpty())
unit_size = base_value;
else if (pseudo_unit == " width " )
unit_size = cr.width();
else if (pseudo_unit == " height " )
unit_size = -cr.top();
else if (pseudo_unit == " depth " )
unit_size = cr.bottom();
else {
bool unit_ok;
unit_size = MmlNode::interpretSpacing( " 1 " + pseudo_unit, & unit_ok);
if (!unit_ok) {
qWarning( " MmlMpaddedNode::interpretSpacing(): could not parse \ " %s\ " " , value.toLatin1().data());
return 0;
}
}

if (ok != 0)
*ok = true;

if (sign.isNull())
return (int)(factor*unit_size);
else if (sign == " + " )
return base_value + (int)(factor*unit_size);
else // sign == " - "
return base_value - (int)(factor*unit_size);
}

int MmlMpaddedNode::lspace() const
{
QString value = explicitAttribute( " lspace " );

if (value.isNull())
return 0;

bool ok;
int lspace = interpretSpacing(value, 0, & ok);

if (ok)
return lspace;

return 0;
}

int MmlMpaddedNode::width() const
{
int child_width = 0;
if (firstChild() != 0)
child_width = firstChild()- & gt; myRect().width();

QString value = explicitAttribute( " width " );
if (value.isNull())
return child_width;

bool ok;
int w = interpretSpacing(value, child_width, & ok);
if (ok)
return w;

return child_width;
}

int MmlMpaddedNode::height() const
{
QRect cr;
if (firstChild() == 0)
cr = QRect(0, 0, 0, 0);
else
cr = firstChild()- & gt; myRect();

QString value = explicitAttribute( " height " );
if (value.isNull())
return -cr.top();

bool ok;
int h = interpretSpacing(value, -cr.top(), & ok);
if (ok)
return h;

return -cr.top();
}

int MmlMpaddedNode::depth() const
{
QRect cr;
if (firstChild() == 0)
cr = QRect(0, 0, 0, 0);
else
cr = firstChild()- & gt; myRect();

QString value = explicitAttribute( " depth " );
if (value.isNull())
return cr.bottom();

bool ok;
int h = interpretSpacing(value, cr.bottom(), & ok);
if (ok)
return h;

return cr.bottom();
}

void MmlMpaddedNode::layoutSymbol()
{
MmlNode *child = firstChild();
if (child == 0)
return;

child- & gt; setRelOrigin(QPoint(0, 0));
}


QRect MmlMpaddedNode::symbolRect() const
{
return QRect(-lspace(), -height(), lspace() + width(), height() + depth());
}

// *******************************************************************
// QtMmlWidget
// *******************************************************************

/*!
\class QtMmlWidget

\brief The QtMmlWidget class renders mathematical formulas written in MathML 2.0.

QtMmlWidget implements the Presentation Markup subset of the
MathML 2.0 specification, with a few \link overview.html exceptions\endlink.

\code
QtMmlWidget *mmlWidget = new QtMmlWidget(this);
QString errorMsg;
int errorLine;
int errorColumn;
bool ok = mmlWidget- & gt; setContent(mmlText, & errorMsg, & errorLine, & errorColumn);
if (!ok) {
qWarning( " MathML error: %s, Line: %d, Column: %d " ,
errorMsg.latin1(), errorLine, errorColumn);
}
\endcode

*/


/*!
\enum QtMmlWidget::MmlFont

This ennumerated type is used in fontName() and setFontName() to
specify a font type.

\value NormalFont The default font type, used to render
expressions for which no mathvariant or fontfamily is specified,
or for which the " normal " mathvariant is specified.

\value FrakturFont The font type used to render expressions for
which the " fraktur " mathvariant is specified.

\value SansSerifFont The font type used to render expressions
for which the " sans-serif " mathvariant is specified.

\value ScriptFont The font type used to render expressions
for which the " script " mathvariant is specified.

\value MonospaceFont The font type used to render expressions
for which the " monospace " mathvariant is specified.

\value DoublestruckFont The font type used to render expressions
for which the " doublestruck " mathvariant is specified.

\sa setFontName() fontName() setBaseFontPointSize() baseFontPointSize()
*/

/*!
Constructs a QtMmlWidget object. The \a parent
parameter is passed to QFrame's constructor.
*/

QtMmlWidget::QtMmlWidget(QWidget *parent)
: QFrame(parent)
{
m_doc = new MmlDocument;
}

/*!
Destructs a QtMmlWidget object.
*/

QtMmlWidget::~QtMmlWidget()
{
delete m_doc;
}

/*!
Returns the name of the font used to render the font \a type.

\sa setFontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
*/

QString QtMmlWidget::fontName(MmlFont type) const
{
return m_doc- & gt; fontName(type);
}

/*!
Sets the name of the font used to render the font \a type to \a name.

\sa fontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
*/

void QtMmlWidget::setFontName(MmlFont type, const QString & name)
{
m_doc- & gt; setFontName(type, name);
m_doc- & gt; layout();
update();
}

/*!
If \a b is true, draws a red bounding rectangle around each
expression; if \a b is false, no such rectangle is drawn.
This is mostly useful for debugging MathML expressions.

\sa drawFrames()
*/

void QtMmlWidget::setDrawFrames(bool b)
{
g_draw_frames = b;
update();
}

/*!
Returns true if each expression should be drawn with a red
bounding rectangle; otherwise returns false.
This is mostly useful for debugging MathML expressions.

\sa setDrawFrames()
*/

bool QtMmlWidget::drawFrames() const
{
return g_draw_frames;
}

/*!
Clears the contents of this widget.
*/
void QtMmlWidget::clear()
{
m_doc- & gt; clear();
}

/*!
Returns the point size of the font used to render expressions
whose scriptlevel is 0.

\sa setBaseFontPointSize() fontName() setFontName()
*/

int QtMmlWidget::baseFontPointSize() const
{
return m_doc- & gt; baseFontPointSize();
}

/*!
Sets the point \a size of the font used to render expressions
whose scriptlevel is 0.

\sa baseFontPointSize() fontName() setFontName()
*/

void QtMmlWidget::setBaseFontPointSize(int size)
{
if (size & lt; g_min_font_point_size)
return;

m_doc- & gt; setBaseFontPointSize(size);
m_doc- & gt; layout();
update();
}

/*!
Returns the size of the formula in pixels.
*/

QSize QtMmlWidget::sizeHint() const
{
QSize size = m_doc- & gt; size();
if (size == QSize(0, 0))
return QSize(100, 50);
return m_doc- & gt; size();
}

/*!
Sets the MathML expression to be rendered. The expression is given
in the string \a text. If the expression is successfully parsed,
this method returns true; otherwise it returns false. If an error
occured \a errorMsg is set to a diagnostic message, while \a
errorLine and \a errorColumn contain the location of the error.
Any of \a errorMsg, \a errorLine and \a errorColumn may be 0,
in which case they are not set.

\a text should contain MathML 2.0 presentation markup elements enclosed
in a & lt; math & gt; element.
*/

bool QtMmlWidget::setContent(const QString & text, QString *errorMsg,
int *errorLine, int *errorColumn)
{
bool result = m_doc- & gt; setContent(text, errorMsg, errorLine, errorColumn);
if (result)
update();
return result;
}

/*! \internal */

void QtMmlWidget::paintEvent(QPaintEvent *e)
{
QFrame::paintEvent(e);
QPainter p(this);
if (e- & gt; rect().intersects(contentsRect()))
p.setClipRegion(e- & gt; region().intersect(contentsRect()));

QSize s = m_doc- & gt; size();
int x = (width() - s.width())/2;
int y = (height() - s.height())/2;
m_doc- & gt; paint( & p, QPoint(x, y));
}

/*! \internal */

void QtMmlWidget::dump() const
{
m_doc- & gt; dump();
}

// *******************************************************************
// Static helper functions
// *******************************************************************

static QString entityDeclarations()
{
QString result = " & lt; !DOCTYPE math [\n " ;

const EntitySpec *ent = g_xml_entity_data;
for (; ent- & gt; name != 0; ++ent) {
result += " \t & lt; !ENTITY " + QString(ent- & gt; name) + " \ " " + ent- & gt; value + " \ " & gt; \n " ;
}

result += " ] & gt; \n " ;

return result;
}

static int interpretSpacing(QString value, int em, int ex, bool *ok)
{
if (ok != 0)
*ok = true;

if (value == " thin " )
return 1;

if (value == " medium " )
return 2;

if (value == " thick " )
return 3;

struct HSpacingValue {
const char *name;
float factor;
};

static const HSpacingValue g_h_spacing_data[] =
{
{ " veryverythinmathspace " , (float) 0.0555556 },
{ " verythinmathspace " , (float) 0.111111 },
{ " thinmathspace " , (float) 0.166667 },
{ " mediummathspace " , (float) 0.222222 },
{ " thickmathspace " , (float) 0.277778 },
{ " verythickmathspace " , (float) 0.333333 },
{ " veryverythickmathspace " , (float) 0.388889 },
{ 0, (float) 0 }
};

const HSpacingValue *v = g_h_spacing_data;
for (; v- & gt; name != 0; ++v) {
if (value == v- & gt; name)
return (int)(em*v- & gt; factor);
}

if (value.endsWith( " em " )) {
value.truncate(value.length() - 2);
bool float_ok;
float factor = value.toFloat( & float_ok);
if (float_ok & & factor & gt; = 0)
return (int)(em*factor);
else {
qWarning( " interpretSpacing(): could not parse \ " %sem\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}
}

if (value.endsWith( " ex " )) {
value.truncate(value.length() - 2);
bool float_ok;
float factor = value.toFloat( & float_ok);
if (float_ok & & factor & gt; = 0)
return (int)(ex*factor);
else {
qWarning( " interpretSpacing(): could not parse \ " %sex\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}
}

if (value.endsWith( " cm " )) {
value.truncate(value.length() - 2);
bool float_ok;
float factor = value.toFloat( & float_ok);
if (float_ok & & factor & gt; = 0) {
Q_ASSERT(qApp- & gt; desktop() != 0);
QDesktopWidget *dw = qApp- & gt; desktop();
Q_ASSERT(dw- & gt; width() != 0);
Q_ASSERT(dw- & gt; widthMM() != 0);
return (int)(factor*10*dw- & gt; width()/dw- & gt; widthMM());
}
else {
qWarning( " interpretSpacing(): could not parse \ " %scm\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}
}

if (value.endsWith( " mm " )) {
value.truncate(value.length() - 2);
bool float_ok;
float factor = value.toFloat( & float_ok);
if (float_ok & & factor & gt; = 0) {
Q_ASSERT(qApp- & gt; desktop() != 0);
QDesktopWidget *dw = qApp- & gt; desktop();
Q_ASSERT(dw- & gt; width() != 0);
Q_ASSERT(dw- & gt; widthMM() != 0);
return (int)(factor*dw- & gt; width()/dw- & gt; widthMM());
}
else {
qWarning( " interpretSpacing(): could not parse \ " %smm\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}
}

if (value.endsWith( " in " )) {
value.truncate(value.length() - 2);
bool float_ok;
float factor = value.toFloat( & float_ok);
if (float_ok & & factor & gt; = 0) {
Q_ASSERT(qApp- & gt; desktop() != 0);
QDesktopWidget *dw = qApp- & gt; desktop();
Q_ASSERT(dw- & gt; width() != 0);
Q_ASSERT(dw- & gt; widthMM() != 0);
return (int)(factor*10*dw- & gt; width()/(2.54*dw- & gt; widthMM()));
}
else {
qWarning( " interpretSpacing(): could not parse \ " %sin\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}
}

if (value.endsWith( " px " )) {
value.truncate(value.length() - 2);
bool float_ok;
int i = (int) value.toFloat( & float_ok);
if (float_ok & & i & gt; = 0)
return i;
else {
qWarning( " interpretSpacing(): could not parse \ " %spx\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}
}

bool float_ok;
int i = (int)value.toFloat( & float_ok);
if (float_ok & & i & gt; = 0)
return i;

qWarning( " interpretSpacing(): could not parse \ " %s\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}

static int interpretPercentSpacing(QString value, int base, bool *ok)
{
if (!value.endsWith( " % " )) {
if (ok != 0)
*ok = false;
return 0;
}

value.truncate(value.length() - 1);
bool float_ok;
float factor = value.toFloat( & float_ok);
if (float_ok & & factor & gt; = 0) {
if (ok != 0)
*ok = true;
return (int)(base*factor/100.0);
}

qWarning( " interpretPercentSpacing(): could not parse \ " %s%%\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}

static int interpretPointSize(QString value, bool *ok)
{
if (!value.endsWith( " pt " )) {
if (ok != 0)
*ok = false;
return 0;
}

value.truncate(value.length() - 2);
bool float_ok;
int pt_size = (int) value.toFloat( & float_ok);
if (float_ok & & pt_size & gt; 0) {
if (ok != 0)
*ok = true;
return pt_size;
}

qWarning( " interpretPointSize(): could not parse \ " %spt\ " " , value.toLatin1().data());
if (ok != 0)
*ok = false;
return 0;
}

static const NodeSpec *mmlFindNodeSpec(Mml::NodeType type)
{
const NodeSpec *spec = g_node_spec_data;
for (; spec- & gt; type != Mml::NoNode; ++spec) {
if (type == spec- & gt; type) return spec;
}
return 0;
}

static const NodeSpec *mmlFindNodeSpec(const QString & tag)
{
const NodeSpec *spec = g_node_spec_data;
for (; spec- & gt; type != Mml::NoNode; ++spec) {
if (tag == spec- & gt; tag) return spec;
}
return 0;
}

static bool mmlCheckChildType(Mml::NodeType parent_type, Mml::NodeType child_type,
QString *error_str)
{
if (parent_type == Mml::UnknownNode || child_type == Mml::UnknownNode)
return true;

const NodeSpec *child_spec = mmlFindNodeSpec(child_type);
const NodeSpec *parent_spec = mmlFindNodeSpec(parent_type);

Q_ASSERT(parent_spec != 0);
Q_ASSERT(child_spec != 0);

QString allowed_child_types(parent_spec- & gt; child_types);
// null list means any child type is valid
if (allowed_child_types.isNull())
return true;

QString child_type_str = QString( " " ) + child_spec- & gt; type_str + " " ;
if (!allowed_child_types.contains(child_type_str)) {
if (error_str != 0)
*error_str = QString( " illegal child " )
+ child_spec- & gt; type_str
+ " for parent "
+ parent_spec- & gt; type_str;
return false;
}

return true;
}

static bool mmlCheckAttributes(Mml::NodeType child_type, const MmlAttributeMap & attr,
QString *error_str)
{
const NodeSpec *spec = mmlFindNodeSpec(child_type);
Q_ASSERT(spec != 0);

QString allowed_attr(spec- & gt; attributes);
// empty list means any attr is valid
if (allowed_attr.isEmpty())
return true;

MmlAttributeMap::const_iterator it = attr.begin(), end = attr.end();
for (; it != end; ++it) {
QString name = it.key();

if (name.indexOf(':') != -1)
continue;

QString padded_name = " " + name + " " ;
if (!allowed_attr.contains(padded_name)) {
if (error_str != 0)
*error_str = QString( " illegal attribute " )
+ name
+ " in "
+ spec- & gt; type_str;
return false;
}
}

return true;
}

static int attributeIndex(const QString & name)
{
for (unsigned i = 0; i & lt; g_oper_spec_rows; ++i) {
if (name == g_oper_spec_names[i])
return i;
}
return -1;
}

static QString decodeEntityValue(QString literal)
{
QString result;

while (!literal.isEmpty()) {

if (!literal.startsWith( " & # " )) {
qWarning(( " decodeEntityValue(): bad entity literal: \ " " + literal + " \ " " ).toLatin1().data());
return QString::null;
}

literal = literal.right(literal.length() - 2);

int i = literal.indexOf(';');
if (i == -1) {
qWarning(( " decodeEntityValue(): bad entity literal: \ " " + literal + " \ " " ).toLatin1().data());
return QString::null;
}

QString char_code = literal.left(i);
literal = literal.right(literal.length() - i - 1);

if (char_code.isEmpty()) {
qWarning(( " decodeEntityValue(): bad entity literal: \ " " + literal + " \ " " ).toLatin1().data());
return QString::null;
}

if (char_code.at(0) == 'x') {
char_code = char_code.right(char_code.length() - 1);
bool ok;
unsigned c = char_code.toUInt( & ok, 16);
if (!ok) {
qWarning(( " decodeEntityValue(): bad entity literal: \ " " + literal + " \ " " ).toLatin1().data());
return QString::null;
}
result += QChar(c);
}
else {
bool ok;
unsigned c = char_code.toUInt( & ok, 10);
if (!ok) {
qWarning(( " decodeEntityValue(): bad entity literal: \ " " + literal + " \ " " ).toLatin1().data());
return QString::null;
}
result += QChar(c);
}
}

return result;
}

static const EntitySpec *searchEntitySpecData(const QString & value, const EntitySpec *from = 0)
{
const EntitySpec *ent = from;
if (ent == 0)
ent = g_xml_entity_data;
for (; ent- & gt; name != 0; ++ent) {
QString ent_value = decodeEntityValue(ent- & gt; value);
if (value == ent_value)
return ent;
}
return 0;
}

struct OperSpecSearchResult
{
OperSpecSearchResult() { prefix_form = infix_form = postfix_form = 0; }

const OperSpec *prefix_form,
*infix_form,
*postfix_form;

const OperSpec * & getForm(Mml::FormType f);
bool haveForm(Mml::FormType f)
{ return getForm(f) != 0; }
void addForm(const OperSpec *spec)
{ getForm(spec- & gt; form) = spec; }
};

const OperSpec * & OperSpecSearchResult::getForm(Mml::FormType f)
{
switch (f) {
case Mml::PrefixForm:
return prefix_form;
case Mml::InfixForm:
return infix_form;
case Mml::PostfixForm:
return postfix_form;
}
return postfix_form; // just to avoid warning
}

/*
Searches g_oper_spec_data and returns any instance of operator name. There may
be more instances, but since the list is sorted, they will be next to each other.
*/
static const OperSpec *searchOperSpecData(const QString & name)
{
const char *name_latin1 = name.toLatin1().data();

// binary search
// establish invariant g_oper_spec_data[begin].name & lt; name & lt; g_oper_spec_data[end].name

int cmp = qstrcmp(name_latin1, g_oper_spec_data[0].name);
if (cmp & lt; 0)
return 0;

if (cmp == 0)
return g_oper_spec_data;

uint begin = 0;
uint end = g_oper_spec_count;

// invariant holds
while (end - begin & gt; 1) {
uint mid = (begin + end)/2;

const OperSpec *spec = g_oper_spec_data + mid;
int cmp = qstrcmp(name_latin1, spec- & gt; name);
if (cmp & lt; 0)
end = mid;
else if (cmp & gt; 0)
begin = mid;
else
return spec;
}

return 0;
}

/*
This searches g_oper_spec_data until at least one name in name_list is found with FormType form,
or until name_list is exhausted. The idea here is that if we don't find the operator in the
specified form, we still want to use some other available form of that operator.
*/
static OperSpecSearchResult _mmlFindOperSpec(const QStringList & name_list, Mml::FormType form)
{
OperSpecSearchResult result;

QStringList::const_iterator it = name_list.begin();
for (; it != name_list.end(); ++it) {
const QString & name = *it;

const OperSpec *spec = searchOperSpecData(name);

if (spec == 0)
continue;

const char *name_latin1 = name.toLatin1().data();

// backtrack to the first instance of name
while (spec & gt; g_oper_spec_data & & qstrcmp((spec - 1)- & gt; name, name_latin1) == 0)
--spec;

// iterate over instances of name until the instances are exhausted or until we
// find an instance in the specified form.
do {
result.addForm(spec++);
if (result.haveForm(form))
break;
} while (qstrcmp(spec- & gt; name, name_latin1) == 0);

if (result.haveForm(form))
break;
}

return result;
}

/*
text is a string between & lt; mo & gt; and & lt; /mo & gt; . It can be a character ('+'), an
entity reference ( " & infin; " ) or a character reference ( " & #x0221E " ). Our
job is to find an operator spec in the operator dictionary (g_oper_spec_data)
that matches text. Things are further complicated by the fact, that many
operators come in several forms (prefix, infix, postfix).

If available, this function returns an operator spec matching text in the specified
form. If such operator is not available, returns an operator spec that matches
text, but of some other form in the preference order specified by the MathML spec.
If that's not available either, returns the default operator spec.
*/
static const OperSpec *mmlFindOperSpec(const QString & text, Mml::FormType form)
{
QStringList name_list;
name_list.append(text);

// First, just try to find text in the operator dictionary.
OperSpecSearchResult result = _mmlFindOperSpec(name_list, form);

if (!result.haveForm(form)) {
// Try to find other names for the operator represented by text.

const EntitySpec *ent = 0;
for (;;) {
ent = searchEntitySpecData(text, ent);
if (ent == 0)
break;
name_list.append(' & ' + QString(ent- & gt; name) + ';');
++ent;
}

result = _mmlFindOperSpec(name_list, form);
}

const OperSpec *spec = result.getForm(form);
if (spec != 0)
return spec;

spec = result.getForm(Mml::InfixForm);
if (spec != 0)
return spec;

spec = result.getForm(Mml::PostfixForm);
if (spec != 0)
return spec;

spec = result.getForm(Mml::PrefixForm);
if (spec != 0)
return spec;

return & g_oper_spec_defaults;
}

static QString mmlDictAttribute(const QString & name, const OperSpec *spec)
{
int i = attributeIndex(name);
if (i == -1)
return QString::null;
else
return spec- & gt; attributes[i];
}

static uint interpretMathVariant(const QString & value, bool *ok)
{
struct MathVariantValue {
const char *value;
uint mv;
};

static const MathVariantValue g_mv_data[] =
{
{ " normal " , Mml::NormalMV },
{ " bold " , Mml::BoldMV },
{ " italic " , Mml::ItalicMV },
{ " bold-italic " , Mml::BoldMV | Mml::ItalicMV },
{ " double-struck " , Mml::DoubleStruckMV },
{ " bold-fraktur " , Mml::BoldMV | Mml::FrakturMV },
{ " script " , Mml::ScriptMV },
{ " bold-script " , Mml::BoldMV | Mml::ScriptMV },
{ " fraktur " , Mml::FrakturMV },
{ " sans-serif " , Mml::SansSerifMV },
{ " bold-sans-serif " , Mml::BoldMV | Mml::SansSerifMV },
{ " sans-serif-italic " , Mml::SansSerifMV | Mml::ItalicMV },
{ " sans-serif-bold-italic " , Mml::SansSerifMV | Mml::ItalicMV | Mml::BoldMV },
{ " monospace " , Mml::MonospaceMV },
{ 0, 0 }
};

const MathVariantValue *v = g_mv_data;
for (; v- & gt; value != 0; ++v) {
if (value == v- & gt; value) {
if (ok != 0)
*ok = true;
return v- & gt; mv;
}
}

if (ok != 0)
*ok = false;

qWarning( " interpretMathVariant(): could not parse value: \ " %s\ " " , value.toLatin1().data());

return Mml::NormalMV;
}

static Mml::FormType interpretForm(const QString & value, bool *ok)
{
if (ok != 0)
*ok = true;

if (value == " prefix " )
return Mml::PrefixForm;
if (value == " infix " )
return Mml::InfixForm;
if (value == " postfix " )
return Mml::PostfixForm;

if (ok != 0)
*ok = false;

qWarning( " interpretForm(): could not parse value \ " %s\ " " , value.toLatin1().data());
return Mml::InfixForm;
}

static Mml::ColAlign interpretColAlign(const QString & value_list, uint colnum, bool *ok)
{
QString value = interpretListAttr(value_list, colnum, " center " );

if (ok != 0)
*ok = true;

if (value == " left " )
return Mml::ColAlignLeft;
if (value == " right " )
return Mml::ColAlignRight;
if (value == " center " )
return Mml::ColAlignCenter;

if (ok != 0)
*ok = false;

qWarning( " interpretColAlign(): could not parse value \ " %s\ " " , value.toLatin1().data());
return Mml::ColAlignCenter;
}

static Mml::RowAlign interpretRowAlign(const QString & value_list, uint rownum, bool *ok)
{
QString value = interpretListAttr(value_list, rownum, " axis " );

if (ok != 0)
*ok = true;

if (value == " top " )
return Mml::RowAlignTop;
if (value == " center " )
return Mml::RowAlignCenter;
if (value == " bottom " )
return Mml::RowAlignBottom;
if (value == " baseline " )
return Mml::RowAlignBaseline;
if (value == " axis " )
return Mml::RowAlignAxis;

if (ok != 0)
*ok = false;

qWarning( " interpretRowAlign(): could not parse value \ " %s\ " " , value.toLatin1().data());
return Mml::RowAlignAxis;
}

static QString interpretListAttr(const QString & value_list, int idx, const QString & def)
{
QStringList l = value_list.split(' ');

if (l.count() == 0)
return def;

if (l.count() & lt; = idx)
return l[l.count() - 1];
else
return l[idx];
}

static Mml::FrameType interpretFrameType(const QString & value_list, uint idx, bool *ok)
{
if (ok != 0)
*ok = true;

QString value = interpretListAttr(value_list, idx, " none " );

if (value == " none " )
return Mml::FrameNone;
if (value == " solid " )
return Mml::FrameSolid;
if (value == " dashed " )
return Mml::FrameDashed;

if (ok != 0)
*ok = false;

qWarning( " interpretFrameType(): could not parse value \ " %s\ " " , value.toLatin1().data());
return Mml::FrameNone;
}


static Mml::FrameSpacing interpretFrameSpacing(const QString & value_list, int em, int ex, bool *ok)
{
Mml::FrameSpacing fs;

QStringList l = value_list.split(' ');
if (l.count() != 2) {
qWarning( " interpretFrameSpacing: could not parse value \ " %s\ " " , value_list.toLatin1().data());
if (ok != 0)
*ok = false;
return Mml::FrameSpacing((int)(0.4*em), (int)(0.5*ex));
}

bool hor_ok, ver_ok;
fs.m_hor = interpretSpacing(l[0], em, ex, & hor_ok);
fs.m_ver = interpretSpacing(l[1], em, ex, & ver_ok);

if (ok != 0)
*ok = hor_ok & & ver_ok;

return fs;
}

static QFont interpretDepreciatedFontAttr(const MmlAttributeMap & font_attr, QFont & fn, int em, int ex)
{
if (font_attr.contains( " fontsize " )) {
QString value = font_attr[ " fontsize " ];

for (;;) {

bool ok;
int ptsize = interpretPointSize(value, & ok);
if (ok) {
fn.setPointSize(ptsize);
break;
}

ptsize = interpretPercentSpacing(value, fn.pointSize(), & ok);
if (ok) {
fn.setPointSize(ptsize);
break;
}

int size = interpretSpacing(value, em, ex, & ok);
if (ok) {
fn.setPixelSize(size);
break;
}

break;
}
}

if (font_attr.contains( " fontweight " )) {
QString value = font_attr[ " fontweight " ];
if (value == " normal " )
fn.setBold(false);
else if (value == " bold " )
fn.setBold(true);
else
qWarning( " interpretDepreciatedFontAttr(): could not parse fontweight \ " %s\ " " , value.toLatin1().data());
}

if (font_attr.contains( " fontstyle " )) {
QString value = font_attr[ " fontstyle " ];
if (value == " normal " )
fn.setItalic(false);
else if (value == " italic " )
fn.setItalic(true);
else
qWarning( " interpretDepreciatedFontAttr(): could not parse fontstyle \ " %s\ " " , value.toLatin1().data());
}

if (font_attr.contains( " fontfamily " )) {
QString value = font_attr[ " fontfamily " ];
fn.setFamily(value);
}

return fn;
}

static QFont interpretMathSize(QString value, QFont & fn, int em, int ex, bool *ok)
{
if (ok != 0)
*ok = true;

if (value == " small " ) {
fn.setPointSize((int)(fn.pointSize()*0.7));
return fn;
}

if (value == " normal " )
return fn;

if (value == " big " ) {
fn.setPointSize((int)(fn.pointSize()*1.5));
return fn;
}

bool size_ok;

int ptsize = interpretPointSize(value, & size_ok);
if (size_ok) {
fn.setPointSize(ptsize);
return fn;
}

int size = interpretSpacing(value, em, ex, & size_ok);
if (size_ok) {
fn.setPixelSize(size);
return fn;
}

if (ok != 0)
*ok = false;
qWarning( " interpretMathSize(): could not parse mathsize \ " %s\ " " , value.toLatin1().data());
return fn;
}

/*!
\class QtMmlDocument

\brief The QtMmlDocument class renders mathematical formulas written in MathML 2.0.

This class provides a direct API to the rendering engine used by
QtMmlWidget. It can be used to paint MathML inside other widgets.

All methods work the same as the corresponding methods in QtMmlWidget.
*/

/*!
Constructs an empty MML document.
*/
QtMmlDocument::QtMmlDocument()
{
m_doc = new MmlDocument;
}

/*!
Destroys the MML document.
*/
QtMmlDocument::~QtMmlDocument()
{
delete m_doc;
}

/*!
Clears the contents of this MML document.
*/
void QtMmlDocument::clear()
{
m_doc- & gt; clear();
}

/*!
Sets the MathML expression to be rendered. The expression is given
in the string \a text. If the expression is successfully parsed,
this method returns true; otherwise it returns false. If an error
occured \a errorMsg is set to a diagnostic message, while \a
errorLine and \a errorColumn contain the location of the error.
Any of \a errorMsg, \a errorLine and \a errorColumn may be 0,
in which case they are not set.

\a text should contain MathML 2.0 presentation markup elements enclosed
in a & lt; math & gt; element.
*/
bool QtMmlDocument::setContent(QString text, QString *errorMsg,
int *errorLine, int *errorColumn)
{
return m_doc- & gt; setContent(text, errorMsg, errorLine, errorColumn);
}

/*!
Renders this MML document with the painter \a p at position \a pos.
*/
void QtMmlDocument::paint(QPainter *p, const QPoint & pos) const
{
m_doc- & gt; paint(p, pos);
}

/*!
Returns the size of this MML document, as rendered, in pixels.
*/
QSize QtMmlDocument::size() const
{
return m_doc- & gt; size();
}

/*!
Returns the name of the font used to render the font \a type.

\sa setFontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
*/
QString QtMmlDocument::fontName(QtMmlWidget::MmlFont type) const
{
return m_doc- & gt; fontName(type);
}

/*!
Sets the name of the font used to render the font \a type to \a name.

\sa fontName() setBaseFontPointSize() baseFontPointSize() QtMmlWidget::MmlFont
*/
void QtMmlDocument::setFontName(QtMmlWidget::MmlFont type, const QString & name)
{
m_doc- & gt; setFontName(type, name);
}

/*!
Returns the point size of the font used to render expressions
whose scriptlevel is 0.

\sa setBaseFontPointSize() fontName() setFontName()
*/
int QtMmlDocument::baseFontPointSize() const
{
return m_doc- & gt; baseFontPointSize();
}

/*!
Sets the point \a size of the font used to render expressions
whose scriptlevel is 0.

\sa baseFontPointSize() fontName() setFontName()
*/
void QtMmlDocument::setBaseFontPointSize(int size)
{
m_doc- & gt; setBaseFontPointSize(size);
}


MiniKombajnPomiarowy3_3_rc3.7z > oscyloskop.cpp

#include " oscyloskop.h "

int bufGraph[Xsize/2];
int bufGraph2[Xsize/2];
extern QString sts;

static int buff[1024];

Oscyloskop::Oscyloskop(QWidget* parent)
{
Oscyloskop::parent = parent;

fileOpened = false;

QStringList tlist;
//tlist & lt; & lt; " 2u " & lt; & lt; " 5u " & lt; & lt; " 8u " & lt; & lt; " 10u " & lt; & lt; " 20u " & lt; & lt; " 50u " & lt; & lt; " 100u " & lt; & lt; " 200u " & lt; & lt; " 500u " & lt; & lt; " 1m " & lt; & lt; " 2m " & lt; & lt; " 5m " & lt; & lt; " 10m " & lt; & lt; " 20m " & lt; & lt; " 50m " ;
//tlist & lt; & lt; " 50ms/dz " & lt; & lt; " 20ms/dz " & lt; & lt; " 10ms/dz " & lt; & lt; " 5ms/dz " & lt; & lt; " 2ms/dz " & lt; & lt; " 1ms/dz " & lt; & lt; " 500us/dz " & lt; & lt; " 200us/dz " & lt; & lt; " 100us/dz "
// & lt; & lt; " 50us/dz " & lt; & lt; " 20us/dz " & lt; & lt; " 10us/dz " & lt; & lt; " 8us/dz " & lt; & lt; " 5us/dz " & lt; & lt; " 2us/dz " ;
tlist & lt; & lt; " 100ms/dz " & lt; & lt; " 40ms/dz " & lt; & lt; " 20ms/dz " & lt; & lt; " 10ms/dz " & lt; & lt; " 4ms/dz " & lt; & lt; " 2ms/dz " & lt; & lt; " 1ms/dz " & lt; & lt; " 400us/dz " & lt; & lt; " 200us/dz " & lt; & lt; " 100us/dz "
& lt; & lt; " 40us/dz " & lt; & lt; " 20us/dz " & lt; & lt; " 16us/dz " ;
tlist2 & lt; & lt; " 10u " & lt; & lt; " 8u " & lt; & lt; " 5u " & lt; & lt; " 2u " ;
//tSpin = new QwwTextSpinBox(tlist, parent);
tSpin = new QComboBox(parent);
tSpin- & gt; setGeometry(100, 580, 110, 20);
tSpin- & gt; addItems(tlist);
//tSpin- & gt; setSuffix( " s/dz " );
//tSpin- & gt; setRange(0,14);
//tSpin- & gt; setValue(7);
tSpin- & gt; setCurrentIndex(7);
tSpin- & gt; setDisabled(1);
QObject::connect(tSpin, SIGNAL(activated(int)), this, SLOT(tSlot()));

xyBox = new QCheckBox( " XY " , parent);
xyBox- & gt; setGeometry(220, 580, 50, 20);
xyBox- & gt; setDisabled(1);
connect(xyBox, SIGNAL(toggled(bool)), this, SLOT(xySlot(bool)));

QStringList vlist;
//vlist & lt; & lt; " 50m " & lt; & lt; " 100m " & lt; & lt; " 200m " & lt; & lt; " 500m " & lt; & lt; " 1 " & lt; & lt; " 2 " & lt; & lt; " 5 " ;
vlist & lt; & lt; " 2.5V/dz " & lt; & lt; " 1V/dz " & lt; & lt; " 500mV/dz " & lt; & lt; " 250mV/dz " & lt; & lt; " 100mV/dz " & lt; & lt; " 50mV/dz " & lt; & lt; " 25mV/dz " ;
//vSpin = new QwwTextSpinBox(vlist, parent);
vSpin = new QComboBox(parent);
vSpin- & gt; setGeometry(270, 580, 110, 20);
vSpin- & gt; addItems(vlist);
vSpin- & gt; setDisabled(1);
QObject::connect(vSpin, SIGNAL(activated(int)), this, SLOT(vSlot()));

v2Spin = new QComboBox(parent);
v2Spin- & gt; setGeometry(410, 580, 110, 20);
v2Spin- & gt; addItems(vlist);
v2Spin- & gt; setDisabled(1);
QObject::connect(v2Spin, SIGNAL(activated(int)), this, SLOT(vSlot()));

xScroll = new QScrollBar(Qt::Horizontal, parent);
xScroll- & gt; setGeometry(0, Ysize+y_s+10, Xsize+x_s*2, 20);
xScroll- & gt; setMinimum(-192);
xScroll- & gt; setMaximum(192);
xScroll- & gt; setDisabled(1);
QObject::connect(xScroll, SIGNAL(valueChanged(int)), this, SLOT(xPosSlot()));

yScroll = new QScrollBar(Qt::Vertical, parent);
yScroll- & gt; setGeometry(Xsize+x_s*2, y_s-7, 20,Ysize+17);
yScroll- & gt; setMinimum(-256);
yScroll- & gt; setMaximum(256);
yScroll- & gt; setDisabled(1);
QObject::connect(yScroll, SIGNAL(valueChanged(int)), this, SLOT(yPosSlot()));

y2Scroll = new QScrollBar(Qt::Vertical, parent);
y2Scroll- & gt; setGeometry(Xsize+x_s*2+20, y_s-7, 20,Ysize+17);
y2Scroll- & gt; setMinimum(-256);
y2Scroll- & gt; setMaximum(256);
y2Scroll- & gt; setDisabled(1);
QObject::connect(y2Scroll, SIGNAL(valueChanged(int)), this, SLOT(yPosSlot()));

channel2box = new QCheckBox(parent);
channel2box- & gt; setGeometry(390, 580, 20, 20);
channel2box- & gt; setDisabled(1);
QObject::connect(channel2box, SIGNAL(clicked()), this, SLOT(channel2Slot()));

QStringList trigTypeList;
trigTypeList & lt; & lt; " ---- " & lt; & lt; " Norm " & lt; & lt; " Auto " & lt; & lt; " Single " ;
trigTypeCombo = new QComboBox(parent);
trigTypeCombo- & gt; setGeometry(550, 580, 65, 20);
trigTypeCombo- & gt; addItems(trigTypeList);
trigTypeCombo- & gt; setDisabled(1);
QObject::connect(trigTypeCombo, SIGNAL(activated(int)), this, SLOT(trigSlot()));

QStringList trigEdgeList;
trigEdgeList & lt; & lt; " Fall " & lt; & lt; " Ris " ;
trigEdgeCombo = new QComboBox(parent);
trigEdgeCombo- & gt; setGeometry(620, 580, 55, 20);
trigEdgeCombo- & gt; addItems(trigEdgeList);
trigEdgeCombo- & gt; setDisabled(1);
QObject::connect(trigEdgeCombo, SIGNAL(activated(int)), this, SLOT(trigSlot()));

QStringList trigFList;
trigFList & lt; & lt; " LF " & lt; & lt; " HF " ;
trigFCombo = new QComboBox(parent);
trigFCombo- & gt; setGeometry(680, 580, 50, 20);
trigFCombo- & gt; addItems(trigFList);
trigFCombo- & gt; setDisabled(1);
QObject::connect(trigFCombo, SIGNAL(activated(int)), this, SLOT(trigSlot()));

trigLevSpin = new QSpinBox(parent);
trigLevSpin- & gt; setGeometry(740, 580, 90, 20);
trigLevSpin- & gt; setRange(-40000, 40000);
trigLevSpin- & gt; setSuffix( " mV " );
trigLevSpin- & gt; setDisabled(1);
QObject::connect(trigLevSpin, SIGNAL(valueChanged(int)), this, SLOT(trigSlot()));

curVBox = new QCheckBox( " Time " , parent);
curVBox- & gt; setGeometry(Xpanel+10, 320, 80, 20);
curVBox- & gt; setDisabled(1);
QObject::connect(curVBox, SIGNAL(clicked()), this, SLOT(cursorSlot()));

curHBox = new QCheckBox( " Voltage " , parent);
curHBox- & gt; setGeometry(Xpanel+10, 400, 80, 20);
curHBox- & gt; setDisabled(1);
QObject::connect(curHBox, SIGNAL(clicked()), this, SLOT(cursorSlot()));

// openBut = new QPushButton( " OPEN " , parent);
// openBut- & gt; setGeometry(880,510,100,20);
// openBut- & gt; setDisabled(1);
// QObject::connect(openBut, SIGNAL(clicked()), this, SLOT(openSlot()));

saveBut = new QPushButton( " SAVE " , parent);
saveBut- & gt; setGeometry(880,540,100,20);
saveBut- & gt; setDisabled(1);
QObject::connect(saveBut, SIGNAL(clicked()), this, SLOT(saveSlot()));


xPosLabel = new QLabel(tr( " Xpos: 0 " ), parent);
xPosLabel- & gt; setGeometry(Xpanel, Ypanel, XsizePanel/2, 20);
xPosLabel- & gt; setDisabled(1);

yPosLabel = new QLabel(tr( " Ypos1: 0 " ), parent);
yPosLabel- & gt; setGeometry(Xpanel, Ypanel+20, XsizePanel/2, 20);
yPosLabel- & gt; setDisabled(1);

yPos2Label = new QLabel(tr( " Ypos2: 0 " ), parent);
yPos2Label- & gt; setGeometry(Xpanel+XsizePanel/2, Ypanel+20, XsizePanel/2, 20);
yPos2Label- & gt; setDisabled(1);

labelRMS = new QLabel( " CH1 RMS: 0V " , parent);
labelRMS- & gt; setGeometry(Xpanel, 100, XsizePanel, 20);
labelRMS- & gt; setDisabled(1);

labelRMS2 = new QLabel( " CH2 RMS: 0V " , parent);
labelRMS2- & gt; setGeometry(Xpanel, 120, XsizePanel, 20);
labelRMS2- & gt; setDisabled(1);

labelAvg = new QLabel( " CH1 Avg: 0V " , parent);
labelAvg- & gt; setGeometry(Xpanel, 150, XsizePanel, 20);
labelAvg- & gt; setDisabled(1);

labelAvg2 = new QLabel( " CH2 Avg: 0V " , parent);
labelAvg2- & gt; setGeometry(Xpanel, 170, XsizePanel, 20);
labelAvg2- & gt; setDisabled(1);

labelVpp = new QLabel( " CH1 Vpp = 0V " , parent);
labelVpp- & gt; setGeometry(Xpanel, 200, XsizePanel, 20);
labelVpp- & gt; setDisabled(1);

labelVpp2 = new QLabel( " CH2 Vpp = 0V " , parent);
labelVpp2- & gt; setGeometry(Xpanel, 220, XsizePanel, 20);
labelVpp2- & gt; setDisabled(1);

labelFreq = new QLabel( " CH1 Freq = 0Hz " , parent);
labelFreq- & gt; setGeometry(Xpanel, 250, XsizePanel, 20);
labelFreq- & gt; setDisabled(1);

labelFreq2 = new QLabel( " CH2 Freq = 0Hz " , parent);
labelFreq2- & gt; setGeometry(Xpanel, 270, XsizePanel, 20);
labelFreq2- & gt; setDisabled(1);

cursorsLabel = new QLabel( " Cursors " , parent);
cursorsLabel- & gt; setGeometry(Xpanel, 300, XsizePanel, 20);
cursorsLabel- & gt; setDisabled(1);

curTimeLabel = new QLabel( " Time: 0s " , parent);
curTimeLabel- & gt; setGeometry(Xpanel+10, 340, XsizePanel, 20);
curTimeLabel- & gt; setDisabled(1);

curFreqLabel = new QLabel( " Freq: 0Hz " , parent);
curFreqLabel- & gt; setGeometry(Xpanel+10, 360, XsizePanel, 20);
curFreqLabel- & gt; setDisabled(1);

curVolt1Label = new QLabel( " Voltage: 0V " , parent);
curVolt1Label- & gt; setGeometry(Xpanel+10, 420, XsizePanel, 20);
curVolt1Label- & gt; setDisabled(1);

curVolt2Label = new QLabel( " Voltage: 0V " , parent);
curVolt2Label- & gt; setGeometry(Xpanel+10, 440, XsizePanel, 20);
curVolt2Label- & gt; setDisabled(1);


trig = 0;
level = 0;
counter = 0;
wzw = 0;
trigForce = 0;
timeBase = 7;
gain1 = 0;
gain2 = 0;
xPos = 0;
yPos = 0;
yPos2 = 0;

cursorAV = 0;
cursorBV = 0;
cursorAH = 0;
cursorBH = 0;

int i;
for(i=0; i & lt; 1024; i++)
buff[i] = 0;
}


void Oscyloskop::show()
{
vSpin- & gt; show();
v2Spin- & gt; show();
tSpin- & gt; show();
xScroll- & gt; show();
yScroll- & gt; show();
y2Scroll- & gt; show();
xyBox- & gt; show();
channel2box- & gt; show();
trigTypeCombo- & gt; show();
trigEdgeCombo- & gt; show();
trigFCombo- & gt; show();
trigLevSpin- & gt; show();
// openBut- & gt; show();
saveBut- & gt; show();
labelRMS- & gt; show();
labelRMS2- & gt; show();
labelAvg- & gt; show();
labelAvg2- & gt; show();
labelVpp- & gt; show();
labelVpp2- & gt; show();
labelFreq- & gt; show();
labelFreq2- & gt; show();
xPosLabel- & gt; show();
yPos2Label- & gt; show();
yPosLabel- & gt; show();
curHBox- & gt; show();
curVBox- & gt; show();
cursorsLabel- & gt; show();
curVolt1Label- & gt; show();
curVolt2Label- & gt; show();
curTimeLabel- & gt; show();
curFreqLabel- & gt; show();

file = new QFile( " oscLog.txt " );
if(file- & gt; open(QFile::WriteOnly | QFile::Text))
{

fileOpened = true;
//file.close();
}

}

void Oscyloskop::hide()
{
vSpin- & gt; hide();
v2Spin- & gt; hide();
tSpin- & gt; hide();
xScroll- & gt; hide();
yScroll- & gt; hide();
y2Scroll- & gt; hide();
xyBox- & gt; hide();
channel2box- & gt; hide();
trigTypeCombo- & gt; hide();
trigEdgeCombo- & gt; hide();
trigFCombo- & gt; hide();
trigLevSpin- & gt; hide();
// openBut- & gt; hide();
saveBut- & gt; hide();
labelRMS- & gt; hide();
labelRMS2- & gt; hide();
labelAvg- & gt; hide();
labelVpp- & gt; hide();
labelFreq- & gt; hide();
labelAvg2- & gt; hide();
labelVpp2- & gt; hide();
labelFreq2- & gt; hide();
xPosLabel- & gt; hide();
yPos2Label- & gt; hide();
yPosLabel- & gt; hide();
curHBox- & gt; hide();
curVBox- & gt; hide();
cursorsLabel- & gt; hide();
curVolt1Label- & gt; hide();
curVolt2Label- & gt; hide();
curTimeLabel- & gt; hide();
curFreqLabel- & gt; hide();

if(fileOpened)
{
file- & gt; close();
fileOpened = false;
}
}

void Oscyloskop::enable()
{
vSpin- & gt; setEnabled(1);
tSpin- & gt; setEnabled(1);
xyBox- & gt; setEnabled(1);
xScroll- & gt; setEnabled(1);
yScroll- & gt; setEnabled(1);
channel2box- & gt; setEnabled(1);
trigTypeCombo- & gt; setEnabled(1);
trigEdgeCombo- & gt; setEnabled(1);
trigFCombo- & gt; setEnabled(1);
trigLevSpin- & gt; setEnabled(1);
// openBut- & gt; setEnabled(1);
saveBut- & gt; setEnabled(1);
labelRMS- & gt; setEnabled(1);
labelAvg- & gt; setEnabled(1);
labelVpp- & gt; setEnabled(1);
labelFreq- & gt; setEnabled(1);
xPosLabel- & gt; setEnabled(1);
yPos2Label- & gt; setEnabled(1);
yPosLabel- & gt; setEnabled(1);
curHBox- & gt; setEnabled(1);
curVBox- & gt; setEnabled(1);
cursorsLabel- & gt; setEnabled(1);

}

QString Oscyloskop::value(double val)
{
if(qAbs(val) & gt; = 30000)
{
val = val/1000;
return QString::number(val, 'f', 1) + " k " ;
}else if(qAbs(val) & gt; = 3000)
{
val = val/1000;
return QString::number(val, 'f', 2) + " k " ;
}else if(qAbs(val) & gt; = 300)
{
return QString::number(val, 'f', 0);
}else if(qAbs(val) & gt; = 30)
{
return QString::number(val, 'f', 1);
}else if(qAbs(val) & gt; = 3)
{
return QString::number(val, 'f', 2);
}else if(qAbs(val) & gt; = 0.3)
{
val = val*1000;
return QString::number(val, 'f', 0) + " m " ;
}else if(qAbs(val) & gt; = 0.03)
{
val = val*1000;
return QString::number(val, 'f', 1) + " m " ;
}else if(qAbs(val) & gt; = 0.003)
{
val = val*1000;
return QString::number(val, 'f', 2) + " m " ;
}else if(qAbs(val) & gt; = 0.0003)
{
val = val*1000000;
return QString::number(val, 'f', 0) + " u " ;
}else if(qAbs(val) & gt; = 0.00003)
{
val = val*1000000;
return QString::number(val, 'f', 1) + " u " ;
}else
{
val = val*1000000;
return QString::number(val, 'f', 2) + " u " ;
}

}

void Oscyloskop::start()
{
if(channel2box- & gt; checkState() == Qt::Checked) //2 channels
comPort- & gt; osc2chStart();
else
comPort- & gt; osc1chStart();
comPort- & gt; setTimeBase(timeBase);
comPort- & gt; setGain1(gain1);
comPort- & gt; setGain2(gain2);
}

bool checkFallingLF(int* in, int i, int lev)
{
lev*=3;
int top = in[i-2] + in[i-1] + in[i];
int bot = in[i+1] + in[i+2] + in[i+3];
if(top & gt; lev & & bot & lt; lev)
return true;
else
return false;
}

bool checkRisingLF(int* in, int i, int lev)
{
lev*=3;
int top = in[i-2] + in[i-1] + in[i];
int bot = in[i+1] + in[i+2] + in[i+3];
if(top & lt; lev & & bot & gt; lev)
return true;
else
return false;
}

bool checkFallingHF(int* in, int i, int lev)
{
int top = in[i];
int bot = in[i+1];
if(top & gt; lev + 4 & & bot & lt; lev - 4)
return true;
else
return false;
}

bool checkRisingHF(int* in, int i, int lev)
{
int top = in[i];
int bot = in[i+1];
if(bot & gt; lev + 4 & & top & lt; lev - 4)
return true;
else
return false;
}

int getTrigIndex(int* in, int length, int window, int pos, int lev, int type)
{
if(pos & gt; window || window & gt; length)
return -1;

int minPos = pos;
int maxPos = length - window + pos;
int i = 0;
for(i = minPos+2; i & lt; maxPos-3; i++)
{
switch(type)
{
case 0: // falling LF
if(checkFallingLF(in, i, lev))
return i;
break;
case 1: //rising LF
if(checkRisingLF(in, i, lev))
return i;
break;
case 2: //falling HF
if(checkFallingHF(in, i, lev))
return i;
break;
case 3: //falling HF
if(checkRisingHF(in, i, lev))
return i;
break;
default:;
}

}
return -1;

}


void Oscyloskop::adjustGraph(int *buf, int yPos)
{
int i;
for(i = 0; i & lt; 384; i++)
buf[i] = buf[i] + yPos*4;
}

void Oscyloskop::copySignal(int* in, int* out, int len, int gain)
{
for(int i = 0; i & lt; len; i++)
out[i] = in[i]*gain/100;
}

bool Oscyloskop::trigger(int* kan1_in, int* kan1_lcd, int* kan2_lcd, int lev, int trig_type, int xpos)
{
if((trig_type & 3) != 3 || trigForce == true || wzw == 0)
{
xpos += 192;
int trig_t = (trig_type & gt; & gt; 2) & 3;
wzw = 0;
trigForce = false;
bool auto_wzw=0;
if((trig_type & 3) == 0)
{
wzw=1;
counter=0;
}
if((trig_type & 3) == 2)
{
if(counter & gt; 30)
{
auto_wzw=1;
counter = 51;
}

}
int Gain1 = 50000/gainTab[gain1] & gt; & gt; gain1;
int Gain2 = 50000/gainTab[gain2] & gt; & gt; gain2;
lev = lev*4 * (1 & lt; & lt; gain1);
int length = 1024;
if(channel2box- & gt; checkState() == Qt::Checked) //2 channels
{
length = 512;
}
int index = xpos;
if(wzw == 0)
{
index = getTrigIndex(kan1_in, length, 384, xpos , lev, trig_t);
if(index & gt; -1)
{
counter = 0;
wzw = 1;
}
}
if(auto_wzw)
index = xpos;
if(index & gt; - 1)
{

copySignal(kan1_in + index - xpos, kan1_lcd, 384, Gain1);
if(channel2box- & gt; checkState() == Qt::Checked) //2 channels
{
copySignal(kan1_in + 512 + index - xpos, kan2_lcd, 384, Gain2);
}
return true;
}
return false;
}
return false;
}

void Oscyloskop::setCursor(QMouseEvent *e)
{
int ex = e- & gt; x();
int ey = e- & gt; y();
if(QApplication::keyboardModifiers() == Qt::NoModifier)
{
if(e- & gt; buttons() == Qt::LeftButton)
{
if(ex & lt; Xsize + x_s & & ex & gt; x_s)
{
if(ey & lt; Ysize +y_s & & ey & gt; y_s)
{
//buff[((ex - x_s)%512)*Tab/512] = (Ysize - ey - Ysize/2 + y_s)*8;
ey = Ysize - ey - Ysize/2 + y_s;
trigLevSpin- & gt; setValue((ey - yPos)*gainTab[gain1]/13);// = level*500/gainTab[gain1] + yPos;
//trigLevSpin- & gt; setValue(level);
parent- & gt; update();
}
}
}
}else if(QApplication::keyboardModifiers() == Qt::SHIFT)
{
if(e- & gt; buttons() == Qt::LeftButton)
{
if(ex & lt; Xsize + x_s & & ex & gt; x_s)
{
if(ey & lt; Ysize +y_s & & ey & gt; y_s)
{
//buff[((ex - x_s)%512)*Tab/512] = (Ysize - ey - Ysize/2 + y_s)*8;
cursorAH = Ysize - ey - Ysize/2 + y_s;
cursorAV = ex - x_s;
parent- & gt; update();
}
}
}
if(e- & gt; buttons() == Qt::RightButton)
{
if(ex & lt; Xsize + x_s & & ex & gt; x_s)
{
if(ey & lt; Ysize +y_s & & ey & gt; y_s)
{
//buff[((ex - x_s)%512)*Tab/512] = (Ysize - ey - Ysize/2 + y_s)*8;
cursorBH = Ysize - ey - Ysize/2 + y_s;
cursorBV = ex - x_s;
parent- & gt; update();
}
}
}
}
}



void Oscyloskop::drawGraph(Buffer *bufIn)
{
Graph graph(parent);
if(bufIn- & gt; length & gt; 2047)
graph.convBufToInt16(bufIn, buff);

fileLog(buff);

if(trigger(buff, bufGraph, bufGraph2, level, trig, xPos))
{
if(channel2box- & gt; checkState() == Qt::Checked) //2 channels
{
labelRMS- & gt; setText( " CH1 RMS: " + calcRMS(bufGraph, 384, gain1));
labelRMS2- & gt; setText( " CH2 RMS: " + calcRMS(bufGraph2, 384, gain2));
labelAvg- & gt; setText( " CH1 Avg: " + calcAvg(bufGraph, 384, gain1));
labelAvg2- & gt; setText( " CH2 Avg: " + calcAvg(bufGraph2, 384, gain2));
labelVpp- & gt; setText( " CH1 Vpp: " + calcVpp(bufGraph, 384, gain1));
labelVpp2- & gt; setText( " CH2 Vpp: " + calcVpp(bufGraph2, 384, gain2));
labelFreq- & gt; setText( " CH1 Freq: " + calcFreq(bufGraph, 384, timeBase));
labelFreq2- & gt; setText( " CH2 Freq: " + calcFreq(bufGraph2, 384, timeBase));
}else
{
labelRMS- & gt; setText( " CH1 RMS: " + calcRMS(bufGraph, 384, gain1));
labelAvg- & gt; setText( " CH1 Avg: " + calcAvg(bufGraph, 384, gain1));
labelVpp- & gt; setText( " CH1 Vpp: " + calcVpp(bufGraph, 384, gain1));
labelFreq- & gt; setText( " CH1 Freq: " + calcFreq(bufGraph, 384, timeBase));
}
adjustGraph(bufGraph, yPos);
adjustGraph(bufGraph2, yPos2);
}
graph.svWindow();
float tlev = level*496/gainTab[gain1] + yPos;
if(tlev & lt; 256 & & tlev & gt; -256)
graph.cursorH(tlev, QColor(20,80,60));
graph.cursorV(2*(xPos+192), QColor(20,80,60));

if(curVBox- & gt; checkState() == Qt::Checked)
{
graph.cursorV(cursorAV, QColor(150, 150, 0));
graph.cursorV(cursorBV, QColor(150, 150, 0));
curTimeLabel- & gt; setText( " Time: " +value((double)(cursorBV-cursorAV)*timeTab[timeBase]/32000000) + " s " );
curFreqLabel- & gt; setText( " Freq: " +value(32000000/(double)abs(cursorBV-cursorAV)/timeTab[timeBase]) + " Hz " );
}
if(curHBox- & gt; checkState() == Qt::Checked)
{
graph.cursorH(cursorAH, QColor(150, 150, 0));
graph.cursorH(cursorBH, QColor(150, 150, 0));
curVolt1Label- & gt; setText( " CH1 Voltage: " +value((cursorBH-cursorAH)*gainTab[gain1]/12800.0) + " V " );
if(channel2box- & gt; checkState() == Qt::Checked)
curVolt2Label- & gt; setText( " CH2 Voltage: " +value((cursorBH-cursorAH)*gainTab[gain2]/12800.0) + " V " );
}

graph.signal(bufGraph, QColor(50,60,255));
if(channel2box- & gt; checkState() == Qt::Checked) //2 channels
graph.signal(bufGraph2, QColor(255,60,50));
if(xyBox- & gt; checkState() == Qt::Checked)
graph.signalXY(bufGraph, bufGraph2, QColor(200, 200, 200));
}

QString Oscyloskop::calcRMS(int* buf, int length, int gain)
{
int i;
int step = 0;
int periods = 0;
int times[2];
bool firstPeriod = 0;
int min = 30000;
int max = -30000;
for(i = 0; i & lt; length; i++)
{
if(buf[i] & lt; min)min = buf[i];
if(buf[i] & gt; max)max = buf[i];
}
min = (5*max + 11*min)/16;
max = (11*max + 5*min)/16;
for(i = 0; i & lt; length; i++)
{
if(step == 0 & & buf[i] & lt; min) //histereza
step = 1;
else if(step == 1 & & buf[i] & gt; (max+min)/2) //zero point
{
step = 2;
times[firstPeriod] = i;
firstPeriod = 1;
periods++;
}else if(step == 2 & & buf[i] & gt; max)
step = 0;

if(periods & gt; 100)break;
}

double rms = 0;
if(times[1] & gt; times[0] & & times[0] & gt; = 0 & & times[1] & lt; length)
{
for(i = times[0]; i & lt; times[1]; i++)
{
rms += buf[i]*buf[i];
}
rms = sqrt(rms/(times[1] - times[0]))*gainTab[gain];
rms/=50;
}
if(rms & gt; = 10000)
{
return QString::number(rms/1000, 'f', 2) + " V " ;
}
else if(rms & gt; = 1000)
{
return QString::number(rms/1000, 'f', 3) + " V " ;
}else
{
return QString::number(rms, 'f', 1) + " mV " ;
}
}

QString Oscyloskop::calcAvg(int* buf, int length, int gain)
{
int i;
int step = 0;
int periods = 0;
int times[2];
bool firstPeriod = 0;
int min = 30000;
int max = -30000;
for(i = 0; i & lt; length; i++)
{
if(buf[i] & lt; min)min = buf[i];
if(buf[i] & gt; max)max = buf[i];
}
min = (5*max + 11*min)/16;
max = (11*max + 5*min)/16;
for(i = 0; i & lt; length; i++)
{
if(step == 0 & & buf[i] & lt; min) //histereza
step = 1;
else if(step == 1 & & buf[i] & gt; (max+min)/2) //zero point
{
step = 2;
times[firstPeriod] = i;
firstPeriod = 1;
periods++;
}else if(step == 2 & & buf[i] & gt; max)
step = 0;

if(periods & gt; 100)break;
}

double avg = 0;
if(times[1] & gt; times[0] & & times[0] & gt; = 0 & & times[1] & lt; length)
{
for(i = times[0]; i & lt; times[1]; i++)
{
avg += buf[i];
}
avg/=(times[1] - times[0]);
avg*=gainTab[gain];
avg/=50;
}

if(avg & gt; = 10000)
{
return QString::number(avg/1000, 'f', 2) + " V " ;
}
else if(avg & gt; = 1000)
{
return QString::number(avg/1000, 'f', 3) + " V " ;
}else
{
return QString::number(avg, 'f', 1) + " mV " ;
}
}

QString Oscyloskop::calcVpp(int* buf, int length, int gain)
{
int i, i2, i3;
double vpp = 0;
int tmp[6]= {-10000, -10000, -10000, 10000, 10000, 10000};
int ind[6] = {-1, -1, -1, -1, -1, -1};
for(i2 = 0; i2 & lt; 3; i2++)
{
for(i = 0; i & lt; length; i++)
{
for(i3 = 0; i3 & lt; 6; i3++)
if(ind[i3] == i)
continue;

if(buf[i] & gt; tmp[i2])
{
tmp[i2] = buf[i];
ind[i2] = i;
}
if(buf[i] & lt; tmp[3+i2])
{
tmp[3+i2] = buf[i];
ind[3+i2] = i;
}
}
}
vpp = tmp[0] + tmp[1] + tmp[2] - tmp[3] - tmp[4] - tmp[5];
vpp/=3;
//voltpp = vpp;
vpp*=gainTab[gain];
vpp/=50;
if(vpp & gt; = 10000)
{
return QString::number(vpp/1000, 'f', 2) + " V " ;
}
else if(vpp & gt; = 1000)
{
return QString::number(vpp/1000, 'f', 3) + " V " ;
}else
{
return QString::number(vpp, 'f', 1) + " mV " ;
}
}

QString Oscyloskop::calcFreq(int *buf, int length, int time)
{
int i;
int step = 0;
int periods = 0;
int times[2];
bool firstPeriod = 0;
double freq = 0;
int min = 30000;
int max = -30000;
for(i = 0; i & lt; length; i++)
{
if(buf[i] & lt; min)min = buf[i];
if(buf[i] & gt; max)max = buf[i];
}
min = (5*max + 11*min)/16;
max = (11*max + 5*min)/16;
for(i = 0; i & lt; length; i++)
{
if(step == 0 & & buf[i] & lt; min) //histereza
step = 1;
else if(step == 1 & & buf[i] & gt; ((min+max)/2)) //zero point
{
step = 2;
times[firstPeriod] = i;
firstPeriod = 1;
periods++;
}else if(step == 2 & & buf[i] & gt; max)
step = 0;

if(periods & gt; 100)break;
}
//if(periods & lt; 2)return " ?? " ;
//if(periods & lt; 2)return QString::number(min*3/8);

freq = times[1]-times[0];
freq/=(periods-1);
freq = 1024000/(freq*(float)timeTab[time]/16.0);

if(freq & lt; 0)
freq = 0;

if(freq & gt; = 10000)
{
return QString::number(freq/1000, 'f', 2) + " kHz " ;
}
else if(freq & gt; = 1000)
{
return QString::number(freq/1000, 'f', 3) + " kHz " ;
}else
{
return QString::number(freq, 'f', 1) + " Hz " ;
}
//return QString::number(freq, 'f', 1);
}

//-------SLOTS------------------------
void Oscyloskop::tSlot()
{
timeBase = 14 - tSpin- & gt; currentIndex();
comPort- & gt; setTimeBase(timeBase);
}

void Oscyloskop::vSlot()
{
gain1 = vSpin- & gt; currentIndex();
gain2 = v2Spin- & gt; currentIndex();
comPort- & gt; setGain1(gain1);
comPort- & gt; setGain2(gain2);
}

void Oscyloskop::xySlot(bool val)
{

}

void Oscyloskop::xPosSlot()
{
xPos = xScroll- & gt; value();
xPosLabel- & gt; setText( " Xpos: " + QString::number(xPos));
parent- & gt; update();
}

void Oscyloskop::yPosSlot()
{
yPos = -yScroll- & gt; value();
yPosLabel- & gt; setText( " Ypos1: " + QString::number(yPos));
yPos2 = -y2Scroll- & gt; value();
yPos2Label- & gt; setText( " Ypos2: " + QString::number(yPos2));
parent- & gt; update();
}

void Oscyloskop::channel2Slot()
{
if(channel2box- & gt; checkState() == Qt::Checked) //2 channels
{
comPort- & gt; enable2channel();
v2Spin- & gt; setEnabled(1);
y2Scroll- & gt; setEnabled(1);
labelRMS2- & gt; setEnabled(1);
labelAvg2- & gt; setEnabled(1);
labelVpp2- & gt; setEnabled(1);
labelFreq2- & gt; setEnabled(1);
tSpin- & gt; setMaxCount(11);
cursorSlot();
}else //1 channel
{
comPort- & gt; disable2channel();
v2Spin- & gt; setDisabled(1);
y2Scroll- & gt; setDisabled(1);
labelRMS2- & gt; setDisabled(1);
labelAvg2- & gt; setDisabled(1);
labelVpp2- & gt; setDisabled(1);
labelFreq2- & gt; setDisabled(1);
tSpin- & gt; setMaxCount(15);
tSpin- & gt; addItems(tlist2);
cursorSlot();
}
}

void Oscyloskop::trigSlot()
{
int temp = 0;
temp = trigTypeCombo- & gt; currentIndex();
temp += trigEdgeCombo- & gt; currentIndex() & lt; & lt; 2;
temp += trigFCombo- & gt; currentIndex() & lt; & lt; 3;
trig = temp;
level = (float)trigLevSpin- & gt; value()/38.0;///gainTab[gain1];
trigForce = true;

}

void Oscyloskop::cursorSlot()
{
if(curHBox- & gt; checkState() == Qt::Checked)
{
curVolt1Label- & gt; setEnabled(1);
if(channel2box- & gt; checkState() == Qt::Checked)
curVolt2Label- & gt; setEnabled(1);
else
curVolt2Label- & gt; setDisabled(1);
}else
{
curVolt1Label- & gt; setDisabled(1);
curVolt2Label- & gt; setDisabled(1);
}
if(curVBox- & gt; checkState() == Qt::Checked)
{
curTimeLabel- & gt; setEnabled(1);
curFreqLabel- & gt; setEnabled(1);
}else
{
curTimeLabel- & gt; setDisabled(1);
curFreqLabel- & gt; setDisabled(1);
}


}

void Oscyloskop::openSlot()
{
QString ofile;
QString name = QFileDialog::getOpenFileName(this, tr( " Save file " ), " " , " Text files (*.txt) " , & ofile);
if(name.isEmpty())
return;
QFile file(name);
file.open(QFile::ReadOnly);
QTextStream in( & file);
int i;
for(i=0; i & lt; 1024; i++)
in & gt; & gt; buff[i];
file.close();
}

void Oscyloskop::saveSlot()
{
QString sfile;
QString name = QFileDialog::getSaveFileName(this, tr( " Save file " ), " " , " Text files (*.txt) " , & sfile);
if(name.isEmpty())
return;
QFile file(name);
file.open(QFile::WriteOnly);
QTextStream in( & file);
int i;

if(curVBox- & gt; checkState() == Qt::Checked)
{
int startIndex = (cursorAV & lt; cursorBV ? cursorAV : cursorBV) - x_s/2 + 4;
int stopIndex = (cursorAV & gt; = cursorBV ? cursorAV : cursorBV) - x_s/2 + 4;

qDebug() & lt; & lt; startIndex & lt; & lt; " " & lt; & lt; stopIndex;
for(i=0; i & lt; 512; i++)
{
in & lt; & lt; bufGraph[startIndex/2+ i*(stopIndex - startIndex)/1024] & lt; & lt; endl;
}
}else
{
for(i=0; i & lt; 1024; i++)
in & lt; & lt; buff[i] & lt; & lt; endl;
}
file.close();
}

void Oscyloskop::fileLog(int *buf)
{
if(fileOpened)
{
QTextStream out(file);
float sum = 0;
for(int i =0; i & lt; 1024; i++)
{
sum += buf[i];
}
out & lt; & lt; QString::number(sum);
out & lt; & lt; endl;
}
}


MiniKombajnPomiarowy3_3_rc3.7z > windowsize.h

#ifndef WINDOWSIZE_H
#define WINDOWSIZE_H

const int Xsize = 768;
const int Ysize = 512;
const int Yhsize = Ysize/2;
const int x_s = 10;
const int y_s = 30;
const int Xtsize = 160;
const int Ytsize = 20;
const int Yscroll = 20;
const int Xpanel = Xsize + x_s*3 + 40;
const int Ypanel = y_s;
const int XsizePanel = 200;
const int YsizePanel = 500;

#endif // WINDOWSIZE_H


MiniKombajnPomiarowy3_3_rc3.7z > qtmmlwidget.h

/****************************************************************************
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of a Qt Solutions component.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** Please note Third Party Software included with Qt Solutions may impose
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact Nokia at qt-info@nokia.com.
**
****************************************************************************/

#ifndef QTMMLWIDGET_H
#define QTMMLWIDGET_H

#include & lt; QtGui/QFrame & gt;
#include & lt; QtXml/QtXml & gt;

class MmlDocument;

#if defined(Q_WS_WIN)
# if !defined(QT_QTMMLWIDGET_EXPORT) & & !defined(QT_QTMMLWIDGET_IMPORT)
# define QT_QTMMLWIDGET_EXPORT
# elif defined(QT_QTMMLWIDGET_IMPORT)
# if defined(QT_QTMMLWIDGET_EXPORT)
# undef QT_QTMMLWIDGET_EXPORT
# endif
# define QT_QTMMLWIDGET_EXPORT __declspec(dllimport)
# elif defined(QT_QTMMLWIDGET_EXPORT)
# undef QT_QTMMLWIDGET_EXPORT
# define QT_QTMMLWIDGET_EXPORT __declspec(dllexport)
# endif
#else
# define QT_QTMMLWIDGET_EXPORT
#endif

class QT_QTMMLWIDGET_EXPORT QtMmlWidget : public QFrame
{
public:
enum MmlFont { NormalFont, FrakturFont, SansSerifFont, ScriptFont,
MonospaceFont, DoublestruckFont };

QtMmlWidget(QWidget *parent = 0);
~QtMmlWidget();

QString fontName(MmlFont type) const;
void setFontName(MmlFont type, const QString & name);
int baseFontPointSize() const;
void setBaseFontPointSize(int size);

bool setContent(const QString & text, QString *errorMsg = 0,
int *errorLine = 0, int *errorColumn = 0);
void dump() const;
virtual QSize sizeHint() const;

void setDrawFrames(bool b);
bool drawFrames() const;

void clear();

protected:
virtual void paintEvent(QPaintEvent *e);

private:
MmlDocument *m_doc;
};


class QT_QTMMLWIDGET_EXPORT QtMmlDocument
{
public:
QtMmlDocument();
~QtMmlDocument();
void clear();

bool setContent(QString text, QString *errorMsg = 0,
int *errorLine = 0, int *errorColumn = 0);
void paint(QPainter *p, const QPoint & pos) const;
QSize size() const;

QString fontName(QtMmlWidget::MmlFont type) const;
void setFontName(QtMmlWidget::MmlFont type, const QString & name);

int baseFontPointSize() const;
void setBaseFontPointSize(int size);
private:
MmlDocument *m_doc;
};

#endif


MiniKombajnPomiarowy3_3_rc3.7z > posix_qextserialport.cpp

#include & lt; fcntl.h & gt;
#include & lt; stdio.h & gt;
#include " qextserialport.h "
#include & lt; QMutexLocker & gt;
#include & lt; QDebug & gt;

void QextSerialPort::platformSpecificInit()
{
fd = 0;
readNotifier = 0;
}

/*!
Standard destructor.
*/
void QextSerialPort::platformSpecificDestruct()
{}

/*!
Sets the baud rate of the serial port. Note that not all rates are applicable on
all platforms. The following table shows translations of the various baud rate
constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an *
are speeds that are usable on both Windows and POSIX.

\note
BAUD76800 may not be supported on all POSIX systems. SGI/IRIX systems do not support
BAUD1800.

\verbatim

RATE Windows Speed POSIX Speed
----------- ------------- -----------
BAUD50 110 50
BAUD75 110 75
*BAUD110 110 110
BAUD134 110 134.5
BAUD150 110 150
BAUD200 110 200
*BAUD300 300 300
*BAUD600 600 600
*BAUD1200 1200 1200
BAUD1800 1200 1800
*BAUD2400 2400 2400
*BAUD4800 4800 4800
*BAUD9600 9600 9600
BAUD14400 14400 9600
*BAUD19200 19200 19200
*BAUD38400 38400 38400
BAUD56000 56000 38400
*BAUD57600 57600 57600
BAUD76800 57600 76800
*BAUD115200 115200 115200
BAUD128000 128000 115200
BAUD256000 256000 115200
\endverbatim
*/
void QextSerialPort::setBaudRate(BaudRateType baudRate)
{
QMutexLocker lock(mutex);
if (Settings.BaudRate!=baudRate) {
switch (baudRate) {
case BAUD14400:
Settings.BaudRate=BAUD9600;
break;

case BAUD56000:
Settings.BaudRate=BAUD38400;
break;

case BAUD76800:

#ifndef B76800
Settings.BaudRate=BAUD57600;
#else
Settings.BaudRate=baudRate;
#endif
break;

case BAUD128000:
case BAUD256000:
Settings.BaudRate=BAUD115200;
break;

default:
Settings.BaudRate=baudRate;
break;
}
}
if (isOpen()) {
switch (baudRate) {

/*50 baud*/
case BAUD50:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows does not support 50 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B50;
#else
cfsetispeed( & Posix_CommConfig, B50);
cfsetospeed( & Posix_CommConfig, B50);
#endif
break;

/*75 baud*/
case BAUD75:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows does not support 75 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B75;
#else
cfsetispeed( & Posix_CommConfig, B75);
cfsetospeed( & Posix_CommConfig, B75);
#endif
break;

/*110 baud*/
case BAUD110:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B110;
#else
cfsetispeed( & Posix_CommConfig, B110);
cfsetospeed( & Posix_CommConfig, B110);
#endif
break;

/*134.5 baud*/
case BAUD134:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows does not support 134.5 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B134;
#else
cfsetispeed( & Posix_CommConfig, B134);
cfsetospeed( & Posix_CommConfig, B134);
#endif
break;

/*150 baud*/
case BAUD150:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows does not support 150 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B150;
#else
cfsetispeed( & Posix_CommConfig, B150);
cfsetospeed( & Posix_CommConfig, B150);
#endif
break;

/*200 baud*/
case BAUD200:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows does not support 200 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B200;
#else
cfsetispeed( & Posix_CommConfig, B200);
cfsetospeed( & Posix_CommConfig, B200);
#endif
break;

/*300 baud*/
case BAUD300:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B300;
#else
cfsetispeed( & Posix_CommConfig, B300);
cfsetospeed( & Posix_CommConfig, B300);
#endif
break;

/*600 baud*/
case BAUD600:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B600;
#else
cfsetispeed( & Posix_CommConfig, B600);
cfsetospeed( & Posix_CommConfig, B600);
#endif
break;

/*1200 baud*/
case BAUD1200:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B1200;
#else
cfsetispeed( & Posix_CommConfig, B1200);
cfsetospeed( & Posix_CommConfig, B1200);
#endif
break;

/*1800 baud*/
case BAUD1800:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B1800;
#else
cfsetispeed( & Posix_CommConfig, B1800);
cfsetospeed( & Posix_CommConfig, B1800);
#endif
break;

/*2400 baud*/
case BAUD2400:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B2400;
#else
cfsetispeed( & Posix_CommConfig, B2400);
cfsetospeed( & Posix_CommConfig, B2400);
#endif
break;

/*4800 baud*/
case BAUD4800:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B4800;
#else
cfsetispeed( & Posix_CommConfig, B4800);
cfsetospeed( & Posix_CommConfig, B4800);
#endif
break;

/*9600 baud*/
case BAUD9600:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B9600;
#else
cfsetispeed( & Posix_CommConfig, B9600);
cfsetospeed( & Posix_CommConfig, B9600);
#endif
break;

/*14400 baud*/
case BAUD14400:
TTY_WARNING( " QextSerialPort: POSIX does not support 14400 baud operation. Switching to 9600 baud. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B9600;
#else
cfsetispeed( & Posix_CommConfig, B9600);
cfsetospeed( & Posix_CommConfig, B9600);
#endif
break;

/*19200 baud*/
case BAUD19200:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B19200;
#else
cfsetispeed( & Posix_CommConfig, B19200);
cfsetospeed( & Posix_CommConfig, B19200);
#endif
break;

/*38400 baud*/
case BAUD38400:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B38400;
#else
cfsetispeed( & Posix_CommConfig, B38400);
cfsetospeed( & Posix_CommConfig, B38400);
#endif
break;

/*56000 baud*/
case BAUD56000:
TTY_WARNING( " QextSerialPort: POSIX does not support 56000 baud operation. Switching to 38400 baud. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B38400;
#else
cfsetispeed( & Posix_CommConfig, B38400);
cfsetospeed( & Posix_CommConfig, B38400);
#endif
break;

/*57600 baud*/
case BAUD57600:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B57600;
#else
cfsetispeed( & Posix_CommConfig, B57600);
cfsetospeed( & Posix_CommConfig, B57600);
#endif
break;

/*76800 baud*/
case BAUD76800:
TTY_PORTABILITY_WARNING( " QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);

#ifdef B76800
Posix_CommConfig.c_cflag|=B76800;
#else
TTY_WARNING( " QextSerialPort: QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud. " );
Posix_CommConfig.c_cflag|=B57600;
#endif //B76800
#else //CBAUD
#ifdef B76800
cfsetispeed( & Posix_CommConfig, B76800);
cfsetospeed( & Posix_CommConfig, B76800);
#else
TTY_WARNING( " QextSerialPort: QextSerialPort was compiled without 76800 baud support. Switching to 57600 baud. " );
cfsetispeed( & Posix_CommConfig, B57600);
cfsetospeed( & Posix_CommConfig, B57600);
#endif //B76800
#endif //CBAUD
break;

/*115200 baud*/
case BAUD115200:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B115200;
#else
cfsetispeed( & Posix_CommConfig, B115200);
cfsetospeed( & Posix_CommConfig, B115200);
#endif
break;

/*128000 baud*/
case BAUD128000:
TTY_WARNING( " QextSerialPort: POSIX does not support 128000 baud operation. Switching to 115200 baud. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B115200;
#else
cfsetispeed( & Posix_CommConfig, B115200);
cfsetospeed( & Posix_CommConfig, B115200);
#endif
break;

/*230400 baud*/
case BAUD230400:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B230400;
#else
cfsetispeed( & Posix_CommConfig, B230400);
cfsetospeed( & Posix_CommConfig, B230400);
#endif
break;

/*256000 baud*/
case BAUD256000:
TTY_WARNING( " QextSerialPort: POSIX does not support 256000 baud operation. Switching to 115200 baud. " );
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B115200;
#else
cfsetispeed( & Posix_CommConfig, B115200);
cfsetospeed( & Posix_CommConfig, B115200);
#endif
break;

/*256000 baud*/
case BAUD460800:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B460800;
#else
cfsetispeed( & Posix_CommConfig, B460800);
cfsetospeed( & Posix_CommConfig, B460800);
#endif
break;

/*256000 baud*/
case BAUD921600:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B921600;
#else
cfsetispeed( & Posix_CommConfig, B921600);
cfsetospeed( & Posix_CommConfig, B921600);
#endif
break;

/*256000 baud*/
case BAUD1152000:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B1152000;
#else
cfsetispeed( & Posix_CommConfig, B1152000);
cfsetospeed( & Posix_CommConfig, B1152000);
#endif
break;

/*256000 baud*/
case BAUD1500000:
#ifdef CBAUD
Posix_CommConfig.c_cflag & =(~CBAUD);
Posix_CommConfig.c_cflag|=B1500000;
#else
cfsetispeed( & Posix_CommConfig, B1500000);
cfsetospeed( & Posix_CommConfig, B1500000);
#endif
break;
}
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
}

/*!
Sets the number of data bits used by the serial port. Possible values of dataBits are:
\verbatim
DATA_5 5 data bits
DATA_6 6 data bits
DATA_7 7 data bits
DATA_8 8 data bits
\endverbatim

\note
This function is subject to the following restrictions:
\par
5 data bits cannot be used with 2 stop bits.
\par
8 data bits cannot be used with space parity on POSIX systems.
*/
void QextSerialPort::setDataBits(DataBitsType dataBits)
{
QMutexLocker lock(mutex);
if (Settings.DataBits!=dataBits) {
if ((Settings.StopBits==STOP_2 & & dataBits==DATA_5) ||
(Settings.StopBits==STOP_1_5 & & dataBits!=DATA_5) ||
(Settings.Parity==PAR_SPACE & & dataBits==DATA_8)) {
}
else {
Settings.DataBits=dataBits;
}
}
if (isOpen()) {
switch(dataBits) {

/*5 data bits*/
case DATA_5:
if (Settings.StopBits==STOP_2) {
TTY_WARNING( " QextSerialPort: 5 Data bits cannot be used with 2 stop bits. " );
}
else {
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag & =(~CSIZE);
Posix_CommConfig.c_cflag|=CS5;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
break;

/*6 data bits*/
case DATA_6:
if (Settings.StopBits==STOP_1_5) {
TTY_WARNING( " QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits. " );
}
else {
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag & =(~CSIZE);
Posix_CommConfig.c_cflag|=CS6;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
break;

/*7 data bits*/
case DATA_7:
if (Settings.StopBits==STOP_1_5) {
TTY_WARNING( " QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits. " );
}
else {
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag & =(~CSIZE);
Posix_CommConfig.c_cflag|=CS7;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
break;

/*8 data bits*/
case DATA_8:
if (Settings.StopBits==STOP_1_5) {
TTY_WARNING( " QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits. " );
}
else {
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag & =(~CSIZE);
Posix_CommConfig.c_cflag|=CS8;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
break;
}
}
}

/*!
Sets the parity associated with the serial port. The possible values of parity are:
\verbatim
PAR_SPACE Space Parity
PAR_MARK Mark Parity
PAR_NONE No Parity
PAR_EVEN Even Parity
PAR_ODD Odd Parity
\endverbatim

\note
This function is subject to the following limitations:
\par
POSIX systems do not support mark parity.
\par
POSIX systems support space parity only if tricked into doing so, and only with
fewer than 8 data bits. Use space parity very carefully with POSIX systems.
*/
void QextSerialPort::setParity(ParityType parity)
{
QMutexLocker lock(mutex);
if (Settings.Parity!=parity) {
if (parity==PAR_MARK || (parity==PAR_SPACE & & Settings.DataBits==DATA_8)) {
}
else {
Settings.Parity=parity;
}
}
if (isOpen()) {
switch (parity) {

/*space parity*/
case PAR_SPACE:
if (Settings.DataBits==DATA_8) {
TTY_PORTABILITY_WARNING( " QextSerialPort: Space parity is only supported in POSIX with 7 or fewer data bits " );
}
else {

/*space parity not directly supported - add an extra data bit to simulate it*/
Posix_CommConfig.c_cflag & =~(PARENB|CSIZE);
switch(Settings.DataBits) {
case DATA_5:
Settings.DataBits=DATA_6;
Posix_CommConfig.c_cflag|=CS6;
break;

case DATA_6:
Settings.DataBits=DATA_7;
Posix_CommConfig.c_cflag|=CS7;
break;

case DATA_7:
Settings.DataBits=DATA_8;
Posix_CommConfig.c_cflag|=CS8;
break;

case DATA_8:
break;
}
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
break;

/*mark parity - WINDOWS ONLY*/
case PAR_MARK:
TTY_WARNING( " QextSerialPort: Mark parity is not supported by POSIX. " );
break;

/*no parity*/
case PAR_NONE:
Posix_CommConfig.c_cflag & =(~PARENB);
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;

/*even parity*/
case PAR_EVEN:
Posix_CommConfig.c_cflag & =(~PARODD);
Posix_CommConfig.c_cflag|=PARENB;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;

/*odd parity*/
case PAR_ODD:
Posix_CommConfig.c_cflag|=(PARENB|PARODD);
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;
}
}
}

/*!
Sets the number of stop bits used by the serial port. Possible values of stopBits are:
\verbatim
STOP_1 1 stop bit
STOP_1_5 1.5 stop bits
STOP_2 2 stop bits
\endverbatim
\note
This function is subject to the following restrictions:
\par
2 stop bits cannot be used with 5 data bits.
\par
POSIX does not support 1.5 stop bits.

*/
void QextSerialPort::setStopBits(StopBitsType stopBits)
{
QMutexLocker lock(mutex);
if (Settings.StopBits!=stopBits) {
if ((Settings.DataBits==DATA_5 & & stopBits==STOP_2) || stopBits==STOP_1_5) {}
else {
Settings.StopBits=stopBits;
}
}
if (isOpen()) {
switch (stopBits) {

/*one stop bit*/
case STOP_1:
Settings.StopBits=stopBits;
Posix_CommConfig.c_cflag & =(~CSTOPB);
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;

/*1.5 stop bits*/
case STOP_1_5:
TTY_WARNING( " QextSerialPort: 1.5 stop bit operation is not supported by POSIX. " );
break;

/*two stop bits*/
case STOP_2:
if (Settings.DataBits==DATA_5) {
TTY_WARNING( " QextSerialPort: 2 stop bits cannot be used with 5 data bits " );
}
else {
Settings.StopBits=stopBits;
Posix_CommConfig.c_cflag|=CSTOPB;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
break;
}
}
}

/*!
Sets the flow control used by the port. Possible values of flow are:
\verbatim
FLOW_OFF No flow control
FLOW_HARDWARE Hardware (RTS/CTS) flow control
FLOW_XONXOFF Software (XON/XOFF) flow control
\endverbatim
\note
FLOW_HARDWARE may not be supported on all versions of UNIX. In cases where it is
unsupported, FLOW_HARDWARE is the same as FLOW_OFF.

*/
void QextSerialPort::setFlowControl(FlowType flow)
{
QMutexLocker lock(mutex);
if (Settings.FlowControl!=flow) {
Settings.FlowControl=flow;
}
if (isOpen()) {
switch(flow) {

/*no flow control*/
case FLOW_OFF:
Posix_CommConfig.c_cflag & =(~CRTSCTS);
Posix_CommConfig.c_iflag & =(~(IXON|IXOFF|IXANY));
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;

/*software (XON/XOFF) flow control*/
case FLOW_XONXOFF:
Posix_CommConfig.c_cflag & =(~CRTSCTS);
Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY);
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;

case FLOW_HARDWARE:
Posix_CommConfig.c_cflag|=CRTSCTS;
Posix_CommConfig.c_iflag & =(~(IXON|IXOFF|IXANY));
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
break;
}
}
}

/*!
Sets the read and write timeouts for the port to millisec milliseconds.
Note that this is a per-character timeout, i.e. the port will wait this long for each
individual character, not for the whole read operation. This timeout also applies to the
bytesWaiting() function.

\note
POSIX does not support millisecond-level control for I/O timeout values. Any
timeout set using this function will be set to the next lowest tenth of a second for
the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds
will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and
writing the port. However millisecond-level control is allowed by the select() system call,
so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for
the purpose of detecting available bytes in the read buffer.

*/
void QextSerialPort::setTimeout(long millisec)
{
QMutexLocker lock(mutex);
Settings.Timeout_Millisec = millisec;
Posix_Copy_Timeout.tv_sec = millisec / 1000;
Posix_Copy_Timeout.tv_usec = millisec % 1000;
if (isOpen()) {
if (millisec == -1)
fcntl(fd, F_SETFL, O_NDELAY);
else
//O_SYNC should enable blocking ::write()
//however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2)
fcntl(fd, F_SETFL, O_SYNC);
tcgetattr(fd, & Posix_CommConfig);
Posix_CommConfig.c_cc[VTIME] = millisec/100;
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);
}
}

/*!
Opens the serial port associated to this class.
This function has no effect if the port associated with the class is already open.
The port is also configured to the current settings, as stored in the Settings structure.
*/
bool QextSerialPort::open(OpenMode mode)
{
QMutexLocker lock(mutex);
if (mode == QIODevice::NotOpen)
return isOpen();
if (!isOpen()) {
qDebug() & lt; & lt; " trying to open file " & lt; & lt; port.toAscii();
//note: linux 2.6.21 seems to ignore O_NDELAY flag
if ((fd = ::open(port.toAscii() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) {
qDebug( " file opened succesfully " );

setOpenMode(mode); // Flag the port as opened
tcgetattr(fd, & old_termios); // Save the old termios
Posix_CommConfig = old_termios; // Make a working copy
cfmakeraw( & Posix_CommConfig); // Enable raw access

/*set up other port settings*/
Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
Posix_CommConfig.c_lflag & =(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
Posix_CommConfig.c_iflag & =(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
Posix_CommConfig.c_oflag & =(~OPOST);
Posix_CommConfig.c_cc[VMIN]= 0;
#ifdef _POSIX_VDISABLE // Is a disable character available on this system?
// Some systems allow for per-device disable-characters, so get the
// proper value for the configured device
const long vdisable = fpathconf(fd, _PC_VDISABLE);
Posix_CommConfig.c_cc[VINTR] = vdisable;
Posix_CommConfig.c_cc[VQUIT] = vdisable;
Posix_CommConfig.c_cc[VSTART] = vdisable;
Posix_CommConfig.c_cc[VSTOP] = vdisable;
Posix_CommConfig.c_cc[VSUSP] = vdisable;
#endif //_POSIX_VDISABLE
setBaudRate(Settings.BaudRate);
setDataBits(Settings.DataBits);
setParity(Settings.Parity);
setStopBits(Settings.StopBits);
setFlowControl(Settings.FlowControl);
setTimeout(Settings.Timeout_Millisec);
tcsetattr(fd, TCSAFLUSH, & Posix_CommConfig);

if (queryMode() == QextSerialPort::EventDriven) {
readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
connect(readNotifier, SIGNAL(activated(int)), this, SIGNAL(readyRead()));
}
} else {
qDebug() & lt; & lt; " could not open file: " & lt; & lt; strerror(errno);
lastErr = E_FILE_NOT_FOUND;
}
}
return isOpen();
}

/*!
Closes a serial port. This function has no effect if the serial port associated with the class
is not currently open.
*/
void QextSerialPort::close()
{
QMutexLocker lock(mutex);
if( isOpen() )
{
// Force a flush and then restore the original termios
flush();
// Using both TCSAFLUSH and TCSANOW here discards any pending input
tcsetattr(fd, TCSAFLUSH | TCSANOW, & old_termios); // Restore termios
// Be a good QIODevice and call QIODevice::close() before POSIX close()
// so the aboutToClose() signal is emitted at the proper time
QIODevice::close(); // Flag the device as closed
// QIODevice::close() doesn't actually close the port, so do that here
::close(fd);
if(readNotifier) {
delete readNotifier;
readNotifier = 0;
}
}
}

/*!
Flushes all pending I/O to the serial port. This function has no effect if the serial port
associated with the class is not currently open.
*/
void QextSerialPort::flush()
{
QMutexLocker lock(mutex);
if (isOpen())
tcflush(fd, TCIOFLUSH);
}

/*!
This function will return the number of bytes waiting in the receive queue of the serial port.
It is included primarily to provide a complete QIODevice interface, and will not record errors
in the lastErr member (because it is const). This function is also not thread-safe - in
multithreading situations, use QextSerialPort::bytesWaiting() instead.
*/
qint64 QextSerialPort::size() const
{
int numBytes;
if (ioctl(fd, FIONREAD, & numBytes) & lt; 0) {
numBytes = 0;
}
return (qint64)numBytes;
}

/*!
Returns the number of bytes waiting in the port's receive queue. This function will return 0 if
the port is not currently open, or -1 on error.
*/
qint64 QextSerialPort::bytesAvailable() const
{
QMutexLocker lock(mutex);
if (isOpen()) {
int bytesQueued;
if (ioctl(fd, FIONREAD, & bytesQueued) == -1) {
return (qint64)-1;
}
return bytesQueued + QIODevice::bytesAvailable();
}
return 0;
}

/*!
This function is included to implement the full QIODevice interface, and currently has no
purpose within this class. This function is meaningless on an unbuffered device and currently
only prints a warning message to that effect.
*/
void QextSerialPort::ungetChar(char)
{
/*meaningless on unbuffered sequential device - return error and print a warning*/
TTY_WARNING( " QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless " );
}

/*!
Translates a system-specific error code to a QextSerialPort error code. Used internally.
*/
void QextSerialPort::translateError(ulong error)
{
switch (error) {
case EBADF:
case ENOTTY:
lastErr=E_INVALID_FD;
break;

case EINTR:
lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL;
break;

case ENOMEM:
lastErr=E_NO_MEMORY;
break;
}
}

/*!
Sets DTR line to the requested state (high by default). This function will have no effect if
the port associated with the class is not currently open.
*/
void QextSerialPort::setDtr(bool set)
{
QMutexLocker lock(mutex);
if (isOpen()) {
int status;
ioctl(fd, TIOCMGET, & status);
if (set) {
status|=TIOCM_DTR;
}
else {
status & =~TIOCM_DTR;
}
ioctl(fd, TIOCMSET, & status);
}
}

/*!
Sets RTS line to the requested state (high by default). This function will have no effect if
the port associated with the class is not currently open.
*/
void QextSerialPort::setRts(bool set)
{
QMutexLocker lock(mutex);
if (isOpen()) {
int status;
ioctl(fd, TIOCMGET, & status);
if (set) {
status|=TIOCM_RTS;
}
else {
status & =~TIOCM_RTS;
}
ioctl(fd, TIOCMSET, & status);
}
}

/*!
Returns the line status as stored by the port function. This function will retrieve the states
of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines
can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned
long with specific bits indicating which lines are high. The following constants should be used
to examine the states of individual lines:

\verbatim
Mask Line
------ ----
LS_CTS CTS
LS_DSR DSR
LS_DCD DCD
LS_RI RI
LS_RTS RTS (POSIX only)
LS_DTR DTR (POSIX only)
LS_ST Secondary TXD (POSIX only)
LS_SR Secondary RXD (POSIX only)
\endverbatim

This function will return 0 if the port associated with the class is not currently open.
*/
unsigned long QextSerialPort::lineStatus()
{
unsigned long Status=0, Temp=0;
QMutexLocker lock(mutex);
if (isOpen()) {
ioctl(fd, TIOCMGET, & Temp);
if (Temp & TIOCM_CTS) {
Status|=LS_CTS;
}
if (Temp & TIOCM_DSR) {
Status|=LS_DSR;
}
if (Temp & TIOCM_RI) {
Status|=LS_RI;
}
if (Temp & TIOCM_CD) {
Status|=LS_DCD;
}
if (Temp & TIOCM_DTR) {
Status|=LS_DTR;
}
if (Temp & TIOCM_RTS) {
Status|=LS_RTS;
}
if (Temp & TIOCM_ST) {
Status|=LS_ST;
}
if (Temp & TIOCM_SR) {
Status|=LS_SR;
}
}
return Status;
}

/*!
Reads a block of data from the serial port. This function will read at most maxSize bytes from
the serial port and place them in the buffer pointed to by data. Return value is the number of
bytes actually read, or -1 on error.

\warning before calling this function ensure that serial port associated with this class
is currently open (use isOpen() function to check if port is open).
*/
qint64 QextSerialPort::readData(char * data, qint64 maxSize)
{
QMutexLocker lock(mutex);
int retVal = ::read(fd, data, maxSize);
if (retVal == -1)
lastErr = E_READ_FAILED;

return retVal;
}

/*!
Writes a block of data to the serial port. This function will write maxSize bytes
from the buffer pointed to by data to the serial port. Return value is the number
of bytes actually written, or -1 on error.

\warning before calling this function ensure that serial port associated with this class
is currently open (use isOpen() function to check if port is open).
*/
qint64 QextSerialPort::writeData(const char * data, qint64 maxSize)
{
QMutexLocker lock(mutex);
int retVal = ::write(fd, data, maxSize);
if (retVal == -1)
lastErr = E_WRITE_FAILED;

return (qint64)retVal;
}


MiniKombajnPomiarowy3_3_rc3.7z > qextserialport.cpp

#include & lt; stdio.h & gt;
#include " qextserialport.h "

/*!
Default constructor. Note that the name of the device used by a QextSerialPort constructed with
this constructor will be determined by #defined constants, or lack thereof - the default behavior
is the same as _TTY_LINUX_. Possible naming conventions and their associated constants are:

\verbatim

Constant Used By Naming Convention
---------- ------------- ------------------------
Q_OS_WIN Windows COM1, COM2
_TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2
_TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0
_TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb
_TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02
_TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1
_TTY_OPENBSD_ OpenBSD /dev/tty00, /dev/tty01
_TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1
& lt; none & gt; Linux /dev/ttyS0, /dev/ttyS1
\endverbatim

This constructor assigns the device name to the name of the first port on the specified system.
See the other constructors if you need to open a different port.
*/
QextSerialPort::QextSerialPort(QextSerialPort::QueryMode mode)
: QIODevice()
{

#ifdef Q_OS_WIN
setPortName( " COM1 " );

#elif defined(_TTY_IRIX_)
setPortName( " /dev/ttyf1 " );

#elif defined(_TTY_HPUX_)
setPortName( " /dev/tty1p0 " );

#elif defined(_TTY_SUN_)
setPortName( " /dev/ttya " );

#elif defined(_TTY_DIGITAL_)
setPortName( " /dev/tty01 " );

#elif defined(_TTY_FREEBSD_)
setPortName( " /dev/ttyd1 " );

#elif defined(_TTY_OPENBSD_)
setPortName( " /dev/tty00 " );

#else
setPortName( " /dev/ttyS0 " );
#endif

construct();
setQueryMode(mode);
platformSpecificInit();
}

/*!
Constructs a serial port attached to the port specified by name.
name is the name of the device, which is windowsystem-specific,
e.g. " COM1 " or " /dev/ttyS0 " .
*/
QextSerialPort::QextSerialPort(const QString & name, QextSerialPort::QueryMode mode)
: QIODevice()
{
construct();
setQueryMode(mode);
setPortName(name);
platformSpecificInit();
}

/*!
Constructs a port with default name and specified settings.
*/
QextSerialPort::QextSerialPort(const PortSettings & settings, QextSerialPort::QueryMode mode)
: QIODevice()
{
construct();
setBaudRate(settings.BaudRate);
setDataBits(settings.DataBits);
setParity(settings.Parity);
setStopBits(settings.StopBits);
setFlowControl(settings.FlowControl);
setTimeout(settings.Timeout_Millisec);
setQueryMode(mode);
platformSpecificInit();
}

/*!
Constructs a port with specified name and settings.
*/
QextSerialPort::QextSerialPort(const QString & name, const PortSettings & settings, QextSerialPort::QueryMode mode)
: QIODevice()
{
construct();
setPortName(name);
setBaudRate(settings.BaudRate);
setDataBits(settings.DataBits);
setParity(settings.Parity);
setStopBits(settings.StopBits);
setFlowControl(settings.FlowControl);
setTimeout(settings.Timeout_Millisec);
setQueryMode(mode);
platformSpecificInit();
}

/*!
Common constructor function for setting up default port settings.
(115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 0 ms timeout).
*/
void QextSerialPort::construct()
{
lastErr = E_NO_ERROR;
Settings.BaudRate=BAUD115200;
Settings.DataBits=DATA_8;
Settings.Parity=PAR_NONE;
Settings.StopBits=STOP_1;
Settings.FlowControl=FLOW_HARDWARE;
Settings.Timeout_Millisec=500;
mutex = new QMutex( QMutex::Recursive );
setOpenMode(QIODevice::NotOpen);
}

void QextSerialPort::setQueryMode(QueryMode mechanism)
{
_queryMode = mechanism;
}

/*!
Sets the name of the device associated with the object, e.g. " COM1 " , or " /dev/ttyS0 " .
*/
void QextSerialPort::setPortName(const QString & name)
{
#ifdef Q_OS_WIN
port = fullPortNameWin( name );
#else
port = name;
#endif
}

/*!
Returns the name set by setPortName().
*/
QString QextSerialPort::portName() const
{
return port;
}

/*!
Reads all available data from the device, and returns it as a QByteArray.
This function has no way of reporting errors; returning an empty QByteArray()
can mean either that no data was currently available for reading, or that an error occurred.
*/
QByteArray QextSerialPort::readAll()
{
int avail = this- & gt; bytesAvailable();
return (avail & gt; 0) ? this- & gt; read(avail) : QByteArray();
}

/*!
Returns the baud rate of the serial port. For a list of possible return values see
the definition of the enum BaudRateType.
*/
BaudRateType QextSerialPort::baudRate(void) const
{
return Settings.BaudRate;
}

/*!
Returns the number of data bits used by the port. For a list of possible values returned by
this function, see the definition of the enum DataBitsType.
*/
DataBitsType QextSerialPort::dataBits() const
{
return Settings.DataBits;
}

/*!
Returns the type of parity used by the port. For a list of possible values returned by
this function, see the definition of the enum ParityType.
*/
ParityType QextSerialPort::parity() const
{
return Settings.Parity;
}

/*!
Returns the number of stop bits used by the port. For a list of possible return values, see
the definition of the enum StopBitsType.
*/
StopBitsType QextSerialPort::stopBits() const
{
return Settings.StopBits;
}

/*!
Returns the type of flow control used by the port. For a list of possible values returned
by this function, see the definition of the enum FlowType.
*/
FlowType QextSerialPort::flowControl() const
{
return Settings.FlowControl;
}

/*!
Returns true if device is sequential, otherwise returns false. Serial port is sequential device
so this function always returns true. Check QIODevice::isSequential() documentation for more
information.
*/
bool QextSerialPort::isSequential() const
{
return true;
}

QString QextSerialPort::errorString()
{
switch(lastErr)
{
case E_NO_ERROR: return " No Error has occurred " ;
case E_INVALID_FD: return " Invalid file descriptor (port was not opened correctly) " ;
case E_NO_MEMORY: return " Unable to allocate memory tables (POSIX) " ;
case E_CAUGHT_NON_BLOCKED_SIGNAL: return " Caught a non-blocked signal (POSIX) " ;
case E_PORT_TIMEOUT: return " Operation timed out (POSIX) " ;
case E_INVALID_DEVICE: return " The file opened by the port is not a valid device " ;
case E_BREAK_CONDITION: return " The port detected a break condition " ;
case E_FRAMING_ERROR: return " The port detected a framing error (usually caused by incorrect baud rate settings) " ;
case E_IO_ERROR: return " There was an I/O error while communicating with the port " ;
case E_BUFFER_OVERRUN: return " Character buffer overrun " ;
case E_RECEIVE_OVERFLOW: return " Receive buffer overflow " ;
case E_RECEIVE_PARITY_ERROR: return " The port detected a parity error in the received data " ;
case E_TRANSMIT_OVERFLOW: return " Transmit buffer overflow " ;
case E_READ_FAILED: return " General read operation failure " ;
case E_WRITE_FAILED: return " General write operation failure " ;
case E_FILE_NOT_FOUND: return " The " +this- & gt; portName()+ " file doesn't exists " ;
default: return QString( " Unknown error: %1 " ).arg(lastErr);
}
}

/*!
Standard destructor.
*/
QextSerialPort::~QextSerialPort()
{
if (isOpen()) {
close();
}
platformSpecificDestruct();
delete mutex;
}


MiniKombajnPomiarowy3_3_rc3.7z > qextserialport.h

#ifndef _QEXTSERIALPORT_H_
#define _QEXTSERIALPORT_H_

#include " qextserialport_global.h "

/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
#ifdef _TTY_NOWARN_
#define _TTY_NOWARN_PORT_
#endif

/*macros for warning and debug messages*/
#ifdef _TTY_NOWARN_PORT_
#define TTY_PORTABILITY_WARNING(s)
#else
#define TTY_PORTABILITY_WARNING(s) qWarning(s)
#endif /*_TTY_NOWARN_PORT_*/
#ifdef _TTY_NOWARN_
#define TTY_WARNING(s)
#else
#define TTY_WARNING(s) qWarning(s)
#endif /*_TTY_NOWARN_*/


/*line status constants*/
#define LS_CTS 0x01
#define LS_DSR 0x02
#define LS_DCD 0x04
#define LS_RI 0x08
#define LS_RTS 0x10
#define LS_DTR 0x20
#define LS_ST 0x40
#define LS_SR 0x80

/*error constants*/
#define E_NO_ERROR 0
#define E_INVALID_FD 1
#define E_NO_MEMORY 2
#define E_CAUGHT_NON_BLOCKED_SIGNAL 3
#define E_PORT_TIMEOUT 4
#define E_INVALID_DEVICE 5
#define E_BREAK_CONDITION 6
#define E_FRAMING_ERROR 7
#define E_IO_ERROR 8
#define E_BUFFER_OVERRUN 9
#define E_RECEIVE_OVERFLOW 10
#define E_RECEIVE_PARITY_ERROR 11
#define E_TRANSMIT_OVERFLOW 12
#define E_READ_FAILED 13
#define E_WRITE_FAILED 14
#define E_FILE_NOT_FOUND 15

enum BaudRateType
{
BAUD50, //POSIX ONLY
BAUD75, //POSIX ONLY
BAUD110,
BAUD134, //POSIX ONLY
BAUD150, //POSIX ONLY
BAUD200, //POSIX ONLY
BAUD300,
BAUD600,
BAUD1200,
BAUD1800, //POSIX ONLY
BAUD2400,
BAUD4800,
BAUD9600,
BAUD14400, //WINDOWS ONLY
BAUD19200,
BAUD38400,
BAUD56000, //WINDOWS ONLY
BAUD57600,
BAUD76800, //POSIX ONLY
BAUD115200,
BAUD128000, //WINDOWS ONLY
BAUD230400,
BAUD256000, //WINDOWS ONLY
BAUD460800,
BAUD921600,
BAUD1152000,
BAUD1500000,
BAUD2500000
};

enum DataBitsType
{
DATA_5,
DATA_6,
DATA_7,
DATA_8
};

enum ParityType
{
PAR_NONE,
PAR_ODD,
PAR_EVEN,
PAR_MARK, //WINDOWS ONLY
PAR_SPACE
};

enum StopBitsType
{
STOP_1,
STOP_1_5, //WINDOWS ONLY
STOP_2
};

enum FlowType
{
FLOW_OFF,
FLOW_HARDWARE,
FLOW_XONXOFF
};

/**
* structure to contain port settings
*/
struct PortSettings
{
BaudRateType BaudRate;
DataBitsType DataBits;
ParityType Parity;
StopBitsType StopBits;
FlowType FlowControl;
long Timeout_Millisec;
};

#include & lt; QIODevice & gt;
#include & lt; QMutex & gt;
#ifdef Q_OS_UNIX
#include & lt; stdio.h & gt;
#include & lt; termios.h & gt;
#include & lt; errno.h & gt;
#include & lt; unistd.h & gt;
#include & lt; sys/time.h & gt;
#include & lt; sys/ioctl.h & gt;
#include & lt; sys/select.h & gt;
#include & lt; QSocketNotifier & gt;
#elif (defined Q_OS_WIN)
#include & lt; windows.h & gt;
#include & lt; QThread & gt;
#include & lt; QReadWriteLock & gt;
#include & lt; QtCore/private/qwineventnotifier_p.h & gt;
#endif

/*!
Encapsulates a serial port on both POSIX and Windows systems.

\note
Be sure to check the full list of members, as QIODevice provides quite a lot of
functionality for QextSerialPort.

\section Usage
QextSerialPort offers both a polling and event driven API. Event driven is typically easier
to use, since you never have to worry about checking for new data.

\b Example
\code
QextSerialPort* port = new QextSerialPort( " COM1 " , QextSerialPort::EventDriven);
connect(port, SIGNAL(readyRead()), myClass, SLOT(onDataAvailable()));
port- & gt; open();

void MyClass::onDataAvailable() {
int avail = port- & gt; bytesAvailable();
if( avail & gt; 0 ) {
QByteArray usbdata;
usbdata.resize(avail);
int read = port- & gt; read(usbdata.data(), usbdata.size());
if( read & gt; 0 ) {
processNewData(usbdata);
}
}
}
\endcode

\section Compatibility
The user will be notified of errors and possible portability conflicts at run-time
by default - this behavior can be turned off by defining _TTY_NOWARN_
(to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability warnings) in the project.

On Windows NT/2000/XP this class uses Win32 serial port functions by default. The user may
select POSIX behavior under NT, 2000, or XP ONLY by defining Q_OS_UNIX in the project.
No guarantees are made as to the quality of POSIX support under NT/2000 however.

\author Stefan Sander, Michal Policht, Brandon Fosdick, Liam Staskawicz
*/
class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice
{
Q_OBJECT
public:
enum QueryMode {
Polling,
EventDriven
};

QextSerialPort(QueryMode mode = EventDriven);
QextSerialPort(const QString & name, QueryMode mode = EventDriven);
QextSerialPort(PortSettings const & s, QueryMode mode = EventDriven);
QextSerialPort(const QString & name, PortSettings const & s, QueryMode mode = EventDriven);
~QextSerialPort();

void setPortName(const QString & name);
QString portName() const;

/**!
* Get query mode.
* \return query mode.
*/
inline QueryMode queryMode() const { return _queryMode; }

/*!
* Set desired serial communication handling style. You may choose from polling
* or event driven approach. This function does nothing when port is open; to
* apply changes port must be reopened.
*
* In event driven approach read() and write() functions are acting
* asynchronously. They return immediately and the operation is performed in
* the background, so they doesn't freeze the calling thread.
* To determine when operation is finished, QextSerialPort runs separate thread
* and monitors serial port events. Whenever the event occurs, adequate signal
* is emitted.
*
* When polling is set, read() and write() are acting synchronously. Signals are
* not working in this mode and some functions may not be available. The advantage
* of polling is that it generates less overhead due to lack of signals emissions
* and it doesn't start separate thread to monitor events.
*
* Generally event driven approach is more capable and friendly, although some
* applications may need as low overhead as possible and then polling comes.
*
* \param mode query mode.
*/
void setQueryMode(QueryMode mode);

void setBaudRate(BaudRateType);
BaudRateType baudRate() const;

void setDataBits(DataBitsType);
DataBitsType dataBits() const;

void setParity(ParityType);
ParityType parity() const;

void setStopBits(StopBitsType);
StopBitsType stopBits() const;

void setFlowControl(FlowType);
FlowType flowControl() const;

void setTimeout(long);

bool open(OpenMode mode);
bool isSequential() const;
void close();
void flush();

qint64 size() const;
qint64 bytesAvailable() const;
QByteArray readAll();

void ungetChar(char c);

ulong lastError() const;
void translateError(ulong error);

void setDtr(bool set=true);
void setRts(bool set=true);
ulong lineStatus();
QString errorString();

#ifdef Q_OS_WIN
virtual bool waitForReadyRead(int msecs); /// & lt; @todo implement.
virtual qint64 bytesToWrite() const;
static QString fullPortNameWin(const QString & name);
#endif

protected:
QMutex* mutex;
QString port;
PortSettings Settings;
ulong lastErr;
QueryMode _queryMode;

// platform specific members
#ifdef Q_OS_UNIX
int fd;
QSocketNotifier *readNotifier;
struct termios Posix_CommConfig;
struct termios old_termios;
struct timeval Posix_Timeout;
struct timeval Posix_Copy_Timeout;
#elif (defined Q_OS_WIN)
HANDLE Win_Handle;
OVERLAPPED overlap;
COMMCONFIG Win_CommConfig;
COMMTIMEOUTS Win_CommTimeouts;
QWinEventNotifier *winEventNotifier;
DWORD eventMask;
QList & lt; OVERLAPPED* & gt; pendingWrites;
QReadWriteLock* bytesToWriteLock;
qint64 _bytesToWrite;
#endif

void construct(); // common construction
void platformSpecificDestruct();
void platformSpecificInit();
qint64 readData(char * data, qint64 maxSize);
qint64 writeData(const char * data, qint64 maxSize);

#ifdef Q_OS_WIN
private slots:
void onWinEvent(HANDLE h);
#endif

private:
Q_DISABLE_COPY(QextSerialPort)

signals:
// /**
// * This signal is emitted whenever port settings are updated.
// * \param valid \p true if settings are valid, \p false otherwise.
// *
// * @todo implement.
// */
// // void validSettings(bool valid);

/*!
* This signal is emitted whenever dsr line has changed its state. You may
* use this signal to check if device is connected.
* \param status \p true when DSR signal is on, \p false otherwise.
*
* \see lineStatus().
*/
void dsrChanged(bool status);

};

#endif


MiniKombajnPomiarowy3_3_rc3.7z > qextserialport_global.h

#ifndef QEXTSERIALPORT_GLOBAL_H
#define QEXTSERIALPORT_GLOBAL_H

#include & lt; QtCore/qglobal.h & gt;

#ifdef QEXTSERIALPORT_LIB
# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT
#else
# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT
#endif

#endif // QEXTSERIALPORT_GLOBAL_H


MiniKombajnPomiarowy3_3_rc3.7z > qextserialenumerator.h

/*!
* \file qextserialenumerator.h
* \author Michal Policht
* \see QextSerialEnumerator
*/

#ifndef _QEXTSERIALENUMERATOR_H_
#define _QEXTSERIALENUMERATOR_H_


#include & lt; QString & gt;
#include & lt; QList & gt;
#include & lt; QObject & gt;
#include " qextserialport_global.h "

#ifdef Q_OS_WIN
#include & lt; windows.h & gt;
#include & lt; setupapi.h & gt;
#include & lt; dbt.h & gt;
#endif /*Q_OS_WIN*/

#ifdef Q_OS_MAC
#include & lt; IOKit/usb/IOUSBLib.h & gt;
#endif

/*!
* Structure containing port information.
*/
struct QextPortInfo {
QString portName; /// & lt; Port name.
QString physName; /// & lt; Physical name.
QString friendName; /// & lt; Friendly name.
QString enumName; /// & lt; Enumerator name.
int vendorID; /// & lt; Vendor ID.
int productID; /// & lt; Product ID
};

#ifdef Q_OS_WIN
#ifdef QT_GUI_LIB
#include & lt; QWidget & gt;
class QextSerialEnumerator;

class QextSerialRegistrationWidget : public QWidget
{
Q_OBJECT
public:
QextSerialRegistrationWidget( QextSerialEnumerator* qese ) {
this- & gt; qese = qese;
}
~QextSerialRegistrationWidget( ) { }

protected:
QextSerialEnumerator* qese;
bool winEvent( MSG* message, long* result );
};
#endif // QT_GUI_LIB
#endif // Q_OS_WIN

/*!
Provides list of ports available in the system.

\section Usage
To poll the system for a list of connected devices, simply use getPorts(). Each
QextPortInfo structure will populated with information about the corresponding device.

\b Example
\code
QList & lt; QextPortInfo & gt; ports = QextSerialEnumerator::getPorts();
foreach( QextPortInfo port, ports ) {
// inspect port...
}
\endcode

To enable event-driven notification of device connection events, first call
setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved()
signals. Event-driven behavior is currently available only on Windows and OS X.

\b Example
\code
QextSerialEnumerator* enumerator = new QextSerialEnumerator();
connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo & )),
myClass, SLOT(onDeviceDiscovered(const QextPortInfo & )));
connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo & )),
myClass, SLOT(onDeviceRemoved(const QextPortInfo & )));
\endcode

\section Credits
Windows implementation is based on Zach Gorman's work from
& lt; a href= " http://www.codeproject.com " & gt; The Code Project & lt; /a & gt; (http://www.codeproject.com/system/setupdi.asp).

OS X implementation, see
http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Finding_Devices/chapter_4_section_2.html

\author Michal Policht, Liam Staskawicz
*/
class QEXTSERIALPORT_EXPORT QextSerialEnumerator : public QObject
{
Q_OBJECT
public:
QextSerialEnumerator( );
~QextSerialEnumerator( );

#ifdef Q_OS_WIN
LRESULT onDeviceChangeWin( WPARAM wParam, LPARAM lParam );
private:
/*!
* Get value of specified property from the registry.
* \param key handle to an open key.
* \param property property name.
* \return property value.
*/
static QString getRegKeyValue(HKEY key, LPCTSTR property);

/*!
* Get specific property from registry.
* \param devInfo pointer to the device information set that contains the interface
* and its underlying device. Returned by SetupDiGetClassDevs() function.
* \param devData pointer to an SP_DEVINFO_DATA structure that defines the device instance.
* this is returned by SetupDiGetDeviceInterfaceDetail() function.
* \param property registry property. One of defined SPDRP_* constants.
* \return property string.
*/
static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property);

/*!
* Search for serial ports using setupapi.
* \param infoList list with result.
*/
static void setupAPIScan(QList & lt; QextPortInfo & gt; & infoList);
void setUpNotificationWin( );
static bool getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo,
PSP_DEVINFO_DATA devData, WPARAM wParam = DBT_DEVICEARRIVAL );
static void enumerateDevicesWin( const GUID & guidDev, QList & lt; QextPortInfo & gt; * infoList );
bool matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam);
#ifdef QT_GUI_LIB
QextSerialRegistrationWidget* notificationWidget;
#endif
#endif /*Q_OS_WIN*/

#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
private:
/*!
* Search for serial ports using IOKit.
* \param infoList list with result.
*/
static void scanPortsOSX(QList & lt; QextPortInfo & gt; & infoList);
static void iterateServicesOSX(io_object_t service, QList & lt; QextPortInfo & gt; & infoList);
static bool getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo );

void setUpNotificationOSX( );
void onDeviceDiscoveredOSX( io_object_t service );
void onDeviceTerminatedOSX( io_object_t service );
friend void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator );
friend void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator );

IONotificationPortRef notificationPortRef;

#else // Q_OS_MAC
private:
/*!
* Search for serial ports on unix.
* \param infoList list with result.
*/
static void scanPortsNix(QList & lt; QextPortInfo & gt; & infoList);
#endif // Q_OS_MAC
#endif /* Q_OS_UNIX */

public:
/*!
Get list of ports.
\return list of ports currently available in the system.
*/
static QList & lt; QextPortInfo & gt; getPorts();
/*!
Enable event-driven notifications of board discovery/removal.
*/
void setUpNotifications( );

signals:
/*!
A new device has been connected to the system.

setUpNotifications() must be called first to enable event-driven device notifications.
Currently only implemented on Windows and OS X.
\param info The device that has been discovered.
*/
void deviceDiscovered( const QextPortInfo & info );
/*!
A device has been disconnected from the system.

setUpNotifications() must be called first to enable event-driven device notifications.
Currently only implemented on Windows and OS X.
\param info The device that was disconnected.
*/
void deviceRemoved( const QextPortInfo & info );
};

#endif /*_QEXTSERIALENUMERATOR_H_*/


MiniKombajnPomiarowy3_3_rc3.7z > qextserialenumerator_unix.cpp

#include & lt; qext_posix/qextserialenumerator.h & gt;
#include & lt; QDebug & gt;
#include & lt; QMetaType & gt;
#include & lt; QStringList & gt;
#include & lt; QDir & gt;

QextSerialEnumerator::QextSerialEnumerator( )
{
if( !QMetaType::isRegistered( QMetaType::type( " QextPortInfo " ) ) )
qRegisterMetaType & lt; QextPortInfo & gt; ( " QextPortInfo " );
}

QextSerialEnumerator::~QextSerialEnumerator( )
{
}

QList & lt; QextPortInfo & gt; QextSerialEnumerator::getPorts()
{
QList & lt; QextPortInfo & gt; infoList;
#ifdef Q_OS_LINUX
QStringList portNamePrefixes, portNameList;
portNamePrefixes & lt; & lt; " ttyS* " ; // list normal serial ports first

QDir dir( " /dev " );
portNameList = dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name);

// remove the values which are not serial ports for e.g. /dev/ttysa
for (int i = 0; i & lt; portNameList.size(); i++) {
bool ok;
QString current = portNameList.at(i);
// remove the ttyS part, and check, if the other part is a number
current.remove(0,4).toInt( & ok, 10);
if (!ok) {
portNameList.removeAt(i);
i--;
}
}

// get the non standard serial ports names
// (USB-serial, bluetooth-serial, 18F PICs, and so on)
// if you know an other name prefix for serial ports please let us know
portNamePrefixes.clear();
portNamePrefixes & lt; & lt; " ttyACM* " & lt; & lt; " ttyUSB* " & lt; & lt; " rfcomm* " ;
portNameList.append(dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name));

foreach (QString str , portNameList) {
QextPortInfo inf;
inf.physName = " /dev/ " +str;
inf.portName = str;

if (str.contains( " ttyS " )) {
inf.friendName = " Serial port " +str.remove(0, 4);
}
else if (str.contains( " ttyUSB " )) {
inf.friendName = " USB-serial adapter " +str.remove(0, 6);
}
else if (str.contains( " rfcomm " )) {
inf.friendName = " Bluetooth-serial adapter " +str.remove(0, 6);
}
inf.enumName = " /dev " ; // is there a more helpful name for this?
infoList.append(inf);
}
#else
qCritical( " Enumeration for POSIX systems (except Linux) is not implemented yet. " );
#endif
return infoList;
}

void QextSerialEnumerator::setUpNotifications( )
{
qCritical( " Notifications for *Nix/FreeBSD are not implemented yet " );
}


MiniKombajnPomiarowy3_3_rc3.7z > mkpcom.h

#ifndef MKPCOM_H
#define MKPCOM_H


#ifdef _TTY_WIN_
#include " qext_win/qextserialport.h "
#include " qext_win/qextserialenumerator.h "
#else
#define Q_OS_UNIX
#include " qext_posix/qextserialport.h "
#include " qext_posix/qextserialenumerator.h "
#endif

#include & lt; QString & gt;
#include & lt; QThread & gt;
#include " structs.h "

class MKPCom;

class Thread : public QThread
{
Q_OBJECT

public:
Thread(QextSerialPort* portrs, Buffer* bufIn, MKPCom* parent);
void run();

private:
QextSerialPort* port;
QByteArray bytes;
Buffer* bufIn;
MKPCom* parent;

public slots:
void onReadyRead();

};

class MKPCom
{
public:
MKPCom();
~MKPCom();
bool Open(QString portName, BaudRateType baud, Buffer* bufIn);
bool Close();
bool Start();
bool osc1chStart();
bool osc2chStart();
bool genStart();
bool sendGenChannel(int* pout);
bool setGain1(int gain);
bool setGain2(int gain);
bool setTimeBase(int t);
bool enable2channel();
bool disable2channel();
bool laStart();
bool setLAstart();
bool setLAtrig(Trigger trig);
bool setLAforceTrig();
bool setLAtimebase(int timebase);

bool setFreq(int per, int tab);

//bool getCh1();
private:
void setParam1(char par, int val);

QextSerialPort* rsPort;
QString portName;
Thread* thr;
int* p;
int* pout;

};



#endif // MKPCOM_H


MiniKombajnPomiarowy3_3_rc3.7z > ustawienia.h

#ifndef USTAWIENIA_H
#define USTAWIENIA_H

#include & lt; QtGui/QMainWindow & gt;
#include & lt; QtGui & gt;

#ifdef _TTY_WIN_
#include " qext_win/qextserialport.h "
#include " qext_win/qextserialenumerator.h "
#else
#include " qext_posix/qextserialport.h "
#include " qext_posix/qextserialenumerator.h "
#endif

class Ustawienia: public QMainWindow
{
Q_OBJECT

public:
Ustawienia(QWidget* parent);

QString getPortName(void);
BaudRateType getPortSpeed(void);
void hide();
void show();
void enable();
void disable();
private:
QWidget* parent;

QComboBox* rsSpeedBox;
QComboBox* rsPortText;
QPushButton* refreshButton;
BaudRateType baud;
QString portName;

void readSettings();
void writeSettings();
void getPorts();

private slots:
void rsSpeedSlot();
void rsNameSlot();
void refreshSlot();
};

#endif // USTAWIENIA_H


MiniKombajnPomiarowy3_3_rc3.7z > oscyloskop.h

#ifndef OSCYLOSKOP_H
#define OSCYLOSKOP_H

#include & lt; QtGui/QMainWindow & gt;
#include & lt; QTextCodec & gt;
#include & lt; QtGui & gt;
#include & lt; math.h & gt;
//#include " qwwtextspinbox.h "
#include " windowsize.h "
#include " mkpcom.h "
#include " graph.h "

static const int gainTab[7] = {500, 200, 100, 50, 20, 10, 5};
static const int timeTab[15] = {8, 10, 8, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000};

class Oscyloskop: public QMainWindow
{
Q_OBJECT

public:
Oscyloskop(QWidget* parent);
void show();
void hide();
void enable();
void start();
void getPortHandle(MKPCom* cp)
{
comPort = cp;
}
int y2ScrollPos(void)
{
return y2Scroll- & gt; value();
}
void drawGraph(Buffer *bufIn);
void adjustGraph(int* buf, int yPos);
bool trigger(int* kan1_in, int* kan1_lcd, int* kan2_lcd, int lev, int trig_type, int xpos);
void setCursor(QMouseEvent *e);
void count(void)
{
counter++;
}
int getGain1()
{
return gainTab[gain1];
}
int getGain2()
{
return gainTab[gain2];
}
int getTimeBase()
{
return timeTab[timeBase];
}

QString calcRMS(int* buf, int length, int gain);
QString calcAvg(int* buf, int length, int gain);
QString calcVpp(int* buf, int length, int gain);
QString calcFreq(int* buf, int length, int time);
QString value(double val);

private:
QWidget* parent;

QComboBox* tSpin;
QComboBox* vSpin;
QComboBox* v2Spin;
QScrollBar* xScroll;
QScrollBar* yScroll;
QScrollBar* y2Scroll;
QCheckBox* xyBox;
QCheckBox* channel2box;
QStringList tlist2;
QComboBox* trigTypeCombo;
QComboBox* trigEdgeCombo;
QComboBox* trigFCombo;
QSpinBox* trigLevSpin;

QCheckBox* curVBox;
QCheckBox* curHBox;

// QPushButton* openBut;
QPushButton* saveBut;

QLabel *xPosLabel;
QLabel *yPosLabel;
QLabel *yPos2Label;
QLabel* labelRMS;
QLabel* labelRMS2;
QLabel* labelAvg;
QLabel* labelAvg2;
QLabel* labelVpp;
QLabel* labelVpp2;
QLabel* labelFreq;
QLabel* labelFreq2;

QLabel* cursorsLabel;
QLabel* curVolt1Label;
QLabel* curVolt2Label;
QLabel* curTimeLabel;
QLabel* curFreqLabel;

void copySignal(int* in, int* out, int len, int gain);
void fileLog(int* buf);

MKPCom* comPort;
int timeBase;
int gain1;
int gain2;
int trig;
float level;
int counter;
bool wzw;
bool trigForce;
int xPos;
int yPos;
int yPos2;
int cursorAV;
int cursorBV;
int cursorAH;
int cursorBH;

QFile* file;
bool fileOpened;

//double average;
//double voltpp;
//slots
private slots:
void tSlot();
void vSlot();
void xySlot(bool val);
void xPosSlot();
void yPosSlot();
void channel2Slot();
void trigSlot();
void cursorSlot();
void openSlot();
void saveSlot();

};

#endif // OSCYLOSKOP_H


MiniKombajnPomiarowy3_3_rc3.7z > osc_sin.txt

254
258
252
248
248
242
228
228
228
224
214
208
200
196
186
172
172
160
154
140
132
128
116
106
100
92
88
68
60
54
46
32
16
8
-2
-12
-24
-32
-40
-54
-64
-78
-88
-94
-106
-120
-130
-142
-150
-156
-168
-180
-184
-190
-198
-210
-212
-216
-226
-234
-244
-244
-254
-252
-262
-266
-268
-276
-276
-284
-280
-276
-282
-282
-282
-284
-284
-280
-276
-276
-274
-274
-270
-268
-264
-254
-250
-248
-246
-238
-228
-224
-216
-208
-208
-196
-190
-184
-174
-164
-154
-136
-128
-124
-112
-102
-90
-80
-70
-58
-48
-42
-28
-16
-8
-2
14
22
40
44
54
64
78
92
100
104
112
124
130
140
148
160
168
168
184
188
200
202
212
218
224
228
230
236
244
244
256
252
260
258
268
268
268
266
268
266
264
266
266
264
262
260
258
252
252
248
240
236
234
224
224
218
210
208
196
188
182
170
160
150
144
136
128
120
110
108
96
82
74
64
58
40
34
22
16
-2
-12
-24
-30
-40
-46
-64
-76
-84
-90
-106
-122
-126
-134
-146
-160
-166
-174
-182
-194
-200
-208
-218
-220
-228
-234
-238
-244
-250
-254
-262
-260
-268
-268
-272
-278
-278
-280
-278
-280
-284
-286
-284
-284
-286
-276
-276
-276
-268
-270
-262
-258
-258
-252
-248
-240
-234
-232
-218
-210
-204
-200
-194
-184
-180
-162
-156
-148
-136
-120
-116
-108
-96
-88
-78
-62
-56
-46
-30
-24
-12
-2
12
24
34
42
52
62
76
84
98
102
116
118
124
138
146
154
164
172
180
188
196
204
206
212
224
228
230
234
248
248
250
252
258
262
260
262
262
262
272
264
266
268
270
266
260
264
254
254
252
252
246
244
234
228
222
220
212
206
198
188
180
172
166
160
148
146
132
120
118
108
98
88
76
68
56
42
36
26
18
4
-8
-14
-28
-36
-48
-60
-68
-84
-90
-106
-118
-122
-128
-148
-160
-162
-170
-184
-194
-194
-204
-212
-222
-228
-232
-240
-246
-248
-256
-260
-262
-264
-270
-276
-278
-274
-280
-284
-282
-284
-282
-282
-280
-282
-280
-278
-278
-276
-268
-264
-262
-256
-258
-244
-242
-236
-232
-218
-216
-212
-204
-194
-182
-178
-170
-160
-152
-140
-124
-114
-106
-94
-88
-76
-66
-52
-40
-36
-28
-12
-8
12
20
28
40
50
60
74
86
96
100
110
120
122
134
144
156
164
172
178
188
194
200
208
220
220
222
232
238
238
246
252
252
258
262
262
262
266
264
272
264
264
272
264
264
262
264
258
260
260
252
244
238
240
232
226
224
218
208
202
196
180
174
166
162
152
140
132
128
112
114
96
96
76
68
60
48
38
28
20
6
0
-16
-26
-32
-44
-58
-68
-82
-90
-98
-110
-122
-134
-146
-152
-160
-170
-180
-186
-194
-208
-214
-216
-222
-230
-240
-244
-252
-252
-260
-260
-268
-272
-270
-274
-276
-280
-280
-288
-278
-284
-284
-286
-282
-280
-282
-272
-272
-272
-262
-266
-262
-252
-250
-240
-236
-230
-224
-222
-212
-210
-196
-190
-184
-168
-160
-156
-136
-136
-122
-108
-104
-90
-84
-68
-60
-42
-36
-26
-12
-4
10
16
26
34
48
56
72
76
96
100
106
114
120
130
136
152
160
168
176
178
190
202
212
216
218
226
230
238
238
248
248
252
260
260
262
266
264
264
268
272
272
268
270
266
260
262
258
256
254
250
244
244
242
234
228
224
220
210
204
192
188
180
172
162
156
146
140
124
118
104
106
92
82
72
60
52
42
32
20
6
-4
-8
-22
-36
-44
-56
-66
-78
-84
-88
-104
-118
-130
-140
-146
-160
-168
-178
-186
-190
-200
-208
-214
-222
-232
-236
-240
-246
-250
-258
-260
-264
-266
-276
-274
-276
-276
-282
-284
-284
-288
-284
-284
-280
-286
-282
-276
-274
-274
-262
-262
-260
-254
-248
-244
-240
-234
-224
-220
-210
-210
-200
-196
-188
-176
-166
-158
-148
-136
-114
-110
-108
-92
-88
-74
-60
-54
-40
-32
-20
-10
2
16
24
30
42
58
66
76
88
98
108
110
120
128
142
146
160
168
172
180
192
198
208
214
216
222
230
232
240
238
248
250
256
258
256
262
266
268
264
266
268
268
270
264
260
262
260
262
252
252
248
248
242
236
226
224
218
216
208
198
192
186
170
166
156
148
138
128
126
114
100
96
90
74
62
54
42
34
20
12
4
-10
-22
-30
-46
-44
-62
-76
-86
-92
-102
-114
-128
-136
-146
-156
-160
-172
-186
-186
-200
-210
-212
-222
-228
-236
-246
-244
-250
-256
-260
-266
-266
-274
-272
-280
-280
-280
-284
-286
-284
-284
-284
-288
-282
-282
-276
-272
-272
-268
-268
-260
-256
-254
-244
-244
-232
-230
-226
-218
-208
-200
-192
-184
-174
-166
-152
-152
-140
-128
-116
-108
-100
-88
-74
-62
-52
-40
-36
-22
-12
-6
8
22
32
40
54
64
72
82
96
104
106
120
126
136
152
156
164
168
186
186
198
210
210
216
224
224
232
240
248
248
250
254
260
260
258
262
266
264
268
268
266
268
270
268
264
266
260
254
254
248
250
242
236
228
226
218
216
204
206
192
184
178
164
162
152
144
130
120
116
104
98
96
76
70
60
42
40
30
12
2
-4
-20
-24
-38
-50
-58
-66
-82
-94
-100
-108
-128
-134
-142
-156
-160
-172
-182
-186
-196
-204
-212


MiniKombajnPomiarowy3_3_rc3.7z > graph.h

#ifndef GRAPH_H
#define GRAPH_H
#include & lt; QtGui/QMainWindow & gt;
#include & lt; QtGui & gt;
#include " windowsize.h "
#include " structs.h "

class Graph
{
public:
Graph(QWidget* parent);
void svWindow();
void vWindow();
void signal(int* buff, QColor color);
void signalXY(int* buff, int* buff2, QColor color);
void signal2x(int* buff, QColor color);
void cursorH(int lev, QColor color);
void cursorV(int pos, QColor color);
void convBufToInt16(Buffer *in, int *out);

private:
QWidget* parent;
QPainter* painter;

};

#endif // GRAPH_H


MiniKombajnPomiarowy3_3_rc3.7z > second_test.txt

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0


MiniKombajnPomiarowy3_3_rc3.7z > generator.cpp

#include " generator.h "

const double PI = 3.14159;

Generator::Generator(QMainWindow* parent, int* b)
{
Generator::parent = parent;
buff = b;
int i;
for(i=0; i & lt; 512; i++)
buffBase[0] = 1000;

Script = new Scriptcalc();

fSpin = new QSpinBox(parent);
fSpin- & gt; setRange(1, 500000);
fSpin- & gt; hide();
fSpin- & gt; setDisabled(1);
fSpin- & gt; setGeometry(100, 580, 110, 20);
fSpin- & gt; setSuffix( " Hz " );
fSpin- & gt; setValue(1000);
QObject::connect(fSpin, SIGNAL(valueChanged(int)), this, SLOT(fSlot()));

fMulSpin = new QSpinBox(parent);
fMulSpin- & gt; setRange(0, 5);
fMulSpin- & gt; hide();
fMulSpin- & gt; setGeometry(215, 580, 85, 20);
fMulSpin- & gt; setPrefix( " x10^ " );
QObject::connect(fMulSpin, SIGNAL(valueChanged(int)), this, SLOT(fMulSlot()));

gSpin = new QSpinBox(parent);
gSpin- & gt; setRange(0, 3000);
gSpin- & gt; hide();
gSpin- & gt; setDisabled(1);
gSpin- & gt; setGeometry(340, 580, 100, 20);
gSpin- & gt; setSuffix( " mV " );
gSpin- & gt; setValue(1250);
QObject::connect(gSpin, SIGNAL(valueChanged(int)), this, SLOT(gSlot()));

QStringList typeList;
typeList & lt; & lt; " sine " & lt; & lt; " square " & lt; & lt; " triangle " & lt; & lt; " white noise " & lt; & lt; " pink noise " & lt; & lt; " arbitrary " & lt; & lt; " function " ;
//tList = new QListWidget(parent);
tList = new QComboBox(parent);
tList- & gt; hide();
tList- & gt; setDisabled(1);
tList- & gt; setGeometry(480, 580, 110, 20);
tList- & gt; addItems(typeList);
QObject::connect(tList, SIGNAL(activated(int)), this, SLOT(typeSlot()));

dSpin = new QSpinBox(parent);
dSpin- & gt; setRange(1, 99);
dSpin- & gt; hide();
dSpin- & gt; setDisabled(1);
dSpin- & gt; setGeometry(600, 580, 60, 20);
dSpin- & gt; setSuffix( " % " );
dSpin- & gt; setValue(50);
QObject::connect(dSpin, SIGNAL(valueChanged(int)), this, SLOT(dSlot()));

oSpin = new QSpinBox(parent);
oSpin- & gt; setRange(-1200, 1200);
oSpin- & gt; hide();
oSpin- & gt; setDisabled(1);
oSpin- & gt; setGeometry(700, 580, 100, 20);
oSpin- & gt; setSuffix( " mV " );
oSpin- & gt; setValue(0);
QObject::connect(oSpin, SIGNAL(valueChanged(int)), this, SLOT(oSlot()));

openBut = new QPushButton( " OPEN " , parent);
openBut- & gt; setGeometry(880,510,100,20);
openBut- & gt; setDisabled(1);
QObject::connect(openBut, SIGNAL(clicked()), this, SLOT(openSlot()));

saveBut = new QPushButton( " SAVE " , parent);
saveBut- & gt; setGeometry(880,540,100,20);
saveBut- & gt; setDisabled(1);
QObject::connect(saveBut, SIGNAL(clicked()), this, SLOT(saveSlot()));


labelFreq = new QLabel( " Freq: 0Hz " , parent);
labelFreq- & gt; setGeometry(Xpanel, 100, XsizePanel, 20);
labelFreq- & gt; setDisabled(1);

// labelGain = new QLabel( " Gain: 0V " , parent);
// labelGain- & gt; setGeometry(Xpanel, 120, XsizePanel, 60);
// labelGain- & gt; setDisabled(1);

mathFuncText = new QPlainTextEdit(parent);
mathFuncText- & gt; hide();
mathFuncText- & gt; setGeometry(Xpanel-20, 400, XsizePanel-10, 60);
mathFuncText- & gt; setDisabled(1);
QObject::connect(mathFuncText, SIGNAL(textChanged()), this, SLOT(mathFuncTextSlot()));

mathFuncButton = new QPushButton( " Generate " ,parent);
mathFuncButton- & gt; hide();
mathFuncButton- & gt; setGeometry(Xpanel, 470, 100, 20);
mathFuncButton- & gt; setDisabled(1);
QObject::connect(mathFuncButton, SIGNAL(clicked()), this, SLOT(mathFuncSlot()));

xFuncSpin = new QDoubleSpinBox(parent);
xFuncSpin- & gt; setRange(-1000000, 1000000);
xFuncSpin- & gt; hide();
xFuncSpin- & gt; setDisabled(1);
xFuncSpin- & gt; setGeometry(Xpanel, 360, 80, 20);
xFuncSpin- & gt; setValue(0);
QObject::connect(xFuncSpin, SIGNAL(valueChanged(double)), this, SLOT(xFuncSlot()));

xFuncSpin2 = new QDoubleSpinBox(parent);
xFuncSpin2- & gt; setRange(-1000000, 1000000);
xFuncSpin2- & gt; hide();
xFuncSpin2- & gt; setDisabled(1);
xFuncSpin2- & gt; setGeometry(Xpanel+80, 360, 80, 20);
xFuncSpin2- & gt; setValue(1);
QObject::connect(xFuncSpin2, SIGNAL(valueChanged(double)), this, SLOT(xFuncSlot()));

labelXRange = new QLabel( " XE " , parent);
labelXRange- & gt; setGeometry(Xpanel-20, 360, 20, 20);
labelXRange- & gt; setDisabled(1);

Gain = 1250;
DcShift = 0;
Type = 0;
Per = 200;
Tab = 512;
Duty = 50;
recentArbPointX = -1;


mmlWidget = new QtMmlWidget(parent);
mmlWidget- & gt; setPalette(Qt::black);
mmlWidget- & gt; setGeometry(0, 0, XsizePanel+16, 96);
mmlWidget- & gt; clear();
//mmlWidget- & gt; hide();


mmlScroll = new QScrollArea(parent);
mmlScroll- & gt; horizontalScrollBar()- & gt; setValue(300);
mmlScroll- & gt; verticalScrollBar()- & gt; setValue(75);
mmlScroll- & gt; setGeometry(Xpanel-40, 260, XsizePanel+20, 100);
mmlScroll- & gt; setWidget(mmlWidget);
mmlScroll- & gt; hide();
mmlScroll- & gt; setDisabled(1);


}

void Generator::show()
{
fSpin- & gt; show();
fMulSpin- & gt; show();
gSpin- & gt; show();
tList- & gt; show();
dSpin- & gt; show();
oSpin- & gt; show();
labelFreq- & gt; show();
//labelGain- & gt; show();
mathFuncText- & gt; show();
mathFuncButton- & gt; show();
xFuncSpin- & gt; show();
xFuncSpin2- & gt; show();
labelXRange- & gt; show();
mmlScroll- & gt; show();
openBut- & gt; show();
saveBut- & gt; show();
}

void Generator::hide()
{
fSpin- & gt; hide();
fMulSpin- & gt; hide();
gSpin- & gt; hide();
tList- & gt; hide();
dSpin- & gt; hide();
oSpin- & gt; hide();
labelFreq- & gt; hide();
//labelGain- & gt; hide();
mathFuncText- & gt; hide();
mathFuncButton- & gt; hide();
xFuncSpin- & gt; hide();
xFuncSpin2- & gt; hide();
labelXRange- & gt; hide();
mmlScroll- & gt; hide();
openBut- & gt; hide();
saveBut- & gt; hide();
}

void Generator::enable()
{
fSpin- & gt; setEnabled(1);
gSpin- & gt; setEnabled(1);
tList- & gt; setEnabled(1);
dSpin- & gt; setEnabled(1);
oSpin- & gt; setEnabled(1);
labelFreq- & gt; setEnabled(1);
//labelGain- & gt; setEnabled(1);
openBut- & gt; setEnabled(1);
saveBut- & gt; setEnabled(1);
mmlScroll- & gt; setEnabled(1);

}

void Generator::start()
{
comPort- & gt; genStart();
fSlot();
typeSlot();
gSlot();
}

void Generator::adjustGraph(int *buf, int length, int *out, int xPos, int yPos, int zoom)
{
int i;
for(i = xPos; i & lt; 768; i++)
{
out[i] = buf[(i*zoom/512-xPos)%length]/2 + yPos;
}
}

void Generator::drawArbRelease()
{
if(recentArbPointX & gt; -1)
comPort- & gt; sendGenChannel(buff);
recentArbPointX = -1;
}

void lineArb(int* buff, int length, int X1, int Y1, int X2, int Y2)
{
int CurrentX, CurrentY, Xinc, Yinc,
Dx, Dy, TwoDx, TwoDy,
TwoDxAccumulatedError, TwoDyAccumulatedError;

Dx = (X2-X1); // obliczenie sk?adowej poziomej
Dy = (Y2-Y1); // obliczenie sk?adowej pionowej

TwoDx = Dx + Dx; // podwojona sk?adowa pozioma
TwoDy = Dy + Dy; // podwojona sk?adowa pionowa

CurrentX = X1; // zaczynamy od X1
CurrentY = Y1; // oraz Y1

Xinc = 1; // ustalamy krok zwi?kszania pozycji w poziomie
Yinc = 1; // ustalamy krok zwi?kszania pozycji w pionie

if(Dx & lt; 0) // jesli sk?adowa pozioma jest ujemna
{
Xinc = -1; // to b?dziemy si? " cofaae " (krok ujemny)
Dx = -Dx; // zmieniamy znak sk?adowej na dodatni
TwoDx = -TwoDx; // jak równie? podwojonej sk?adowej
}

if (Dy & lt; 0) // jeœli sk?adowa pionowa jest ujemna
{
Yinc = -1; // to b?dziemy si? " cofaae " (krok ujemny)
Dy = -Dy; // zmieniamy znak sk?adowej na dodatki
TwoDy = -TwoDy; // jak równiez podwojonej sk?adowej
}

//GLCD_SetPixel(X1,Y1, color); // stawiamy pierwszy krok (zapalamy pierwszy piksel)

if ((Dx != 0) || (Dy != 0)) // sprawdzamy czy linia sk?ada si? z wi?cej ni? jednego punktu ;)
{
// sprawdzamy czy sk?adowa pionowa jest mniejsza lub równa sk?adowej poziomej
if (Dy & lt; = Dx) // jeœli tak, to idziemy " po iksach "
{
TwoDxAccumulatedError = 0; // zerujemy zmienn?
do // ruszamy w drog?
{
CurrentX += Xinc; // do aktualnej pozycji dodajemy krok
TwoDxAccumulatedError += TwoDy; // a tu dodajemy podwojon? sk?adow? pionow?
if(TwoDxAccumulatedError & gt; Dx) // jeœli TwoDxAccumulatedError jest wi?kszy od Dx
{
CurrentY += Yinc; // zwi?kszamy aktualn? pozycj? w pionie
TwoDxAccumulatedError -= TwoDx; // i odejmujemy TwoDx
}
//GLCD_SetPixel(CurrentX,CurrentY, color);// stawiamy nast?pny krok (zapalamy piksel)
buff[(CurrentX%512)] = CurrentY;
}while (CurrentX != X2); // idziemy tak d?ugo, a? osi?gniemy punkt docelowy
}
else // w przeciwnym razie idziemy " po igrekach "
{
TwoDyAccumulatedError = 0;
do
{
CurrentY += Yinc;
TwoDyAccumulatedError += TwoDx;
if(TwoDyAccumulatedError & gt; Dy)
{
CurrentX += Xinc;
TwoDyAccumulatedError -= TwoDy;
}
//GLCD_SetPixel(CurrentX,CurrentY, color);
buff[(CurrentX%512)] = CurrentY;
}while (CurrentY != Y2);
}
}
}

void Generator::refreshBuff(void)
{
int i;
for(i = 0; i & lt; 512; i++)
{
numData[13] = (float)i*6.28318/512.0;
numData[0] = xFuncSpin- & gt; value() + (float)i*(xFuncSpin2- & gt; value() - xFuncSpin- & gt; value())/512.0;
float result = Script- & gt; calculateRPN(RPN, numData);
if(result & gt; 0.9996)
result = 0.9996;
else if(result & lt; -1)
result = -1;
buffBase[i] = result*2048.0;
}
}


void Generator::drawFunc()
{
int i;

for(i=0; i & lt; 512; i++)
{
buff[i] = 0;
}
char infix[200];

Script- & gt; expressToInfix(mathFuncText- & gt; toPlainText(), infix, numData);
qDebug() & lt; & lt; mathFuncText- & gt; toPlainText();
qDebug() & lt; & lt; (char*)infix;
QString mml = Script- & gt; presentExpress(infix, numData);
QString err_msg;
int err_lin, err_col;
mmlWidget- & gt; setContent(mml, & err_msg, & err_lin, & err_col);

QSize qsiz = mmlWidget- & gt; sizeHint();
if(qsiz.width() & lt; XsizePanel+16)
qsiz.setWidth(XsizePanel+16);
if(qsiz.height() & lt; 96)
qsiz.setHeight(96);
mmlWidget- & gt; resize(qsiz);
mmlScroll- & gt; widget();

//labelGain- & gt; setText(QString::number(qsiz.width()));
Script- & gt; infixToRPN((unsigned char*)infix, RPN);
//QString qinfix((const char*)infix);
//QString qRPN((const char*)RPN);
qDebug() & lt; & lt; " RPN: " & lt; & lt; (char*)RPN;
refreshBuff();

//labelFreq- & gt; setText(qinfix);
//labelGain- & gt; setText(qRPN);
bufChange(Tab, 6, Gain, 50, DcShift);
parent- & gt; update();

//comPort- & gt; sendGenChannel(buff);
}

void Generator::drawArb(QMouseEvent *e)
{
int ex = e- & gt; x();
int ey = e- & gt; y();
if(Type == 5)
{
if(e- & gt; buttons() == Qt::LeftButton)
{
if(ex & lt; Xsize + x_s & & ex & gt; x_s)
{
if(ey & lt; Ysize +y_s & & ey & gt; y_s)
{
buffBase[((ex - x_s)%512)] = (Ysize - ey - Ysize/2 + y_s)*8;
parent- & gt; update();
if(recentArbPointX & gt; -1)
{
lineArb(buffBase, Tab, recentArbPointX, recentArbPointY, (ex - x_s), (Ysize - ey - Ysize/2 + y_s)*8);
}
recentArbPointX = (ex - x_s);
recentArbPointY = (Ysize - ey - Ysize/2 + y_s)*8;
bufChange(Tab, 5, Gain, 50, 0);
}
}
}
}
}

void Generator::drawGraph(int xPos, int yPos)
{
int out[768];
//int out2[768];

Graph graph(parent);
graph.svWindow();
graph.cursorV(512, QColor(20,80,60));

adjustGraph(buffBase, 512, out, 0, 0, 512);
graph.signal2x(out, QColor(100,100,20));

adjustGraph(buff, Tab, out, xPos, yPos, Tab);
graph.signal2x(out, QColor(20,30,240));
//calculateRealOut(out, realOut, Tab, 10);


}

void Generator::fMulSlot()
{
int mul=1;
int i = fMulSpin- & gt; value();
while(i--)
mul*=10;
fSpin- & gt; setSingleStep(mul);
}

#define F_clk 2048000000 //x64
#define F_max 32000000 //x64

void Generator::fSlot()
{
freq = fSpin- & gt; value();

int Freq = freq*64;
int tab_c = 512;
int Freq_set = Freq;
int step = 1;
int per_c = 100;

for(int Freq_c=Freq; Freq_set==Freq; Freq_c+=step)
{
tab_c=F_max/Freq_c; //wyznaczenie dzielnika
tab_c & lt; & lt; =1; //dzielnik musi byc parzysty
if(tab_c & gt; 511)tab_c=512;
per_c=F_clk/tab_c;
per_c/=Freq_c;

Freq_set=F_clk/per_c;
Freq_set/=tab_c;
}
if(Freq_set & gt; 32000000)
{
Freq_set=32000000;
per_c=32;
tab_c=2;
}
Tab = tab_c;
Per = per_c;
labelFreq- & gt; setText( " Freq: " + QString::number(32000000/per_c/tab_c) + " Hz " );
//labelGain- & gt; setText(QString::number(per_c));
comPort- & gt; setFreq(per_c, tab_c);
bufChange(Tab, Type, Gain, Duty, DcShift);


}

void Generator::bufChange(int tab, int type, int gain, int duty, int dc_shift)
{
static int tabs;
static int types;
static int gains;
static int dutys;
static int dc_shifts;

//gain*=1.6376;
//dc_shift*=1.6376;
int tmp;
int i;
tmp=(512*duty);
duty=tmp/100;
for(i=0; i & lt; 512; i++)
{
if(type==0) //sinus
{
//tmp= 512*i/tab;
//tmp=32768*cos(tmp*2*PI/512); //musi byc kosinus, aby probrac dobre probki przy max f
tmp = 32768*cos(i*2*PI/512);

}else if(type==1) //prostok?t
{
if(i & lt; duty) //PWM
tmp=32767;
else
tmp=-32768;
}else if(type==2) //trójk?t
{
if(i & gt; duty) //pi?a
{
tmp= 65536*(i-duty);
tmp=32767-tmp/(512-duty);;
}
else
{
tmp= 65536*i;
tmp= tmp/duty -32768;
}
}else if(type==3)
{

break;
}else if(type==4)
{
break;
}else if(type==5)
{
//tmp= 256*(uint32_t)i/tab;
//lc=tmp+64;
//tmp=pgm_read_byte( & sin_tab[lc])-128;
//tmp=eeprom_read_byte( & e_kan_out[i]);
//tmp= 512*i/tab;
//tmp=16*buffBase[tmp];
tmp = 16*buffBase[i];
//break;
}else if(type==6)
{
tmp = 16*buffBase[i];
break;
}
//tmp*=gain;
buffBase[i]=(tmp/16) + dc_shift;
if(buffBase[i] & lt; -2048)buffBase[i]=-2048;
else if(buffBase[i] & gt; 2047)buffBase[i]=2047;
}

for(i=0; i & lt; tab; i++)
buff[i] = buffBase[i*512/tab]*gain/1250;

if(tabs != tab || types != type || gains != gain || dutys != duty || dc_shifts != dc_shift)
{
comPort- & gt; sendGenChannel(buff);
parent- & gt; update();
}
if(type == 6)
{
refreshBuff();
comPort- & gt; sendGenChannel(buff);
parent- & gt; update();
}
tabs = tab;
types = type;
gains = gain;
dutys = duty;
dc_shifts = dc_shift;
}


void Generator::calculateRealOut(int *bufin, int *bufout, int size, int period)
{
int i;
for(i=0; i & lt; size; i++)
bufout[i] = 0;
for(i=2; i & lt; 512; i++)
{
//int i1 = (i+size)%size;
//qDebug() & lt; & lt; i1;
//bufout[i] = bufin[i]*0.626 + bufin[(i-1)%size]*1.88 + bufin[(i-2)%size]*0.626 - bufout[(i-1)%size] - bufout[(i-2)%size]*2.109 - bufout[(i-3)%size]
bufout[i] = (float)bufin[i]*0.714 + (float)bufin[i-1]*0.714 - (float)bufout[i-1]*1 - (float)bufout[i-2]*(0.429);
}
}

//--------------------------------------------------


void Generator::typeSlot()
{
Type = tList- & gt; currentIndex();
/*if(tList- & gt; currentRow() == 0) //sin
{
for(i = 0; i & lt; 512; i++)
buff[i] = sin(i*2*PI/512)*1024;
}else if(tList- & gt; currentRow() == 2) //triangle
{
for(i = 0; i & lt; 512; i++)
buff[i] = i*2;
}*/
if(Type == 6)
{
mathFuncText- & gt; setEnabled(1);
mathFuncButton- & gt; setEnabled(1);
xFuncSpin- & gt; setEnabled(1);
xFuncSpin2- & gt; setEnabled(1);
labelXRange- & gt; setEnabled(1);
}else
{
mathFuncText- & gt; setDisabled(1);
mathFuncButton- & gt; setDisabled(1);
xFuncSpin- & gt; setDisabled(1);
xFuncSpin2- & gt; setDisabled(1);
labelXRange- & gt; setDisabled(1);
}
bufChange(Tab, Type, Gain, Duty, DcShift);
//comPort- & gt; sendGenChannel();

}

void Generator::gSlot()
{
Gain = gSpin- & gt; value();
bufChange(Tab, Type, Gain, Duty, DcShift);
}

void Generator::dSlot()
{
Duty = dSpin- & gt; value();
bufChange(Tab, Type, Gain, Duty, DcShift);
}

void Generator::oSlot()
{
DcShift = oSpin- & gt; value();
bufChange(Tab, Type, Gain, Duty, DcShift);
}

void Generator::mathFuncSlot()
{
drawFunc();
}

void Generator::mathFuncTextSlot()
{
QString text = mathFuncText- & gt; toPlainText();

if(text.contains('\n'))
{
mathFuncText- & gt; undo();
text = mathFuncText- & gt; toPlainText();
if(Script- & gt; syntaxCheck(text))
drawFunc();
}

if(Script- & gt; syntaxCheck(text))
mathFuncButton- & gt; setEnabled(1);
else
mathFuncButton- & gt; setDisabled(1);
}

void Generator::xFuncSlot()
{
QString text = mathFuncText- & gt; toPlainText();
if(Script- & gt; syntaxCheck(text))
drawFunc();
}

void Generator::openSlot()
{
QString ofile;
QString name = QFileDialog::getOpenFileName(this, tr( " Save file " ), " " , " Text files (*.txt) " , & ofile);
if(name.isEmpty())
return;
QFile file(name);
file.open(QFile::ReadOnly);
QTextStream in( & file);
int i;
for(i=0; i & lt; 512; i++)
in & gt; & gt; buffBase[i];
file.close();
Type = 5;
tList- & gt; setCurrentIndex(5);
bufChange(Tab, Type, Gain, 50, 0);
comPort- & gt; sendGenChannel(buff);

}

void Generator::saveSlot()
{
QString sfile;
QString name = QFileDialog::getSaveFileName(this, tr( " Save file " ), " " , " Text files (*.txt) " , & sfile);
if(name.isEmpty())
return;
QFile file(name);
file.open(QFile::WriteOnly);
QTextStream in( & file);
int i;
for(i=0; i & lt; 512; i++)
in & lt; & lt; buffBase[i] & lt; & lt; endl;
file.close();
}


MiniKombajnPomiarowy3_3_rc3.7z > mainwindow.cpp

#include " mainwindow.h "
#include " oscyloskop.h "
#include " math.h "
#include " structs.h "

Buffer buff;
int buff_gen[512];
bool bufReady = false;

extern QString sts;


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextCodec::setCodecForTr (QTextCodec::codecForName ( " UTF-8 " ));
QFont font;
font.setPointSize(9);
font.setBold(0);
this- & gt; setFont(font);
//tab = new QTabWidget(this);
this- & gt; setMinimumSize(Xsize+x_s*2+XsizePanel+40,Ysize+y_s*2+Ytsize+Yscroll);
//layout = new QGridLayout();
//setLayout(layout);
tab = new QWidget(this);
tabs = new QTabWidget(tab);
//tabs- & gt; setMinimumSize(Xsize+x_s+10,Ysize+y_s+10);
tabs- & gt; setMinimumSize(Xsize+x_s+10,0);
tabs- & gt; addTab(new QWidget(), " & Oscyloskop " );
tabs- & gt; addTab(new QWidget(), " & Generator " );
tabs- & gt; addTab(new QWidget(), " & Analizator " );
tabs- & gt; addTab(new QWidget(), " Analizator st. & log. " );
//tabs- & gt; addTab(new QWidget(), " & Wobuloskop " );
//tabs- & gt; addTab(new QWidget(), " & Multimetr " );
tabs- & gt; addTab(new QWidget(), " & Ustawienia " );
//tabs- & gt; addTab(new QWidget(), " & Pomoc " );
this- & gt; setCentralWidget(tab);
connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tabSlot()));
// QSpacerItem* spacer;
// spacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum);
// layout- & gt; addItem(spacer, 0, 0);
//layout- & gt; addWidget(tabs, 1, 1, Qt::AlignCenter);
device = 0;
portOpened = 0;

label = new QLabel(tr( " Off " ), this);
label- & gt; setMinimumSize(100,20);
label- & gt; setGeometry(10, 580, 200, 20);
// layout- & gt; addWidget(label, 2, 2, Qt::AlignCenter);

osc = new Oscyloskop(this);
gen = new Generator(this, buff_gen);
gen- & gt; hide();
ana = new Analizator(this);
ana- & gt; hide();
anaLog = new AnalizatorLog(this);
anaLog- & gt; hide();
ust = new Ustawienia(this);
ust- & gt; hide();

timeLabel = new QLabel(this);
QPalette spalette;
spalette.setColor(QPalette::WindowText, Qt::green);
timeLabel- & gt; setPalette(spalette);
voltLabel = new QLabel(this);
voltLabel- & gt; setPalette(spalette);

openPort = new QPushButton(this);
openPort- & gt; setText( " Open port " );
openPort- & gt; setGeometry(880,580,100,20);
connect(openPort, SIGNAL(clicked()), this, SLOT(comSlot()));

startTimer(50);


// osc- & gt; enable();
// gen- & gt; enable();
// ana- & gt; enable();
// anaLog- & gt; enable();


}

void MainWindow::timerEvent(QTimerEvent *e)
{
if(bufReady)
{

update();
}
label- & gt; setText(sts);
osc- & gt; count();
}


void MainWindow::setTextPos(QMouseEvent *e)
{
int ex = e- & gt; x();
int ey = e- & gt; y();
if(ex & lt; Xsize + x_s & & ex & gt; x_s)
{
if(ey & lt; Ysize +y_s & & ey & gt; y_s)
{
double T = ex-Xsize/2 - x_s;
double U = Ysize - ey - Ysize/2 + y_s;
timeLabel- & gt; setGeometry((ex & lt; Xsize+x_s-100)? ex : ex-100, (ey & lt; Ysize+y_s-35)? ey : ey-30, 100, 15);
voltLabel- & gt; setGeometry((ex & lt; Xsize+x_s-100)? ex : ex-100, (ey & lt; Ysize+y_s-35)? ey+20 : ey-10, 100, 15);
if(device == 0)
{
T = T*osc- & gt; getTimeBase()/65000000;
U = U*osc- & gt; getGain1()/13000;
timeLabel- & gt; setText( " T: " + osc- & gt; value(T) + " s " );
voltLabel- & gt; setText( " U: " + osc- & gt; value(U) + " V " );
}else if(device == 1)
{
T = T*5/2560/gen- & gt; getFreq();
U = U*488/100000;
timeLabel- & gt; setText( " T: " + osc- & gt; value(T) + " s " );
voltLabel- & gt; setText( " U: " + osc- & gt; value(U) + " V " );
}else if(device == 2)
{
T = T + 384 - ana- & gt; getXPos()*2;
T = T*ana- & gt; getTimeBase()/64;
U = U*10/64;
timeLabel- & gt; setText( " F: " + osc- & gt; value(T) + " Hz " );
voltLabel- & gt; setText( " U/Uz: " + osc- & gt; value(U) + " dB " );
}
timeLabel- & gt; show();
voltLabel- & gt; show();
}
}
}

void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
if(device & lt; 3)
setTextPos(e);
if(device == 0)
osc- & gt; setCursor(e);
else if(device == 1)
gen- & gt; drawArb(e);
else if(device == 3)
anaLog- & gt; drawCursor(e);
}

void MainWindow::mousePressEvent(QMouseEvent *e)
{
if(device & lt; 3)
setTextPos(e);
if(device == 0)
osc- & gt; setCursor(e);
else if(device == 3)
anaLog- & gt; drawCursor(e);
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e)
{
timeLabel- & gt; hide();
voltLabel- & gt; hide();
gen- & gt; drawArbRelease();
}

//**************************************************************************************************8
void MainWindow::paintEvent(QPaintEvent *e)
{
/* complex dfft[1024], dfft2[1024];
int i;
for(i=0; i & lt; 1024; i++)
{
dfft2[i].real = dfft[i].real = (100*sin(i*16*3.14159/512)+ 20*sin(i*18*3.14159/512)) *(0.54-0.46*cos(i*2*3.14159/512));
dfft2[i].imag = dfft[i].imag = 0;
}
mcmpfft(dfft2, 512, -1);
int ierror;
mcztfft(dfft, 512, 512, 1024, 0.1, 1, 1024, & ierror);
sts = ierror+'0';
for(i=0; i & lt; 512; i++)
{
buff[i] = log10(dfft[i].real*dfft[i].real + dfft[i].imag*dfft[i].imag)*100-500;
}
for(i=0; i & lt; 512; i++)
{
buff[i+512] = log10(dfft2[i].real*dfft2[i].real + dfft2[i].imag*dfft2[i].imag)*100-500;
}*/


if(device == 0)
osc- & gt; drawGraph( & buff);
else if(device == 1)
gen- & gt; drawGraph(0, 0);
else if(device == 2)
ana- & gt; drawGraph( & buff);
else if(device == 3)
anaLog- & gt; drawGraph( & buff, bufReady);
bufReady = false;
}

MainWindow::~MainWindow()
{

}

QMainWindow* MainWindow::getPointer(void)
{
return this;
}

void MainWindow::tabSlot()
{
if(tabs- & gt; currentIndex() == 0)
{
sts= " Oscyloskop " ;
}else if(tabs- & gt; currentIndex() == 1)
{
sts= " Generator " ;
}else if(tabs- & gt; currentIndex() == 2)
sts= " Analizator " ;
else if(tabs- & gt; currentIndex() == 3)
sts= " Analizator st. log. " ;
else if(tabs- & gt; currentIndex() == 4)
sts= " Ustawienia " ;

closeRecentDevice();
device = tabs- & gt; currentIndex();
openNewDevice();
update();
}

void MainWindow::openNewDevice()
{
if(device == 0)
{
osc- & gt; show();
if(portOpened)osc- & gt; start();
}else if(device == 1)
{
gen- & gt; show();
if(portOpened)gen- & gt; start();
}else if(device == 2)
{
ana- & gt; show();
if(portOpened)ana- & gt; start();
}else if(device == 3)
{
anaLog- & gt; show();
if(portOpened)anaLog- & gt; start();
}else if(device == 4)
ust- & gt; show();

}

void MainWindow::closeRecentDevice()
{
if(device == 0)
{
osc- & gt; hide();
}else if(device == 1)
{
gen- & gt; hide();
}else if(device == 2)
{
ana- & gt; hide();
}else if(device == 3)
{
anaLog- & gt; hide();
}else if(device == 4)
ust- & gt; hide();
}

void MainWindow::comSlot()
{

if(!portOpened)
{
comPort = new MKPCom();
osc- & gt; getPortHandle(comPort);
gen- & gt; getPortHandle(comPort);
ana- & gt; getPortHandle(comPort);
anaLog- & gt; getPortHandle(comPort);
if(comPort- & gt; Open(ust- & gt; getPortName(),ust- & gt; getPortSpeed(), & buff))
{
//text( " Port opened: " );
sts[0] = 'O';
sts[1] = 'p';
sts[2] = 'e';
sts[3] = 'n';
sts[4] = 0;
//text(comPort- & gt; Start());
comPort- & gt; Start();
/*if(device == 0)
osc- & gt; start();
else if(device == 1)
gen- & gt; start();
else if(device == 3)
anaLog- & gt; start();*/
osc- & gt; enable();
gen- & gt; enable();
ana- & gt; enable();
anaLog- & gt; enable();
ust- & gt; disable();
portOpened = true;
openPort- & gt; setText( " Close port " );
openNewDevice();
}else
{
text( " Unable to open " );
portOpened = false;
}
return;
}
if(portOpened)
{
portOpened = false;
comPort- & gt; Close();
openPort- & gt; setText( " Open port " );
ust- & gt; enable();
return;
}
}

void MainWindow::text(QString txt)
{
sts = txt;
}




/*
void MainWindow::tSlot()
{
osc- & gt; tSlot();
}

void MainWindow::vSlot()
{
osc- & gt; vSlot();
}

void MainWindow::channel2Slot()
{
osc- & gt; channel2Slot();
}

void MainWindow::trigSlot()
{
osc- & gt; trigSlot();
}
*/
//------------Generator slots---------
/*
void MainWindow::fMulSlot()
{
gen- & gt; fMulSlot();
}

void MainWindow::fSlot()
{
gen- & gt; fSlot();
}

void MainWindow::typeSlot()
{
gen- & gt; typeSlot();
}

void MainWindow::gSlot()
{
gen- & gt; gSlot();
}
*/
//-----------Analizator slots-----------
/*
void MainWindow::taSlot()
{
ana- & gt; taSlot();
}

void MainWindow::vaSlot()
{
ana- & gt; vaSlot();
}
*/
//-----------Ustawienia slots-----------
/*
void MainWindow::rsSpeedSlot()
{
ust- & gt; rsSpeedSlot();
}

void MainWindow::rsNameSlot()
{
ust- & gt; rsNameSlot();
}
*/


MiniKombajnPomiarowy3_3_rc3.7z > settings.txt

#/dev/ttyUSB0 /dev#19#3#MKP


MiniKombajnPomiarowy3_3_rc3.7z > analizatorlog.cpp

#include " analizatorlog.h "

//extern QString sts;

static int timeTab[14] = {250, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000}; //sample time in ns


AnalizatorLog::AnalizatorLog(QWidget* parent)
{
AnalizatorLog::parent = parent;

QStringList tlist;
tlist & lt; & lt; " 4MSPS " & lt; & lt; " 2MSPS " & lt; & lt; " 1MSPS " & lt; & lt; " 500KSPS " & lt; & lt; " 200KSPS " & lt; & lt; " 100KSPS " & lt; & lt; " 50KSPS " & lt; & lt; " 20KSPS " & lt; & lt; " 10KSPS "
& lt; & lt; " 5KSPS " & lt; & lt; " 2KSPS " & lt; & lt; " 1KSPS " & lt; & lt; " 500SPS " & lt; & lt; " 200SPS " ;
tSpin = new QComboBox(parent);
tSpin- & gt; setGeometry(100, 580, 110, 20);
tSpin- & gt; addItems(tlist);
//tSpin- & gt; setSuffix( " s/dz " );
//tSpin- & gt; setRange(0,14);
//tSpin- & gt; setValue(7);
tSpin- & gt; setCurrentIndex(7);
tSpin- & gt; setDisabled(1);
tSpin- & gt; hide();
QObject::connect(tSpin, SIGNAL(activated(int)), this, SLOT(tlSlot()));

xScroll = new QScrollBar(Qt::Horizontal, parent);
xScroll- & gt; setGeometry(0, Ysize+y_s+10, Xsize+x_s*2, 20);
xScroll- & gt; setMinimum(0);
xScroll- & gt; setMaximum(1984);
xScroll- & gt; setDisabled(1);
QObject::connect(xScroll, SIGNAL(valueChanged(int)), this, SLOT(xPosSlot()));

zoomSpin = new QSpinBox(parent);
zoomSpin- & gt; setRange(1, 24);
zoomSpin- & gt; hide();
zoomSpin- & gt; setDisabled(1);
zoomSpin- & gt; setGeometry(300, 580, 100, 20);
zoomSpin- & gt; setSuffix( " x " );
zoomSpin- & gt; setValue(1);
QObject::connect(zoomSpin, SIGNAL(valueChanged(int)), this, SLOT(zoomSlot()));

QStringList trigList;
trigList & lt; & lt; " X " & lt; & lt; " 0 " & lt; & lt; " 1 " & lt; & lt; " / " & lt; & lt; " \x5C " ;
int i = 0;
for(i=0; i & lt; 8; i++)
{
trigBox[i] = new QComboBox(parent);
trigBox[i]- & gt; setGeometry(560+i*20, 580, 40 , 20);
trigBox[i]- & gt; addItems(trigList);
trigBox[i]- & gt; setCurrentIndex(0);
trigBox[i]- & gt; setStyleSheet( " QComboBox::drop-down {border-width: 0px;} QComboBox::down-arrow {image: url(noimg); border-width: 0px;} " );
QObject::connect(trigBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(trigSlot()));
}

startButton = new QPushButton(parent);
startButton- & gt; setText( " Start " );
startButton- & gt; setGeometry(440,580,100,20);
startButton- & gt; setDisabled(1);
QObject::connect(startButton, SIGNAL(clicked()), this, SLOT(startSlot()));


labelVal = new QLabel( " Value: 0 " , parent);
labelVal- & gt; setGeometry(Xpanel, 100, XsizePanel, 20);
labelVal- & gt; setDisabled(1);
labelVal- & gt; hide();

labelTime = new QLabel( " Time: 0 " , parent);
labelTime- & gt; setGeometry(Xpanel, 120, XsizePanel, 20);
labelTime- & gt; setDisabled(1);
labelTime- & gt; hide();

curPos = 0;
xPos = 0;
zoom = 1;
trigState = 0;
timebase = 0;

}



void AnalizatorLog::triggerFunc(fundef fun)
{
int i = 0;
for(i=0; i & lt; 8; i++)
(trigBox[i]- & gt; *fun)();

}

void AnalizatorLog::show()
{
tSpin- & gt; show();
labelVal- & gt; show();
labelTime- & gt; show();
xScroll- & gt; show();
zoomSpin- & gt; show();
startButton- & gt; show();
triggerFunc( & QWidget::show);
}

void AnalizatorLog::hide()
{
tSpin- & gt; hide();
labelVal- & gt; hide();
labelTime- & gt; hide();
xScroll- & gt; hide();
zoomSpin- & gt; hide();
startButton- & gt; hide();
triggerFunc( & QWidget::hide);
}

void AnalizatorLog::enable()
{
tSpin- & gt; setEnabled(1);
labelVal- & gt; setEnabled(1);
labelTime- & gt; setEnabled(1);
xScroll- & gt; setEnabled(1);
zoomSpin- & gt; setEnabled(1);
startButton- & gt; setEnabled(1);
}

void AnalizatorLog::start()
{
comPort- & gt; laStart();
}

int AnalizatorLog::logicFromSignal(Buffer *in, int *out, int pos, int zoom, int cursor)
{
int i, b, x;

for(i = 0; i & lt; 2048; i++)
{
x = i*4/zoom+pos;
for(b = 0; b & lt; 8; b++)
{
if(x & gt; 2047)
out[b*2048+i] = -1200;
//else if(in- & gt; at[x & gt; & gt; 1] & (0x100 & lt; & lt; b) & & x & 1)
// out[b*2048+i] = -256*b +950;
else if(in- & gt; at[x & gt; & gt; 1] & (1 & lt; & lt; b))
out[b*2048+i] = -256*b +950;
else
out[b*2048+i] = -256*b +840;

/*if(x & gt; 1023)
out[b*2048+2*i+1] = -1200;
else if(in[x] & (0x100 & lt; & lt; b))
out[b*2048+2*i+1] = -256*b +950;
else
out[b*2048+2*i+1] = -256*b +840;*/
}
}
int curVal = cursor*2/zoom+pos;
if(curVal & lt; 2048)
//if(curVal & 1)
// return (in- & gt; at[curVal & gt; & gt; 1] & gt; & gt; 8) & 0xff;
//else
return (in- & gt; at[curVal & gt; & gt; 1]) & 0xff;
else
return -1;
}

void AnalizatorLog::drawGraph(Buffer *buff, bool getBuf)
{
if(getBuf)
{
trigState = 0;
startButton- & gt; setText( " Start " );
}
Graph graph(parent);
graph.svWindow();
qDebug() & lt; & lt; QString::number(buff- & gt; at[0]) & lt; & lt; QString::number(buff- & gt; at[1]) & lt; & lt; QString::number(buff- & gt; at[2]);
int value = logicFromSignal(buff, lcdBuf, xPos, zoom, curPos);
graph.cursorV(curPos, QColor(20,80,60));
int b;
for(b=0; b & lt; 8; b++)
graph.signal(lcdBuf+b*2048, QColor(20+b*25,30,240-b*25));


if(value & lt; 0)
labelVal- & gt; setText( " Value: -- " );
else
labelVal- & gt; setText( " Value: " + QString::number(value));
float curTime = (float)(curPos + xPos/2*zoom)*timeTab[timebase]/zoom/500;
if(curTime & lt; 1000)
labelTime- & gt; setText( " Time: " + QString::number(curTime, 'f', 2) + " us " );
else if(curTime & lt; 1000000)
labelTime- & gt; setText( " Time: " + QString::number(curTime/1000, 'f', 3) + " ms " );
else
labelTime- & gt; setText( " Time: " + QString::number(curTime/1000000, 'f', 3) + " s " );
//labeldaB- & gt; setText( " Power: " + QString::number(power, 'f', 1) + " daB " );
//labelTHDN- & gt; setText( " THD+N: " + QString::number(thd_n, 'f', 2) + " % " );
}

void AnalizatorLog::drawCursor(QMouseEvent *e)
{
int ex = e- & gt; x();
int ey = e- & gt; y();
if(ex & lt; Xsize + x_s & & ex & gt; x_s)
{
if(ey & lt; Ysize +y_s & & ey & gt; y_s)
{
curPos = ex- x_s;
parent- & gt; update();
}

}
}

//-------SLOTS--------------
void AnalizatorLog::tlSlot()
{
timebase = tSpin- & gt; currentIndex();
comPort- & gt; setLAtimebase(timebase);
//podstawa czasu
}

void AnalizatorLog::xPosSlot()
{
xPos = xScroll- & gt; value();
parent- & gt; update();
}

void AnalizatorLog::zoomSlot()
{
zoom = zoomSpin- & gt; value();
parent- & gt; update();
}

void AnalizatorLog::startSlot()
{

if(trigState == 0)
{
trigState = 1;
startButton- & gt; setText( " Force trig " );
comPort- & gt; setLAstart();
// sts = " wait for trig " ;
}
else if(trigState == 1)
{
trigState = 0;
startButton- & gt; setText( " Start " );
comPort- & gt; setLAforceTrig();
//comPort- & gt; osc1chStart();
// sts = " forced trig " ;
//wyzwalanie
}
}

void AnalizatorLog::trigSlot()
{
int i;
for(i=0; i & lt; 8; i++)
{
if(trigBox[i]- & gt; currentIndex() == 0) //X
{
trigger.edge & = ~(1 & lt; & lt; i);
trigger.level & = ~(1 & lt; & lt; i);
trigger.state & = ~(1 & lt; & lt; i);
}else if(trigBox[i]- & gt; currentIndex() == 1) //0
{
trigger.edge & = ~(1 & lt; & lt; i);
trigger.level |= (1 & lt; & lt; i);
trigger.state & = ~(1 & lt; & lt; i);
}else if(trigBox[i]- & gt; currentIndex() == 2) //1
{
trigger.edge & = ~(1 & lt; & lt; i);
trigger.level |= (1 & lt; & lt; i);
trigger.state |= (1 & lt; & lt; i);
}else if(trigBox[i]- & gt; currentIndex() == 3) // /
{
trigger.edge |= (1 & lt; & lt; i);
trigger.level & = ~(1 & lt; & lt; i);
trigger.state |= (1 & lt; & lt; i);
}else if(trigBox[i]- & gt; currentIndex() == 4)// " \ "
{
trigger.edge |= (1 & lt; & lt; i);
trigger.level & = ~(1 & lt; & lt; i);
trigger.state & = ~(1 & lt; & lt; i);
}
}
comPort- & gt; setLAtrig(trigger);
}


MiniKombajnPomiarowy3_3_rc3.7z > PortListener.cpp

#include " PortListener.h "
#include & lt; QtDebug & gt;

PortListener::PortListener(const QString & portName)
{
qDebug() & lt; & lt; " hi there " ;
this- & gt; port = new QextSerialPort(portName, QextSerialPort::EventDriven);
port- & gt; setBaudRate(BAUD57600);
port- & gt; setFlowControl(FLOW_OFF);
port- & gt; setParity(PAR_NONE);
port- & gt; setDataBits(DATA_8);
port- & gt; setStopBits(STOP_2);

if (port- & gt; open(QIODevice::ReadWrite) == true) {
connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(port, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool)));
if (!(port- & gt; lineStatus() & LS_DSR))
qDebug() & lt; & lt; " warning: device is not turned on " ;
qDebug() & lt; & lt; " listening for data on " & lt; & lt; port- & gt; portName();
}
else {
qDebug() & lt; & lt; " device failed to open: " & lt; & lt; port- & gt; errorString();
}
}

void PortListener::onReadyRead()
{
QByteArray bytes;
int a = port- & gt; bytesAvailable();
bytes.resize(a);
port- & gt; read(bytes.data(), bytes.size());


qDebug() & lt; & lt; " bytes read: " & lt; & lt; bytes.size();
qDebug() & lt; & lt; " bytes: " & lt; & lt; bytes;
}

void PortListener::onDsrChanged(bool status)
{
if (status)
qDebug() & lt; & lt; " device was turned on " ;
else
qDebug() & lt; & lt; " device was turned off " ;
}


MiniKombajnPomiarowy3_3_rc3.7z > analizator.h

#ifndef ANALIZATOR_H
#define ANALIZATOR_H

#include & lt; QtGui/QMainWindow & gt;
#include & lt; QtGui & gt;
#include & lt; QGridLayout & gt;
#include & lt; math.h & gt;
#include " windowsize.h "
#include " mkpcom.h "
#include " graph.h "

static const int freqTab[13] = {62500, 50000, 25000, 10000, 5000, 2500, 1000, 500, 250, 100, 50, 25, 10};


class Analizator: public QMainWindow
{
Q_OBJECT

public:
Analizator(QWidget* parent);
void drawGraph(Buffer* buff);
void show();
void hide();
void enable();
void start();
void getPortHandle(MKPCom* cp)
{
comPort = cp;
}
int getTimeBase()
{
return freqTab[timeBase-2];
}
int getXPos()
{
return xPos;
}

private:
QWidget* parent;
QComboBox* tSpin;
QComboBox* vSpin;
QScrollBar* xScroll;
QCheckBox* maxHoldBox;

QLabel* labeldaB;
QLabel* labelTHDN;

MKPCom* comPort;

double fft(double *x, double *y, int v, double *SinTab, int M);
void adjustGraph(int *buf, double *in, int xPos);
double sinTab[1280];
double bufx[1024];
double bufy[1024];
int lcdBuf[512];
int lcdBufMax[512];
int timeBase;
int gain1;
int xPos;

private slots:
void taSlot();
void vaSlot();
void xPosSlot();
void maxHoldSlot();
};

#endif // ANALIZATOR_H


MiniKombajnPomiarowy3_3_rc3.7z > graph.cpp

#include " graph.h "

Graph::Graph(QWidget* parent)
{
this- & gt; parent = parent;
painter = new QPainter(parent);
}

void Graph::svWindow()
{
//QPainter painter(parent);
painter- & gt; setPen(QPen(QBrush(Qt::black, Qt::SolidPattern), Ysize));
painter- & gt; drawLine(x_s+Yhsize,y_s+Yhsize,x_s+Xsize-Yhsize,y_s+Yhsize);
painter- & gt; setPen(QColor(10, 110, 10));

for(int i=0; i & lt; Ysize/64+1; i++)
{
painter- & gt; drawLine(x_s,i*64+y_s,Xsize+x_s,i*64+y_s);
}

for(int i=0; i & lt; Xsize/64+1; i++)
{
painter- & gt; drawLine(i*64+x_s, y_s, i*64+x_s, Ysize+y_s);
}
painter- & gt; setPen(QColor(10, 240, 10));
painter- & gt; drawLine(Xsize/2+x_s,y_s,Xsize/2+x_s,Ysize+y_s);
painter- & gt; drawLine(x_s,Yhsize+y_s,Xsize+x_s,Yhsize+y_s);
}

void Graph::vWindow()
{

}

void Graph::convBufToInt16(Buffer *in, int *out)
{
int i = 0;
for(i=0; i & lt; 1024; i++)
{
out[i] = (short int)(((unsigned char)in- & gt; at[2*i+1] & lt; & lt; 8) + (unsigned char)in- & gt; at[2*i]);
}
}

void Graph::signal(int *buff, QColor color)
{
painter- & gt; setPen(color);
int pos1, pos2;
for(int i=1; i & lt; Xsize-1; i+=2)
{
pos1 = buff[i/2]/4;
pos2 = buff[i/2+1]/4;
int alpha = 255 - pow(abs(pos2 - pos1)*65536, 0.3);
if(alpha & gt; 255)alpha = 255;
if(alpha & lt; 10)alpha = 10;
color.setAlpha(alpha);
painter- & gt; setPen(color);
if(pos1 & gt; Yhsize & & pos2 & gt; Yhsize)continue;
else if(pos1 & gt; Yhsize)pos1=Yhsize;
else if(pos2 & gt; 256)pos2=256;
else if(pos1 & lt; -Yhsize & & pos2 & lt; -Yhsize)continue;
else if(pos1 & lt; -Yhsize)pos1=-Yhsize;
else if(pos2 & lt; -256)pos2=-256;
painter- & gt; drawLine(x_s+i,y_s-pos1+Yhsize,x_s+i+1,y_s-pos2+Yhsize);
}
}

void Graph::signalXY(int *buff, int *buff2, QColor color)
{
painter- & gt; setPen(color);
int pos1, pos2;
int y1, y2;
for(int i=1; i & lt; Xsize-1; i+=2)
{
pos1 = buff[i/2]/4;
pos2 = buff[i/2+1]/4;
y1 = buff2[i/2]/4;
y2 = buff2[i/2+1]/4;
int alpha = 255 - pow(abs(pos2 - pos1)*65536, 0.3);
if(alpha & gt; 255)alpha = 255;
if(alpha & lt; 10)alpha = 10;
color.setAlpha(alpha);
painter- & gt; setPen(color);
if(pos1 & gt; Yhsize & & pos2 & gt; Yhsize)continue;
else if(pos1 & gt; Yhsize)pos1=Yhsize;
else if(pos2 & gt; 256)pos2=256;
else if(pos1 & lt; -Yhsize & & pos2 & lt; -Yhsize)continue;
else if(pos1 & lt; -Yhsize)pos1=-Yhsize;
else if(pos2 & lt; -256)pos2=-256;

// if(y1 & gt; 512 & & y2 & gt; 512)continue;
// else if(y1 & gt; 512)y1=512;
// else if(y2 & gt; 256)y2=256;
// else if(y1 & lt; -Yhsize & & y2 & lt; -Yhsize)continue;
// else if(y1 & lt; -Yhsize)y1=-Yhsize;
// else if(y2 & lt; -256)y2=-256;
painter- & gt; drawLine(x_s+y1,y_s-pos1+Yhsize,x_s+y2,y_s-pos2+Yhsize);
}
}

void Graph::signal2x(int *buff, QColor color)
{
painter- & gt; setPen(color);
int pos1, pos2;
for(int i=1; i & lt; Xsize-1; i++)
{
pos1 = buff[i]/4;
pos2 = buff[i+1]/4;
if(pos1 & gt; Yhsize & & pos2 & gt; Yhsize)continue;
else if(pos1 & gt; Yhsize)pos1=Yhsize;
else if(pos2 & gt; 256)pos2=256;
else if(pos1 & lt; -Yhsize & & pos2 & lt; -Yhsize)continue;
else if(pos1 & lt; -Yhsize)pos1=-Yhsize;
else if(pos2 & lt; -256)pos2=-256;
painter- & gt; drawLine(x_s+i,y_s-pos1+Yhsize,x_s+i+1,y_s-pos2+Yhsize);
}
}



void Graph::cursorH(int lev, QColor color)
{
painter- & gt; setPen(color);
painter- & gt; drawLine(x_s, y_s+Yhsize - lev, x_s+768, y_s+Yhsize - lev);
}

void Graph::cursorV(int pos, QColor color)
{
painter- & gt; setPen(color);
painter- & gt; drawLine(x_s + pos, y_s+Ysize, x_s + pos, y_s);
}


MiniKombajnPomiarowy3_3_rc3.7z > ustawienia.cpp

#include " ustawienia.h "


extern QString sts;
//const BaudRateType portBaud [10] = {BAUD19200, BAUD38400, BAUD57600, BAUD115200, BAUD230400,
// BAUD460800, BAUD921600, BAUD1152000, BAUD2500000};

const BaudRateType portBaud [10] = {BAUD19200, BAUD38400, BAUD57600, BAUD115200, BAUD230400,
BAUD460800, BAUD921600};

Ustawienia::Ustawienia(QWidget* parent)
{
Ustawienia::parent = parent;

QStringList speedList;
speedList & lt; & lt; " 19200 " & lt; & lt; " 38400 " & lt; & lt; " 57600 " & lt; & lt; " 115200 " & lt; & lt; " 230400 " & lt; & lt; " 460800 " & lt; & lt; " 921600 " & lt; & lt; " 1152000 " & lt; & lt; " 1500000 " & lt; & lt; " 2500000 " ;
rsSpeedBox = new QComboBox(parent);
rsSpeedBox- & gt; setGeometry(100, 100, 200, 20);
rsSpeedBox- & gt; addItems(speedList);
rsSpeedBox- & gt; setCurrentIndex(3);
QObject::connect(rsSpeedBox, SIGNAL(activated(int)), this, SLOT(rsSpeedSlot()));

rsPortText = new QComboBox(parent);
rsPortText- & gt; setObjectName(QString::fromUtf8( " RS232 PORT " ));
rsPortText- & gt; setGeometry(100, 130, 200, 30);
//rsPortText- & gt; setMaximumBlockCount(1);
rsPortText- & gt; clear();
QObject::connect(rsPortText, SIGNAL(activated(int)), this, SLOT(rsNameSlot()));

refreshButton = new QPushButton( " Refresh " , parent);
refreshButton- & gt; setGeometry(320, 130, 80, 30);
QObject::connect(refreshButton, SIGNAL(clicked()), this, SLOT(refreshSlot()));

baud = BAUD115200;
portName = " /dev/ttyUSB0 " ;
readSettings();

getPorts();




}

void Ustawienia::getPorts()
{

QList & lt; QextPortInfo & gt; ports = QextSerialEnumerator::getPorts();
// qDebug() & lt; & lt; ports.at(0).portName;
int i;
int curInd = -1;

i = rsPortText- & gt; count();
for(;i & gt; = 0; --i)
rsPortText- & gt; removeItem(i);

for (i = 0; i & lt; ports.size(); i++)
{
#ifdef _TTY_WIN_
QString rsport = ports.at(i).portName;
//rsport = rsport.remove(5, 4);
rsport = rsport.left(5);
#else
QString rsport = ports.at(i).physName;
#endif
rsPortText- & gt; addItem(rsport + " " +ports.at(i).enumName);
if(rsport == portName)
curInd = i;
}
if(curInd & gt; -1)
rsPortText- & gt; setCurrentIndex(curInd);
else
rsPortText- & gt; setCurrentIndex(i-1);
}

void Ustawienia::hide()
{
rsSpeedBox- & gt; hide();
rsPortText- & gt; hide();
refreshButton- & gt; hide();
}

void Ustawienia::show()
{
rsSpeedBox- & gt; show();
rsPortText- & gt; show();
refreshButton- & gt; show();
}

void Ustawienia::enable()
{
rsSpeedBox- & gt; setEnabled(1);
rsPortText- & gt; setEnabled(1);
refreshButton- & gt; setEnabled(1);
}

void Ustawienia::disable()
{
rsSpeedBox- & gt; setDisabled(1);
rsPortText- & gt; setDisabled(1);
refreshButton- & gt; setDisabled(1);
}

void Ustawienia::readSettings()
{
QFile file( " settings.txt " );
file.open(QFile::ReadWrite);
QTextStream in( & file);
QString str;
in & gt; & gt; str;
if(str.indexOf('#') & gt; -1)
{
portName = str.section('#', 1, 1);
baud = (BaudRateType)str.section('#', 2, 2).toInt();
rsSpeedBox- & gt; setCurrentIndex(str.section('#', 3, 3).toInt());
}else
{
in & lt; & lt; " #/dev/ttyS0#115200#3#MKP " ;
}
file.close();
}

void Ustawienia::writeSettings()
{
QFile file( " settings.txt " );
file.open(QFile::WriteOnly);
QTextStream in( & file);
in & lt; & lt; " # " & lt; & lt; portName & lt; & lt; " # " & lt; & lt; QString::number(baud) & lt; & lt; " # " & lt; & lt; QString::number(rsSpeedBox- & gt; currentIndex()) & lt; & lt; " #MKP " ;
file.close();
}

QString Ustawienia::getPortName()
{
qDebug() & lt; & lt; " portname " & lt; & lt; portName;
return portName;
}

BaudRateType Ustawienia::getPortSpeed()
{
return baud;
}

void Ustawienia::rsSpeedSlot()
{
baud = portBaud[rsSpeedBox- & gt; currentIndex()];
writeSettings();
}

void Ustawienia::rsNameSlot()
{
portName = rsPortText- & gt; currentText().section( " " , 0);
writeSettings();
}

void Ustawienia::refreshSlot()
{
getPorts();
}


MiniKombajnPomiarowy3_3_rc3.7z > analizatorlog.h

#ifndef ANALIZATORLOG_H
#define ANALIZATORLOG_H

#include & lt; QtGui/QMainWindow & gt;
#include & lt; QGridLayout & gt;
#include & lt; QtGui & gt;
#include " mkpcom.h "
#include " windowsize.h "
#include " graph.h "



class AnalizatorLog: public QMainWindow
{
Q_OBJECT

public:
AnalizatorLog(QWidget* parent);

void show();
void hide();
void enable();
void start();
void drawGraph(Buffer *buff, bool getBuf);
void drawCursor(QMouseEvent* e);
void getPortHandle(MKPCom* cp)
{
comPort = cp;
}

typedef void (QWidget::*fundef)(void);

private:
QWidget* parent;
QComboBox* tSpin;
QSpinBox* zoomSpin;
QLabel* labelVal;
QLabel* labelTime;
QScrollBar* xScroll;
QPushButton* startButton;
QComboBox* trigBox[8];

int logicFromSignal(Buffer *in, int *out, int pos, int zoom, int cursor);
void triggerFunc(fundef fun);

MKPCom* comPort;
int lcdBuf[8*2048];
int curPos;
int xPos;
int zoom;
int trigState;
int timebase;
Trigger trigger;

private slots:
void tlSlot();
void xPosSlot();
void zoomSlot();
void startSlot();
void trigSlot();
};

#endif // ANALIZATORLOG_H


MiniKombajnPomiarowy3_3_rc3.7z > interface.h

#ifndef INTERFACE_H
#define INTERFACE_H

#include " mainwindow.h "

class Interface
{
public:
Interface(QMainWindow* w);
//void text(char* txt);
private:
QMainWindow* window;
};

#endif // INTERFACE_H