OSCAR-code/report.cpp
2011-09-13 02:10:43 +10:00

266 lines
8.6 KiB
C++

#include "report.h"
#include "ui_report.h"
#include <QMessageBox>
#include <QBuffer>
#include <Graphs/gYAxis.h>
#include <Graphs/gXAxis.h>
//#include <QTimer>
#include <QPrinter>
#include <QPrintDialog>
#include <QRegExp>
#include <QFile>
#include <QDir>
Report::Report(QWidget *parent, Profile * _profile, gGraphView * shared, Overview * overview) :
QWidget(parent),
ui(new Ui::Report),
profile(_profile),
m_overview(overview)
{
ui->setupUi(this);
Q_ASSERT(profile!=NULL);
GraphView=new gGraphView(this,shared);
setMaximumSize(graph_print_width,800);
setMinimumSize(graph_print_width,800);
GraphView->setMaximumSize(graph_print_width,graph_print_height);
GraphView->setMinimumSize(graph_print_width,graph_print_height);
GraphView->hide();
// Reusing the layer data from overview screen,
// (Can't reuse the graphs objects without breaking things)
graphs["Usage"]=UC=new gGraph(GraphView,"Usage",graph_print_height,0);
UC->AddLayer(m_overview->uc);
graphs["AHI"]=AHI=new gGraph(GraphView,"AHI",graph_print_height,0);
AHI->AddLayer(m_overview->bc);
graphs["Pressure"]=PR=new gGraph(GraphView,"Pressure",graph_print_height,0);
PR->AddLayer(m_overview->pr);
graphs["Leaks"]=LK=new gGraph(GraphView,"Leaks",graph_print_height,0);
LK->AddLayer(m_overview->lk);
graphs["%PB"]=NPB=new gGraph(GraphView,"% in PB",graph_print_height,0);
NPB->AddLayer(m_overview->npb);
for (QHash<QString,gGraph *>::iterator g=graphs.begin();g!=graphs.end();g++) {
gGraph *gr=g.value();
gr->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
gXAxis *gx=new gXAxis();
gx->setUtcFix(true);
gr->AddLayer(gx,LayerBottom,0,gXAxis::Margin);
gr->AddLayer(new gXGrid());
}
GraphView->hideSplitter();
m_ready=false;
}
Report::~Report()
{
GraphView->TrashGraphs();
for (QHash<QString,gGraph *>::iterator g=graphs.begin();g!=graphs.end();g++) {
delete g.value();
}
delete ui;
}
void Report::ReloadGraphs()
{
for (QHash<QString,gGraph *>::iterator g=graphs.begin();g!=graphs.end();g++) {
g.value()->setDay(NULL);
}
startDate=profile->FirstDay();
endDate=profile->LastDay();
for (QHash<QString,gGraph *>::iterator g=graphs.begin();g!=graphs.end();g++) {
g.value()->ResetBounds();
}
m_ready=true;
}
QPixmap Report::Snapshot(gGraph * graph)
{
QDateTime d1(startDate,QTime(0,0,0),Qt::UTC);
qint64 first=qint64(d1.toTime_t())*1000L;
QDateTime d2(endDate,QTime(23,59,59),Qt::UTC);
qint64 last=qint64(d2.toTime_t())*1000L;
GraphView->TrashGraphs();
GraphView->AddGraph(graph);
GraphView->ResetBounds();
GraphView->SetXBounds(first,last);
QPixmap pixmap=GraphView->renderPixmap(graph_print_width,graph_print_height,false);
return pixmap;
}
QString Report::ParseTemplate(QString input)
{
QString output;
QRegExp rx("\\{\\{(.*)\\}\\}");
rx.setMinimal(true);
int lastpos=0,pos=0;
while ((pos=rx.indexIn(input,pos))!=-1) {
output+=input.mid(lastpos,pos-lastpos);
QString block=rx.cap(1);
QString code=block.section(".",0,0).toLower();
QString key=block.section(".",1,-1);
QHash<QString,QVariant> * pr=NULL;
if (code=="profile") {
pr=&profile->p_preferences;
} else if (code=="pref") {
pr=&pref.p_preferences;
} else if (code=="local") {
pr=&locals;
}
QString value;
if (pr) {
if (pr->contains(key)) {
if ((*pr)[key].type()==QVariant::String){
value=(*pr)[key].toString();
value.replace("\n","<br/>");
output+=value;
} else if ((*pr)[key].type()==QVariant::Double){
bool ok;
value=QString::number((*pr)[key].toDouble(&ok),'f',2);
if (ok) output+=value; else output+="[NaN]";
} else if ((*pr)[key].type()==QVariant::Int){
bool ok;
value=QString::number((*pr)[key].toInt(&ok));
if (ok) output+=value; else output+="[NaN]";
} else if ((*pr)[key].type()==QVariant::Date){
value=(*pr)[key].toDate().toString();
output+=value;
} else {
qDebug() << "Unknown key type" << (*pr)[key].typeName() << " in " << code << "." << key << "in template";
}
} else {
qDebug() << "Key not found" << code << "." << key << "in template";
}
} else if (code=="graph") {
if (graphs.contains(key)) {
if (!graphs[key]->isEmpty()) {
QPixmap pixmap=Snapshot(graphs[key]);
QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG");
//output += "<div align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\" width="+QString::number(graph_print_width)+"px height=\""+QString::number(graph_print_height)+"px\"></div>\n";
output += "<div align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\" width=\"100%\" height=\""+QString::number(graph_print_height)+"\"></div>\n";
}
} else {
qDebug() << "Graph not found" << key << "in template";
}
} else if (code=="logo") {
QPixmap pixmap(":/docs/sheep.png");
QByteArray byteArray;
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG");
output += "<img src=\"data:image/png;base64," + byteArray.toBase64() + "\" width=\"100\" height=\"100\">";
}
pos+=rx.matchedLength();
lastpos=pos;
}
output+=input.mid(lastpos); // will just return the input if no tags are used
return output;
}
QString Report::GenerateReport(QString templ,QDate start, QDate end)
{
//if (!m_ready) return;
startDate=start;
endDate=end;
QString filename=pref.Get("{home}/Reports");
QDir dir(filename);
if (!dir.exists()) {
dir.mkdir(filename);
}
filename+="/"+templ+".sht";
QFile file;
file.setFileName(filename);
QByteArray input;
if (file.exists()) {
file.open(QIODevice::ReadOnly);
input=file.readAll();
file.close();
} else {
QString f2=":/docs/template_"+templ+".sht";
file.setFileName(f2);
if (!file.exists()) return "";
file.open(QIODevice::ReadOnly);
input=file.readAll();
file.close();
file.setFileName(filename);
file.open(QIODevice::WriteOnly);
file.write(input);
file.close();
}
QString html=input;
locals["start"]=start;
locals["end"]=end;
locals["width"]=graph_print_width-10;
if ((*profile).Exists("DOB") && !(*profile)["DOB"].toString().isEmpty()) {
QDate dob=(*profile)["DOB"].toDate();
QDateTime d1(dob,QTime(0,0,0));
QDateTime d2(QDate::currentDate(),QTime(0,0,0));
int years=d1.daysTo(d2)/365.25;
locals["Age"]=years;
}
if (!(*profile).Exists("UnitSystem")) {
(*profile)["UnitSystem"]="Metric";
}
if ((*profile).Exists("Height") && !(*profile)["Height"].toString().isEmpty()) {
if ((*profile)["UnitSystem"].toString()=="Metric")
locals["DistanceMeasure"]="cm";
else locals["DistanceMeasure"]="inches";
}
//QFile file(":/docs/template_overview.sht");
//file.open(QIODevice::ReadOnly);
//QString html=file.readAll();
//ui->webView->setHtml(output);
return ParseTemplate(html);
}
void Report::Print(QString html)
{
if (html.isEmpty()) return;
ui->webView->setHtml(html);
QPrinter printer;
#ifdef Q_WS_X11
printer.setPrinterName("Print to File (PDF)");
printer.setOutputFormat(QPrinter::PdfFormat);
#endif
printer.setPrintRange(QPrinter::AllPages);
printer.setOrientation(QPrinter::Portrait);
//printer.setPaperSize(QPrinter::A4);
printer.setResolution(QPrinter::HighResolution);
//printer.setPageSize();
printer.setFullPage(false);
printer.setNumCopies(1);
printer.setPageMargins(10,10,10,10,QPrinter::Millimeter);
QPrintDialog *dialog = new QPrintDialog(&printer);
//printer.setOutputFileName("printYou.pdf");
if ( dialog->exec() == QDialog::Accepted) {
ui->webView->print(&printer);
}
}