void PrintLayout::printTable() { struct dive *dive; int done = 0; // percents done int i, row = 0, progress, total = estimateTotalDives(); if (!total) return; // 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.verticalHeader()->setVisible(false); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) table.horizontalHeader()->setResizeMode(QHeaderView::Fixed); table.verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); #else table.horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); table.verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); #endif table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // fit table to one page initially table.resize(scaledPageW, scaledPageH); // don't show border table.setStyleSheet( "QTableView { border: none }"); // create and fill a table model TablePrintModel model; addTablePrintHeadingRow(&model, row); // add one heading row row++; progress = 0; for_each_dive(i, dive) { if (!dive->selected && printOptions->print_selected) continue; addTablePrintDataRow(&model, row, dive); row++; progress++; emit signalProgress((progress * 10) / total); } done = 10; table.setModel(&model); // set model to table // resize columns to percentages from page width int accW = 0; int cols = model.columns; int tableW = table.width(); for (i = 0; i < model.columns; i++) { int pw = qCeil((qreal)(tablePrintColumnWidths.at(i) * table.width()) / 100.0); accW += pw; if (i == cols - 1 && accW > tableW) /* adjust last column */ pw -= accW - tableW; 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); /* the algorithm bellow processes the table rows in multiple passes, * compensating for loss of space due to moving rows on a new page instead * of truncating them. * there is a 'passes' array defining how much percents of the total * progress each will take. given, the first and last stage of this function * use 10% each, then the sum of passes[] here should be 80%. * two should be enough! */ const int passes[] = { 70, 10 }; int tableHeight = 0, lastAccIndex = 0, rowH, accH, headings; bool isHeading = false; for (unsigned int pass = 0; pass < sizeof(passes) / sizeof(passes[0]); pass++) { progress = headings = accH = 0; total = model.rows - lastAccIndex; for (i = lastAccIndex; i < model.rows; i++) { rowH = table.rowHeight(i); accH += rowH; if (isHeading) { headings += rowH; isHeading = false; } if (accH > scaledPageH) { lastAccIndex = i; pageIndexes.append(pageIndexes.last() + (accH - rowH)); addTablePrintHeadingRow(&model, i); isHeading = true; accH = 0; i--; } tableHeight += table.rowHeight(i); progress++; emit signalProgress(done + (progress * passes[pass]) / total); } done += passes[pass]; } done = 90; pageIndexes.append(pageIndexes.last() + accH + headings); table.resize(scaledPageW, tableHeight); // attach a painter and render pages by using pageIndexes QPainter painter(printer); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.scale(scaleX, scaleY); total = pageIndexes.size() - 1; progress = 0; for (i = 0; i < total; i++) { if (i > 0) printer->newPage(); QRegion region(0, pageIndexes.at(i) - 1, table.width(), pageIndexes.at(i + 1) - pageIndexes.at(i) + 1); table.render(&painter, QPoint(0, 0), region); progress++; emit signalProgress(done + (progress * 10) / total); } }
void PrintLayout::printTable() { // 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; 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; } pageIndexes.append(pageIndexes.last() + accH); // resize the whole widget so that it can be rendered table.resize(scaledPageW, tableHeight); // 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); } }
void Button::placeButton() { QTableView* table = qobject_cast<QTableView*>(this->parent()); if (!table) { setVisible(false); return ; } if (_point.isNull()) { QSize s = table->viewport()->size(); //qDebug() << s; _point = QPoint(s.width(),s.height()); } QAbstractItemModel* model = table->model(); if (!model) return; int n,m,bsize1,bsize2,offset1,offset2,point1,point2; getSizes(table,model,&m,&n,&bsize1,&bsize2,&point1,&point2,&offset1,&offset2); int coord1; int coord2 = 0; int sizes[m]; if (_orientation == Qt::Horizontal) { for (int i=0;i<m;i++) sizes[i] = table->columnWidth(i); for (int i=0;i<n;i++) coord2 += table->rowHeight(i); } else { for (int i=0;i<m;i++) sizes[i] = table->rowHeight(i); for (int i=0;i<n;i++) coord2 += table->columnWidth(i); } if (_type == InsertRemove::Insert) nearestBorder(_policy,point1+offset1,sizes,m,&_modelIndex,&coord1); else // _type == InsertRemove::Remove nearestMiddle(_policy,point1+offset1,sizes,m,&_modelIndex,&coord1); coord1 -= bsize1 / 2; QSize vp = usefulWidgetSize(table); QPoint sh = table->viewport()->mapToParent(QPoint(0,0)); //насколько viewport меньше table if (_orientation == Qt::Horizontal) { if (coord2 - offset2 + bsize2 + sh.y() > vp.height()) coord2 = vp.height() - bsize2 + offset2 - sh.y(); } else { if (coord2 - offset2 + bsize2 + sh.x() > vp.width()) coord2 = vp.width() - bsize2 + offset2 - sh.x(); } if (_orientation == Qt::Horizontal) { QPoint p = table->viewport()->mapToParent(QPoint(coord1 - offset1,coord2 - offset2)); setGeometry(QRect(p,size())); } else { QPoint p = table->viewport()->mapToParent(QPoint(coord2 - offset2,coord1 - offset1)); setGeometry(QRect(p,size())); } if (_type == InsertRemove::Insert) { setVisible(_modelIndex>=0); } else { setVisible((_policy & InsertRemove::RemoveAllowed) && (_modelIndex>-1)); } }