mirror of
https://gitee.com/drabel/LibQQt.git
synced 2025-01-04 10:18:44 +08:00
504 lines
14 KiB
C++
Executable File
504 lines
14 KiB
C++
Executable File
#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;
|
||
}
|