summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qt-ui/models.cpp106
-rw-r--r--qt-ui/models.h41
-rw-r--r--qt-ui/printlayout.cpp223
-rw-r--r--qt-ui/printlayout.h21
4 files changed, 259 insertions, 132 deletions
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 0af5c7019..25429154f 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -1438,3 +1438,109 @@ void YearlyStatisticsModel::update_yearly_stats()
item->parent = rootItem;
}
}
+
+/*#################################################################
+ * #
+ * # Table Print Model
+ * #
+ * ################################################################
+ */
+TablePrintModel::TablePrintModel()
+{
+ columns = 7;
+ rows = 0;
+}
+
+TablePrintModel::~TablePrintModel()
+{
+ for (int i = 0; i < list.size(); i++)
+ delete list.at(i);
+}
+
+void TablePrintModel::insertRow(int index)
+{
+ struct TablePrintItem *item = new struct TablePrintItem();
+ item->colorBackground = 0xffffffff;
+ if (index == -1) {
+ beginInsertRows(QModelIndex(), rows, rows);
+ list.append(item);
+ } else {
+ beginInsertRows(QModelIndex(), index, index);
+ list.insert(index, item);
+ }
+ endInsertRows();
+ rows++;
+}
+
+void TablePrintModel::callReset()
+{
+ reset();
+}
+
+QVariant TablePrintModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+ if (role == Qt::BackgroundRole)
+ return QColor(list.at(index.row())->colorBackground);
+ if (role == Qt::DisplayRole)
+ switch (index.column()) {
+ case 0:
+ return list.at(index.row())->number;
+ case 1:
+ return list.at(index.row())->date;
+ case 2:
+ return list.at(index.row())->depth;
+ case 3:
+ return list.at(index.row())->duration;
+ case 4:
+ return list.at(index.row())->divemaster;
+ case 5:
+ return list.at(index.row())->buddy;
+ case 6:
+ return list.at(index.row())->location;
+ }
+ return QVariant();
+}
+
+bool TablePrintModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (index.isValid()) {
+ if (role == Qt::DisplayRole) {
+ switch (index.column()) {
+ case 0:
+ list.at(index.row())->number = value.toString();
+ case 1:
+ list.at(index.row())->date = value.toString();
+ case 2:
+ list.at(index.row())->depth = value.toString();
+ case 3:
+ list.at(index.row())->duration = value.toString();
+ case 4:
+ list.at(index.row())->divemaster = value.toString();
+ case 5:
+ list.at(index.row())->buddy = value.toString();
+ case 6:
+ list.at(index.row())->location = value.toString();
+ }
+ return true;
+ }
+ if (role == Qt::BackgroundRole) {
+ list.at(index.row())->colorBackground = value.value<unsigned int>();
+ return true;
+ }
+ }
+ return false;
+}
+
+int TablePrintModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return rows;
+}
+
+int TablePrintModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return columns;
+}
diff --git a/qt-ui/models.h b/qt-ui/models.h
index e8a7daaf3..22cfe4b7e 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -230,4 +230,45 @@ public:
YearlyStatisticsModel(QObject* parent = 0);
void update_yearly_stats();
};
+
+/* TablePrintModel:
+ * for now we use a blank table model with row items TablePrintItem.
+ * these are pretty much the same as DiveItem, but have color
+ * properties, as well. perhaps later one a more unified model has to be
+ * considered, but the current TablePrintModel idea has to be extended
+ * to support variadic column lists and column list orders that can
+ * be controlled by the user.
+ */
+struct TablePrintItem {
+ QString number;
+ QString date;
+ QString depth;
+ QString duration;
+ QString divemaster;
+ QString buddy;
+ QString location;
+ unsigned int colorBackground;
+};
+
+class TablePrintModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+private:
+ QList<struct TablePrintItem *> list;
+
+public:
+ ~TablePrintModel();
+ TablePrintModel();
+
+ int rows, columns;
+ void insertRow(int index = -1);
+ void callReset();
+
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent) const;
+};
+
#endif
diff --git a/qt-ui/printlayout.cpp b/qt-ui/printlayout.cpp
index 7061f082b..7a4944ede 100644
--- a/qt-ui/printlayout.cpp
+++ b/qt-ui/printlayout.cpp
@@ -1,9 +1,10 @@
+#include <QtCore/qmath.h>
#include <QDebug>
#include <QPainter>
#include <QDesktopWidget>
#include <QApplication>
-#include <QTextDocument>
-#include <QAbstractTextDocumentLayout>
+#include <QTableView>
+#include <QHeaderView>
#include "mainwindow.h"
#include "profilegraphics.h"
#include "printlayout.h"
@@ -21,8 +22,6 @@ struct options {
};
*/
-#define TABLE_PRINT_COL 7
-
PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct options *optionsPtr)
{
dialog = dialogPtr;
@@ -30,20 +29,21 @@ PrintLayout::PrintLayout(PrintDialog *dialogPtr, QPrinter *printerPtr, struct op
printOptions = optionsPtr;
// table print settings
- tableColumnNames.append(tr("Dive#"));
- tableColumnNames.append(tr("Date"));
- tableColumnNames.append(tr("Depth"));
- tableColumnNames.append(tr("Duration"));
- tableColumnNames.append(tr("Master"));
- tableColumnNames.append(tr("Buddy"));
- tableColumnNames.append(tr("Location"));
- tableColumnWidths.append("7");
- tableColumnWidths.append("10");
- tableColumnWidths.append("10");
- tableColumnWidths.append("10");
- tableColumnWidths.append("15");
- tableColumnWidths.append("15");
- tableColumnWidths.append("100");
+ tablePrintHeadingBackground = 0xffeeeeee;
+ tablePrintColumnNames.append(tr("Dive#"));
+ tablePrintColumnNames.append(tr("Date"));
+ tablePrintColumnNames.append(tr("Depth"));
+ tablePrintColumnNames.append(tr("Duration"));
+ tablePrintColumnNames.append(tr("Master"));
+ tablePrintColumnNames.append(tr("Buddy"));
+ tablePrintColumnNames.append(tr("Location"));
+ tablePrintColumnWidths.append(7);
+ tablePrintColumnWidths.append(10);
+ tablePrintColumnWidths.append(10);
+ tablePrintColumnWidths.append(10);
+ tablePrintColumnWidths.append(15);
+ tablePrintColumnWidths.append(15);
+ tablePrintColumnWidths.append(33);
}
void PrintLayout::print()
@@ -74,6 +74,10 @@ void PrintLayout::setup()
scaleX = (qreal)printerDpi/(qreal)screenDpiX;
scaleY = (qreal)printerDpi/(qreal)screenDpiY;
+
+ // a printer page scalled to screen DPI
+ scaledPageW = pageRect.width() / scaleX;
+ scaledPageH = pageRect.height() / scaleY;
}
// experimental
@@ -90,7 +94,7 @@ void PrintLayout::printSixDives() const
profile->clear();
profile->setPrintMode(true, !printOptions->color_selected);
QSize originalSize = profile->size();
- profile->resize(pageRect.height()/scaleY, pageRect.width()/scaleX);
+ profile->resize(scaledPageW, scaledPageH);
int i;
struct dive *dive;
@@ -122,127 +126,100 @@ void PrintLayout::printTwoDives() const
// nop
}
-void PrintLayout::printTable() const
+void PrintLayout::printTable()
{
- QTextDocument doc;
- QSizeF pageSize;
- pageSize.setWidth(pageRect.width());
- pageSize.setHeight(pageRect.height());
- doc.documentLayout()->setPaintDevice(printer);
- doc.setPageSize(pageSize);
-
- QString styleSheet(
- "<style type='text/css'>"
- "table {"
- " border-width: 1px;"
- " border-style: solid;"
- " border-color: #999999;"
- "}"
- "th {"
- " background-color: #eeeeee;"
- " font-size: small;"
- " padding: 3px 5px 3px 5px;"
- "}"
- "td {"
- " font-size: small;"
- " padding: 3px 5px 3px 5px;"
- "}"
- "</style>"
- );
- // setDefaultStyleSheet() doesn't work here?
- const QString heading(insertTableHeadingRow());
- const QString lineBreak("<br>");
- QString htmlText = styleSheet + "<table cellspacing='0' width='100%'>";
- QString htmlTextPrev;
- int pageCountNew = 1, pageCount = 0, lastPageWithHeading = 0;
- bool insertHeading = true;
-
- int i;
+ // create and setup a table
+ QTableView table;
+ table.setAttribute(Qt::WA_DontShowOnScreen);
+ table.setSelectionMode(QAbstractItemView::NoSelection);
+ table.setFocusPolicy(Qt::NoFocus);
+ table.horizontalHeader()->setVisible(false);
+ table.horizontalHeader()->setResizeMode(QHeaderView::Fixed);
+ table.verticalHeader()->setVisible(false);
+ table.verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+ table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ // fit table to one page initially
+ table.resize(scaledPageW, scaledPageH);
+
+ // create and fill a table model
+ TablePrintModel model;
struct dive *dive;
+ int i, row = 0;
+ addTablePrintHeadingRow(&model, row); // add one heading row
+ row++;
for_each_dive(i, dive) {
if (!dive->selected && printOptions->print_selected)
continue;
- if (insertHeading) {
- htmlTextPrev = htmlText;
- htmlText += heading;
- doc.setHtml(htmlText);
- pageCount = doc.pageCount();
- // prevent adding two headings on the same page
- if (pageCount == lastPageWithHeading) {
- htmlText = htmlTextPrev;
- // add line breaks until a new page is reached
- while (pageCount == lastPageWithHeading) {
- htmlTextPrev = htmlText;
- htmlText += lineBreak;
- doc.setHtml(htmlText);
- pageCount = doc.pageCount();
- }
- // revert last line break from the new page and add heading
- htmlText = htmlTextPrev;
- htmlText += heading;
- }
- insertHeading = false;
- lastPageWithHeading = pageCount;
- }
- htmlTextPrev = htmlText;
- htmlText += insertTableDataRow(dive);
- doc.setHtml(htmlText);
- pageCount = pageCountNew;
- pageCountNew = doc.pageCount();
- // if the page count increases revert and add heading instead
- if (pageCountNew > pageCount) {
- htmlText = htmlTextPrev;
- insertHeading = true;
+ addTablePrintDataRow(&model, row, dive);
+ row++;
+ }
+ table.setModel(&model); // set model to table
+ // resize columns to percentages from page width
+ for (int i = 0; i < model.columns; i++) {
+ int pw = qCeil((qreal)(tablePrintColumnWidths.at(i) * table.width()) / 100);
+ table.horizontalHeader()->resizeSection(i, pw);
+ }
+ // reset the model at this point
+ model.callReset();
+
+ // a list of vertical offsets where pages begin and some helpers
+ QList<unsigned int> pageIndexes;
+ pageIndexes.append(0);
+ int tableHeight = 0, rowH = 0, accH = 0;
+
+ // process all rows
+ for (int i = 0; i < model.rows; i++) {
+ rowH = table.rowHeight(i);
+ accH += rowH;
+ if (accH > scaledPageH) { // push a new page index and add a heading
+ pageIndexes.append(pageIndexes.last() + (accH - rowH));
+ addTablePrintHeadingRow(&model, i);
+ accH = 0;
i--;
}
+ tableHeight += rowH;
}
- htmlText += "</table>";
- doc.setHtml(htmlText);
- doc.print(printer);
-}
+ pageIndexes.append(pageIndexes.last() + accH);
+ // resize the whole widget so that it can be rendered
+ table.resize(scaledPageW, tableHeight);
-QString PrintLayout::insertTableHeadingRow() const
-{
- int i;
- QString ret("<tr>");
- for (i = 0; i < TABLE_PRINT_COL; i++)
- ret += insertTableHeadingCol(i);
- ret += "</tr>";
- return ret;
-}
-
-QString PrintLayout::insertTableHeadingCol(int col) const
-{
- QString ret("<th align='left' width='");
- ret += tableColumnWidths.at(col);
- ret += "%'>";
- ret += tableColumnNames.at(col);
- ret += "</th>";
- return ret;
+ // attach a painter and render pages by using pageIndexes
+ QPainter painter(printer);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ painter.scale(scaleX, scaleY);
+ for (int i = 0; i < pageIndexes.size() - 1; i++) {
+ if (i > 0)
+ printer->newPage();
+ QRegion region(0, pageIndexes.at(i) - 1,
+ table.width(),
+ pageIndexes.at(i + 1) - pageIndexes.at(i) + 2);
+ table.render(&painter, QPoint(0, 0), region);
+ }
}
-QString PrintLayout::insertTableDataRow(struct dive *dive) const
+void PrintLayout::addTablePrintDataRow(TablePrintModel *model, int row, struct dive *dive) const
{
- // use the DiveItem class
struct DiveItem di;
di.dive = dive;
-
- // fill row
- QString ret("<tr>");
- ret += insertTableDataCol(QString::number(dive->number));
- ret += insertTableDataCol(di.displayDate());
- ret += insertTableDataCol(di.displayDepth());
- ret += insertTableDataCol(di.displayDuration());
- ret += insertTableDataCol(dive->divemaster);
- ret += insertTableDataCol(dive->buddy);
- ret += insertTableDataCol(dive->location);
- ret += "</tr>";
- return ret;
+ model->insertRow();
+ model->setData(model->index(row, 0), QString::number(dive->number), Qt::DisplayRole);
+ model->setData(model->index(row, 1), di.displayDate(), Qt::DisplayRole);
+ model->setData(model->index(row, 2), di.displayDepth(), Qt::DisplayRole);
+ model->setData(model->index(row, 3), di.displayDuration(), Qt::DisplayRole);
+ model->setData(model->index(row, 4), dive->divemaster, Qt::DisplayRole);
+ model->setData(model->index(row, 5), dive->buddy, Qt::DisplayRole);
+ model->setData(model->index(row, 6), dive->location, Qt::DisplayRole);
}
-QString PrintLayout::insertTableDataCol(QString data) const
+void PrintLayout::addTablePrintHeadingRow(TablePrintModel *model, int row) const
{
- return "<td>" + data + "</td>";
+ model->insertRow(row);
+ for (int i = 0; i < model->columns; i++) {
+ model->setData(model->index(row, i), tablePrintColumnNames.at(i), Qt::DisplayRole);
+ model->setData(model->index(row, i), tablePrintHeadingBackground, Qt::BackgroundRole);
+ }
}
// experimental
diff --git a/qt-ui/printlayout.h b/qt-ui/printlayout.h
index 7a1922e4a..ac363ab8d 100644
--- a/qt-ui/printlayout.h
+++ b/qt-ui/printlayout.h
@@ -1,10 +1,13 @@
#ifndef PRINTLAYOUT_H
#define PRINTLAYOUT_H
+#include <QObject>
#include <QPrinter>
-#include <QStringList>
+#include <QList>
class PrintDialog;
+class TablePrintModel;
+struct dive;
class PrintLayout : public QObject {
Q_OBJECT
@@ -19,21 +22,21 @@ private:
struct options *printOptions;
QPainter *painter;
- int screenDpiX, screenDpiY, printerDpi;
+ int screenDpiX, screenDpiY, printerDpi, scaledPageW, scaledPageH;
qreal scaleX, scaleY;
QRect pageRect;
- QStringList tableColumnNames;
- QStringList tableColumnWidths;
+ QList<QString> tablePrintColumnNames;
+ QList<unsigned int> tablePrintColumnWidths;
+ unsigned int tablePrintHeadingBackground;
void setup();
void printSixDives() const;
void printTwoDives() const;
- void printTable() const;
- QString insertTableHeadingRow() const;
- QString insertTableHeadingCol(int) const;
- QString insertTableDataRow(struct dive *) const;
- QString insertTableDataCol(QString) const;
+ void printTable();
+ void addTablePrintDataRow(TablePrintModel *model, int row, struct dive *dive) const;
+ void addTablePrintHeadingRow(TablePrintModel *model, int row) const;
+
QPixmap convertPixmapToGrayscale(QPixmap) const;
};