/**************************************************************************** ** ** Copyright (C) 2020 Minnesota Department of Transportation ** Office of Materials & Road Research ** 1400 Gervais Avenue ** Saint Paul, Minnesota 55109-2044 ** USA ** http://www.dot.state.mn.us/app/pavecool ** ** ** $QT_BEGIN_LICENSE:GPL$ ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** If you did not receive a copy of the GNU General Public License ** see http://www.gnu.org/licenses ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "globals.h" // ALL THE GLOBAL DEFINITIONS bool setSpin(double oldval, double *newval, double incr) {// resets the spinner if the start point is not a multiple of the increment if(qFabs(qFabs(*newval - oldval) - incr) < EN12) // indicates spinner was used instead of edit box { if(qFabs(remainder(*newval, incr)) > EN12) { *newval = *newval > oldval ? qFloor(*newval/incr) * incr : qCeil(*newval/incr) * incr; } return true; } else return false; } int pdfRect(QRectF *rect, double wpage, double top, double ht, int ncells, int n) { // returns the top of the next line's rect // n is the horizontal cell index (zero-based) // top gets updated for next line double lt, wd; wd = wpage/ncells; lt = double(n)*wd; QRectF rectTmp = QRectF(lt, top, wd, ht); *rect = rectTmp; return int(rectTmp.bottom()); // return rectTmp.y() + rectTmp.height(); } int decl(bool si) {// decimal places for length (mm or in) return si ? DEC_MM : DEC_IN; } int nint(double x) // provided by koahnig at qt-project.org {// avoids binary rounding error in int conversion return x < 0 ? int(qCeil(x)) : int(qFloor(x)); } long nlong(double x) {// avoids binary rounding error in long conversion return x < 0 ? long(qCeil(x)) : long(qFloor(x)); } double incl(bool si) {// spin button increments for length (mm or in) return si ? INC_MM : INC_IN; } // The following facilitate conversions between stored and displayed data (SI or English units) // insi and outsi refer to the input and output units (true = SI) double convt(bool insi, double tin, bool outsi) {// temperature °C or °F if((insi && outsi) || (!insi && !outsi)) return tin; else if(insi) return tin * K_R + 32.; else return (tin - 32.) / K_R; } double convl(bool insi, double lin, bool outsi) {// length mm or in if((insi && outsi) || (!insi && !outsi)) return lin; else if(insi) return lin / IN_MM; else return lin * IN_MM; } double convll(bool insi, double lin, bool outsi) {// input length m or ft, output m if((insi && outsi) || (!insi && !outsi)) return lin; else if(insi) return lin / FT_M; else return lin * FT_M; } double convlll(bool insi, double lin, bool outsi) {// length km or mi if((insi && outsi) || (!insi && !outsi)) return lin; else if(insi) return lin / MI_KM; else return lin * MI_KM; } double convf(bool insi, double fin, bool outsi) {// force N (kN) or lbs (kips) if((insi && outsi) || (!insi && !outsi)) return fin; else if(insi) return fin / LB_N; else return fin * LB_N; } double convp(bool insi, double pin, bool outsi) {// pressure kPa (MPa) or psi (ksi) if((insi && outsi) || (!insi && !outsi)) return pin; else if(insi) return pin / PSI_KPA; else return pin * PSI_KPA; } double convd(bool insi, double din, bool outsi) {// density kg/m3 or pcf if((insi && outsi) || (!insi && !outsi)) return din; else if(insi) return din / PCF_KGM3; else return din * PCF_KGM3; } double rnd2dec(double value, int dec, bool sigfig) {// RoundToDecimal written by Corey Spagnoli 1/14/98 adapted by Bruce Tanquist long temp_value; double ret_value; double raise_to; double tolerance; double final_diff; bool bneg = value < 0.0; if(bneg) { value = -value; } // Significant figures option added by Bruce Tanquist 5/11/01 if(sigfig) { if(value < EN12) { dec = 0; // avoid log(0) error } else { dec -= (1 + nint(log10(value))); } } raise_to = qPow(10.0, double(dec)); tolerance = 1.0 / raise_to; temp_value = long(round(value * raise_to)); ret_value = double(temp_value) / raise_to; final_diff = value - ret_value; if(final_diff < -tolerance || final_diff > tolerance) { ret_value = value; } value = ret_value; if(bneg) { value = -value; } return value; } QString txtt(bool si) { return si ? "°C" : "°F"; } QString txtl(bool si) { return si ? QObject::tr("mm") : QObject::tr("in."); } QString txtll(bool si) { return si ? QObject::tr("m") : QObject::tr("ft."); } QString txtlll(bool si) { return si ? QObject::tr("km") : QObject::tr("mi."); } QString txtf(bool si) { return si ? QObject::tr("N") : QObject::tr("lb."); } QString txtff(bool si) { return si ? QObject::tr("kN") : QObject::tr("kips"); } QString txtp(bool si) { return si ? QObject::tr("kPa") : QObject::tr("psi"); } QString txte(bool si) { return si ? QObject::tr("MPa") : QObject::tr("ksi"); } QString txtu(bool si) { return si ? QObject::tr("µm") : QObject::tr("mils"); } QString tontxt(bool si) { return si ? QObject::tr("tonnes") : QObject::tr("tons"); } QString txtv(bool si) { return si ? "km/h" : "mph"; } QString trimright(QString txt, QString ttrim) {// trims all of the ttrim characters from the right side of txt while(txt.right(1) == ttrim) txt.resize(txt.size() - 1); return txt; } QString txtdbl(double value, int dec, bool sigfig, bool trimzero, bool comma) {// convert a double to text with options for decimal place, significant digits, remove extra zeroes and add commas int i, decimal; QString tNum; value = rnd2dec(value, dec, sigfig); // run conversion with precision 6 to make sure the decimal point is found tNum = QString::number(value, 'f', 6); decimal = tNum.indexOf("."); tNum = sigfig ? QString::number(value, 'e', dec) : QString::number(value, 'f', dec); tNum.remove("."); if(decimal > 0) { int lg = tNum.length(); if(decimal > lg) for(i = 0; i < decimal - lg; i++) tNum.insert(lg+i, "0"); tNum.insert(decimal, "."); if(trimzero) tNum = trimright(tNum, "0"); tNum = trimright(tNum, "."); } else if(decimal == 0) { tNum.insert(0, "."); tNum.insert(0, "0"); if(trimzero) tNum = trimright(tNum, "0"); } else // decimal < 0 { for(i = decimal; i < 0; i++) tNum.insert(0, "0"); tNum.insert(0, "."); tNum.insert(0, "0"); if(trimzero) tNum = trimright(tNum, "0"); } if(comma) { int length = tNum.indexOf("."); if(length == -1) length = tNum.size(); for(i = 1; i < 4; i++) if(i*3 < length) tNum.insert(length-i*3, ","); } return tNum; } QString txthrmin(int hour, int min, bool b24) {// convert hour and minute strings to one time string with option for 12 or 24 hour format if(hour < 0 || hour > 23) hour = 0; if(min < 0 || min > 59) min = 0; QString tm; QString th; QString tmin = QString::number(min); QString tc = ":"; QString tz = "0"; if(b24) tm = ""; else if(hour < 12) tm = " AM"; else tm = " PM"; if(min < 10) tmin = tc + tz + tmin; else tmin = tc + tmin; if(b24) { th = QString::number(hour); if(hour < 10) th = tz + th; } else { if(hour == 0) hour = 12; else if(hour > 12) hour -= 12; th = QString::number(hour); } return th + tmin + tm; } QTime TimeText(QString *time, bool b24) {// interpret a string with numbers, am, pm, a, p and other characters to produce // a QTime variable and formatted time string with option for 12 or 24 hour format QString ttime = *time; QString th; // hours QString tm = "0"; QString tmin; QString tc = ":"; QString tz = "0"; ttime.remove(" "); ttime.remove("."); ttime.remove(","); ttime.remove(";"); ttime.remove("-"); ttime.replace("a","A"); ttime.replace("p","P"); ttime.replace("m","M"); int na = ttime.indexOf("A"); ttime.remove("A"); int np = ttime.indexOf("P"); ttime.remove("P"); int nz; // indicates leading zero (military time) ttime.remove("M"); int nmin = 0; // minutes // check to see if there are more or less than 2 characters after the colon int nt = ttime.indexOf(":"); int nl = ttime.length(); if(nt > -1 && nl == nt+2) ttime.insert(nt+1, "0"); // insert 0 if only 1 char in minutes ttime.remove(":"); nl = ttime.length(); if(nl > 4) ttime.remove(4, nl-4); // remove extra digits QString ttmp = ttime.at(0); nz = ttmp.toInt(); // zero indicates military time nt = ttime.toInt(); if(nl > 2) // assume hours and minutes entered { tmin = ttime.right(2); nmin = tmin.toInt(); if(nt >= 100) nt /= 100; // remove minutes else if(b24) nt = 0; } if(na >= 0 && nt == 12) nt = 0; else if(np >= 0 && nt < 12) nt += 12; if(nt == 24) nt = 0; else if(nt > 24) nt = 12; else if(!b24 && na + np == -2 // no am or pm indicated && nz > 0 && nt < 6) // assume pm if 12:00 to 5:59 { nt += 12; } if(nmin >= 60) nmin = 0; tmin = QString::number(nmin); tmin = nmin < 10 ? tc + tz + tmin : tc + tmin; if(b24) { th = QString::number(nt); tm = ""; if(nt < 10) th = tz + th; } else { if(nt < 12) tm = " AM"; else tm = " PM"; if(nt == 0) th = "12"; else if(nt > 12) th = QString::number(nt-12); else th = QString::number(nt); } *time = th + tmin + tm; return QTime(nt, nmin); }