1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00
LibQQt/qqtword.cpp
tianduanrui 3f857669fc init
2016-12-29 16:49:18 +08:00

504 lines
14 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "qqtword.h"
#include "qqtdefine.h"
QQTWord::QQTWord(QObject *parent) :
QObject(parent),
fmt(0), mainFmt(0),headerFmt(0),titleFmt(0), title2Fmt(0)
{
//setup printer
pr= new QQTPrinter(QPrinter::HighResolution);
pr->setFullPage(true);
pr->setColorMode(QPrinter::Color);
pr->setPaperSize(QPrinter::A4);
pr->setOrientation(QPrinter::Portrait);
pr->setOutputFormat(QPrinter::PdfFormat);
//Font目标是打印纸上所见即所得。
//Pos目标不是纸上的是屏幕上的所以更换屏幕必须更换DPI
//这个数值是迪文屏上的标准分辨率,打印机使用会失真;
//迪文View 142,138 //PCView 96 //打印机View 1200
//打印机分辨率1200不会失真绘图必须进行坐标变换。
//数值增大DrawText可用空间减小甚至切掉一部分
#ifdef __MIPS_LINUX__
//这是实验结果,和理论结果不符合。
logicalDpiX = 136;
logicalDpiY = 156;
#else
//这个值是理论值,绘图格子比较大
logicalDpiX = 96;
logicalDpiY = 96;
#endif
QRect rect = pr->paperRect();
sceneRect = QRectF(0.0, 0.0, logicalDpiX *rect.width()/pr->logicalDpiX(), logicalDpiY*rect.height()/pr->logicalDpiY());
#if 0
//1200 9917,14033 printerRect 固定
//116 958,1356 sceneRect
//142 1113,1660 sceneRect
pline() << pr->logicalDpiX() << pr->logicalDpiY();
pline() << logicalDpiX << logicalDpiY << pr->pageRect() << sceneRect;
pline() << pr->paperRect(QPrinter::DevicePixel);
pline() << pr->paperRect(QPrinter::Millimeter);
pline() << pr->paperRect(QPrinter::Point);
pline() << pr->paperRect(QPrinter::Inch);
pline() << pr->paperRect(QPrinter::Pica);
pline() << pr->paperRect(QPrinter::Didot);
pline() << pr->paperRect(QPrinter::Cicero);
#endif
m_mainFont = QApplication::font();
if(mainFmt)
delete mainFmt;
mainFmt = new QFontMetrics(m_mainFont);
m_titleFont= QApplication::font();
m_titleFont.setPointSize(22);
if(titleFmt)
delete titleFmt;
titleFmt = new QFontMetrics(m_titleFont);
m_title2Font = QApplication::font();;
m_title2Font.setPointSize(16);
if(title2Fmt)
delete title2Fmt;
title2Fmt =new QFontMetrics(m_title2Font);
setMargin();
setHeaderSize();
setFooterSize();
setFont();
setHeaderFont();
setLineSpacing();
setHeaderLine();
setFooterLine();
initWord();
}
void QQTWord::setMargin(qreal left, qreal right, qreal top, qreal botoom)
{
leftMargin=134.6;
rightMargin=134.6;
topMargin=177.7;
bottomMargin=177.7;
}
QRectF QQTWord::clientRectF()
{
return QRectF(leftMargin, topMargin,
sceneRect.width()-leftMargin-rightMargin,
sceneRect.height()-topMargin-bottomMargin);
}
QRectF QQTWord::paperRect()
{
return QRectF(0, 0,
sceneRect.width(),
sceneRect.height());
}
void QQTWord::setFont(QFont font)
{
//normal font 11
m_font = QApplication::font();
if(fmt)
delete fmt;
fmt = new QFontMetrics(m_font);
}
void QQTWord::setLineSpacing(qreal spacing)
{
//单倍行距
mainHeight = mainFmt->height();
titleHeight = titleFmt->height();
title2Height = title2Fmt->height();
headerHeight = headerFmt->height();
mainSpacing = mainFmt->height() * 2;
titleSpacing = titleFmt->height() * 2;
title2Spacing = title2Fmt->height() * 2;
headerSpacing = headerFmt->height() * 1;
}
void QQTWord::addText(const QString &text, QFont font, Qt::Alignment align, QPointF point)
{
QFontMetrics fmt = QFontMetrics(font);
int spacing = fmt.height() * 2;
int height = fmt.height();
int width=fmt.width(text);
//pline() << font.pointSize() << fmt.height();
adjustdy(height + spacing);
QQTGraphicsTextItem* item = pageScene->addText(text, font);
if(align & Qt::AlignLeft)
item->moveBy(dx, dy+height);
else if(align & Qt::AlignRight)
item->moveBy(xpos2 - width, dy+height);
else if(align & Qt::AlignHCenter)
item->moveBy((pageScene->width()/2)-(width/2), dy+height);
dy += height + spacing;
}
void QQTWord::addSignoffText(const QString &text, QFont font)
{
adjustdy(mainHeight + mainSpacing);
int ddy = dy;
dy = ypos2 - ( (mainHeight + mainSpacing) * 2 );
addText(text, m_mainFont, Qt::AlignRight);
dy = ddy;
}
void QQTWord::addTable(const QTableView *table, QPointF pos)
{
Q_ASSERT(table);
QAbstractItemModel* model = table->model();
QFont tableFont = table->font();
QFontMetrics tableFmt = QFontMetrics(tableFont);
int tableRowHeight = 0;
if(!table->horizontalHeader()->isHidden())
{
tableRowHeight = table->horizontalHeader()->height();
adjustdy(tableRowHeight);
for (int col=0; col<model->columnCount(); col++) {
int logicalIndex=table->horizontalHeader()->logicalIndex(col);
int actColSize= table->columnWidth(logicalIndex);
if(table->horizontalHeader()->isSectionHidden(col))
continue;
QPen pen(Qt::gray, 0.1);
QBrush brush(QColor(255, 250, 250));
//QBrush brush(tableView->horizontalHeader()->palette().background());
pageScene->addRect(dx,dy, actColSize,tableRowHeight, pen, brush);
QString txt = model->headerData(logicalIndex,Qt::Horizontal,Qt::DisplayRole).toString();
txt = tableFmt.elidedText(txt, Qt::ElideRight, actColSize-2);
QQTGraphicsTextItem *item = pageScene->addText(txt, tableFont);
item->moveBy(dx, dy);
dx += actColSize;
}
dy += tableRowHeight;
}
QHash<int, ESpanFlags> spans = tableSpans(table);
QHashIterator<int, ESpanFlags> it(spans);
while(0 && it.hasNext())
{
it.next();
pline() << it.key() << it.value();
pline() << it.value().testFlag(ESpanLeft) <<
it.value().testFlag(ESpanTop) <<
it.value().testFlag(ESpanRight) <<
it.value().testFlag(ESpanBottom) <<
it.value().testFlag(ESpanMiddle) ;
}
//Table rows
QPen pen(Qt::gray, 0.1);
QBrush brush(Qt::gray, Qt::SolidPattern);
int row = 0;
for (;;) {
if (row >= model->rowCount()) {
break;
}
if(table->isRowHidden(row))
continue;
tableRowHeight = table->rowHeight(row);
adjustdy(tableRowHeight);
for (int col=0; col<model->columnCount(); col++) {
int logicalIndex=table->horizontalHeader()->logicalIndex(col);
int actColSize=table->columnWidth(logicalIndex);
if(table->isColumnHidden(col))
continue;
int point = row * model->columnCount() + col;
ESpanFlags flags = spans.value(point);
QPen pen(Qt::gray, 0.1);
QBrush brush(table->palette().window());
bool balt = table->alternatingRowColors();
if(ESpanNone == flags)
{
if(balt)
{
int modulo= row % 2;
if (modulo != 0) {
//rectangle grey
pageScene->addRect(dx,dy,actColSize,tableRowHeight, pen, brush);
}
else
{
pageScene->addRect(dx,dy,actColSize,tableRowHeight, pen);
}
}
else
{
pageScene->addRect(dx,dy,actColSize,tableRowHeight, pen);
}
}
if(flags.testFlag(ESpanLeft))
pageScene->addLine(dx, dy, dx, dy+tableRowHeight, pen);
if(flags.testFlag(ESpanTop))
pageScene->addLine(dx, dy, dx+actColSize, dy, pen);
if(flags.testFlag(ESpanRight))
pageScene->addLine(dx+actColSize, dy, dx+actColSize, dy+tableRowHeight, pen);
if(flags.testFlag(ESpanBottom))
pageScene->addLine(dx, dy+tableRowHeight, dx+actColSize, dy+tableRowHeight, pen);
if(ESpanNone == flags ||
(flags.testFlag(ESpanLeft)&&flags.testFlag(ESpanTop)))
{
QString txt = model->data(model->index(row,logicalIndex)).toString();
txt=tableFmt.elidedText(txt,Qt::ElideRight,actColSize-2);
QQTGraphicsTextItem *item = pageScene->addText(txt, tableFont);
item->moveBy(dx,dy);
}
dx+=actColSize;
}
row++;
dy += tableRowHeight;
dx = xpos;
}
}
void QQTWord::exportPdf(const QString &pdf)
{
// setup printer
pr->setOutputFileName(pdf);
// print pdf
QPainter p(pr);
QQTGraphicsScene* pageScene = 0;
foreach (pageScene, pageSceneVector) {
pageScene->render(&p, pr->paperRect(), sceneRect);
if(pageScene != pageSceneVector.last())
pr->newPage();
}
}
QQTGraphicsScene *QQTWord::getPage(int num)
{
if(num < 1 || num > pageSceneVector.size())
return NULL;
return pageSceneVector.at(num-1);
}
void QQTWord::print()
{
pr->print();
}
void QQTWord::setHeaderFont(QFont font)
{
//header font
m_headerFont = QApplication::font();;
m_headerFont.setPointSize(9);
if(headerFmt)
delete headerFmt;
headerFmt =new QFontMetrics(m_headerFont);
}
void QQTWord::setHeaderSize(qreal size)
{
headerSize=70;
}
void QQTWord::setHeaderLine(bool show)
{
}
void QQTWord::setHeaderText(const QString &text, QFont font, Qt::Alignment align)
{
headerText = text;
paintPageHeader();
}
void QQTWord::setFooterSize(qreal size)
{
footerSize=70;
}
void QQTWord::setFooterLine(bool show)
{
}
void QQTWord::setFooterText(const QString &text, QFont font, Qt::Alignment align)
{
footerText = text;
paintPageFooter();
}
void QQTWord::initWord()
{
while ( ! pageSceneVector.isEmpty() ) {
QQTGraphicsScene* pageScene = pageSceneVector.first();
pageScene->clear();
delete pageScene;
pageSceneVector.remove(0);
}
headerText = "";
footerText = "";
createFrame();
}
void QQTWord::adjustdy(qreal dy0)
{
dx = xpos;
if(dy + dy0 < ypos2)
return;
createFrame();
}
void QQTWord::createFrame()
{
xpos = leftMargin;
xpos2 = sceneRect.width() - rightMargin;
ypos = topMargin;
ypos2 = sceneRect.height() - bottomMargin;
dx = xpos;
dy = ypos;
pageScene = new QQTGraphicsScene(sceneRect);
pageSceneVector.append(pageScene);
paintPageHeader();
paintPageFooter();
}
void QQTWord::paintPageHeader()
{
// Page header
if (headerText.isEmpty())
return;
int sx = xpos;
int sy = ypos-headerSize;
//页眉
QQTGraphicsTextItem *headerItem = pageScene->addText(headerText, m_headerFont);
headerItem->moveBy(sx, sy);
//std text
QString date=QDate::currentDate().toString(QLocale().dateFormat());
QString time=QTime::currentTime().toString(QLocale().timeFormat(QLocale::ShortFormat));
QString headerStdText;
headerStdText = date+" "+time;
QQTGraphicsTextItem *item = pageScene->addText(headerStdText, m_headerFont);
item->moveBy(xpos2 - headerFmt->width(headerStdText), sy);
sy += headerItem->boundingRect().height();
//line
pageScene->addLine(xpos, sy, xpos2, sy, QPen(Qt::black, 1.0));
}
void QQTWord::paintPageFooter()
{
if (footerText.isEmpty())
return;
// footer
int sx = xpos;
QString footerStdText = tr("") + QString::number(pageSceneVector.size()) + tr("");
QQTGraphicsTextItem *item=pageScene->addText(footerStdText, m_headerFont);
int height = item->boundingRect().height();
int sy = ypos2 + footerSize - height;
item->moveBy(xpos2 - headerFmt->width(footerStdText), sy);
pageScene->addLine(xpos, sy, xpos2, sy, QPen(Qt::black, 1.0));
QQTGraphicsTextItem *footerItem=pageScene->addText(footerText, m_headerFont);
footerItem->moveBy(xpos, sy);
}
QHash<int, ESpanFlags> QQTWord::tableSpans(const QTableView *table)
{
Q_ASSERT(table);
QAbstractItemModel* model = table->model();
int colCount = model->columnCount();
int rowCount = model->rowCount();
QHash<int, ESpanFlags> spans;
for (int row = 0; row < rowCount; row++)
{
for(int col = 0; col < colCount; col++)
{
int rowSpan = table->rowSpan(row, col);
int colSpan = table->columnSpan(row, col);
int point = ( row ) * colCount + ( col );
ESpanFlags flags = ESpanNone;
//没有合并
if(rowSpan == 1 && colSpan == 1)
{
spans.insert(point, flags);
continue;
}
for(int i = 0; i < rowSpan; i++)
{
point = ( row + i ) * colCount + col + 0;
//如果此处有Span但是Spans已经赋值那么break
if(ESpanNone != spans.value(point, ESpanNone))
break;
for(int j = 0; j < colSpan; j++)
{
point = ( row + i ) * colCount + col + j;
//如果此处有Span但是Spans已经赋值那么break
if(ESpanNone != spans.value(point, ESpanNone))
break;
ESpanFlags flags = ESpanNone;
if(i == 0)
flags |= ESpanFlags(ESpanTop);
if(i == rowSpan - 1)
flags |= ESpanFlags(ESpanBottom);
if(j == 0)
flags |= ESpanFlags(ESpanLeft);
if(j == colSpan - 1)
flags |= ESpanFlags(ESpanRight);
if(i != 0 && j != 0 && i != rowSpan-1 && j != colSpan-1)
flags |= ESpanMiddle;
spans.insert(point, flags);
}
}
}
}
return spans;
}