File indexing completed on 2024-04-28 05:44:49

0001 /***************************************************************************
0002  *   Copyright (C) 2010-2011 by Daniel Nicoletti                           *
0003  *   dantti12@gmail.com                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; see the file COPYING. If not, write to       *
0017  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0018  *   Boston, MA 02110-1301, USA.                                           *
0019  ***************************************************************************/
0020 
0021 #include "CheckableHeader.h"
0022 
0023 #include <QPainter>
0024 #include <QApplication>
0025 #include <QMouseEvent>
0026 
0027 #include <QLoggingCategory>
0028 
0029 #define UNIVERSAL_PADDING 3
0030 
0031 CheckableHeader::CheckableHeader(Qt::Orientation orientation, QWidget *parent)
0032  : QHeaderView(orientation, parent),
0033    m_state(Qt::Unchecked),
0034    m_visible(true)
0035 {
0036 }
0037 
0038 void CheckableHeader::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
0039 {
0040     const QStyle *style = QApplication::style();
0041     painter->save();
0042     QHeaderView::paintSection(painter, rect, logicalIndex);
0043     painter->restore();
0044 
0045     if (logicalIndex == 0 && m_visible) {
0046         QStyleOptionButton option;
0047         option.state = QStyle::State_None;
0048         option.rect = rect;
0049         if (QApplication::isRightToLeft()) {
0050             option.rect.setRight(rect.right() - UNIVERSAL_PADDING);
0051         } else {
0052             option.rect.setLeft(rect.left() + UNIVERSAL_PADDING);
0053         }
0054         option.rect.setLeft(rect.left() + UNIVERSAL_PADDING);
0055         switch (m_state) {
0056         case Qt::Unchecked :
0057             option.state |= QStyle::State_Off;
0058             break;
0059         case Qt::PartiallyChecked :
0060             option.state |= QStyle::State_NoChange;
0061             break;
0062         case Qt::Checked :
0063             option.state |= QStyle::State_On;
0064             break;
0065         }
0066 
0067         // Get the cursor position to check if it has focus
0068         QPoint pos = mapFromGlobal(QCursor::pos());
0069         QRect rect = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
0070 
0071         if (insideCheckBox(rect, pos)) {
0072             option.state |= QStyle::State_HasFocus;
0073         }
0074 
0075         // draw item data as CheckBox
0076         painter->save();
0077         style->drawControl(QStyle::CE_CheckBox, &option, painter);
0078         painter->restore();
0079     }
0080 }
0081 
0082 bool CheckableHeader::insideCheckBox(const QRect &rect, const QPoint &pos) const
0083 {
0084 //     kDebug() << rect << pos;
0085     if ((pos.x() >= rect.x() && (pos.x() <= rect.x() + rect.width())) &&
0086         (pos.y() >= rect.y() && (pos.y() <= rect.y() + rect.height()))) {
0087         return true;
0088     }
0089     return false;
0090 }
0091 
0092 QSize CheckableHeader::sizeHint() const
0093 {
0094     const QStyle *style = QApplication::style();
0095     QStyleOptionButton option;
0096     QRect rect = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
0097 
0098     QSize size = QHeaderView::sizeHint();
0099 //     kDebug() << size << rect;
0100     if (size.height() < (rect.height() + 2 * UNIVERSAL_PADDING)) {
0101         size.setHeight(rect.height() + 2 * UNIVERSAL_PADDING);
0102     }
0103 
0104     return size;
0105 }
0106 
0107 QSize CheckableHeader::sectionSizeFromContents(int logicalIndex) const
0108 {
0109     QSize size = QHeaderView::sectionSizeFromContents(logicalIndex);
0110     if (logicalIndex == 0) {      
0111         const QStyle *style = QApplication::style();
0112         QStyleOptionButton option;
0113         QRect rect = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
0114         
0115         QString text = model()->headerData(0, Qt::Horizontal).toString();
0116         QFontMetrics metric = QFontMetrics(QFont());
0117         int textSize = metric.width(text);
0118         
0119         int minimunSize = textSize + 2 * (rect.width() + 2 * (UNIVERSAL_PADDING + 1));
0120         if (size.width() < minimunSize) {
0121             size.setWidth(minimunSize);
0122         }
0123     }
0124     return size;
0125 }
0126 
0127 void CheckableHeader::mouseMoveEvent(QMouseEvent *event)
0128 {
0129     headerDataChanged(Qt::Horizontal, 0, 0);
0130     QHeaderView::mouseMoveEvent(event);
0131 }
0132 
0133 void CheckableHeader::leaveEvent(QEvent *event)
0134 {
0135     headerDataChanged(Qt::Horizontal, 0, 0);
0136     QHeaderView::leaveEvent(event);
0137 //     kDebug();
0138 }
0139 
0140 void CheckableHeader::mousePressEvent(QMouseEvent *event)
0141 {
0142     if (!m_visible) {
0143         return;
0144     }
0145 
0146     const QStyle *style = QApplication::style();
0147     QStyleOptionButton option;
0148     option.rect.setSize(sizeHint());
0149     option.rect.setWidth(viewport()->width());
0150     QRect rect = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
0151     QPoint pos = mapFromGlobal(QCursor::pos());
0152 //     kDebug() << rect << pos;
0153 
0154     if (insideCheckBox(rect, pos)) {
0155         if (m_state == Qt::Checked) {
0156             m_state = Qt::Unchecked;
0157         } else {
0158             m_state = Qt::Checked;
0159         }
0160         emit toggled(m_state);
0161         headerDataChanged(Qt::Horizontal, 0, 0);
0162     } else {
0163         QHeaderView::mousePressEvent(event);
0164     }
0165 }
0166 
0167 void CheckableHeader::setCheckState(Qt::CheckState state)
0168 {
0169     m_state = state;
0170 }
0171 
0172 void CheckableHeader::setCheckBoxVisible(bool visible)
0173 {
0174     m_visible = visible;
0175     headerDataChanged(Qt::Horizontal, 0, 0);
0176 }
0177 
0178 #include "moc_CheckableHeader.cpp"