From a5d037c51ccbaa3f2a71bd39db187414bd1c78fe Mon Sep 17 00:00:00 2001 From: Marius Bugge Monsen Date: Tue, 28 Jul 2009 20:03:49 +1000 Subject: Update QGraphicsListView to be able to use QmlComponent for creating view items. --- src/experimental/qgraphicsgridview.cpp | 16 +- src/experimental/qgraphicsgridview.h | 2 +- src/experimental/qgraphicspathview.cpp | 15 +- src/experimental/qkineticlistcontroller.cpp | 15 +- src/experimental/qprinterlistview.cpp | 380 ++++++++++++++++++++ src/experimental/qprinterlistview.h | 77 +++++ src/experimental/qprinterlistview_p.h | 77 +++++ src/experimental/qprintertableview.cpp | 364 +++++++++++++++++++ src/experimental/qprintertableview.h | 74 ++++ src/experimental/qprintertableview_p.h | 77 +++++ src/qdataroles_p.h | 48 ++- src/qgraphicslistview.cpp | 518 +++++++++++++++------------- src/qgraphicslistview.h | 21 +- src/qgraphicslistview_p.h | 4 +- src/qlistmodelinterface.cpp | 3 +- src/qlistmodelinterface.h | 2 +- src/qprinterlistview.cpp | 380 -------------------- src/qprinterlistview.h | 77 ----- src/qprinterlistview_p.h | 77 ----- src/qprintertableview.cpp | 364 ------------------- src/qprintertableview.h | 74 ---- src/qprintertableview_p.h | 77 ----- src/qtablemodelinterface.cpp | 2 +- src/qtablemodelinterface.h | 2 +- src/src.pro | 16 +- 25 files changed, 1421 insertions(+), 1341 deletions(-) create mode 100644 src/experimental/qprinterlistview.cpp create mode 100644 src/experimental/qprinterlistview.h create mode 100644 src/experimental/qprinterlistview_p.h create mode 100644 src/experimental/qprintertableview.cpp create mode 100644 src/experimental/qprintertableview.h create mode 100644 src/experimental/qprintertableview_p.h delete mode 100644 src/qprinterlistview.cpp delete mode 100644 src/qprinterlistview.h delete mode 100644 src/qprinterlistview_p.h delete mode 100644 src/qprintertableview.cpp delete mode 100644 src/qprintertableview.h delete mode 100644 src/qprintertableview_p.h diff --git a/src/experimental/qgraphicsgridview.cpp b/src/experimental/qgraphicsgridview.cpp index c95813e..b8375c3 100644 --- a/src/experimental/qgraphicsgridview.cpp +++ b/src/experimental/qgraphicsgridview.cpp @@ -360,24 +360,25 @@ void QtGraphicsGridView::doLayout() d->scrollItems(firstVisibleIndex); int index = firstVisibleIndex; for (; index <= lastVisibleIndex; ++index) { - initStyleOption(&option, index); + //initStyleOption(&option, index); const int i = index - firstVisibleIndex; if (i >= d->items.count()) - d->items.append(d->creator->create(index, this)); - QtGraphicsListViewItem *item = d->items.at(i); + d->items.append(QPair(index, d->creator->create(index, this))); + QGraphicsObject *item = d->items.at(i).second; const QPointF pos = d->gridPosition(index); - const QSizeF size = item->sizeHint(index, &option, Qt::PreferredSize, QSizeF(gridSize, gridSize)); + const QSizeF size = item->boundingRect().size(); const QRectF grid(pos.x(), pos.y(), gridSize, gridSize); const QRectF aligned = QStyle::alignedRect(option.direction, Qt::AlignCenter, size.toSize(), grid.toRect()); - item->setGeometry(aligned); + //item->setGeometry(aligned); + item->setPos(aligned.topLeft());//### FIXME } // remove unused items const int from = index - firstVisibleIndex; while (from < d->items.count()) - d->creator->recycle(d->items.takeLast()); + d->creator->recycle(d->items.takeLast().second); } /*! @@ -427,13 +428,14 @@ void QtGraphicsGridView::initStyleOption(QStyleOptionViewItemV4 *option) const /*! \reimp */ +/* void QtGraphicsGridView::initStyleOption(QStyleOptionViewItemV4 *option, int index) const { QtGraphicsListView::initStyleOption(option, index); option->state &= ~QStyle::State_HasFocus; option->state &= ~QStyle::State_Selected; } - +*/ QT_END_NAMESPACE #include "moc_qgraphicsgridview.cpp" diff --git a/src/experimental/qgraphicsgridview.h b/src/experimental/qgraphicsgridview.h index 48a02f2..a00dd0c 100644 --- a/src/experimental/qgraphicsgridview.h +++ b/src/experimental/qgraphicsgridview.h @@ -53,7 +53,7 @@ public: virtual QRectF itemGeometry(int index) const; virtual int itemAt(const QPointF &position) const; virtual void initStyleOption(QStyleOptionViewItemV4 *option) const; - virtual void initStyleOption(QStyleOptionViewItemV4 *option, int index) const; + //virtual void initStyleOption(QStyleOptionViewItemV4 *option, int index) const; protected: QtGraphicsGridView(QtGraphicsGridViewPrivate &, Qt::Orientation orientation, QGraphicsWidget *parent, Qt::WindowFlags wFlags = 0); diff --git a/src/experimental/qgraphicspathview.cpp b/src/experimental/qgraphicspathview.cpp index ed1876c..a20f8d5 100644 --- a/src/experimental/qgraphicspathview.cpp +++ b/src/experimental/qgraphicspathview.cpp @@ -165,9 +165,9 @@ void QtGraphicsPathView::doLayout() qreal progress = /*animationProgress()*/1 - (running && forward ? 1 : 0); while (!path.isEmpty() && counter < count) { - initStyleOption(&option, index); + //initStyleOption(&option, index); qreal c = qreal(counter) + progress; - QSizeF size = d->itemSizeHint(&option, index); + QSizeF size = d->itemSize(index); //qreal scale = (qreal(count - qAbs(c - (count / 2))) / qreal(count)); qreal t = qBound(qreal(0), c / qreal(count), qreal(1)); QPointF pos = path.pointAtPercent(t); @@ -176,15 +176,16 @@ void QtGraphicsPathView::doLayout() pos += boundingRect.topLeft(); // ### FIXME: look up and recycle the items - QtGraphicsListViewItem *item = 0; + QGraphicsObject *item = 0; if (counter >= d->items.count()) { item = d->creator->create(index, this); - d->items.append(item); + d->items.append(QPair(index, item)); } else { - item = d->items.at(counter); - item->setIndex(index); // ### + item = d->items.at(counter).second; + d->creator->reassign(index, item, this); + //item->setIndex(index); // ### } - item->setGeometry(QRectF(pos, size)); + item->setPos(pos); ++index; if (index >= count) // loop diff --git a/src/experimental/qkineticlistcontroller.cpp b/src/experimental/qkineticlistcontroller.cpp index 8935d95..5fca8b5 100644 --- a/src/experimental/qkineticlistcontroller.cpp +++ b/src/experimental/qkineticlistcontroller.cpp @@ -95,15 +95,12 @@ bool QtKineticListControllerPrivate::kineticUpdateOffset(qreal *offset, qreal ma const QSizeF viewSize = view->size(); const QPointF viewCenter(viewSize.width() / 2, viewSize.height() / 2); const int centerIndex = view->itemAt(viewCenter); - // ### this should be done in the view - get item geometry - if (QtGraphicsListViewItem *centerItem = view->itemForIndex(centerIndex)) { - const QPointF itemCenter = centerItem->geometry().center(); - const QPointF delta = viewCenter - itemCenter; - if (view->orientation() == Qt::Horizontal) - scrollVelocity += l * delta.x(); - else - scrollVelocity += l * delta.y(); - } + const QPointF itemCenter = view->itemGeometry(centerIndex).center(); + const QPointF delta = viewCenter - itemCenter; + if (view->orientation() == Qt::Horizontal) + scrollVelocity += l * delta.x(); + else + scrollVelocity += l * delta.y(); scrollVelocity *= frictionFactor; return true; } diff --git a/src/experimental/qprinterlistview.cpp b/src/experimental/qprinterlistview.cpp new file mode 100644 index 0000000..689d9fb --- /dev/null +++ b/src/experimental/qprinterlistview.cpp @@ -0,0 +1,380 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Itemviews NG project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 or 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "qprinterlistview.h" +#include "qprinterlistview_p.h" + +#ifndef QT_NO_PRINTER + +#include "qlistcontroller.h" +#include "qlistmodelinterface.h" +#include "qgraphicslistview.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QtPrinterListViewPrivate::QtPrinterListViewPrivate(QPrinter *p) + : q_ptr(0), + ownsPrinter(p == 0), + printer(ownsPrinter ? new QPrinter : p), + model(0), + orientation(Qt::Vertical), + header(0), + footer(0), + creator(0) +{ + headerFooterSpacing = 5; // in mm +} + +QtPrinterListViewPrivate::~QtPrinterListViewPrivate() +{ + delete header; + delete footer; + delete creator; + if (ownsPrinter) + delete printer; +} + +qreal QtPrinterListViewPrivate::printHeader(QPainter &painter) +{ + if (header == 0) + return 0; + header->drawContents(&painter); + return header->size().height() + headerFooterSpacingInPixels(); +} + +qreal QtPrinterListViewPrivate::printFooter(QPainter &painter) +{ + if (footer == 0) + return 0; + qreal pageHeight = printer->pageRect().height(); + const qreal footerSize = footer->size().height(); + painter.translate(0, pageHeight - footerSize); + footer->drawContents(&painter); + painter.translate(0, - (pageHeight - footerSize)); + return footerSize + headerFooterSpacingInPixels(); +} + +QTextDocument *QtPrinterListViewPrivate::getOrCreateHeader() const +{ + if (header == 0) { + header = new QTextDocument(); + header->setUndoRedoEnabled(false); + header->setDocumentMargin(0); + } + return header; +} + +QTextDocument *QtPrinterListViewPrivate::getOrCreateFooter() const +{ + if (footer == 0) { + footer = new QTextDocument(); + footer->setUndoRedoEnabled(false); + footer->setDocumentMargin(0); + } + return footer; +} + +/*! + \class QtPrinterListView + \brief QtPrinterListView allows you to print a list model. + + Usage; + \code + QtPrinterListView printerView(myListModel); + QPrintDialog dialog(printerView.printer()); + if (dialog.exec() == QPrintDialog::Accepted) { + printerView.print(); + } + \endcode +*/ + +/*! + This is an overloaded member function, provided for convenience. It + differs from the above function only in what argument(s) it accepts. This + will cause QtPrinterListView to create an internal, default constructed + QPrinter object, which will be used to print the list. +*/ +QtPrinterListView::QtPrinterListView(QtListModelInterface *model) + : d_ptr(new QtPrinterListViewPrivate(0)) +{ + Q_ASSERT(model); + d_ptr->q_ptr = this; + d_ptr->model = model; +} + +/*! + Constructs a QtPrinterListView based on printer and with \a model as the + model that will be printed +*/ +QtPrinterListView::QtPrinterListView(QPrinter *printer, QtListModelInterface *model) + : d_ptr(new QtPrinterListViewPrivate(printer)) +{ + Q_ASSERT(model); + d_ptr->q_ptr = this; + d_ptr->model = model; +} + +/*! + Destructor +*/ +QtPrinterListView::~QtPrinterListView() +{ + delete d_ptr; +} + +/*! + Returns the printer used by this view to print to to allow setting of printer properties. +*/ +QPrinter *QtPrinterListView::printer() +{ + Q_D(QtPrinterListView); + return d->printer; +} + +/*! + Sets the orientation of the list layout to be the given orientation. + The orientation defines the print direction of the list. +*/ +void QtPrinterListView::setOrientation(Qt::Orientation orientation) +{ + Q_D(QtPrinterListView); + d->orientation = orientation; +} + +/*! + Returns the orientation for this list. + The orientation defines the print direction of the list. + */ +Qt::Orientation QtPrinterListView::orientation() const +{ + Q_D(const QtPrinterListView); + return d->orientation; +} + +/*! + Returns the text document used for each page header. + \sa setHeaderText() +*/ +QTextDocument *QtPrinterListView::headerDocument() +{ + Q_D(QtPrinterListView); + return d->getOrCreateHeader(); +} + +/*! + Returns the text document used for each page footer. + \sa setFooterText() +*/ +QTextDocument *QtPrinterListView::footerDocument() +{ + Q_D(QtPrinterListView); + return d->getOrCreateFooter(); +} + +/*! + Sets the header on all pages to have the \a header text. + This replaces any content that the header had previously. + \sa headerDocument() +*/ +void QtPrinterListView::setHeaderText(const QString &header) +{ + Q_D(QtPrinterListView); + d->getOrCreateHeader()->setPlainText(header); +} + +/*! + Sets the footer on all pages to have the \a footer text. + This replaces any content that the footer had previously. + \sa footerDocument() +*/ +void QtPrinterListView::setFooterText(const QString &footer) +{ + Q_D(QtPrinterListView); + d->getOrCreateFooter()->setPlainText(footer); +} + +/*! + Return the text set as header. + \sa headerDocument() +*/ +QString QtPrinterListView::headerText() const +{ + Q_D(const QtPrinterListView); + return d->getOrCreateHeader()->toPlainText(); +} + +/*! + Return the text set as footer. + \sa headerDocument() +*/ +QString QtPrinterListView::footerText() const +{ + Q_D(const QtPrinterListView); + if (d->footer == 0) + return QString(); + return d->footer->toPlainText(); +} + +QtGraphicsListViewItemCreatorBase *QtPrinterListView::viewItemCreator() const +{ + Q_D(const QtPrinterListView); + return d->creator; +} + +/*! + note that ownership is taken. +*/ +void QtPrinterListView::setViewItemCreator(QtGraphicsListViewItemCreatorBase *creator) +{ + Q_D(QtPrinterListView); + delete d->creator; + d->creator = creator; +} + +extern int qt_defaultDpiY(); +extern int qt_defaultDpiX(); + +/*! + Start the actual printing using the printer() options. + Returns true if printing was successful, or false otherwise. +*/ +bool QtPrinterListView::print() +{ + Q_D(QtPrinterListView); + if (! d->printer->isValid()) { + qWarning() << "QtPrinterListView::print: printer not valid, please setup the printer before calling print"; + return false; + } + + // next use a view just for the filling of the options... + QtGraphicsListView view; + view.setModel(d->model); + + QPainter painter; + if (!painter.begin(d->printer)) { + qWarning() << "QtPrinterListView::print: printer fails to begin(), sorry can't print"; + return false; + } + + // re-layout the header footer to the current page size. + if (d->header) { + d->header->documentLayout()->setPaintDevice(d->printer); + d->header->setPageSize(d->printer->pageRect().size()); + } + if (d->footer) { + d->footer->documentLayout()->setPaintDevice(d->printer); + d->footer->setPageSize(d->printer->pageRect().size()); + } + + QtGraphicsListViewItem *listViewItem; + if (d->creator) + listViewItem = d->creator->create(0, &view); + else + listViewItem = view.itemCreator()->create(0, &view); + listViewItem->setCacheMode(QGraphicsItem::NoCache); + + QStyleOptionViewItemV4 widgetOptions; + QStyleOptionGraphicsItem graphicsViewOptions; + view.initStyleOption(&widgetOptions); + + const qreal headerSize = d->printHeader(painter); + const qreal footerSize = d->printFooter(painter); + const bool vertical = d->orientation == Qt::Vertical; + const qreal scaleX = d->printer->logicalDpiX() / (qreal) qt_defaultDpiX(); + const qreal scaleY = d->printer->logicalDpiY() / (qreal) qt_defaultDpiY(); + QSizeF constraint = d->printer->pageRect().size(); + // cache the space we have for actual list items. + const qreal contentSize = vertical ? constraint.height() - headerSize - footerSize : constraint.width(); + + view.resize(constraint - QSizeF(0, headerSize + footerSize)); + + // a constraint is -1 in the direction we allow items to grow in. + if (vertical) { + constraint.setHeight(-1); + } else { + constraint.setWidth(-1); + // in this direction headers/footers eat our precious space + constraint.setHeight(constraint.height() - headerSize - - footerSize); + } + + qreal progression = vertical ? headerSize : 0; // init + const int max = d->model->count(); + for (int index = 0; index < max; ++index) { + view.initStyleOption(&widgetOptions, index); + + //QSizeF itemSize = listViewItem->sizeHint(index, &widgetOptions, Qt::PreferredSize, constraint); + listViewItem->setIndex(index); + QRectF geometry = view.itemGeometry(index); + if (vertical) + geometry.setWidth(constraint.width() / scaleX); + else + geometry.setHeight(constraint.height() / scaleY - headerSize - footerSize); + listViewItem->setGeometry(geometry); + geometry = listViewItem->geometry();// the listViewItem can be stubborn + graphicsViewOptions.rect = geometry.toRect(); + if ((vertical && progression - headerSize + geometry.height() > contentSize) + || (!vertical && progression + geometry.width()> contentSize)) { + if (! d->printer->newPage()) { + qWarning() << "QtPrinterListView::print: Failed to start a new page, aborting printing"; + return false; + } + progression = vertical ? headerSize : 0; // reset + d->printHeader(painter); + d->printFooter(painter); + } + + painter.save(); + painter.translate(vertical ? 0 : progression, + vertical ? progression : headerSize); + painter.scale(scaleX, scaleY); + listViewItem->paint(&painter, &graphicsViewOptions); + painter.restore(); + progression += vertical ? geometry.height() * scaleY: geometry.width() * scaleX; + } + return true; +} + +/*! + Prints the \a model to the \a printer +*/ +//static +void QtPrinterListView::printModel(QPrinter *printer, QtListModelInterface *model, const QString &header, const QString &footer) +{ + QtPrinterListView printerView(printer, model); + if (!header.isEmpty()) + printerView.setHeaderText(header); + if (!footer.isEmpty()) + printerView.setFooterText(footer); + + printerView.print(); +} + +QT_END_NAMESPACE + +#endif diff --git a/src/experimental/qprinterlistview.h b/src/experimental/qprinterlistview.h new file mode 100644 index 0000000..99d0c96 --- /dev/null +++ b/src/experimental/qprinterlistview.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Itemviews NG project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 or 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ +#ifndef QTPRINTERLISTVIEW_H +#define QTPRINTERLISTVIEW_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +//QT_MODULE(Gui) + +class QtPrinterListViewPrivate; +class QtListModelInterface; +class QtGraphicsListViewItemCreatorBase; +class QTextDocument; + +class Q_ITEMVIEWSNG_EXPORT QtPrinterListView +{ +public: + QtPrinterListView(QPrinter *printer, QtListModelInterface *model); + QtPrinterListView(QtListModelInterface *model); + ~QtPrinterListView(); + + QPrinter *printer(); + bool print(); + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + + QTextDocument *headerDocument(); + QTextDocument *footerDocument(); + + void setHeaderText(const QString &header); + void setFooterText(const QString &footer); + QString headerText() const; + QString footerText() const; + + QtGraphicsListViewItemCreatorBase *viewItemCreator() const; + void setViewItemCreator(QtGraphicsListViewItemCreatorBase *creator); + + static void printModel(QPrinter *printer, QtListModelInterface *model, const QString &header = QString(), const QString &footer = QString()); + +protected: + QtPrinterListViewPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QtPrinterListView) + Q_DISABLE_COPY(QtPrinterListView) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QTPRINTERLISTVIEW_H diff --git a/src/experimental/qprinterlistview_p.h b/src/experimental/qprinterlistview_p.h new file mode 100644 index 0000000..31ae385 --- /dev/null +++ b/src/experimental/qprinterlistview_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Itemviews NG project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 or 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef QTPRINTERLISTVIEW_P_H +#define QTPRINTERLISTVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_PRINTER +class QTextDocument; + +class QtPrinterListViewPrivate +{ + Q_DECLARE_PUBLIC(QtPrinterListView) +public: + QtPrinterListViewPrivate(QPrinter *printer); + ~QtPrinterListViewPrivate(); + + QtPrinterListView *q_ptr; + + bool ownsPrinter; + QPrinter * const printer; + QtListModelInterface *model; + + Qt::Orientation orientation; + mutable QTextDocument *header; + mutable QTextDocument *footer; + + qreal headerFooterSpacing; // in mm + + QtGraphicsListViewItemCreatorBase *creator; + + /// print a header and return the height we used + qreal printHeader(QPainter &painter); + qreal printFooter(QPainter &painter); + QTextDocument *getOrCreateHeader() const; + QTextDocument *getOrCreateFooter() const; + inline qreal headerFooterSpacingInPixels() { + return headerFooterSpacing * (printer->resolution() / 25.4); + } +}; + +#endif +QT_END_NAMESPACE + +#endif//QTPRINTERLISTVIEW_P_H diff --git a/src/experimental/qprintertableview.cpp b/src/experimental/qprintertableview.cpp new file mode 100644 index 0000000..aa3fefb --- /dev/null +++ b/src/experimental/qprintertableview.cpp @@ -0,0 +1,364 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Itemviews NG project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 or 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "qprintertableview.h" +#include "qprintertableview_p.h" + +#ifndef QT_NO_PRINTER + +#include "qgraphicstableview.h" +#include "qtablemodelinterface.h" +#include "qgraphicsheader.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// #define DEBUG_TABLES + +QtPrinterTableViewPrivate::QtPrinterTableViewPrivate(QPrinter *p) + : q_ptr(0), + ownsPrinter(p == 0), + printer(ownsPrinter ? new QPrinter : p), + model(0), + orientation(Qt::Vertical), + header(0), + footer(0) +{ + headerFooterSpacing = 5; // in mm +} + +QtPrinterTableViewPrivate::~QtPrinterTableViewPrivate() +{ + delete header; + delete footer; + if (ownsPrinter) + delete printer; +} + +qreal QtPrinterTableViewPrivate::printHeader(QPainter &painter) +{ + if (header == 0) + return 0; + header->drawContents(&painter); + return header->size().height() + headerFooterSpacingInPixels(); +} + +qreal QtPrinterTableViewPrivate::printFooter(QPainter &painter) +{ + if (footer == 0) + return 0; + qreal pageHeight = printer->pageRect().height(); + const qreal footerSize = footer->size().height(); + painter.translate(0, pageHeight - footerSize); + footer->drawContents(&painter); + painter.translate(0, - (pageHeight - footerSize)); + return footerSize + headerFooterSpacingInPixels(); +} + +QTextDocument *QtPrinterTableViewPrivate::getOrCreateHeader() const +{ + if (header == 0) { + header = new QTextDocument(); + header->setUndoRedoEnabled(false); + header->setDocumentMargin(0); + } + return header; +} + +QTextDocument *QtPrinterTableViewPrivate::getOrCreateFooter() const +{ + if (footer == 0) { + footer = new QTextDocument(); + footer->setUndoRedoEnabled(false); + footer->setDocumentMargin(0); + } + return footer; +} + +/*! + \class QtPrinterTableView + \brief QtPrinterTableView allows you to print a table model. +*/ + +QtPrinterTableView::QtPrinterTableView(QtTableModelInterface *model, QtGraphicsHeader *verticalHeader, QtGraphicsHeader *horizontalHeader) + : d_ptr(new QtPrinterTableViewPrivate(0)) +{ + Q_ASSERT(model); + d_ptr->q_ptr = this; + d_ptr->model = model; + d_ptr->horizontalHeader = horizontalHeader; + d_ptr->verticalHeader = verticalHeader; +} + +QtPrinterTableView::QtPrinterTableView(QPrinter *printer, QtTableModelInterface *model, QtGraphicsHeader *verticalHeader, QtGraphicsHeader *horizontalHeader) + : d_ptr(new QtPrinterTableViewPrivate(printer)) +{ + Q_ASSERT(model); + d_ptr->q_ptr = this; + d_ptr->model = model; + d_ptr->horizontalHeader = horizontalHeader; + d_ptr->verticalHeader = verticalHeader; +} + +QtPrinterTableView::~QtPrinterTableView() +{ + delete d_ptr; +} + +QPrinter *QtPrinterTableView::printer() +{ + Q_D(QtPrinterTableView); + return d->printer; +} + +void QtPrinterTableView::setOrientation(Qt::Orientation orientation) +{ + Q_D(QtPrinterTableView); + d->orientation = orientation; +} + +Qt::Orientation QtPrinterTableView::orientation() const +{ + Q_D(const QtPrinterTableView); + return d->orientation; +} + +QTextDocument *QtPrinterTableView::headerDocument() +{ + Q_D(QtPrinterTableView); + return d->getOrCreateHeader(); +} + +QTextDocument *QtPrinterTableView::footerDocument() +{ + Q_D(QtPrinterTableView); + return d->getOrCreateFooter(); +} + +void QtPrinterTableView::setHeaderText(const QString &header) +{ + Q_D(QtPrinterTableView); + d->getOrCreateHeader()->setPlainText(header); +} + +void QtPrinterTableView::setFooterText(const QString &footer) +{ + Q_D(QtPrinterTableView); + d->getOrCreateFooter()->setPlainText(footer); +} + +QString QtPrinterTableView::headerText() const +{ + Q_D(const QtPrinterTableView); + return d->getOrCreateHeader()->toPlainText(); +} + +QString QtPrinterTableView::footerText() const +{ + Q_D(const QtPrinterTableView); + if (d->footer == 0) + return QString(); + return d->footer->toPlainText(); +} + +extern int qt_defaultDpiY(); +extern int qt_defaultDpiX(); + +bool QtPrinterTableView::print() +{ + Q_D(QtPrinterTableView); + if (! d->printer->isValid()) { + qWarning() << "QtPrinterTableView::print: printer not valid, please setup the printer before calling print"; + return false; + } + + // next use a view just for the filling of the options... + QGraphicsScene scene; + QtGraphicsTableView view; + scene.addItem(&view); + view.setModel(d->model); + + + class QTableHeaderDataProvider2 : public QtGraphicsHeaderDataProvider + { + public: + QTableHeaderDataProvider2(QtTableModelInterface *model_) : model(model_) {} + QHash data(int logicalIndex, const QList &roles) const + { + // ### call the model - temporary implementation + QHash hash; + for (int i = 0; i < roles.count(); ++i) + if (roles.at(i) == Qt::DisplayRole) + hash.insert(Qt::DisplayRole, logicalIndex + 1); + return hash; + } + QtTableModelInterface *model; + }; + + if (d->horizontalHeader) { + QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Horizontal, &view); + header->setDataProvider(new QTableHeaderDataProvider2(d->model)); + header->copySections(*d->horizontalHeader); + view.setHorizontalHeader(header); + } + if (d->verticalHeader) { + QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Vertical, &view); + header->setDataProvider(new QTableHeaderDataProvider2(d->model)); + header->copySections(*d->verticalHeader); + view.setVerticalHeader(header); + } + + QPainter painter; + if (!painter.begin(d->printer)) { + qWarning() << "QtPrinterTableView::print: printer fails to begin(), sorry can't print"; + return false; + } + + // re-layout the header footer to the current page size. + if (d->header) { + d->header->documentLayout()->setPaintDevice(d->printer); + d->header->setPageSize(d->printer->pageRect().size()); + } + if (d->footer) { + d->footer->documentLayout()->setPaintDevice(d->printer); + d->footer->setPageSize(d->printer->pageRect().size()); + } + + const qreal headerSize = d->printHeader(painter); + const qreal footerSize = d->printFooter(painter); + const bool vertical = d->orientation == Qt::Vertical; + const qreal scaleX = d->printer->logicalDpiX() / (qreal) qt_defaultDpiX(); + const qreal scaleY = d->printer->logicalDpiY() / (qreal) qt_defaultDpiY(); + painter.scale(scaleX, scaleY); + + const QRect rect = d->printer->pageRect(); + QSizeF visibleSize(rect.width() / scaleX, rect.height() / scaleY); + if (vertical) + visibleSize = QSizeF(visibleSize.width(), visibleSize.height() - headerSize - footerSize); + else // then rotate it. + visibleSize = QSizeF(visibleSize.height() - headerSize - footerSize, visibleSize.width()); + + view.setGeometry(0, 0, visibleSize.width(), visibleSize.height()); + view.setHorizontalOffset(0); + + int row = 0; + int column; + bool first = true; + qreal offsetInColumn = 0; // for those columns too wide and thus split over more than one page + while (row < d->model->rowCount()) { + column = 0; + view.setFirstRow(row); + qreal height = visibleSize.height(); + while (true) { + const qreal rowHeight = view.rowHeight(row); + if (height - rowHeight < 0) + break; + if (row >= d->model->rowCount()) + break; + ++row; + height -= rowHeight; + } + while (column < d->model->columnCount()) { + if (!first) { + d->printer->newPage(); + d->printHeader(painter); + d->printFooter(painter); + } + first = false; + view.setFirstColumn(column); + view.setHorizontalOffset(offsetInColumn); + + qreal width = visibleSize.width(); + while (true) { + const qreal columnWidth = view.columnWidth(column); + if (width == visibleSize.width() && columnWidth - offsetInColumn > visibleSize.width()) { + // the column doesn't fit on a page. Lets split it. + offsetInColumn += visibleSize.width(); + width = 0; + break; + } else if (offsetInColumn > 0) { // we still have a part of a split column to print! + width -= columnWidth - offsetInColumn; + offsetInColumn = 0; + ++column; + continue; + } + + if (width - columnWidth + offsetInColumn < 0) + break; + if (column >= d->model->columnCount()) + break; + ++column; + width -= columnWidth; + } + view.doLayout(); + + painter.save(); // for each page + painter.translate(0, headerSize); + if (!vertical) { + painter.translate(0, visibleSize.width()); + painter.rotate(-90); + } +#ifdef DEBUG_TABLES + painter.setPen(QPen(QColor(Qt::green))); + painter.drawRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); +#endif + painter.setClipRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); + // find and paint children which are the cells + QList items = scene.items(view.rect()); + QList::Iterator iter = items.begin(); + for (;iter != items.end(); ++iter) { + QGraphicsItem *parent = *iter; + while (parent != &view && parent != 0) // only draw children of our view + parent = parent->parentItem(); + if (parent == 0) + continue; + if (!(*iter)->isVisible()) + continue; + painter.save(); + painter.translate((*iter)->mapToItem(&view, QPointF())); +#ifdef DEBUG_TABLES + QGraphicsWidget *w = dynamic_cast(*iter); + if (w) { + painter.save(); + painter.setPen(QPen(QColor(Qt::red))); + painter.drawRect(QRectF(QPointF(), w->size())); + painter.restore(); + } +#endif + (*iter)->paint(&painter, 0); + painter.restore(); + } + painter.restore(); // for each page + } + } + return true; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/experimental/qprintertableview.h b/src/experimental/qprintertableview.h new file mode 100644 index 0000000..be08ca6 --- /dev/null +++ b/src/experimental/qprintertableview.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Itemviews NG project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 or 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ +#ifndef QTPRINTERTABLEVIEW_H +#define QTPRINTERLTABLEIEW_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +//QT_MODULE(Gui) + +class QtPrinterTableViewPrivate; +class QtTableModelInterface; +class QtGraphicsHeader; +class QTextDocument; + +class Q_ITEMVIEWSNG_EXPORT QtPrinterTableView +{ +public: + explicit QtPrinterTableView(QPrinter *printer, QtTableModelInterface *model, QtGraphicsHeader *verticalHeader = 0, QtGraphicsHeader *horizontalHeader = 0); + explicit QtPrinterTableView(QtTableModelInterface *model, QtGraphicsHeader *verticalHeader = 0, QtGraphicsHeader *horizontalHeader = 0); + ~QtPrinterTableView(); + + QPrinter *printer(); + bool print(); + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + + QTextDocument *headerDocument(); + QTextDocument *footerDocument(); + + void setHeaderText(const QString &header); + void setFooterText(const QString &footer); + QString headerText() const; + QString footerText() const; + + // TODO add the setter of the creator object, add static print object + +protected: + QtPrinterTableViewPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QtPrinterTableView) + Q_DISABLE_COPY(QtPrinterTableView) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QTPRINTERTABLEVIEW_H diff --git a/src/experimental/qprintertableview_p.h b/src/experimental/qprintertableview_p.h new file mode 100644 index 0000000..f2927c2 --- /dev/null +++ b/src/experimental/qprintertableview_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Itemviews NG project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 or 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef QTPRINTERTABLEVIEW_P_H +#define QTPRINTERTABLEVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_PRINTER +class QTextDocument; + +class QtPrinterTableViewPrivate +{ + Q_DECLARE_PUBLIC(QtPrinterTableView) +public: + QtPrinterTableViewPrivate(QPrinter *printer); + ~QtPrinterTableViewPrivate(); + + QtPrinterTableView *q_ptr; + + bool ownsPrinter; + QPrinter * const printer; + QtTableModelInterface *model; + QtGraphicsHeader *horizontalHeader; + QtGraphicsHeader *verticalHeader; + + Qt::Orientation orientation; + mutable QTextDocument *header; + mutable QTextDocument *footer; + + qreal headerFooterSpacing; // in mm + + /// print a header and return the height we used + qreal printHeader(QPainter &painter); + qreal printFooter(QPainter &painter); + QTextDocument *getOrCreateHeader() const; + QTextDocument *getOrCreateFooter() const; + inline qreal headerFooterSpacingInPixels() { + return headerFooterSpacing * (printer->resolution() / 25.4); + } +}; + +#endif +QT_END_NAMESPACE + +#endif//QTPRINTERTABLEVIEW_P_H diff --git a/src/qdataroles_p.h b/src/qdataroles_p.h index e71c650..6eb8f5a 100644 --- a/src/qdataroles_p.h +++ b/src/qdataroles_p.h @@ -36,16 +36,52 @@ // #include +#include QT_BEGIN_NAMESPACE -struct QtDataRoles : private QObject +class QtDataRoles : private QObject { - static QHash roles() { - QHash roles; - const QMetaObject &staticMetaObject = static_cast(0)->staticQtMetaObject; - const int index = staticMetaObject.indexOfEnumerator("DataRoles"); - const QMetaEnum metaEnum = staticMetaObject.enumerator(index); + Q_OBJECT + Q_ENUMS(ItemDataRole) +public: + enum ItemDataRole { + DisplayRole = 0, + DecorationRole = 1, + EditRole = 2, + ToolTipRole = 3, + StatusTipRole = 4, + WhatsThisRole = 5, + // Metadata + FontRole = 6, + TextAlignmentRole = 7, + BackgroundColorRole = 8, + BackgroundRole = 8, + TextColorRole = 9, + ForegroundRole = 9, + CheckStateRole = 10, + // Accessibility + AccessibleTextRole = 11, + AccessibleDescriptionRole = 12, + // More general purpose + SizeHintRole = 13, + // Internal UiLib roles. Start worrying when public roles go that high. + DisplayPropertyRole = 27, + DecorationPropertyRole = 28, + ToolTipPropertyRole = 29, + StatusTipPropertyRole = 30, + WhatsThisPropertyRole = 31, + // Reserved + UserRole = 32 + }; + + static QHash roles() { + QHash roles; + const QMetaObject &metaObject = QtDataRoles().staticMetaObject;//static_cast(0)->staticQtMetaObject; + const int index = metaObject.indexOfEnumerator("ItemDataRole"); + if (index == -1) + qWarning() << "QtDataRoles: could not find ItemDataRoles enumerator"; + const QMetaEnum metaEnum = metaObject.enumerator(index); for (int i = 0; i < metaEnum.keyCount(); ++i) roles.insert(metaEnum.value(i), metaEnum.key(i)); return roles; diff --git a/src/qgraphicslistview.cpp b/src/qgraphicslistview.cpp index 85dd752..70d3ec6 100644 --- a/src/qgraphicslistview.cpp +++ b/src/qgraphicslistview.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE alter the individual list items appearance, for example;
  • Reimplement paint() to change the look for just this list.
  • -
  • Add any number of child QGraphicsItem objects that do the painting instead.
  • +
  • Add any number of child QGraphicsObject instances that do the painting instead.
@@ -70,8 +70,8 @@ QtGraphicsListViewItem::QtGraphicsListViewItem(int index, QtGraphicsListView *vi : QGraphicsWidget(view, 0), d_ptr(new QtGraphicsListViewItemPrivate) { Q_D(QtGraphicsListViewItem); - Q_ASSERT(view); - setCacheMode(QGraphicsItem::ItemCoordinateCache); + setCacheMode(QGraphicsObject::ItemCoordinateCache); + setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); d->q_ptr = this; d->view = view; d->index = index; @@ -111,36 +111,38 @@ void QtGraphicsListViewItem::setIndex(int index) /*! \reimp */ -QSizeF QtGraphicsListViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const + +QRectF QtGraphicsListViewItem::boundingRect() const { - Q_D(const QtGraphicsListViewItem); - d->view->initStyleOption(&d->option); - d->view->initStyleOption(&d->option, d->index); - return sizeHint(d->index, &d->option, which, constraint); + return QRectF(QPointF(), geometry().size()); } /*! - Returns \a which size hint for the item indicated by the given \a index, - using the given \a option and \a constrainst. + \reimp */ -QSizeF QtGraphicsListViewItem::sizeHint(int index, const QStyleOptionViewItemV4 *option, Qt::SizeHint which, const QSizeF &constraint) const +QSizeF QtGraphicsListViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { Q_D(const QtGraphicsListViewItem); - switch (which) { - case Qt::MinimumSize: - case Qt::PreferredSize: { - const QVariant value = d->view->d_func()->cachedData(index, Qt::SizeHintRole); - if (value.isValid()) - return qvariant_cast(value); - else - return d->view->style()->sizeFromContents(QStyle::CT_ItemViewItem, option, QSize(), option->widget); - } - case Qt::MaximumSize: - return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - default: - break; + Q_UNUSED(constraint); + if (d->view) { + d->view->initStyleOption(&d->option); + initStyleOption(&d->option); + switch (which) { + case Qt::MinimumSize: + case Qt::PreferredSize: { + const QVariant value = d->view->d_func()->cachedData(d->index, Qt::SizeHintRole); + if (value.isValid()) + return qvariant_cast(value); + else + return d->view->style()->sizeFromContents(QStyle::CT_ItemViewItem, &d->option, QSize(), d->option.widget); + } + case Qt::MaximumSize: + return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + default: + break; + } } - return QGraphicsWidget::sizeHint(which, constraint); + return QSizeF(); } /*! @@ -151,11 +153,13 @@ void QtGraphicsListViewItem::paint(QPainter *painter, const QStyleOptionGraphics Q_D(QtGraphicsListViewItem); // ### this code is less than optimal, but we will hopefully get rid of the style calls // ### by moving to a purely scene-graph based approach for items - d->view->copyStyleOptionState(option, &d->option); - d->view->initStyleOption(&d->option); - d->view->initStyleOption(&d->option, d->index); - d->option.rect = rect().toRect(); - d->view->style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); + if (d->view) { + copyStyleOptionState(option, &d->option); + d->view->initStyleOption(&d->option); + initStyleOption(&d->option); + d->option.rect = boundingRect().toRect(); + d->view->style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); + } } /*! @@ -186,6 +190,128 @@ QHash QtGraphicsListViewItem::data(const QList &roles) const return QHash(); } +/*! + Initialize the given \a option with the settings and data + specific for the item at the given \a index. + */ +void QtGraphicsListViewItem::initStyleOption(QStyleOptionViewItemV4 *option) const +{ + Q_D(const QtGraphicsListViewItem); + Q_ASSERT(option); + + if (!d->view) + return; + + if (d->view->selectionManager()) { + // Current Item + if (d->view->selectionManager()->currentItem() == d->index) + option->state |= QStyle::State_HasFocus; + else + option->state &= ~QStyle::State_HasFocus; + // selectionManager + if (d->view->selectionManager()->isSelected(d->index)) + option->state |= QStyle::State_Selected; + else + option->state &= ~QStyle::State_Selected; + } + + // Data + QVariant value; + + // FontRole + value = d->view->cachedData(d->index, Qt::FontRole); + if (value.isValid()) { + option->font = qvariant_cast(value).resolve(option->font); + option->fontMetrics = QFontMetrics(option->font); + } + + // TextAlignmentRole + value = d->view->cachedData(d->index, Qt::TextAlignmentRole); + if (value.isValid()) + option->displayAlignment = (Qt::Alignment)value.toInt(); + + // ForegroundRole + value = d->view->cachedData(d->index, Qt::ForegroundRole); + if (qVariantCanConvert(value)) + option->palette.setBrush(QPalette::Text, qvariant_cast(value)); + + // CheckStateRole + value = d->view->cachedData(d->index, Qt::CheckStateRole); + if (value.isValid()) { + option->features |= QStyleOptionViewItemV2::HasCheckIndicator; + option->checkState = static_cast(value.toInt()); + } + + // DecorationRole + value = d->view->cachedData(d->index, Qt::DecorationRole); + if (value.isValid()) { + option->features |= QStyleOptionViewItemV2::HasDecoration; + switch (value.type()) { + case QVariant::Icon: + option->icon = qvariant_cast(value); + break; + case QVariant::Color: { + QPixmap pixmap(option->decorationSize); + pixmap.fill(qvariant_cast(value)); + option->icon = QIcon(pixmap); } + default: + break; + } + } + + // DisplayRole + value = d->view->cachedData(d->index, Qt::DisplayRole); + if (value.isValid()) { + option->features |= QStyleOptionViewItemV2::HasDisplay; + switch (value.type()) { + case QVariant::Double: + option->text = option->locale.toString(value.toDouble()); + break; + case QVariant::Int: + case QVariant::LongLong: + option->text = option->locale.toString(value.toLongLong()); + break; + case QVariant::UInt: + case QVariant::ULongLong: + option->text = option->locale.toString(value.toULongLong()); + break; + case QVariant::Date: + option->text = option->locale.toString(value.toDate(), QLocale::ShortFormat); + break; + case QVariant::Time: + option->text = option->locale.toString(value.toTime(), QLocale::ShortFormat); + break; + case QVariant::DateTime: + option->text = option->locale.toString(value.toDateTime().date(), QLocale::ShortFormat); + option->text += QLatin1Char(' '); + option->text += option->locale.toString(value.toDateTime().time(), QLocale::ShortFormat); + break; + default: { + QString text = value.toString(); + for (int i = 0; i < text.count(); ++i) + if (text.at(i).unicode() == '\n') + text[i] = QChar::LineSeparator; + option->text = text; + break; } + } + } +} + +/*! + Copies style option state information from the + given \a source to the given \a destination + */ +void QtGraphicsListViewItem::copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *destination) +{ + if (source && destination) { + destination->state = source->state; + destination->direction = source->direction; + destination->rect = source->rect; + destination->fontMetrics = source->fontMetrics; + destination->palette = source->palette; + } +} + /*! Returns the view where this item is shown. */ @@ -219,17 +345,18 @@ QtGraphicsListViewItemCreatorBase::~QtGraphicsListViewItemCreatorBase() /*! This method basically does a recycle and a create in one go. */ -QtGraphicsListViewItem *QtGraphicsListViewItemCreatorBase::reassign(int index, QtGraphicsListViewItem *item) +QGraphicsObject *QtGraphicsListViewItemCreatorBase::reassign(int index, QGraphicsObject *item, QtGraphicsListView *view) { + Q_UNUSED(view); Q_ASSERT(item); - item->setIndex(index); + static_cast(item)->setIndex(index); return item; } /*! Give back the \a item to the creator pool of unused objects. */ -void QtGraphicsListViewItemCreatorBase::recycle(QtGraphicsListViewItem *item) +void QtGraphicsListViewItemCreatorBase::recycle(QGraphicsObject *item) { delete item; } @@ -300,14 +427,14 @@ void QtGraphicsListViewPrivate::_q_itemsChanged(int index, int count, const QLis checkCache(index, count); //qDebug() << "QtGraphicsListViewPrivate::_q_itemsChanged" << index << count; for (int i = 0; i < items.count(); ++i) { - QtGraphicsListViewItem *item = items.at(i); - int itemIndex = item->index(); + QGraphicsObject *item = items.at(i).second; + int itemIndex = items.at(i).first; if (itemIndex >= index + count) // change happened above break; - //if (itemIndex < index + viewItems.count()) - // break; // change happened below - if (itemIndex >= index) - item->itemChanged(roles); + //if (itemIndex >= index && item->isWidget()) + // item->itemChanged(roles); + Q_UNUSED(roles); + item->update(); // ### } q->updateLayout(); // ### FIXME: be more discriminate } @@ -353,14 +480,14 @@ void QtGraphicsListViewPrivate::_q_selectionsChanged(const QtListSelectionChange { if (items.isEmpty()) return; - const int from = items.first()->index(); - const int to = items.last()->index(); + const int from = items.first().first; + const int to = items.last().first; if (from <= change.index() && (change.index() + change.count() - 1) <= to) { - const QList indexes = change.indexes(); - for (int i = 0; i < indexes.count(); ++i) { - const int index = indexes.at(i); + const QList changeIndexes = change.indexes(); + for (int i = 0; i < changeIndexes.count(); ++i) { + const int index = changeIndexes.at(i); if (from <= index && index <= to) - items.at(index - from)->update(); + items.at(index - from).second->update(); } } } @@ -370,13 +497,15 @@ void QtGraphicsListViewPrivate::_q_selectionsChanged(const QtListSelectionChange */ void QtGraphicsListViewPrivate::_q_currentChanged(int current, int previous) { + if (items.isEmpty()) + return; //qDebug() << "QtGraphicsListViewPrivate::_q_currentChanged" << current << previous; - const int from = items.first()->index(); - const int to = items.last()->index(); + const int from = items.first().first; + const int to = items.last().first; if (from <= current && current <= to) - items.at(current - from)->update(); + items.at(current - from).second->update(); if (from <= previous && previous <= to) - items.at(current - from)->update(); + items.at(current - from).second->update(); } /*! @@ -439,18 +568,21 @@ int QtGraphicsListViewPrivate::currentItem() const */ void QtGraphicsListViewPrivate::scrollItems(int firstVisibleIndex) { + Q_Q(QtGraphicsListView); // shift items around if (!items.isEmpty()) { // scrolling down or right - move from first to last - while (items.first()->index() < firstVisibleIndex) { - const int index = items.last()->index() + 1; - items.append(creator->reassign(index, items.takeFirst())); + while (items.first().first < firstVisibleIndex) { + const int index = items.last().first + 1; + QPair item = items.takeFirst(); + items.append(QPair(index, creator->reassign(index, item.second, q))); } // scrolling up or left - move from last to first (assuming same view size) const int firstNonVisibleIndex = firstVisibleIndex + items.count(); - while (items.last()->index() >= firstNonVisibleIndex) { - const int index = items.first()->index() - 1; - items.prepend(creator->reassign(index, items.takeLast())); + while (items.last().first >= firstNonVisibleIndex) { + const int index = items.first().first - 1; + QPair item = items.takeLast(); + items.prepend(QPair(index, creator->reassign(index, item.second, q))); } } } @@ -458,9 +590,28 @@ void QtGraphicsListViewPrivate::scrollItems(int firstVisibleIndex) /*! \internal */ -QSizeF QtGraphicsListViewPrivate::itemSizeHint(const QStyleOptionViewItemV4 *option, int index, const QSizeF &constraint) const -{ - return items.isEmpty() ? QSizeF() : items.first()->sizeHint(index, option, Qt::PreferredSize, constraint); +QSizeF QtGraphicsListViewPrivate::itemSize(int index) const +{ + Q_Q(const QtGraphicsListView); + const QSizeF constraint = (orientation == Qt::Horizontal + ? QSizeF(-1, q->size().height()) + : QSizeF(q->size().width(), -1)); + if (items.isEmpty()) { // construct an item + if (QGraphicsObject *item = creator->create(index, 0)) { + QSizeF size = (item->isWidget() + ? static_cast(item)->size() + : item->boundingRect().size()); // ### FIXME: don't use bounding rect + creator->recycle(item); // ### FIXME: save it for re-use later + return size; + } + qWarning() << "QtGraphicsListView: could not create a new item"; + return QSizeF(); + } + // average size of visible items + QSizeF size; + for (int i = 0; i < items.count(); ++i) + size += items.at(i).second->boundingRect().size(); + return size / items.count(); } // QtGraphicsListView @@ -666,17 +817,16 @@ QRectF QtGraphicsListView::itemGeometry(int index) const Q_D(const QtGraphicsListView); if (!d->model) return QRectF(); - if (QtGraphicsListViewItem *item = itemForIndex(index)) - return item->geometry(); - const QSizeF constraint = size(); + if (QGraphicsObject *item = itemForIndex(index)) + return QRectF(item->pos(), item->boundingRect().size()); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); const int count = d->model->count(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); if (d->orientation == Qt::Vertical) { qreal y = -d->offset; for (int i = d->firstIndex; i < count; ++i) { - initStyleOption(&option, i); - const QSizeF size = d->itemSizeHint(&option, i, constraint); + const QSizeF size = d->itemSize(i); if (i == index) return QRectF(QPointF(0, y), size); y += size.height(); @@ -684,8 +834,7 @@ QRectF QtGraphicsListView::itemGeometry(int index) const } else { // Horizontal qreal x = -d->offset; for (int i = d->firstIndex; i < count; ++i) { - initStyleOption(&option, i); - const QSizeF size = d->itemSizeHint(&option, i, constraint); + const QSizeF size = d->itemSize(i); if (i == index) return QRectF(QPointF(x, 0), size); x += size.width(); @@ -705,16 +854,15 @@ int QtGraphicsListView::itemAt(const QPointF &position) const if (!d->model) return -1; // ### FIXME: check the visible items first - const QSizeF constraint = size(); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); const int count = d->model->count(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); int index = d->firstIndex; if (d->orientation == Qt::Vertical) { qreal y = -d->offset; while (y <= position.y() && index < count) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); y += size.height(); if (y >= position.y()) return index; @@ -723,8 +871,7 @@ int QtGraphicsListView::itemAt(const QPointF &position) const } else { qreal x = -d->offset; while (x <= position.x() && index < count) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); x += size.width(); if (x >= position.x()) return index; @@ -754,11 +901,10 @@ void QtGraphicsListView::doLayout() Q_D(QtGraphicsListView); d->layoutTimer.stop(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); - const QRectF area = boundingRect(); - const QSizeF constraint = area.size(); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); const int count = d->model ? d->model->count() : 0; const bool vertical = (d->orientation == Qt::Vertical); const qreal areaStart = (vertical ? area.y() : area.x()); @@ -779,8 +925,7 @@ void QtGraphicsListView::doLayout() // the visible area starts at coordinate == 0 if (coordinate < 0) { // the cached offset was above or to the left of the visible area while (index < count) { - initStyleOption(&option, index); - const QSizeF hint = d->itemSizeHint(&option, index, constraint); + const QSizeF hint = d->itemSize(index); const qreal size = vertical ? hint.height() : hint.width(); if (coordinate + size > areaStart) break; @@ -789,8 +934,7 @@ void QtGraphicsListView::doLayout() } } else if (coordinate > 0) { // the cached offset was below or to the right while (index >= 0 && coordinate > 0) { - initStyleOption(&option, index); - const QSizeF hint = d->itemSizeHint(&option, index, constraint); + const QSizeF hint = d->itemSize(index); const qreal size = vertical ? hint.height() : hint.width(); coordinate -= size; --index; @@ -808,8 +952,8 @@ void QtGraphicsListView::doLayout() // set existing item positions for (int i = 0; i < d->items.count() && index < count && coordinate < areaEnd; ++i) { - QtGraphicsListViewItem *item = d->items.at(i); - const QSizeF size = item->size(); + QGraphicsObject *item = d->items.at(i).second; + const QSizeF size = item->boundingRect().size(); if (vertical) { item->setPos(0, coordinate); coordinate += size.height(); @@ -822,16 +966,23 @@ void QtGraphicsListView::doLayout() // add more items and set geometry while (index < count && coordinate < areaEnd) { - QtGraphicsListViewItem *item = d->creator->create(index, this); - d->items.append(item); - initStyleOption(&option, index); - const QSizeF size = item->sizeHint(index, &option, Qt::PreferredSize, constraint); - if (vertical) { - item->setGeometry(0, coordinate, area.width(), size.height()); - coordinate += size.height(); - } else { - item->setGeometry(coordinate, 0, size.width(), area.height()); - coordinate += size.width(); + if (QGraphicsObject *item = d->creator->create(index, this)) { + d->items.append(QPair(index, item)); + const bool isWidget = item->isWidget(); + const QSizeF size = (isWidget + ? static_cast(item)->effectiveSizeHint(Qt::PreferredSize, constraint) + : item->boundingRect().size()); // ### don't use bounding rect + if (vertical) { + item->setPos(0, coordinate); + if (isWidget) + static_cast(item)->resize(area.width(), size.height()); + coordinate += size.height(); + } else { + item->setPos(coordinate, 0); + if (isWidget) + static_cast(item)->resize(size.width(), area.height()); + coordinate += size.width(); + } } ++index; } @@ -839,8 +990,7 @@ void QtGraphicsListView::doLayout() // remove unused items const int visibleCount = index - firstVisibleIndex; while (visibleCount < d->items.count()) - d->creator->recycle(d->items.takeLast()); - + d->creator->recycle(d->items.takeLast().second); } /*! @@ -853,24 +1003,22 @@ int QtGraphicsListView::maximumFirstIndex() const { // ### cache this value Q_D(const QtGraphicsListView); - const QSizeF constraint = size(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); int last = (d->model ? d->model->count() : 0) - 1; int index = last; if (orientation() == Qt::Vertical) { qreal height = size().height() + d->offset; for (; index >= 0; --index) { - initStyleOption(&option, index); - height -= d->itemSizeHint(&option, index, constraint).height(); + height -= d->itemSize(index).height(); if (height < 0) break; } } else { qreal width = size().width() + d->offset; for (; index >= 0; --index) { - initStyleOption(&option, index); - width -= d->itemSizeHint(&option, index, constraint).width(); + width -= d->itemSize(index).width(); if (width < 0) break; } @@ -892,24 +1040,22 @@ qreal QtGraphicsListView::maximumOffset() const { // ### cache this value Q_D(const QtGraphicsListView); - const QSizeF constraint = size(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); qreal max = 0; qreal content = 0; int count = d->model ? d->model->count() : 0; if (orientation() == Qt::Vertical) { for (int index = 0; index < count; ++index) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); content += size.height(); max = qMax(max, size.height()); } return qMax(content - size().height(), 0); } else { // Horizontal for (int index = 0; index < count; ++index) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); content += size.width(); max = qMax(max, size.width()); } @@ -1006,7 +1152,9 @@ void QtGraphicsListView::setFirstIndexToEnsureIndexIsVisible(int index) Q_D(QtGraphicsListView); // ### cache if (index > d->firstIndex) { - const QSizeF constraint = size(); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); QStyleOptionViewItemV4 option; initStyleOption(&option); if (orientation() == Qt::Vertical) { @@ -1062,124 +1210,6 @@ void QtGraphicsListView::initStyleOption(QStyleOptionViewItemV4 *option) const option->state |= QStyle::State_Active; } -/*! - Initialize the given \a option with the settings and data - specific for the item at the given \a index. - */ -void QtGraphicsListView::initStyleOption(QStyleOptionViewItemV4 *option, int index) const -{ - Q_D(const QtGraphicsListView); - Q_ASSERT(option); - - // Current Item - if (d->selectionManager && d->selectionManager->currentItem() == index) - option->state |= QStyle::State_HasFocus; - else - option->state &= ~QStyle::State_HasFocus; - - // selectionManager - if (d->selectionManager && d->selectionManager->isSelected(index)) - option->state |= QStyle::State_Selected; - else - option->state &= ~QStyle::State_Selected; - - // Data - QVariant value; - - // FontRole - value = d->cachedData(index, Qt::FontRole); - if (value.isValid()) { - option->font = qvariant_cast(value).resolve(option->font); - option->fontMetrics = QFontMetrics(option->font); - } - - // TextAlignmentRole - value = d->cachedData(index, Qt::TextAlignmentRole); - if (value.isValid()) - option->displayAlignment = (Qt::Alignment)value.toInt(); - - // ForegroundRole - value = d->cachedData(index, Qt::ForegroundRole); - if (qVariantCanConvert(value)) - option->palette.setBrush(QPalette::Text, qvariant_cast(value)); - - // CheckStateRole - value = d->cachedData(index, Qt::CheckStateRole); - if (value.isValid()) { - option->features |= QStyleOptionViewItemV2::HasCheckIndicator; - option->checkState = static_cast(value.toInt()); - } - - // DecorationRole - value = d->cachedData(index, Qt::DecorationRole); - if (value.isValid()) { - option->features |= QStyleOptionViewItemV2::HasDecoration; - switch (value.type()) { - case QVariant::Icon: - option->icon = qvariant_cast(value); - break; - case QVariant::Color: { - QPixmap pixmap(option->decorationSize); - pixmap.fill(qvariant_cast(value)); - option->icon = QIcon(pixmap); } - default: - break; - } - } - - // DisplayRole - value = d->cachedData(index, Qt::DisplayRole); - if (value.isValid()) { - option->features |= QStyleOptionViewItemV2::HasDisplay; - switch (value.type()) { - case QVariant::Double: - option->text = option->locale.toString(value.toDouble()); - break; - case QVariant::Int: - case QVariant::LongLong: - option->text = option->locale.toString(value.toLongLong()); - break; - case QVariant::UInt: - case QVariant::ULongLong: - option->text = option->locale.toString(value.toULongLong()); - break; - case QVariant::Date: - option->text = option->locale.toString(value.toDate(), QLocale::ShortFormat); - break; - case QVariant::Time: - option->text = option->locale.toString(value.toTime(), QLocale::ShortFormat); - break; - case QVariant::DateTime: - option->text = option->locale.toString(value.toDateTime().date(), QLocale::ShortFormat); - option->text += QLatin1Char(' '); - option->text += option->locale.toString(value.toDateTime().time(), QLocale::ShortFormat); - break; - default: { - QString text = value.toString(); - for (int i = 0; i < text.count(); ++i) - if (text.at(i).unicode() == '\n') - text[i] = QChar::LineSeparator; - option->text = text; - break; } - } - } -} - -/*! - Copies style option state information from the - given \a source to the given \a destination - */ -void QtGraphicsListView::copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *destination) -{ - if (source && destination) { - destination->state = source->state; - destination->direction = source->direction; - destination->rect = source->rect; - destination->fontMetrics = source->fontMetrics; - destination->palette = source->palette; - } -} - /*! */ /* @@ -1221,11 +1251,14 @@ bool QtGraphicsListView::event(QEvent *event) QVariant QtGraphicsListView::itemChange(GraphicsItemChange change, const QVariant &value) { Q_D(QtGraphicsListView); - if (change == QGraphicsItem::ItemChildRemovedChange) { - QGraphicsItem *item = qvariant_cast(value); - int index = d->items.indexOf(static_cast(item)); - if (index != -1) - d->items.removeAt(index); + if (change == QGraphicsObject::ItemChildRemovedChange) { + void *ptr = qvariant_cast(value); + for (int i = 0; i < d->items.count(); ++i) { + if (d->items.at(i).second == ptr) { + d->items.removeAt(i); + break; + } + } } return QGraphicsWidget::itemChange(change, value); } @@ -1255,16 +1288,15 @@ void QtGraphicsListView::setItemCreator(QtGraphicsListViewItemCreatorBase *creat Returns a view item for the given \a index if such an item exists, otherwise returns null. */ -QtGraphicsListViewItem* QtGraphicsListView::itemForIndex(int index) const +QGraphicsObject* QtGraphicsListView::itemForIndex(int index) const { Q_D(const QtGraphicsListView); if (!d->items.isEmpty()) { - const int firstIndex = d->items.first()->index(); - const int lastIndex = d->items.last()->index(); + const int firstIndex = d->items.first().first; + const int lastIndex = d->items.last().first; if (firstIndex <= index && index <= lastIndex) { - QtGraphicsListViewItem *item = d->items.at(index - firstIndex); + QGraphicsObject *item = d->items.at(index - firstIndex).second; Q_ASSERT(item); - Q_ASSERT(item->index() == index); return item; } } @@ -1282,6 +1314,14 @@ void QtGraphicsListView::itemGeometryChanged(QtGraphicsListViewItem *item) } } +/*! + */ +QVariant QtGraphicsListView::cachedData(int index, int role) const +{ + Q_D(const QtGraphicsListView); + return d->cachedData(index, role); +} + QT_END_NAMESPACE #include "moc_qgraphicslistview.cpp" diff --git a/src/qgraphicslistview.h b/src/qgraphicslistview.h index 0c14fb7..5e2d3a1 100644 --- a/src/qgraphicslistview.h +++ b/src/qgraphicslistview.h @@ -53,15 +53,18 @@ public: int index() const; void setIndex(int index); - virtual QSizeF sizeHint(Qt::SizeHint which = Qt::PreferredSize, const QSizeF &constraint = QSizeF()) const; - virtual QSizeF sizeHint(int index, const QStyleOptionViewItemV4 *option, Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + QRectF boundingRect() const; + virtual QSizeF sizeHint(Qt::SizeHint which = Qt::PreferredSize, const QSizeF &constraint = QSizeF()) const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); virtual void itemChanged(const QList &roles = QList()); + virtual void initStyleOption(QStyleOptionViewItemV4 *option) const; QHash data(const QList &roles = QList()) const; QtGraphicsListView *view() const; + void copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *dest); + protected: QtGraphicsListViewItemPrivate *d_ptr; @@ -74,16 +77,16 @@ class Q_ITEMVIEWSNG_EXPORT QtGraphicsListViewItemCreatorBase { public: virtual ~QtGraphicsListViewItemCreatorBase(); - virtual QtGraphicsListViewItem *create(int index, QtGraphicsListView *view) = 0; - virtual QtGraphicsListViewItem *reassign(int index, QtGraphicsListViewItem *item); - virtual void recycle(QtGraphicsListViewItem *item); + virtual QGraphicsObject *create(int index, QtGraphicsListView *view) = 0; + virtual QGraphicsObject *reassign(int index, QGraphicsObject *item, QtGraphicsListView *view); + virtual void recycle(QGraphicsObject *item); }; template class Q_ITEMVIEWSNG_EXPORT QtGraphicsListViewItemCreator : public QtGraphicsListViewItemCreatorBase { public: - inline QtGraphicsListViewItem *create(int index, QtGraphicsListView *view) { return new T(index, view); } + inline QGraphicsObject *create(int index, QtGraphicsListView *view) { return new T(index, view); } }; class Q_ITEMVIEWSNG_EXPORT QtGraphicsListView : public QGraphicsWidget @@ -119,13 +122,11 @@ public: virtual qreal maximumOffset() const; virtual void initStyleOption(QStyleOptionViewItemV4 *option) const; - virtual void initStyleOption(QStyleOptionViewItemV4 *option, int index) const; - void copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *dest); QtGraphicsListViewItemCreatorBase *itemCreator() const; void setItemCreator(QtGraphicsListViewItemCreatorBase *creator); - QtGraphicsListViewItem *itemForIndex(int index) const; + QGraphicsObject *itemForIndex(int index) const; //bool layoutsBlocked() const; // ### FIXME: should not be needed //void setLayoutsBlocked(bool block); @@ -153,6 +154,8 @@ protected: virtual bool event(QEvent *event); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + QVariant cachedData(int index, int role) const; + QtGraphicsListViewPrivate *d_ptr; private: diff --git a/src/qgraphicslistview_p.h b/src/qgraphicslistview_p.h index 0fe0129..3da1b02 100644 --- a/src/qgraphicslistview_p.h +++ b/src/qgraphicslistview_p.h @@ -83,7 +83,7 @@ public: // used by updateLayout void scrollItems(int firstVisibleIndex); - QSizeF itemSizeHint(const QStyleOptionViewItemV4 *option, int index, const QSizeF &constraints = QSizeF()) const; + QSizeF itemSize(int index) const; QtGraphicsListView *q_ptr; QtListController *controller; @@ -106,7 +106,7 @@ public: bool layoutsBlocked; - QList items; + QList > items; QtGraphicsListViewItemCreatorBase *creator; QBasicTimer layoutTimer; }; diff --git a/src/qlistmodelinterface.cpp b/src/qlistmodelinterface.cpp index ff1abcd..768d87e 100644 --- a/src/qlistmodelinterface.cpp +++ b/src/qlistmodelinterface.cpp @@ -84,9 +84,10 @@ bool QtListModelInterface::setData(int index, const QHash &values) /*! Returns the supported roles for this model. */ -QHash QtListModelInterface::roles() const +QHash QtListModelInterface::roles() const { return QtDataRoles::roles(); + } /*! diff --git a/src/qlistmodelinterface.h b/src/qlistmodelinterface.h index d90d37b..5d3592d 100644 --- a/src/qlistmodelinterface.h +++ b/src/qlistmodelinterface.h @@ -43,7 +43,7 @@ public: virtual int count() const = 0; virtual QHash data(int index, const QList &roles = (QList())) const = 0; virtual bool setData(int index, const QHash &values); - virtual QHash roles() const; + virtual QHash roles() const; Q_SIGNALS: void itemsInserted(int index, int count); diff --git a/src/qprinterlistview.cpp b/src/qprinterlistview.cpp deleted file mode 100644 index 689d9fb..0000000 --- a/src/qprinterlistview.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Itemviews NG project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 or 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "qprinterlistview.h" -#include "qprinterlistview_p.h" - -#ifndef QT_NO_PRINTER - -#include "qlistcontroller.h" -#include "qlistmodelinterface.h" -#include "qgraphicslistview.h" - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -QtPrinterListViewPrivate::QtPrinterListViewPrivate(QPrinter *p) - : q_ptr(0), - ownsPrinter(p == 0), - printer(ownsPrinter ? new QPrinter : p), - model(0), - orientation(Qt::Vertical), - header(0), - footer(0), - creator(0) -{ - headerFooterSpacing = 5; // in mm -} - -QtPrinterListViewPrivate::~QtPrinterListViewPrivate() -{ - delete header; - delete footer; - delete creator; - if (ownsPrinter) - delete printer; -} - -qreal QtPrinterListViewPrivate::printHeader(QPainter &painter) -{ - if (header == 0) - return 0; - header->drawContents(&painter); - return header->size().height() + headerFooterSpacingInPixels(); -} - -qreal QtPrinterListViewPrivate::printFooter(QPainter &painter) -{ - if (footer == 0) - return 0; - qreal pageHeight = printer->pageRect().height(); - const qreal footerSize = footer->size().height(); - painter.translate(0, pageHeight - footerSize); - footer->drawContents(&painter); - painter.translate(0, - (pageHeight - footerSize)); - return footerSize + headerFooterSpacingInPixels(); -} - -QTextDocument *QtPrinterListViewPrivate::getOrCreateHeader() const -{ - if (header == 0) { - header = new QTextDocument(); - header->setUndoRedoEnabled(false); - header->setDocumentMargin(0); - } - return header; -} - -QTextDocument *QtPrinterListViewPrivate::getOrCreateFooter() const -{ - if (footer == 0) { - footer = new QTextDocument(); - footer->setUndoRedoEnabled(false); - footer->setDocumentMargin(0); - } - return footer; -} - -/*! - \class QtPrinterListView - \brief QtPrinterListView allows you to print a list model. - - Usage; - \code - QtPrinterListView printerView(myListModel); - QPrintDialog dialog(printerView.printer()); - if (dialog.exec() == QPrintDialog::Accepted) { - printerView.print(); - } - \endcode -*/ - -/*! - This is an overloaded member function, provided for convenience. It - differs from the above function only in what argument(s) it accepts. This - will cause QtPrinterListView to create an internal, default constructed - QPrinter object, which will be used to print the list. -*/ -QtPrinterListView::QtPrinterListView(QtListModelInterface *model) - : d_ptr(new QtPrinterListViewPrivate(0)) -{ - Q_ASSERT(model); - d_ptr->q_ptr = this; - d_ptr->model = model; -} - -/*! - Constructs a QtPrinterListView based on printer and with \a model as the - model that will be printed -*/ -QtPrinterListView::QtPrinterListView(QPrinter *printer, QtListModelInterface *model) - : d_ptr(new QtPrinterListViewPrivate(printer)) -{ - Q_ASSERT(model); - d_ptr->q_ptr = this; - d_ptr->model = model; -} - -/*! - Destructor -*/ -QtPrinterListView::~QtPrinterListView() -{ - delete d_ptr; -} - -/*! - Returns the printer used by this view to print to to allow setting of printer properties. -*/ -QPrinter *QtPrinterListView::printer() -{ - Q_D(QtPrinterListView); - return d->printer; -} - -/*! - Sets the orientation of the list layout to be the given orientation. - The orientation defines the print direction of the list. -*/ -void QtPrinterListView::setOrientation(Qt::Orientation orientation) -{ - Q_D(QtPrinterListView); - d->orientation = orientation; -} - -/*! - Returns the orientation for this list. - The orientation defines the print direction of the list. - */ -Qt::Orientation QtPrinterListView::orientation() const -{ - Q_D(const QtPrinterListView); - return d->orientation; -} - -/*! - Returns the text document used for each page header. - \sa setHeaderText() -*/ -QTextDocument *QtPrinterListView::headerDocument() -{ - Q_D(QtPrinterListView); - return d->getOrCreateHeader(); -} - -/*! - Returns the text document used for each page footer. - \sa setFooterText() -*/ -QTextDocument *QtPrinterListView::footerDocument() -{ - Q_D(QtPrinterListView); - return d->getOrCreateFooter(); -} - -/*! - Sets the header on all pages to have the \a header text. - This replaces any content that the header had previously. - \sa headerDocument() -*/ -void QtPrinterListView::setHeaderText(const QString &header) -{ - Q_D(QtPrinterListView); - d->getOrCreateHeader()->setPlainText(header); -} - -/*! - Sets the footer on all pages to have the \a footer text. - This replaces any content that the footer had previously. - \sa footerDocument() -*/ -void QtPrinterListView::setFooterText(const QString &footer) -{ - Q_D(QtPrinterListView); - d->getOrCreateFooter()->setPlainText(footer); -} - -/*! - Return the text set as header. - \sa headerDocument() -*/ -QString QtPrinterListView::headerText() const -{ - Q_D(const QtPrinterListView); - return d->getOrCreateHeader()->toPlainText(); -} - -/*! - Return the text set as footer. - \sa headerDocument() -*/ -QString QtPrinterListView::footerText() const -{ - Q_D(const QtPrinterListView); - if (d->footer == 0) - return QString(); - return d->footer->toPlainText(); -} - -QtGraphicsListViewItemCreatorBase *QtPrinterListView::viewItemCreator() const -{ - Q_D(const QtPrinterListView); - return d->creator; -} - -/*! - note that ownership is taken. -*/ -void QtPrinterListView::setViewItemCreator(QtGraphicsListViewItemCreatorBase *creator) -{ - Q_D(QtPrinterListView); - delete d->creator; - d->creator = creator; -} - -extern int qt_defaultDpiY(); -extern int qt_defaultDpiX(); - -/*! - Start the actual printing using the printer() options. - Returns true if printing was successful, or false otherwise. -*/ -bool QtPrinterListView::print() -{ - Q_D(QtPrinterListView); - if (! d->printer->isValid()) { - qWarning() << "QtPrinterListView::print: printer not valid, please setup the printer before calling print"; - return false; - } - - // next use a view just for the filling of the options... - QtGraphicsListView view; - view.setModel(d->model); - - QPainter painter; - if (!painter.begin(d->printer)) { - qWarning() << "QtPrinterListView::print: printer fails to begin(), sorry can't print"; - return false; - } - - // re-layout the header footer to the current page size. - if (d->header) { - d->header->documentLayout()->setPaintDevice(d->printer); - d->header->setPageSize(d->printer->pageRect().size()); - } - if (d->footer) { - d->footer->documentLayout()->setPaintDevice(d->printer); - d->footer->setPageSize(d->printer->pageRect().size()); - } - - QtGraphicsListViewItem *listViewItem; - if (d->creator) - listViewItem = d->creator->create(0, &view); - else - listViewItem = view.itemCreator()->create(0, &view); - listViewItem->setCacheMode(QGraphicsItem::NoCache); - - QStyleOptionViewItemV4 widgetOptions; - QStyleOptionGraphicsItem graphicsViewOptions; - view.initStyleOption(&widgetOptions); - - const qreal headerSize = d->printHeader(painter); - const qreal footerSize = d->printFooter(painter); - const bool vertical = d->orientation == Qt::Vertical; - const qreal scaleX = d->printer->logicalDpiX() / (qreal) qt_defaultDpiX(); - const qreal scaleY = d->printer->logicalDpiY() / (qreal) qt_defaultDpiY(); - QSizeF constraint = d->printer->pageRect().size(); - // cache the space we have for actual list items. - const qreal contentSize = vertical ? constraint.height() - headerSize - footerSize : constraint.width(); - - view.resize(constraint - QSizeF(0, headerSize + footerSize)); - - // a constraint is -1 in the direction we allow items to grow in. - if (vertical) { - constraint.setHeight(-1); - } else { - constraint.setWidth(-1); - // in this direction headers/footers eat our precious space - constraint.setHeight(constraint.height() - headerSize - - footerSize); - } - - qreal progression = vertical ? headerSize : 0; // init - const int max = d->model->count(); - for (int index = 0; index < max; ++index) { - view.initStyleOption(&widgetOptions, index); - - //QSizeF itemSize = listViewItem->sizeHint(index, &widgetOptions, Qt::PreferredSize, constraint); - listViewItem->setIndex(index); - QRectF geometry = view.itemGeometry(index); - if (vertical) - geometry.setWidth(constraint.width() / scaleX); - else - geometry.setHeight(constraint.height() / scaleY - headerSize - footerSize); - listViewItem->setGeometry(geometry); - geometry = listViewItem->geometry();// the listViewItem can be stubborn - graphicsViewOptions.rect = geometry.toRect(); - if ((vertical && progression - headerSize + geometry.height() > contentSize) - || (!vertical && progression + geometry.width()> contentSize)) { - if (! d->printer->newPage()) { - qWarning() << "QtPrinterListView::print: Failed to start a new page, aborting printing"; - return false; - } - progression = vertical ? headerSize : 0; // reset - d->printHeader(painter); - d->printFooter(painter); - } - - painter.save(); - painter.translate(vertical ? 0 : progression, - vertical ? progression : headerSize); - painter.scale(scaleX, scaleY); - listViewItem->paint(&painter, &graphicsViewOptions); - painter.restore(); - progression += vertical ? geometry.height() * scaleY: geometry.width() * scaleX; - } - return true; -} - -/*! - Prints the \a model to the \a printer -*/ -//static -void QtPrinterListView::printModel(QPrinter *printer, QtListModelInterface *model, const QString &header, const QString &footer) -{ - QtPrinterListView printerView(printer, model); - if (!header.isEmpty()) - printerView.setHeaderText(header); - if (!footer.isEmpty()) - printerView.setFooterText(footer); - - printerView.print(); -} - -QT_END_NAMESPACE - -#endif diff --git a/src/qprinterlistview.h b/src/qprinterlistview.h deleted file mode 100644 index 99d0c96..0000000 --- a/src/qprinterlistview.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Itemviews NG project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 or 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ -#ifndef QTPRINTERLISTVIEW_H -#define QTPRINTERLISTVIEW_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -//QT_MODULE(Gui) - -class QtPrinterListViewPrivate; -class QtListModelInterface; -class QtGraphicsListViewItemCreatorBase; -class QTextDocument; - -class Q_ITEMVIEWSNG_EXPORT QtPrinterListView -{ -public: - QtPrinterListView(QPrinter *printer, QtListModelInterface *model); - QtPrinterListView(QtListModelInterface *model); - ~QtPrinterListView(); - - QPrinter *printer(); - bool print(); - - void setOrientation(Qt::Orientation orientation); - Qt::Orientation orientation() const; - - QTextDocument *headerDocument(); - QTextDocument *footerDocument(); - - void setHeaderText(const QString &header); - void setFooterText(const QString &footer); - QString headerText() const; - QString footerText() const; - - QtGraphicsListViewItemCreatorBase *viewItemCreator() const; - void setViewItemCreator(QtGraphicsListViewItemCreatorBase *creator); - - static void printModel(QPrinter *printer, QtListModelInterface *model, const QString &header = QString(), const QString &footer = QString()); - -protected: - QtPrinterListViewPrivate *d_ptr; - -private: - Q_DECLARE_PRIVATE(QtPrinterListView) - Q_DISABLE_COPY(QtPrinterListView) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QTPRINTERLISTVIEW_H diff --git a/src/qprinterlistview_p.h b/src/qprinterlistview_p.h deleted file mode 100644 index 31ae385..0000000 --- a/src/qprinterlistview_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Itemviews NG project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 or 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef QTPRINTERLISTVIEW_P_H -#define QTPRINTERLISTVIEW_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER -class QTextDocument; - -class QtPrinterListViewPrivate -{ - Q_DECLARE_PUBLIC(QtPrinterListView) -public: - QtPrinterListViewPrivate(QPrinter *printer); - ~QtPrinterListViewPrivate(); - - QtPrinterListView *q_ptr; - - bool ownsPrinter; - QPrinter * const printer; - QtListModelInterface *model; - - Qt::Orientation orientation; - mutable QTextDocument *header; - mutable QTextDocument *footer; - - qreal headerFooterSpacing; // in mm - - QtGraphicsListViewItemCreatorBase *creator; - - /// print a header and return the height we used - qreal printHeader(QPainter &painter); - qreal printFooter(QPainter &painter); - QTextDocument *getOrCreateHeader() const; - QTextDocument *getOrCreateFooter() const; - inline qreal headerFooterSpacingInPixels() { - return headerFooterSpacing * (printer->resolution() / 25.4); - } -}; - -#endif -QT_END_NAMESPACE - -#endif//QTPRINTERLISTVIEW_P_H diff --git a/src/qprintertableview.cpp b/src/qprintertableview.cpp deleted file mode 100644 index aa3fefb..0000000 --- a/src/qprintertableview.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Itemviews NG project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 or 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "qprintertableview.h" -#include "qprintertableview_p.h" - -#ifndef QT_NO_PRINTER - -#include "qgraphicstableview.h" -#include "qtablemodelinterface.h" -#include "qgraphicsheader.h" - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -// #define DEBUG_TABLES - -QtPrinterTableViewPrivate::QtPrinterTableViewPrivate(QPrinter *p) - : q_ptr(0), - ownsPrinter(p == 0), - printer(ownsPrinter ? new QPrinter : p), - model(0), - orientation(Qt::Vertical), - header(0), - footer(0) -{ - headerFooterSpacing = 5; // in mm -} - -QtPrinterTableViewPrivate::~QtPrinterTableViewPrivate() -{ - delete header; - delete footer; - if (ownsPrinter) - delete printer; -} - -qreal QtPrinterTableViewPrivate::printHeader(QPainter &painter) -{ - if (header == 0) - return 0; - header->drawContents(&painter); - return header->size().height() + headerFooterSpacingInPixels(); -} - -qreal QtPrinterTableViewPrivate::printFooter(QPainter &painter) -{ - if (footer == 0) - return 0; - qreal pageHeight = printer->pageRect().height(); - const qreal footerSize = footer->size().height(); - painter.translate(0, pageHeight - footerSize); - footer->drawContents(&painter); - painter.translate(0, - (pageHeight - footerSize)); - return footerSize + headerFooterSpacingInPixels(); -} - -QTextDocument *QtPrinterTableViewPrivate::getOrCreateHeader() const -{ - if (header == 0) { - header = new QTextDocument(); - header->setUndoRedoEnabled(false); - header->setDocumentMargin(0); - } - return header; -} - -QTextDocument *QtPrinterTableViewPrivate::getOrCreateFooter() const -{ - if (footer == 0) { - footer = new QTextDocument(); - footer->setUndoRedoEnabled(false); - footer->setDocumentMargin(0); - } - return footer; -} - -/*! - \class QtPrinterTableView - \brief QtPrinterTableView allows you to print a table model. -*/ - -QtPrinterTableView::QtPrinterTableView(QtTableModelInterface *model, QtGraphicsHeader *verticalHeader, QtGraphicsHeader *horizontalHeader) - : d_ptr(new QtPrinterTableViewPrivate(0)) -{ - Q_ASSERT(model); - d_ptr->q_ptr = this; - d_ptr->model = model; - d_ptr->horizontalHeader = horizontalHeader; - d_ptr->verticalHeader = verticalHeader; -} - -QtPrinterTableView::QtPrinterTableView(QPrinter *printer, QtTableModelInterface *model, QtGraphicsHeader *verticalHeader, QtGraphicsHeader *horizontalHeader) - : d_ptr(new QtPrinterTableViewPrivate(printer)) -{ - Q_ASSERT(model); - d_ptr->q_ptr = this; - d_ptr->model = model; - d_ptr->horizontalHeader = horizontalHeader; - d_ptr->verticalHeader = verticalHeader; -} - -QtPrinterTableView::~QtPrinterTableView() -{ - delete d_ptr; -} - -QPrinter *QtPrinterTableView::printer() -{ - Q_D(QtPrinterTableView); - return d->printer; -} - -void QtPrinterTableView::setOrientation(Qt::Orientation orientation) -{ - Q_D(QtPrinterTableView); - d->orientation = orientation; -} - -Qt::Orientation QtPrinterTableView::orientation() const -{ - Q_D(const QtPrinterTableView); - return d->orientation; -} - -QTextDocument *QtPrinterTableView::headerDocument() -{ - Q_D(QtPrinterTableView); - return d->getOrCreateHeader(); -} - -QTextDocument *QtPrinterTableView::footerDocument() -{ - Q_D(QtPrinterTableView); - return d->getOrCreateFooter(); -} - -void QtPrinterTableView::setHeaderText(const QString &header) -{ - Q_D(QtPrinterTableView); - d->getOrCreateHeader()->setPlainText(header); -} - -void QtPrinterTableView::setFooterText(const QString &footer) -{ - Q_D(QtPrinterTableView); - d->getOrCreateFooter()->setPlainText(footer); -} - -QString QtPrinterTableView::headerText() const -{ - Q_D(const QtPrinterTableView); - return d->getOrCreateHeader()->toPlainText(); -} - -QString QtPrinterTableView::footerText() const -{ - Q_D(const QtPrinterTableView); - if (d->footer == 0) - return QString(); - return d->footer->toPlainText(); -} - -extern int qt_defaultDpiY(); -extern int qt_defaultDpiX(); - -bool QtPrinterTableView::print() -{ - Q_D(QtPrinterTableView); - if (! d->printer->isValid()) { - qWarning() << "QtPrinterTableView::print: printer not valid, please setup the printer before calling print"; - return false; - } - - // next use a view just for the filling of the options... - QGraphicsScene scene; - QtGraphicsTableView view; - scene.addItem(&view); - view.setModel(d->model); - - - class QTableHeaderDataProvider2 : public QtGraphicsHeaderDataProvider - { - public: - QTableHeaderDataProvider2(QtTableModelInterface *model_) : model(model_) {} - QHash data(int logicalIndex, const QList &roles) const - { - // ### call the model - temporary implementation - QHash hash; - for (int i = 0; i < roles.count(); ++i) - if (roles.at(i) == Qt::DisplayRole) - hash.insert(Qt::DisplayRole, logicalIndex + 1); - return hash; - } - QtTableModelInterface *model; - }; - - if (d->horizontalHeader) { - QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Horizontal, &view); - header->setDataProvider(new QTableHeaderDataProvider2(d->model)); - header->copySections(*d->horizontalHeader); - view.setHorizontalHeader(header); - } - if (d->verticalHeader) { - QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Vertical, &view); - header->setDataProvider(new QTableHeaderDataProvider2(d->model)); - header->copySections(*d->verticalHeader); - view.setVerticalHeader(header); - } - - QPainter painter; - if (!painter.begin(d->printer)) { - qWarning() << "QtPrinterTableView::print: printer fails to begin(), sorry can't print"; - return false; - } - - // re-layout the header footer to the current page size. - if (d->header) { - d->header->documentLayout()->setPaintDevice(d->printer); - d->header->setPageSize(d->printer->pageRect().size()); - } - if (d->footer) { - d->footer->documentLayout()->setPaintDevice(d->printer); - d->footer->setPageSize(d->printer->pageRect().size()); - } - - const qreal headerSize = d->printHeader(painter); - const qreal footerSize = d->printFooter(painter); - const bool vertical = d->orientation == Qt::Vertical; - const qreal scaleX = d->printer->logicalDpiX() / (qreal) qt_defaultDpiX(); - const qreal scaleY = d->printer->logicalDpiY() / (qreal) qt_defaultDpiY(); - painter.scale(scaleX, scaleY); - - const QRect rect = d->printer->pageRect(); - QSizeF visibleSize(rect.width() / scaleX, rect.height() / scaleY); - if (vertical) - visibleSize = QSizeF(visibleSize.width(), visibleSize.height() - headerSize - footerSize); - else // then rotate it. - visibleSize = QSizeF(visibleSize.height() - headerSize - footerSize, visibleSize.width()); - - view.setGeometry(0, 0, visibleSize.width(), visibleSize.height()); - view.setHorizontalOffset(0); - - int row = 0; - int column; - bool first = true; - qreal offsetInColumn = 0; // for those columns too wide and thus split over more than one page - while (row < d->model->rowCount()) { - column = 0; - view.setFirstRow(row); - qreal height = visibleSize.height(); - while (true) { - const qreal rowHeight = view.rowHeight(row); - if (height - rowHeight < 0) - break; - if (row >= d->model->rowCount()) - break; - ++row; - height -= rowHeight; - } - while (column < d->model->columnCount()) { - if (!first) { - d->printer->newPage(); - d->printHeader(painter); - d->printFooter(painter); - } - first = false; - view.setFirstColumn(column); - view.setHorizontalOffset(offsetInColumn); - - qreal width = visibleSize.width(); - while (true) { - const qreal columnWidth = view.columnWidth(column); - if (width == visibleSize.width() && columnWidth - offsetInColumn > visibleSize.width()) { - // the column doesn't fit on a page. Lets split it. - offsetInColumn += visibleSize.width(); - width = 0; - break; - } else if (offsetInColumn > 0) { // we still have a part of a split column to print! - width -= columnWidth - offsetInColumn; - offsetInColumn = 0; - ++column; - continue; - } - - if (width - columnWidth + offsetInColumn < 0) - break; - if (column >= d->model->columnCount()) - break; - ++column; - width -= columnWidth; - } - view.doLayout(); - - painter.save(); // for each page - painter.translate(0, headerSize); - if (!vertical) { - painter.translate(0, visibleSize.width()); - painter.rotate(-90); - } -#ifdef DEBUG_TABLES - painter.setPen(QPen(QColor(Qt::green))); - painter.drawRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); -#endif - painter.setClipRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); - // find and paint children which are the cells - QList items = scene.items(view.rect()); - QList::Iterator iter = items.begin(); - for (;iter != items.end(); ++iter) { - QGraphicsItem *parent = *iter; - while (parent != &view && parent != 0) // only draw children of our view - parent = parent->parentItem(); - if (parent == 0) - continue; - if (!(*iter)->isVisible()) - continue; - painter.save(); - painter.translate((*iter)->mapToItem(&view, QPointF())); -#ifdef DEBUG_TABLES - QGraphicsWidget *w = dynamic_cast(*iter); - if (w) { - painter.save(); - painter.setPen(QPen(QColor(Qt::red))); - painter.drawRect(QRectF(QPointF(), w->size())); - painter.restore(); - } -#endif - (*iter)->paint(&painter, 0); - painter.restore(); - } - painter.restore(); // for each page - } - } - return true; -} - -QT_END_NAMESPACE - -#endif diff --git a/src/qprintertableview.h b/src/qprintertableview.h deleted file mode 100644 index be08ca6..0000000 --- a/src/qprintertableview.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Itemviews NG project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 or 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ -#ifndef QTPRINTERTABLEVIEW_H -#define QTPRINTERLTABLEIEW_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -//QT_MODULE(Gui) - -class QtPrinterTableViewPrivate; -class QtTableModelInterface; -class QtGraphicsHeader; -class QTextDocument; - -class Q_ITEMVIEWSNG_EXPORT QtPrinterTableView -{ -public: - explicit QtPrinterTableView(QPrinter *printer, QtTableModelInterface *model, QtGraphicsHeader *verticalHeader = 0, QtGraphicsHeader *horizontalHeader = 0); - explicit QtPrinterTableView(QtTableModelInterface *model, QtGraphicsHeader *verticalHeader = 0, QtGraphicsHeader *horizontalHeader = 0); - ~QtPrinterTableView(); - - QPrinter *printer(); - bool print(); - - void setOrientation(Qt::Orientation orientation); - Qt::Orientation orientation() const; - - QTextDocument *headerDocument(); - QTextDocument *footerDocument(); - - void setHeaderText(const QString &header); - void setFooterText(const QString &footer); - QString headerText() const; - QString footerText() const; - - // TODO add the setter of the creator object, add static print object - -protected: - QtPrinterTableViewPrivate *d_ptr; - -private: - Q_DECLARE_PRIVATE(QtPrinterTableView) - Q_DISABLE_COPY(QtPrinterTableView) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QTPRINTERTABLEVIEW_H diff --git a/src/qprintertableview_p.h b/src/qprintertableview_p.h deleted file mode 100644 index f2927c2..0000000 --- a/src/qprintertableview_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the Itemviews NG project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 or 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef QTPRINTERTABLEVIEW_P_H -#define QTPRINTERTABLEVIEW_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER -class QTextDocument; - -class QtPrinterTableViewPrivate -{ - Q_DECLARE_PUBLIC(QtPrinterTableView) -public: - QtPrinterTableViewPrivate(QPrinter *printer); - ~QtPrinterTableViewPrivate(); - - QtPrinterTableView *q_ptr; - - bool ownsPrinter; - QPrinter * const printer; - QtTableModelInterface *model; - QtGraphicsHeader *horizontalHeader; - QtGraphicsHeader *verticalHeader; - - Qt::Orientation orientation; - mutable QTextDocument *header; - mutable QTextDocument *footer; - - qreal headerFooterSpacing; // in mm - - /// print a header and return the height we used - qreal printHeader(QPainter &painter); - qreal printFooter(QPainter &painter); - QTextDocument *getOrCreateHeader() const; - QTextDocument *getOrCreateFooter() const; - inline qreal headerFooterSpacingInPixels() { - return headerFooterSpacing * (printer->resolution() / 25.4); - } -}; - -#endif -QT_END_NAMESPACE - -#endif//QTPRINTERTABLEVIEW_P_H diff --git a/src/qtablemodelinterface.cpp b/src/qtablemodelinterface.cpp index bce124b..ccdcfbc 100644 --- a/src/qtablemodelinterface.cpp +++ b/src/qtablemodelinterface.cpp @@ -63,7 +63,7 @@ bool QtTableModelInterface::setData(int row, int column, const QHash QtTableModelInterface::roles() const +QHash QtTableModelInterface::roles() const { return QtDataRoles::roles(); } diff --git a/src/qtablemodelinterface.h b/src/qtablemodelinterface.h index 78f6dad..780c1ae 100644 --- a/src/qtablemodelinterface.h +++ b/src/qtablemodelinterface.h @@ -44,7 +44,7 @@ public: virtual int columnCount() const = 0; virtual QHash data(int row, int column, const QList &roles = QList()) const = 0; virtual bool setData(int row, int column, const QHash &values); - virtual QHash roles() const; + virtual QHash roles() const; // ### we may need something along the lines of cacheHint() that gives the model an idea // ### of what can be kept, what can be thrown away and what needs to be fetched diff --git a/src/src.pro b/src/src.pro index f371479..f089a44 100644 --- a/src/src.pro +++ b/src/src.pro @@ -19,10 +19,6 @@ HEADERS += qgraphicsscrollbar.h \ qlistselectionmanager_p.h \ qlistwidgetng.h \ qlistwidgetng_p.h \ - qprinterlistview.h \ - qprinterlistview_p.h \ - qprintertableview.h \ - qprintertableview_p.h \ qsectionspans_p.h \ qtablecontroller.h \ qtablecontroller_p.h \ @@ -51,13 +47,17 @@ HEADERS += qgraphicsscrollbar.h \ qtreewidgetng_p.h \ qdataroles_p.h \ # experimental/qlistiteminterface.h \ - experimental/qgraphicsflowview.h \ + # experimental/qgraphicsflowview.h \ experimental/qgraphicspathview.h \ experimental/qgraphicsgridview.h \ experimental/qkineticlistcontroller.h \ experimental/qkineticlistcontroller_p.h \ experimental/qgraphicsscrollarea.h \ experimental/qgraphicsscrollarea_p.h \ + # experimental/qprinterlistview.h \ + # experimental/qprinterlistview_p.h \ + # experimental/qprintertableview.h \ + # experimental/qprintertableview_p.h \ SOURCES += qgraphicsscrollbar.cpp \ qgraphicsheader.cpp \ @@ -69,8 +69,6 @@ SOURCES += qgraphicsscrollbar.cpp \ qlistfromtreeadaptor.cpp \ qlistselectionmanager.cpp \ qlistwidgetng.cpp \ - qprinterlistview.cpp \ - qprintertableview.cpp \ qtablecontroller.cpp \ qgraphicstableview.cpp \ qtabledefaultmodel.cpp \ @@ -85,11 +83,13 @@ SOURCES += qgraphicsscrollbar.cpp \ qtreeselectionmanager.cpp \ qtreewidgetng.cpp \ # experimental/qlistiteminterface.cpp \ - experimental/qgraphicsflowview.cpp \ + # experimental/qgraphicsflowview.cpp \ experimental/qgraphicspathview.cpp \ experimental/qgraphicsgridview.cpp \ experimental/qkineticlistcontroller.cpp \ experimental/qgraphicsscrollarea.cpp \ + # experimental/qprinterlistview.cpp \ + # experimental/qprintertableview.cpp \ win32 { DEFINES += Q_ITEMVIEWSNG_EXPORT=__declspec(dllexport) -- cgit v1.2.3