File indexing completed on 2024-05-05 04:48:25

0001 /****************************************************************************************
0002  * Copyright (c) 2004-2009 Mark Kretschmann <kretschmann@kde.org>                       *
0003  * Copyright (c) 2009 Artur Szymiec <artur.szymiec@gmail.com>                           *
0004  * Copyright (c) 2013 Ralf Engels <ralf-engels@gmx.de>                                  *
0005  *                                                                                      *
0006  * This program is free software; you can redistribute it and/or modify it under        *
0007  * the terms of the GNU General Public License as published by the Free Software        *
0008  * Foundation; either version 2 of the License, or (at your option) any later           *
0009  * version.                                                                             *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ****************************************************************************************/
0018 
0019 #include "EqualizerDialog.h"
0020 
0021 #include "amarokconfig.h"
0022 #include "EngineController.h"
0023 
0024 #include "core/support/Amarok.h"
0025 #include "core/support/Debug.h"
0026 
0027 EqualizerDialog * EqualizerDialog::s_instance = nullptr;
0028 
0029 EqualizerDialog::EqualizerDialog( QWidget* parent )
0030     : QDialog( parent )
0031 {
0032     DEBUG_BLOCK
0033 
0034     setWindowTitle( i18n( "Configure Equalizer" ) );
0035 
0036     setupUi( this );
0037 
0038     EqualizerController *equalizer = The::engineController()->equalizerController();
0039     // Check if equalizer is supported - disable controls if not
0040     if( !equalizer->isEqSupported() )
0041     {
0042         EqualizerWidget->setDisabled( true );
0043         activeCheckBox->setEnabled( false );
0044         activeCheckBox->setChecked( false );
0045     }
0046 
0047     connect(buttonBox, &QDialogButtonBox::accepted, this, &EqualizerDialog::accept);
0048     connect(buttonBox, &QDialogButtonBox::rejected, this, &EqualizerDialog::restoreOriginalSettings);
0049 
0050     // Assign slider items to vectors
0051     m_bands.append( eqPreampSlider );
0052     m_bands.append( eqBand0Slider );
0053     m_bands.append( eqBand1Slider );
0054     m_bands.append( eqBand2Slider );
0055     m_bands.append( eqBand3Slider );
0056     m_bands.append( eqBand4Slider );
0057     m_bands.append( eqBand5Slider );
0058     m_bands.append( eqBand6Slider );
0059     m_bands.append( eqBand7Slider );
0060     m_bands.append( eqBand8Slider );
0061     m_bands.append( eqBand9Slider );
0062     m_bandValues.append( eqPreampValue );
0063     m_bandValues.append( eqBand0Value );
0064     m_bandValues.append( eqBand1Value );
0065     m_bandValues.append( eqBand2Value );
0066     m_bandValues.append( eqBand3Value );
0067     m_bandValues.append( eqBand4Value );
0068     m_bandValues.append( eqBand5Value );
0069     m_bandValues.append( eqBand6Value );
0070     m_bandValues.append( eqBand7Value );
0071     m_bandValues.append( eqBand8Value );
0072     m_bandValues.append( eqBand9Value );
0073     m_bandLabels.append( eqPreampLabel );
0074     m_bandLabels.append( eqBand0Label );
0075     m_bandLabels.append( eqBand1Label );
0076     m_bandLabels.append( eqBand2Label );
0077     m_bandLabels.append( eqBand3Label );
0078     m_bandLabels.append( eqBand4Label );
0079     m_bandLabels.append( eqBand5Label );
0080     m_bandLabels.append( eqBand6Label );
0081     m_bandLabels.append( eqBand7Label );
0082     m_bandLabels.append( eqBand8Label );
0083     m_bandLabels.append( eqBand9Label );
0084 
0085     // Ask engine for maximum gain value and compute scale to display values
0086     mValueScale = equalizer->eqMaxGain();
0087     const QString mlblText = i18n( "%0\ndB" ).arg( QString::number( mValueScale, 'f', 1 ) );
0088     eqMaxEq->setText( QStringLiteral("+") + mlblText );
0089     eqMinEq->setText( QStringLiteral("-") + mlblText );
0090 
0091     // Ask engine for band frequencies and set labels
0092     const QStringList equalizerBandFreq = equalizer->eqBandsFreq();
0093     QStringListIterator i( equalizerBandFreq );
0094 
0095     // Check if preamp is supported by Phonon backend
0096     if( equalizerBandFreq.size() == s_equalizerBandsNum ) {
0097         // Preamp not supported, so hide its slider
0098         eqPreampLabel->hide();
0099         eqPreampSlider->hide();
0100         eqPreampValue->hide();
0101     }
0102     else if( i.hasNext() ) // If preamp is present then skip its label as it is hard-coded in UI
0103         i.next();
0104     foreach( QLabel* mLabel, m_bandLabels )
0105         if( mLabel->objectName() != "eqPreampLabel" )
0106             mLabel->setText( i.hasNext() ?  i.next() : "N/A" );
0107 
0108     updatePresets();
0109     activeCheckBox->setChecked( equalizer->enabled() );
0110 
0111     equalizer->applyEqualizerPresetByIndex( AmarokConfig::equalizerMode() - 1 );
0112     equalizer->setGains( equalizer->gains() );
0113     updateUi();
0114 
0115     connect( equalizer, &EqualizerController::presetsChanged, this, &EqualizerDialog::presetsChanged );
0116     connect( equalizer, &EqualizerController::gainsChanged, this, &EqualizerDialog::gainsChanged );
0117     connect( equalizer, &EqualizerController::presetApplied, this, &EqualizerDialog::presetApplied );
0118 
0119     // Configure signal and slots to handle presets
0120     connect( activeCheckBox, &QCheckBox::toggled, this, &EqualizerDialog::toggleEqualizer );
0121     connect( eqPresets, QOverload<int>::of(&QComboBox::currentIndexChanged),
0122              equalizer, &EqualizerController::applyEqualizerPresetByIndex );
0123     connect( eqPresets, &QComboBox::editTextChanged, this, &EqualizerDialog::updateUi );
0124     foreach( QSlider* mSlider, m_bands )
0125         connect( mSlider, &QSlider::valueChanged, this, &EqualizerDialog::bandsChanged );
0126 
0127     eqPresetSaveBtn->setIcon( QIcon::fromTheme( QStringLiteral("document-save") ) );
0128     connect( eqPresetSaveBtn, &QAbstractButton::clicked, this, &EqualizerDialog::savePreset );
0129 
0130     eqPresetDeleteBtn->setIcon( QIcon::fromTheme( QStringLiteral("edit-delete") ) );
0131     connect( eqPresetDeleteBtn, &QAbstractButton::clicked, this, &EqualizerDialog::deletePreset );
0132 
0133     eqPresetResetBtn->setIcon( QIcon::fromTheme( QStringLiteral("edit-undo") ) );
0134     connect( eqPresetResetBtn, &QAbstractButton::clicked, this, &EqualizerDialog::restorePreset );
0135 }
0136 
0137 EqualizerDialog::~EqualizerDialog()
0138 { }
0139 
0140 void EqualizerDialog::showOnce( QWidget *parent )
0141 {
0142     DEBUG_BLOCK
0143 
0144     if( s_instance == nullptr )
0145         s_instance = new EqualizerDialog( parent );
0146 
0147     s_instance->activateWindow();
0148     s_instance->show();
0149     s_instance->raise();
0150     s_instance->storeOriginalSettings();
0151 }
0152 
0153 QList<int>
0154 EqualizerDialog::gains() const
0155 {
0156     QList<int> result;
0157     foreach( QSlider* mSlider, m_bands )
0158         result << mSlider->value();
0159     return result;
0160 }
0161 
0162 void
0163 EqualizerDialog::gainsChanged( const QList<int> &eqGains )
0164 {
0165     for( int i = 0; i < m_bands.count() && i < eqGains.count(); i++ )
0166     {
0167         // Update slider values with signal blocking to prevent circular loop
0168         m_bands[i]->blockSignals( true );
0169         m_bands[i]->setValue( eqGains[ i ] );
0170         m_bands[i]->blockSignals( false );
0171     }
0172     updateToolTips();
0173     updateLabels();
0174     updateUi();
0175 }
0176 
0177 void
0178 EqualizerDialog::storeOriginalSettings()
0179 {
0180     m_originalActivated = activeCheckBox->isChecked();
0181     m_originalPreset = selectedPresetName();
0182     m_originalGains = gains();
0183 }
0184 
0185 void
0186 EqualizerDialog::restoreOriginalSettings()
0187 {
0188     // Only restore original settings if the equalizer was originally enabled
0189     // or if the equalizer is currently enabled. This prevents a reset of the
0190     // equalizer when cancel button is clicked with equalizer toggle off.
0191     if( m_originalActivated || activeCheckBox->isChecked() )
0192     {
0193         activeCheckBox->setChecked( m_originalActivated );
0194         int originalPresetIndex = EqualizerPresets::eqGlobalList().indexOf( m_originalPreset );
0195         The::engineController()->equalizerController()->applyEqualizerPresetByIndex( originalPresetIndex );
0196         eqPresets->setEditText( m_originalPreset );
0197         The::engineController()->equalizerController()->setGains( m_originalGains );
0198     }
0199     this->reject();
0200 }
0201 
0202 void
0203 EqualizerDialog::presetApplied( int index ) //SLOT
0204 {
0205     if( index < 0 )
0206         return;
0207 
0208     // if not called from the eqPreset->indexChanged signal we need
0209     // to update the combo box too.
0210     if( eqPresets->currentIndex() != index )
0211     {
0212         eqPresets->blockSignals( true );
0213         eqPresets->setCurrentIndex( index );
0214         eqPresets->blockSignals( false );
0215     }
0216 }
0217 
0218 void
0219 EqualizerDialog::bandsChanged() //SLOT
0220 {
0221     updateToolTips();
0222     updateLabels();
0223     updateUi();
0224     // The::engineController()->equalizerController()->blockSignals( true );
0225     The::engineController()->equalizerController()->setGains( gains() );
0226     // The::engineController()->equalizerController()->blockSignals( false );
0227 }
0228 
0229 void
0230 EqualizerDialog::updateUi() // SLOT
0231 {
0232     const QString currentName = selectedPresetName();
0233 
0234     const bool enabledState = activeCheckBox->isChecked();
0235     const bool userState = EqualizerPresets::eqUserList().contains( currentName );
0236     const bool modified = ( EqualizerPresets::eqCfgGetPresetVal( currentName ) != gains() );
0237     const bool nameModified = ! EqualizerPresets::eqGlobalList().contains( currentName );
0238     const bool resetable = EqualizerPresets::eqCfgCanRestorePreset( currentName );
0239 
0240     eqPresets->setEnabled( enabledState );
0241     eqBandsGroupBox->setEnabled( enabledState );
0242     eqPresetSaveBtn->setEnabled( enabledState && ( modified || nameModified ) );
0243     eqPresetDeleteBtn->setEnabled( enabledState && userState );
0244     eqPresetResetBtn->setEnabled( enabledState && ( resetable || modified ) );
0245 }
0246 
0247 void
0248 EqualizerDialog::updatePresets()
0249 {
0250     const QString currentName = selectedPresetName();
0251 
0252     eqPresets->blockSignals( true );
0253     eqPresets->clear();
0254     eqPresets->addItems( EqualizerPresets::eqGlobalTranslatedList() );
0255     const int index = EqualizerPresets::eqGlobalList().indexOf( currentName );
0256     if( index >= 0 )
0257         eqPresets->setCurrentIndex( index );
0258     eqPresets->blockSignals( false );
0259 }
0260 
0261 void
0262 EqualizerDialog::presetsChanged( const QString &name )
0263 {
0264     Q_UNUSED( name )
0265     updatePresets();
0266     if( EqualizerPresets::eqGlobalList().indexOf( selectedPresetName() ) == -1 )
0267         presetApplied( 0 );
0268     updateUi();
0269 }
0270 
0271 void
0272 EqualizerDialog::savePreset() //SLOT
0273 {
0274     The::engineController()->equalizerController()->savePreset( selectedPresetName(), gains() );
0275 }
0276 
0277 void
0278 EqualizerDialog::deletePreset() //SLOT
0279 {
0280     The::engineController()->equalizerController()->deletePreset( selectedPresetName() );
0281 }
0282 
0283 QString
0284 EqualizerDialog::selectedPresetName() const
0285 {
0286     const QString currentText = eqPresets->currentText();
0287     const int index = EqualizerPresets::eqGlobalTranslatedList().indexOf( currentText );
0288     if( index < 0 )
0289         return currentText;
0290 
0291     return EqualizerPresets::eqGlobalList().at( index );
0292 }
0293 
0294 void
0295 EqualizerDialog::restorePreset() //SLOT
0296 {
0297     DEBUG_BLOCK
0298 
0299     EqualizerPresets::eqCfgRestorePreset( selectedPresetName() );
0300     The::engineController()->equalizerController()->setGains( EqualizerPresets::eqCfgGetPresetVal( selectedPresetName() ) );
0301 }
0302 
0303 void
0304 EqualizerDialog::updateToolTips()
0305 {
0306     foreach( QSlider* mSlider, m_bands )
0307         mSlider->setToolTip( QString::number( mSlider->value()*mValueScale/100.0, 'f', 1 ) );
0308 }
0309 
0310 void
0311 EqualizerDialog::updateLabels()
0312 {
0313     for( int i = 0; i < m_bandValues.count() && i < m_bands.count(); i++ )
0314         m_bandValues[i]->setText( QString::number( m_bands[i]->value() * mValueScale / 100.0, 'f', 1 ) );
0315 }
0316 
0317 void
0318 EqualizerDialog::toggleEqualizer( bool enabled )
0319 {
0320     DEBUG_BLOCK
0321 
0322     EqualizerController *eq = The::engineController()->equalizerController();
0323     if( !enabled )
0324         eq->applyEqualizerPresetByIndex( -1 );
0325     else
0326         eq->applyEqualizerPresetByIndex( eqPresets->currentIndex() );
0327 }
0328