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
|
@ -11,22 +11,12 @@
|
|||
#include "../dive.h"
|
||||
#include "../display.h"
|
||||
#include "models.h"
|
||||
|
||||
/*
|
||||
struct options {
|
||||
enum { PRETTY, TABLE, TWOPERPAGE } type;
|
||||
int print_selected;
|
||||
int color_selected;
|
||||
bool notes_up;
|
||||
int profile_height, notes_height, tanks_height;
|
||||
};
|
||||
*/
|
||||
#include "modeldelegates.h"
|
||||
|
||||
PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct options *optionsPtr)
|
||||
{
|
||||
dialog = dialogPtr;
|
||||
printer = printerPtr;
|
||||
painter = NULL;
|
||||
printOptions = optionsPtr;
|
||||
|
||||
// table print settings
|
||||
|
@ -45,6 +35,27 @@ PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct op
|
|||
tablePrintColumnWidths.append(15);
|
||||
tablePrintColumnWidths.append(15);
|
||||
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()
|
||||
|
@ -81,14 +92,25 @@ void PrintLayout::setup()
|
|||
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)
|
||||
{
|
||||
// setup a painter
|
||||
painter = new QPainter();
|
||||
painter->begin(printer);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->scale(scaleX, scaleY);
|
||||
QPainter painter;
|
||||
painter.begin(printer);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter.scale(scaleX, scaleY);
|
||||
|
||||
// setup the profile widget
|
||||
ProfileGraphicsView *profile = mainWindow()->graphics();
|
||||
|
@ -101,15 +123,24 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
|
|||
divesPerColumn = divesPerRow;
|
||||
divesPerRow = swap;
|
||||
}
|
||||
// estimate profile and table height and resize the widget
|
||||
const int scaledW = scaledPageW / divesPerColumn;
|
||||
const int scaledH = scaledPageH / divesPerRow;
|
||||
/* make the table 1/3 of the reserved height. potentially this could depend
|
||||
* on orientation and other parameters as well. */
|
||||
const int tableHeight = scaledH / 3;
|
||||
profile->resize(scaledW, scaledH - tableHeight);
|
||||
// padding in pixels between two dives. no padding if only one dive per page.
|
||||
const int padDef = 20;
|
||||
const int padW = (divesPerColumn < 2) ? 0 : padDef;
|
||||
const int padH = (divesPerRow < 2) ? 0 : padDef;
|
||||
// estimate dimensions for a single dive
|
||||
const int scaledW = ESTIMATE_DIVE_DIM(scaledPageW, divesPerColumn, padW);
|
||||
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;
|
||||
struct dive *dive;
|
||||
for_each_dive(i, dive) {
|
||||
|
@ -123,23 +154,102 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
|
|||
printer->newPage();
|
||||
}
|
||||
}
|
||||
// draw a profile
|
||||
profile->plot(dive, true);
|
||||
QPixmap pm = QPixmap::grabWidget(profile);
|
||||
painter->drawPixmap(scaledW * col, scaledH * row, pm);
|
||||
/* TODO: table should be drawn here, preferably by another function */
|
||||
QPixmap profilePm = QPixmap::grabWidget(profile); // Qt4
|
||||
painter.drawPixmap((scaledW + padW) * col,
|
||||
(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++;
|
||||
}
|
||||
|
||||
// cleanup
|
||||
painter->end();
|
||||
delete painter;
|
||||
painter = NULL;
|
||||
painter.end();
|
||||
delete table;
|
||||
profile->setPrintMode(false);
|
||||
profile->resize(originalSize);
|
||||
profile->clear();
|
||||
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()
|
||||
{
|
||||
// create and setup a table
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue