File indexing completed on 2024-06-16 07:42:27

0001 /*
0002     SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
0003     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 
0009 
0010 #include "k3bmsfedit.h"
0011 #include "k3bglobals.h"
0012 
0013 #include <QStringList>
0014 #include <QFontMetrics>
0015 #include <QApplication>
0016 #include <QLineEdit>
0017 #include <QStyle>
0018 #include <QStyleOptionSpinBox>
0019 
0020 #include <cmath>
0021 
0022 class K3b::MsfEdit::Private
0023 {
0024 public:
0025     void _k_editingFinished();
0026     QString stringValue() const;
0027 
0028     Msf value;
0029     Msf minimum;
0030     Msf maximum;
0031     MsfEdit* q;
0032     
0033     QSize cachedSizeHint;
0034     int minutesWidth;
0035 };
0036 
0037 
0038 void K3b::MsfEdit::Private::_k_editingFinished()
0039 {
0040     q->setValue( Msf::fromString( q->lineEdit()->text() ) );
0041 }
0042 
0043 
0044 QString K3b::MsfEdit::Private::stringValue() const
0045 {
0046     return QString( "%1:%2:%3" )
0047         .arg( QString::number( value.minutes() ).rightJustified( minutesWidth, QLatin1Char( '0' ) ) )
0048         .arg( QString::number( value.seconds() ).rightJustified( 2, QLatin1Char( '0' ) ) )
0049         .arg( QString::number( value.frames() ).rightJustified( 2, QLatin1Char( '0' ) ) );
0050 }
0051 
0052 
0053 K3b::MsfEdit::MsfEdit( QWidget* parent )
0054     : QAbstractSpinBox( parent ),
0055       d( new Private() )
0056 {
0057     d->q = this;
0058 
0059     // some very high value (10000 minutes)
0060     setMaximum( 10000*60*75 );
0061 
0062     lineEdit()->setText( d->stringValue() );
0063 
0064     connect( this, SIGNAL(editingFinished()),
0065              this, SLOT(_k_editingFinished()) );
0066 }
0067 
0068 
0069 K3b::MsfEdit::~MsfEdit()
0070 {
0071     delete d;
0072 }
0073 
0074 
0075 void K3b::MsfEdit::stepBy( int steps )
0076 {
0077     // look if we are currently editing minutes or seconds
0078     QString text = lineEdit()->text();
0079     const int pos = lineEdit()->cursorPosition();
0080     text = text.mid( pos );
0081     int num = text.count( ':' );
0082     
0083     Msf newValue = d->value;
0084     if( num == 1 ) {
0085         newValue.addSeconds( steps );
0086     }
0087     else if( num == 2 ) {
0088         newValue.addMinutes( steps );
0089     }
0090     else {
0091         newValue.addFrames( steps );
0092     }
0093     
0094     setValue( newValue );
0095     lineEdit()->setCursorPosition( pos );
0096 }
0097 
0098 
0099 QSize K3b::MsfEdit::sizeHint() const
0100 {
0101     if (d->cachedSizeHint.isEmpty()) {
0102         ensurePolished();
0103 
0104         const QFontMetrics fm(fontMetrics());
0105         int h = lineEdit()->sizeHint().height();
0106         int w = fm.boundingRect( lineEdit()->inputMask() ).width();
0107         w += 2; // cursor blinking space
0108 
0109         QStyleOptionSpinBox opt;
0110         initStyleOption(&opt);
0111         QSize hint(w, h);
0112         QSize extra(35, 6);
0113         opt.rect.setSize(hint + extra);
0114         extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
0115                                                 QStyle::SC_SpinBoxEditField, this).size();
0116         // get closer to final result by repeating the calculation
0117         opt.rect.setSize(hint + extra);
0118         extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
0119                                                 QStyle::SC_SpinBoxEditField, this).size();
0120         hint += extra;
0121 
0122         opt.rect = rect();
0123         d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
0124     }
0125     return d->cachedSizeHint;
0126 }
0127 
0128 
0129 K3b::Msf K3b::MsfEdit::value() const
0130 {
0131     return d->value;
0132 }
0133 
0134 
0135 K3b::Msf K3b::MsfEdit::minimum() const
0136 {
0137     return d->minimum;
0138 }
0139 
0140 
0141 K3b::Msf K3b::MsfEdit::maximum() const
0142 {
0143     return d->maximum;
0144 }
0145 
0146 
0147 void K3b::MsfEdit::setMinimum( const Msf& min )
0148 {
0149     d->minimum = min;
0150     if( d->value < d->minimum )
0151         d->value = d->minimum;
0152     if( d->maximum < d->minimum )
0153         d->maximum = d->minimum;
0154 }
0155 
0156 
0157 void K3b::MsfEdit::setMaximum( const Msf& max )
0158 {
0159     d->maximum = max;
0160     if( d->value > d->maximum )
0161         d->value = d->maximum;
0162     if( d->minimum > d->maximum )
0163         d->minimum = d->maximum;
0164 
0165     // Compute number of allowed positions for given maximum
0166     d->minutesWidth = static_cast<int>( std::log10( static_cast<float>( d->maximum.minutes() ) ) ) + 1;
0167     QString inputMask( ":99:99" );
0168     for( int i = 0; i < d->minutesWidth; ++i )
0169         inputMask.prepend( '9' );
0170     lineEdit()->setInputMask( inputMask );
0171 }
0172 
0173 
0174 void K3b::MsfEdit::setValue( const K3b::Msf& value )
0175 {
0176     if( d->value != value ) {
0177         d->value = value;
0178         if( d->value < d->minimum )
0179             d->value = d->minimum;
0180         else if( d->value > d->maximum )
0181             d->value = d->maximum;
0182         
0183         lineEdit()->setText( d->stringValue() );
0184         emit valueChanged( d->value );
0185     }
0186 }
0187 
0188 
0189 QAbstractSpinBox::StepEnabled K3b::MsfEdit::stepEnabled () const
0190 {
0191     StepEnabled stepEnabled;
0192     if( d->value > d->minimum )
0193         stepEnabled |= StepDownEnabled;
0194     if( d->value < d->maximum || d->maximum.totalFrames() == 0 )
0195         stepEnabled |= StepUpEnabled;
0196     return stepEnabled;
0197 }
0198 
0199 #include "moc_k3bmsfedit.cpp"