File indexing completed on 2024-05-19 03:49:40

0001 /*
0002     File                 : SpreadsheetHeaderView.cpp
0003     Project              : LabPlot
0004     Description          : Horizontal header for SpreadsheetView displaying comments in a second header
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2016 Alexander Semke <alexander.semke@web.de>
0007     SPDX-FileCopyrightText: 2007 Tilman Benkert <thzs@gmx.net>
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "SpreadsheetHeaderView.h"
0012 #include "SpreadsheetCommentsHeaderModel.h"
0013 #include "backend/lib/macros.h"
0014 
0015 /*!
0016  \class SpreadsheetCommentsHeaderView
0017  \brief Slave header for SpreadsheetDoubleHeaderView
0018 
0019  This class is only to be used by SpreadsheetDoubleHeaderView.
0020  It allows for displaying two horizontal headers in a SpreadsheetView.
0021  A SpreadsheetCommentsHeaderView displays the column comments
0022  in a second header below the normal header. It is completely
0023  controlled by a SpreadsheetDoubleHeaderView object and thus has
0024  a master-slave relationship to it. This would be an inner class
0025  of SpreadsheetDoubleHeaderView if Qt allowed this.
0026 
0027  \ingroup commonfrontend
0028 */
0029 
0030 SpreadsheetCommentsHeaderView::SpreadsheetCommentsHeaderView(QWidget* parent)
0031     : QHeaderView(Qt::Horizontal, parent) {
0032 }
0033 
0034 SpreadsheetCommentsHeaderView::~SpreadsheetCommentsHeaderView() {
0035     delete model();
0036 }
0037 
0038 void SpreadsheetCommentsHeaderView::setModel(QAbstractItemModel* model) {
0039     Q_ASSERT(model->inherits("SpreadsheetModel"));
0040     delete QHeaderView::model();
0041     auto* new_model = new SpreadsheetCommentsHeaderModel(static_cast<SpreadsheetModel*>(model));
0042     QHeaderView::setModel(new_model);
0043 }
0044 
0045 /*!
0046  \class SpreadsheetDoubleHeaderView
0047  \brief Horizontal header for SpreadsheetView displaying comments in a second header
0048 
0049  This class is only to be used by SpreadsheetView.
0050  It allows for displaying two horizontal headers.
0051  A \c SpreadsheetDoubleHeaderView displays the column name, plot designation, and
0052  type icon in a normal QHeaderView and below that a second header
0053  which displays the column comments.
0054 
0055  \sa SpreadsheetCommentsHeaderView
0056  \sa QHeaderView
0057 
0058  \ingroup commonfrontend
0059 */
0060 SpreadsheetHeaderView::SpreadsheetHeaderView(QWidget* parent)
0061     : QHeaderView(Qt::Horizontal, parent) {
0062     setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
0063     m_slave = new SpreadsheetCommentsHeaderView();
0064     m_slave->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
0065     m_showComments = true;
0066 }
0067 
0068 SpreadsheetHeaderView::~SpreadsheetHeaderView() {
0069     delete m_slave;
0070 }
0071 
0072 QSize SpreadsheetHeaderView::sizeHint() const {
0073     QSize master_size = QHeaderView::sizeHint();
0074     if (m_showComments)
0075         master_size.setHeight(master_size.height() + m_slave->sizeHint().height());
0076     else
0077         master_size.setHeight(master_size.height());
0078 
0079     return master_size;
0080 }
0081 
0082 void SpreadsheetHeaderView::setModel(QAbstractItemModel* model) {
0083     Q_ASSERT(model->inherits("SpreadsheetModel"));
0084     m_slave->setModel(model);
0085     QHeaderView::setModel(model);
0086     connect(model, &QAbstractItemModel::headerDataChanged, this, &SpreadsheetHeaderView::headerDataChanged);
0087 }
0088 
0089 void SpreadsheetHeaderView::paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const {
0090     QRect master_rect = rect;
0091     if (m_showComments)
0092         master_rect = rect.adjusted(0, 0, 0, -m_slave->sizeHint().height());
0093 
0094     QHeaderView::paintSection(painter, master_rect, logicalIndex);
0095     if (m_showComments && rect.height() > QHeaderView::sizeHint().height()) {
0096         QRect slave_rect = rect.adjusted(0, QHeaderView::sizeHint().height(), 0, 0);
0097         m_slave->paintSection(painter, slave_rect, logicalIndex);
0098     }
0099 }
0100 
0101 /*!
0102   Returns whether comments are shown currently or not.
0103 */
0104 bool SpreadsheetHeaderView::areCommentsShown() const {
0105     return m_showComments;
0106 }
0107 
0108 /*!
0109   Show or hide (if \c on = \c false) the column comments.
0110 */
0111 void SpreadsheetHeaderView::showComments(bool on) {
0112     m_showComments = on;
0113     refresh();
0114 }
0115 
0116 /*!
0117   adjust geometry and repaint header .
0118 */
0119 void SpreadsheetHeaderView::refresh() {
0120     // TODO
0121     //  adjust geometry and repaint header (still looking for a more elegant solution)
0122     int width = sectionSize(count() - 1);
0123     m_slave->setStretchLastSection(true); // ugly hack (flaw in Qt? Does anyone know a better way?)
0124     m_slave->updateGeometry();
0125     m_slave->setStretchLastSection(false); // ugly hack part 2
0126     setStretchLastSection(true); // ugly hack (flaw in Qt? Does anyone know a better way?)
0127     updateGeometry();
0128     setStretchLastSection(false); // ugly hack part 2
0129     resizeSection(count() - 1, width);
0130 
0131     update();
0132 }
0133 
0134 /*!
0135   Reacts to a header data change.
0136 */
0137 void SpreadsheetHeaderView::headerDataChanged(Qt::Orientation orientation, int /*logicalFirst*/, int logicalLast) {
0138     if (logicalLast < 0)
0139         return;
0140     if (orientation == Qt::Horizontal)
0141         refresh();
0142 }