mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Print: provide means to print profile tables
This patch adds a couple of classes and some other modifications in PrintLayout that handle the printing of tables under a profile. models.h : ProfilePrintModel The class uses a 'struct *dive' to output all required data for a certain dive at specific rows and columns. It also handles font formatting and text alignment. modeldelagatates.h : ProfilePrintDelegate The class is used only for drawing a custom grid for profile tables. PrintLayout::createProfileTable() The function is used to create and setup the profile table object PrintLayout::printProfileDives() The function now has correct padding of dive profiles on a page and also the printing of actual tables below them. Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
374f3d0de6
commit
e727b899a6
6 changed files with 402 additions and 32 deletions
|
@ -300,3 +300,30 @@ void AirTypesDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
|
||||||
AirTypesDelegate::AirTypesDelegate(QObject* parent) : ComboBoxDelegate(airTypes(), parent)
|
AirTypesDelegate::AirTypesDelegate(QObject* parent) : ComboBoxDelegate(airTypes(), parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfilePrintDelegate::ProfilePrintDelegate(QObject *parent)
|
||||||
|
: QStyledItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this method overrides the default table drawing method and places grid lines only at certain rows and columns */
|
||||||
|
void ProfilePrintDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const QRect rect(option.rect);
|
||||||
|
const int row = index.row();
|
||||||
|
const int col = index.column();
|
||||||
|
|
||||||
|
// grid color
|
||||||
|
painter->setPen(QPen(QColor(0xff999999)));
|
||||||
|
// top line
|
||||||
|
if (row == 2 || row == 3 || row == 10 || col == 3 || col == 4)
|
||||||
|
painter->drawLine(rect.topLeft(), rect.topRight());
|
||||||
|
if (row > 1 && row < 10) {
|
||||||
|
// left line - draw always for these rows
|
||||||
|
painter->drawLine(rect.topLeft(), rect.bottomLeft());
|
||||||
|
// "fix" for missing (?) right line after col 5
|
||||||
|
if (col > 5 || (col > 4 && row == 2))
|
||||||
|
painter->drawLine(rect.topRight(), rect.bottomRight());
|
||||||
|
}
|
||||||
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
|
class QPainter;
|
||||||
|
|
||||||
class StarWidgetsDelegate : public QStyledItemDelegate {
|
class StarWidgetsDelegate : public QStyledItemDelegate {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -60,4 +61,15 @@ public slots:
|
||||||
void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint);
|
void revertModelData(QWidget* widget, QAbstractItemDelegate::EndEditHint hint);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ProfilePrintDelagate:
|
||||||
|
* this delegate is used to modify the look of the table that is printed
|
||||||
|
* bellow profiles.
|
||||||
|
*/
|
||||||
|
class ProfilePrintDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ProfilePrintDelegate(QObject *parent = 0);
|
||||||
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
197
qt-ui/models.cpp
197
qt-ui/models.cpp
|
@ -1567,3 +1567,200 @@ int TablePrintModel::columnCount(const QModelIndex &parent) const
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*#################################################################
|
||||||
|
* #
|
||||||
|
* # Profile Print Model
|
||||||
|
* #
|
||||||
|
* ################################################################
|
||||||
|
*/
|
||||||
|
|
||||||
|
ProfilePrintModel::ProfilePrintModel(QObject *parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is just a helper function to truncate C strings near 'maxlen' characters
|
||||||
|
* by finding word bounderies and adding '...' at the end of the truncated string.
|
||||||
|
* not really optimal for all languages!
|
||||||
|
*/
|
||||||
|
QString ProfilePrintModel::truncateString(char *str, const int maxlen) const
|
||||||
|
{
|
||||||
|
if (!str)
|
||||||
|
return QString("");
|
||||||
|
QString trunc = QString(str);
|
||||||
|
const int len = trunc.length();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
char c = trunc.at(i).toAscii();
|
||||||
|
if (c == ' ' || c == '\n' || c == '\t') {
|
||||||
|
if (i > maxlen) {
|
||||||
|
trunc = trunc.left(i) + QString("...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return trunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfilePrintModel::setDive(struct dive *divePtr)
|
||||||
|
{
|
||||||
|
dive = divePtr;
|
||||||
|
// reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProfilePrintModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProfilePrintModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ProfilePrintModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
const int row = index.row();
|
||||||
|
const int col = index.column();
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole: {
|
||||||
|
struct DiveItem di;
|
||||||
|
di.dive = dive;
|
||||||
|
QString unit;
|
||||||
|
char buf[80];
|
||||||
|
const QString empty = QString("");
|
||||||
|
const QString unknown = QString(tr("unknown"));
|
||||||
|
|
||||||
|
// dive# + date, depth, location, duration
|
||||||
|
if (row == 0) {
|
||||||
|
if (col == 0)
|
||||||
|
return QString(tr("Dive #%1 - %2")).arg(dive->number).arg(di.displayDate());
|
||||||
|
if (col == 5) {
|
||||||
|
unit = (get_units()->length == units::METERS) ? "m" : "ft";
|
||||||
|
return QString(tr("Max depth: %1 %2")).arg(di.displayDepth()).arg(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row == 1) {
|
||||||
|
if (col == 0)
|
||||||
|
return truncateString(dive->location, 32);
|
||||||
|
if (col == 5)
|
||||||
|
return QString(tr("Duration: %1 min")).arg(di.displayDuration());
|
||||||
|
}
|
||||||
|
// cylinder headings
|
||||||
|
if (row == 2) {
|
||||||
|
if (col == 0)
|
||||||
|
return QString(tr("Cylinder"));
|
||||||
|
if (col == 1)
|
||||||
|
return QString(tr("Gasmix"));
|
||||||
|
if (col == 2)
|
||||||
|
return QString(tr("Gas Used"));
|
||||||
|
}
|
||||||
|
// cylinder data
|
||||||
|
if (row > 2 && row < 10 && row - 3 < MAX_CYLINDERS) {
|
||||||
|
cylinder_t *cyl = &dive->cylinder[row - 3];
|
||||||
|
if (cyl->type.description) { // how do we check if a cylinder is added?
|
||||||
|
if (col == 0) {
|
||||||
|
if (cyl->type.description[0] != '\0')
|
||||||
|
return QString(cyl->type.description);
|
||||||
|
return unknown;
|
||||||
|
}
|
||||||
|
if (col == 1) {
|
||||||
|
get_gas_string(cyl->gasmix.o2.permille, cyl->gasmix.he.permille, buf, sizeof(buf));
|
||||||
|
return QString(buf);
|
||||||
|
}
|
||||||
|
if (col == 2) {
|
||||||
|
return get_cylinder_used_gas_string(cyl, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// dive notes
|
||||||
|
if (row == 10 && col == 0)
|
||||||
|
return truncateString(dive->notes, 64);
|
||||||
|
// sac, cns, otu - headings
|
||||||
|
if (col == 3) {
|
||||||
|
if (row == 2)
|
||||||
|
return QString(tr("SAC"));
|
||||||
|
if (row == 4)
|
||||||
|
return QString(tr("Max. CNS"));
|
||||||
|
if (row == 6)
|
||||||
|
return QString(tr("OTU"));
|
||||||
|
}
|
||||||
|
// sac, cns, otu - data
|
||||||
|
if (col == 4) {
|
||||||
|
if (row == 2)
|
||||||
|
return di.displaySac();
|
||||||
|
if (row == 4)
|
||||||
|
return QString::number(dive->maxcns);
|
||||||
|
if (row == 6)
|
||||||
|
return QString::number(dive->otu);
|
||||||
|
}
|
||||||
|
// weights heading
|
||||||
|
if (row == 2 && col == 5)
|
||||||
|
return QString(tr("Weights"));
|
||||||
|
// total weight
|
||||||
|
if (row == 9) {
|
||||||
|
weight_t tw = { total_weight(dive) };
|
||||||
|
if (tw.grams) {
|
||||||
|
if (col == 5)
|
||||||
|
return QString("Total weight");
|
||||||
|
if (col == 6)
|
||||||
|
return get_weight_string(tw, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// weight data
|
||||||
|
if (row > 2 && row < 10 && row - 3 < MAX_WEIGHTSYSTEMS) {
|
||||||
|
weightsystem_t *ws = &dive->weightsystem[row - 3];
|
||||||
|
if (ws->weight.grams) {
|
||||||
|
if (col == 5) {
|
||||||
|
if (ws->description && ws->description[0] != '\0')
|
||||||
|
return QString(ws->description);
|
||||||
|
return unknown;
|
||||||
|
}
|
||||||
|
if (col == 6) {
|
||||||
|
return get_weight_string(ws->weight, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
case Qt::FontRole: {
|
||||||
|
QFont font;
|
||||||
|
const int baseSize = 8;
|
||||||
|
// dive #
|
||||||
|
if (row == 0 && col == 0) {
|
||||||
|
font.setBold(true);
|
||||||
|
font.setPixelSize(baseSize + 1);
|
||||||
|
return QVariant::fromValue(font);
|
||||||
|
}
|
||||||
|
// dive location
|
||||||
|
if (row == 1 && col == 0) {
|
||||||
|
font.setPixelSize(baseSize);
|
||||||
|
font.setBold(true);
|
||||||
|
return QVariant::fromValue(font);
|
||||||
|
}
|
||||||
|
// depth/duration
|
||||||
|
if ((row == 0 || row == 1) && col == 5) {
|
||||||
|
font.setPixelSize(baseSize);
|
||||||
|
return QVariant::fromValue(font);
|
||||||
|
}
|
||||||
|
// notes
|
||||||
|
if (row == 9 && col == 0) {
|
||||||
|
font.setPixelSize(baseSize + 1);
|
||||||
|
return QVariant::fromValue(font);
|
||||||
|
}
|
||||||
|
font.setPixelSize(baseSize);
|
||||||
|
return QVariant::fromValue(font);
|
||||||
|
}
|
||||||
|
case Qt::TextAlignmentRole: {
|
||||||
|
unsigned int align = Qt::AlignCenter;
|
||||||
|
// dive #, location, notes
|
||||||
|
if ((row < 2 || row == 10) && col == 0)
|
||||||
|
align = Qt::AlignLeft | Qt::AlignVCenter;
|
||||||
|
// depth, duration
|
||||||
|
if (row < 2 && col == 5)
|
||||||
|
align = Qt::AlignRight | Qt::AlignVCenter;
|
||||||
|
return QVariant::fromValue(align);
|
||||||
|
}
|
||||||
|
} // switch (role)
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
|
@ -274,4 +274,24 @@ public:
|
||||||
int columnCount(const QModelIndex &parent) const;
|
int columnCount(const QModelIndex &parent) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ProfilePrintModel:
|
||||||
|
* this model is used when printing a data table under a profile. it requires
|
||||||
|
* some exact usage of setSpan(..) on the target QTableView widget.
|
||||||
|
*/
|
||||||
|
class ProfilePrintModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct dive *dive;
|
||||||
|
QString truncateString(char *str, const int maxlen) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProfilePrintModel(QObject *parent = 0);
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
void setDive(struct dive *divePtr);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,22 +11,12 @@
|
||||||
#include "../dive.h"
|
#include "../dive.h"
|
||||||
#include "../display.h"
|
#include "../display.h"
|
||||||
#include "models.h"
|
#include "models.h"
|
||||||
|
#include "modeldelegates.h"
|
||||||
/*
|
|
||||||
struct options {
|
|
||||||
enum { PRETTY, TABLE, TWOPERPAGE } type;
|
|
||||||
int print_selected;
|
|
||||||
int color_selected;
|
|
||||||
bool notes_up;
|
|
||||||
int profile_height, notes_height, tanks_height;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct options *optionsPtr)
|
PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct options *optionsPtr)
|
||||||
{
|
{
|
||||||
dialog = dialogPtr;
|
dialog = dialogPtr;
|
||||||
printer = printerPtr;
|
printer = printerPtr;
|
||||||
painter = NULL;
|
|
||||||
printOptions = optionsPtr;
|
printOptions = optionsPtr;
|
||||||
|
|
||||||
// table print settings
|
// table print settings
|
||||||
|
@ -45,6 +35,27 @@ PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct op
|
||||||
tablePrintColumnWidths.append(15);
|
tablePrintColumnWidths.append(15);
|
||||||
tablePrintColumnWidths.append(15);
|
tablePrintColumnWidths.append(15);
|
||||||
tablePrintColumnWidths.append(33);
|
tablePrintColumnWidths.append(33);
|
||||||
|
// profile print settings
|
||||||
|
const int dw = 15; // base percentage
|
||||||
|
profilePrintColumnWidths.append(dw);
|
||||||
|
profilePrintColumnWidths.append(dw);
|
||||||
|
profilePrintColumnWidths.append(dw);
|
||||||
|
profilePrintColumnWidths.append(dw);
|
||||||
|
profilePrintColumnWidths.append(dw - 5);
|
||||||
|
profilePrintColumnWidths.append(dw + 5);
|
||||||
|
profilePrintColumnWidths.append(dw - 5); // fit to 100%
|
||||||
|
const int sr = 8; // smallest row height in pixels
|
||||||
|
profilePrintRowHeights.append(sr + 2);
|
||||||
|
profilePrintRowHeights.append(sr + 7);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr);
|
||||||
|
profilePrintRowHeights.append(sr + 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintLayout::print()
|
void PrintLayout::print()
|
||||||
|
@ -81,14 +92,25 @@ void PrintLayout::setup()
|
||||||
scaledPageH = pageRect.height() / scaleY;
|
scaledPageH = pageRect.height() / scaleY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the used formula here is:
|
||||||
|
* s = (S - (n - 1) * p) / n
|
||||||
|
* where:
|
||||||
|
* s is the length of a single element (unknown)
|
||||||
|
* S is the total available length
|
||||||
|
* n is the number of elements to fit
|
||||||
|
* p is the padding between elements
|
||||||
|
*/
|
||||||
|
#define ESTIMATE_DIVE_DIM(S, n, p) \
|
||||||
|
((S) - ((n) - 1) * (p)) / (n);
|
||||||
|
|
||||||
void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
|
void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
|
||||||
{
|
{
|
||||||
// setup a painter
|
// setup a painter
|
||||||
painter = new QPainter();
|
QPainter painter;
|
||||||
painter->begin(printer);
|
painter.begin(printer);
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
painter->scale(scaleX, scaleY);
|
painter.scale(scaleX, scaleY);
|
||||||
|
|
||||||
// setup the profile widget
|
// setup the profile widget
|
||||||
ProfileGraphicsView *profile = mainWindow()->graphics();
|
ProfileGraphicsView *profile = mainWindow()->graphics();
|
||||||
|
@ -101,15 +123,24 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
|
||||||
divesPerColumn = divesPerRow;
|
divesPerColumn = divesPerRow;
|
||||||
divesPerRow = swap;
|
divesPerRow = swap;
|
||||||
}
|
}
|
||||||
// estimate profile and table height and resize the widget
|
// padding in pixels between two dives. no padding if only one dive per page.
|
||||||
const int scaledW = scaledPageW / divesPerColumn;
|
const int padDef = 20;
|
||||||
const int scaledH = scaledPageH / divesPerRow;
|
const int padW = (divesPerColumn < 2) ? 0 : padDef;
|
||||||
/* make the table 1/3 of the reserved height. potentially this could depend
|
const int padH = (divesPerRow < 2) ? 0 : padDef;
|
||||||
* on orientation and other parameters as well. */
|
// estimate dimensions for a single dive
|
||||||
const int tableHeight = scaledH / 3;
|
const int scaledW = ESTIMATE_DIVE_DIM(scaledPageW, divesPerColumn, padW);
|
||||||
profile->resize(scaledW, scaledH - tableHeight);
|
const int scaledH = ESTIMATE_DIVE_DIM(scaledPageH, divesPerRow, padH);
|
||||||
|
// padding in pixels between profile and table
|
||||||
|
const int padPT = 10;
|
||||||
|
// create a model and table
|
||||||
|
ProfilePrintModel model;
|
||||||
|
QTableView *table = createProfileTable(&model, scaledW);
|
||||||
|
// profilePrintTableMaxH updates after the table is created
|
||||||
|
const int tableH = profilePrintTableMaxH;
|
||||||
|
// resize the profile widget
|
||||||
|
profile->resize(scaledW, scaledH - tableH - padPT);
|
||||||
|
|
||||||
// plot the dives at specific rows and columns
|
// plot the dives at specific rows and columns on the page
|
||||||
int i, row = 0, col = 0;
|
int i, row = 0, col = 0;
|
||||||
struct dive *dive;
|
struct dive *dive;
|
||||||
for_each_dive(i, dive) {
|
for_each_dive(i, dive) {
|
||||||
|
@ -123,23 +154,102 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
|
||||||
printer->newPage();
|
printer->newPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// draw a profile
|
||||||
profile->plot(dive, true);
|
profile->plot(dive, true);
|
||||||
QPixmap pm = QPixmap::grabWidget(profile);
|
QPixmap profilePm = QPixmap::grabWidget(profile); // Qt4
|
||||||
painter->drawPixmap(scaledW * col, scaledH * row, pm);
|
painter.drawPixmap((scaledW + padW) * col,
|
||||||
/* TODO: table should be drawn here, preferably by another function */
|
(scaledH + padH) * row,
|
||||||
|
profilePm);
|
||||||
|
// draw a table
|
||||||
|
model.setDive(dive);
|
||||||
|
QPixmap tablePm = QPixmap::grabWidget(table); // Qt4
|
||||||
|
painter.drawPixmap((scaledW + padW) * col,
|
||||||
|
(scaledH + padH) * row + (scaledH - tableH),
|
||||||
|
tablePm);
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
painter->end();
|
painter.end();
|
||||||
delete painter;
|
delete table;
|
||||||
painter = NULL;
|
|
||||||
profile->setPrintMode(false);
|
profile->setPrintMode(false);
|
||||||
profile->resize(originalSize);
|
profile->resize(originalSize);
|
||||||
profile->clear();
|
profile->clear();
|
||||||
profile->plot(current_dive, true);
|
profile->plot(current_dive, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we create a table that has a fixed height, but can stretch to fit certain width */
|
||||||
|
QTableView *PrintLayout::createProfileTable(ProfilePrintModel *model, const int tableW)
|
||||||
|
{
|
||||||
|
// setup a new table
|
||||||
|
QTableView *table = new QTableView();
|
||||||
|
QHeaderView *vHeader = table->verticalHeader();
|
||||||
|
QHeaderView *hHeader = table->horizontalHeader();
|
||||||
|
table->setAttribute(Qt::WA_DontShowOnScreen);
|
||||||
|
table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
table->setFocusPolicy(Qt::NoFocus);
|
||||||
|
table->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
hHeader->setVisible(false);
|
||||||
|
hHeader->setResizeMode(QHeaderView::Fixed);
|
||||||
|
vHeader->setVisible(false);
|
||||||
|
vHeader->setResizeMode(QHeaderView::Fixed);
|
||||||
|
// set the model
|
||||||
|
table->setModel(model);
|
||||||
|
|
||||||
|
/* setup cell span for the table using QTableView::setSpan().
|
||||||
|
* changes made here reflect on ProfilePrintModel::data(). */
|
||||||
|
const int cols = model->columnCount();
|
||||||
|
const int rows = model->rowCount();
|
||||||
|
// top section
|
||||||
|
table->setSpan(0, 0, 1, cols - 2);
|
||||||
|
table->setSpan(1, 0, 1, cols - 2);
|
||||||
|
table->setSpan(10, 0, 1, cols);
|
||||||
|
table->setSpan(0, 5, 1, 2);
|
||||||
|
table->setSpan(1, 5, 1, 12);
|
||||||
|
// sac, cns, otu
|
||||||
|
table->setSpan(2, 3, 2, 1);
|
||||||
|
table->setSpan(4, 3, 2, 1);
|
||||||
|
table->setSpan(6, 3, 2, 1);
|
||||||
|
table->setSpan(8, 3, 2, 1);
|
||||||
|
table->setSpan(2, 4, 2, 1);
|
||||||
|
table->setSpan(4, 4, 2, 1);
|
||||||
|
table->setSpan(6, 4, 2, 1);
|
||||||
|
table->setSpan(8, 4, 2, 1);
|
||||||
|
// weights
|
||||||
|
table->setSpan(2, 5, 1, 2);
|
||||||
|
|
||||||
|
/* resize row heights to the 'profilePrintRowHeights' indexes.
|
||||||
|
* profilePrintTableMaxH will then hold the table height. */
|
||||||
|
int i;
|
||||||
|
profilePrintTableMaxH = 0;
|
||||||
|
for (i = 0; i < rows; i++) {
|
||||||
|
int h = profilePrintRowHeights.at(i);
|
||||||
|
profilePrintTableMaxH += h;
|
||||||
|
vHeader->resizeSection(i, h);
|
||||||
|
}
|
||||||
|
// resize columns. columns widths are percentages from the table width.
|
||||||
|
int accW = 0;
|
||||||
|
for (i = 0; i < cols; i++) {
|
||||||
|
int pw = qCeil((qreal)(profilePrintColumnWidths.at(i) * tableW) / 100.0);
|
||||||
|
accW += pw;
|
||||||
|
if (i == cols - 1 && accW > tableW) /* adjust last column */
|
||||||
|
pw -= accW - tableW;
|
||||||
|
hHeader->resizeSection(i, pw);
|
||||||
|
}
|
||||||
|
// resize
|
||||||
|
table->resize(tableW, profilePrintTableMaxH);
|
||||||
|
// hide the grid and set a stylesheet
|
||||||
|
table->setItemDelegate(new ProfilePrintDelegate());
|
||||||
|
table->setShowGrid(false);
|
||||||
|
table->setStyleSheet(
|
||||||
|
"QTableView { border: none }"
|
||||||
|
"QTableView::item { border: 0px; padding-left: 2px; padding-right: 2px; }"
|
||||||
|
);
|
||||||
|
// return
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
void PrintLayout::printTable()
|
void PrintLayout::printTable()
|
||||||
{
|
{
|
||||||
// create and setup a table
|
// create and setup a table
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
#include <QPrinter>
|
#include <QPrinter>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
class QTableView;
|
||||||
class PrintDialog;
|
class PrintDialog;
|
||||||
class TablePrintModel;
|
class TablePrintModel;
|
||||||
|
class ProfilePrintModel;
|
||||||
struct dive;
|
struct dive;
|
||||||
|
|
||||||
class PrintLayout : public QObject {
|
class PrintLayout : public QObject {
|
||||||
|
@ -19,7 +21,6 @@ public:
|
||||||
private:
|
private:
|
||||||
PrintDialog *dialog;
|
PrintDialog *dialog;
|
||||||
QPrinter *printer;
|
QPrinter *printer;
|
||||||
QPainter *painter;
|
|
||||||
struct options *printOptions;
|
struct options *printOptions;
|
||||||
|
|
||||||
int screenDpiX, screenDpiY, printerDpi, scaledPageW, scaledPageH;
|
int screenDpiX, screenDpiY, printerDpi, scaledPageW, scaledPageH;
|
||||||
|
@ -27,11 +28,14 @@ private:
|
||||||
QRect pageRect;
|
QRect pageRect;
|
||||||
|
|
||||||
QList<QString> tablePrintColumnNames;
|
QList<QString> tablePrintColumnNames;
|
||||||
QList<unsigned int> tablePrintColumnWidths;
|
|
||||||
unsigned int tablePrintHeadingBackground;
|
unsigned int tablePrintHeadingBackground;
|
||||||
|
QList<unsigned int> tablePrintColumnWidths;
|
||||||
|
unsigned int profilePrintTableMaxH;
|
||||||
|
QList<unsigned int> profilePrintColumnWidths, profilePrintRowHeights;
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
void printProfileDives(int divesPerRow, int divesPerColumn);
|
void printProfileDives(int divesPerRow, int divesPerColumn);
|
||||||
|
QTableView *createProfileTable(ProfilePrintModel *model, const int tableW);
|
||||||
void printTable();
|
void printTable();
|
||||||
void addTablePrintDataRow(TablePrintModel *model, int row, struct dive *dive) const;
|
void addTablePrintDataRow(TablePrintModel *model, int row, struct dive *dive) const;
|
||||||
void addTablePrintHeadingRow(TablePrintModel *model, int row) const;
|
void addTablePrintHeadingRow(TablePrintModel *model, int row) const;
|
||||||
|
|
Loading…
Add table
Reference in a new issue