File indexing completed on 2024-04-28 04:49:53
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"