diff options
-rw-r--r-- | qt-ui/models.cpp | 106 | ||||
-rw-r--r-- | qt-ui/models.h | 41 | ||||
-rw-r--r-- | qt-ui/printlayout.cpp | 223 | ||||
-rw-r--r-- | qt-ui/printlayout.h | 21 |
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; }; |