diff options
author | Lubomir I. Ivanov <neolit123@gmail.com> | 2013-10-03 17:50:40 +0300 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-10-03 09:38:37 -0700 |
commit | e727b899a633a6c7eaf075dcf7380aadd6f85b7f (patch) | |
tree | 3293413f356cf1589c7ccc23f8e67d36ad866b7d /qt-ui/printlayout.cpp | |
parent | 374f3d0de62722cf4153d12754edf6fb110ce33d (diff) | |
download | subsurface-e727b899a633a6c7eaf075dcf7380aadd6f85b7f.tar.gz |
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>
Diffstat (limited to 'qt-ui/printlayout.cpp')
-rw-r--r-- | qt-ui/printlayout.cpp | 172 |
1 files changed, 141 insertions, 31 deletions
diff --git a/qt-ui/printlayout.cpp b/qt-ui/printlayout.cpp index 3d0937636..4f741d64e 100644 --- a/qt-ui/printlayout.cpp +++ b/qt-ui/printlayout.cpp @@ -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); - - // plot the dives at specific rows and columns + // 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 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 |