File indexing completed on 2024-04-21 04:50:16

0001 /*
0002     SPDX-FileCopyrightText: 2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
0004     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "k3bviewcolumnadjuster.h"
0009 
0010 #include <QAbstractItemModel>
0011 #include <QDebug>
0012 #include <QEvent>
0013 #include <QHash>
0014 #include <QList>
0015 #include <QSet>
0016 #include <QTreeView>
0017 #include <QHeaderView>
0018 
0019 
0020 class K3b::ViewColumnAdjuster::Private
0021 {
0022 public:
0023     Private( ViewColumnAdjuster* parent )
0024         : view( 0 ),
0025           q( parent ) {
0026     }
0027 
0028     int columnSizeHint( int col );
0029 
0030     void _k_adjustColumns();
0031 
0032     QTreeView* view;
0033     QSet<int> fixedColumns;
0034     QHash<int, int> margins;
0035 
0036 private:
0037     ViewColumnAdjuster* q;
0038 };
0039 
0040 
0041 void K3b::ViewColumnAdjuster::Private::_k_adjustColumns()
0042 {
0043     if ( q->receivers( SIGNAL(columnsNeedAjusting()) ) ) {
0044         emit q->columnsNeedAjusting();
0045     }
0046     else {
0047         q->adjustColumns();
0048     }
0049 }
0050 
0051 
0052 int K3b::ViewColumnAdjuster::Private::columnSizeHint( int col )
0053 {
0054     int w = static_cast<QAbstractItemView*>( view )->sizeHintForColumn( col );
0055     QModelIndex firstRow = view->model()->index( 0, col );
0056     if ( firstRow.isValid() && firstRow.flags().testFlag( Qt::ItemIsUserCheckable ) ) {
0057         w += 10; // HACK
0058     }
0059     if ( !view->header()->isHidden() ) {
0060         w = qMax( w, view->header()->sectionSizeHint( col ) );
0061     }
0062     return w;
0063 }
0064 
0065 
0066 K3b::ViewColumnAdjuster::ViewColumnAdjuster( QObject* parent )
0067     : QObject( parent ),
0068       d( new Private(this) )
0069 {
0070 }
0071 
0072 
0073 K3b::ViewColumnAdjuster::ViewColumnAdjuster( QTreeView* parent )
0074     : QObject( parent ),
0075       d( new Private(this) )
0076 {
0077     setView( parent );
0078 }
0079 
0080 
0081 K3b::ViewColumnAdjuster::~ViewColumnAdjuster()
0082 {
0083     delete d;
0084 }
0085 
0086 
0087 void K3b::ViewColumnAdjuster::setView( QTreeView* view )
0088 {
0089     if ( d->view != view ) {
0090         if ( d->view ) {
0091             d->view->removeEventFilter( this );
0092             d->view->model()->disconnect( this );
0093         }
0094         d->view = view;
0095         if ( d->view ) {
0096             d->view->header()->setSectionResizeMode( QHeaderView::Fixed );
0097             d->view->installEventFilter( this );
0098             connect( d->view->model(), SIGNAL(modelReset()), SLOT(_k_adjustColumns()) );
0099             connect( d->view->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(_k_adjustColumns()) );
0100             connect( d->view->model(), SIGNAL(headerDataChanged(Qt::Orientation,int,int)), SLOT(_k_adjustColumns()) );
0101             connect( d->view->model(), SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(_k_adjustColumns()) );
0102             connect( d->view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(_k_adjustColumns()) );
0103             connect( d->view->model(), SIGNAL(columnsInserted(QModelIndex,int,int)), SLOT(_k_adjustColumns()) );
0104             connect( d->view->model(), SIGNAL(columnsRemoved(QModelIndex,int,int)), SLOT(_k_adjustColumns()) );
0105             d->view->header()->setSectionResizeMode( QHeaderView::Interactive );
0106         }
0107     }
0108 }
0109 
0110 
0111 void K3b::ViewColumnAdjuster::addFixedColumn( int col )
0112 {
0113     d->fixedColumns << col;
0114 }
0115 
0116 
0117 void K3b::ViewColumnAdjuster::setColumnMargin( int col, int margin )
0118 {
0119     d->margins[col] = margin;
0120 }
0121 
0122 
0123 int K3b::ViewColumnAdjuster::columnMargin( int column ) const
0124 {
0125     if ( d->margins.contains( column ) ) {
0126         return d->margins[column];
0127     }
0128     else {
0129         return 0;
0130     }
0131 }
0132 
0133 
0134 bool K3b::ViewColumnAdjuster::eventFilter(QObject* watched, QEvent* event)
0135 {
0136     if (watched == d->view) {
0137         if (event->type() == QEvent::Resize || event->type() == QEvent::UpdateLater) {
0138             d->_k_adjustColumns();
0139         }
0140     }
0141 
0142     // we never "eat" an event
0143     return false;
0144 }
0145 
0146 
0147 int K3b::ViewColumnAdjuster::columnSizeHint( int col ) const
0148 {
0149     return d->columnSizeHint( col );
0150 }
0151 
0152 
0153 void K3b::ViewColumnAdjuster::adjustColumns()
0154 {
0155     // fixed sizes
0156     int x = 0;
0157     QList<int> otherCols;
0158     for ( int i = 0; i < d->view->model()->columnCount( d->view->rootIndex() ); ++i ) {
0159         if ( d->fixedColumns.contains( i ) ) {
0160             int w = d->columnSizeHint( i ) + columnMargin( i );
0161             d->view->setColumnWidth( i, w );
0162             x += w;
0163         }
0164         else {
0165             otherCols << i;
0166         }
0167     }
0168 
0169     if ( otherCols.count() ) {
0170         QList<int> otherColSizes;
0171         int xx = 0;
0172         int widthLeft = d->view->viewport()->contentsRect().width() - x;
0173         int max = widthLeft / otherCols.count();
0174         for ( int i = 0; i < otherCols.count(); ++i ) {
0175             int sh = d->columnSizeHint( otherCols[i] ) + columnMargin( otherCols[i] );
0176             otherColSizes << qMin( sh, max );
0177             xx += qMin( sh, max );
0178         }
0179 
0180         // do we have something left
0181         for ( int i = 0; i < otherCols.count(); ++i ) {
0182             d->view->setColumnWidth( otherCols[i], qMax( 0, otherColSizes[i] + ( widthLeft-xx )/otherColSizes.count() ) );
0183         }
0184     }
0185 }
0186 
0187 #include "moc_k3bviewcolumnadjuster.cpp"