File indexing completed on 2025-01-19 04:24:10
0001 /**************************************************************************************** 0002 * Copyright (c) 2010 Rainer Sigle <rainer.sigle@web.de> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. if not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #define DEBUG_PREFIX "TabsApplet" 0018 0019 #include "TabsApplet.h" 0020 0021 #include "TabsItem.h" 0022 #include "TabsView.h" 0023 #include "core/support/Amarok.h" 0024 #include "core/support/Debug.h" 0025 #include "context/ContextView.h" 0026 #include "context/widgets/AppletHeader.h" 0027 0028 #include <KConfigDialog> 0029 #include <KConfigGroup> 0030 #include <KDialog> 0031 #include <QDialog> 0032 #include <Plasma/IconWidget> 0033 #include <Plasma/Label> 0034 #include <QDialogButtonBox> 0035 #include <QPushButton> 0036 #include <QVBoxLayout> 0037 0038 /** 0039 * \brief Constructor 0040 * 0041 * TabsApplet constructor 0042 * 0043 * \param parent : the TabsApplet parent (used by Context::Applet) 0044 * \param args : (used by Context::Applet) 0045 */ 0046 TabsApplet::TabsApplet( QObject* parent, const QVariantList& args ) 0047 : Context::Applet( parent, args ) 0048 , m_tabsView( 0 ) 0049 , m_currentState( InitState ) 0050 , m_layout( 0 ) 0051 , m_fetchGuitar( true ) 0052 , m_fetchBass( true ) 0053 , m_showTabBrowser( false ) 0054 { 0055 DEBUG_BLOCK 0056 setHasConfigurationInterface( true ); 0057 0058 EngineController *engine = The::engineController(); 0059 connect( engine, SIGNAL(stopped(qint64,qint64)), this, SLOT(stopped()) ); 0060 } 0061 0062 TabsApplet::~TabsApplet() 0063 { 0064 DEBUG_BLOCK 0065 delete m_tabsView; 0066 if( m_reloadIcon ) 0067 delete m_reloadIcon.data(); 0068 } 0069 0070 /** 0071 * \brief Initialization 0072 * 0073 * Initializes the TabsApplet with default parameters 0074 */ 0075 void 0076 TabsApplet::init() 0077 { 0078 // applet base initialization 0079 Context::Applet::init(); 0080 0081 // create the header label 0082 enableHeader( true ); 0083 setHeaderText( i18nc( "Guitar tablature", "Tabs" ) ); 0084 0085 // creates the tab view 0086 m_tabsView = new TabsView( this ); 0087 0088 // Set the collapse size 0089 setCollapseOffHeight( -1 ); 0090 setCollapseHeight( m_header->height() ); 0091 setMinimumHeight( collapseHeight() ); 0092 setPreferredHeight( collapseHeight() ); 0093 0094 // create the reload icon 0095 QAction* reloadAction = new QAction( this ); 0096 reloadAction->setIcon( QIcon::fromTheme( "view-refresh" ) ); 0097 reloadAction->setVisible( true ); 0098 reloadAction->setEnabled( true ); 0099 reloadAction->setText( i18nc( "Guitar tablature", "Reload tabs" ) ); 0100 m_reloadIcon = addLeftHeaderAction( reloadAction ); 0101 m_reloadIcon.data()->setEnabled( false ); 0102 connect( m_reloadIcon.data(), SIGNAL(clicked()), this, SLOT(reloadTabs()) ); 0103 0104 // create the settings icon 0105 QAction* settingsAction = new QAction( this ); 0106 settingsAction->setIcon( QIcon::fromTheme( "preferences-system" ) ); 0107 settingsAction->setEnabled( true ); 0108 settingsAction->setText( i18n( "Settings" ) ); 0109 QWeakPointer<Plasma::IconWidget> settingsIcon = addRightHeaderAction( settingsAction ); 0110 connect( settingsIcon.data(), SIGNAL(clicked()), this, SLOT(showConfigurationInterface()) ); 0111 0112 m_layout = new QGraphicsLinearLayout( Qt::Vertical ); 0113 m_layout->addItem( m_header ); 0114 m_layout->addItem( m_tabsView ); 0115 setLayout( m_layout ); 0116 0117 // read configuration data and update the engine. 0118 KConfigGroup config = Amarok::config("Tabs Applet"); 0119 m_fetchGuitar = config.readEntry( "FetchGuitar", true ); 0120 m_fetchBass = config.readEntry( "FetchBass", true ); 0121 0122 Plasma::DataEngine *engine = dataEngine( "amarok-tabs" ); 0123 engine->setProperty( "fetchGuitarTabs", m_fetchGuitar ); 0124 engine->setProperty( "fetchBassTabs", m_fetchBass ); 0125 engine->connectSource( "tabs", this ); 0126 0127 updateInterface( InitState ); 0128 } 0129 0130 void 0131 TabsApplet::stopped() 0132 { 0133 setHeaderText( i18nc( "Guitar tablature", "Tabs" ) ); 0134 updateInterface( StoppedState ); 0135 } 0136 0137 void 0138 TabsApplet::dataUpdated( const QString& name, const Plasma::DataEngine::Data& data ) 0139 { 0140 DEBUG_BLOCK 0141 Q_UNUSED( name ) 0142 0143 // remove previously fetched stuff 0144 m_tabsView->clear(); 0145 m_tabsView->clearTabBrowser(); 0146 setBusy( false ); 0147 0148 if( data.empty() ) 0149 { 0150 setHeaderText( i18nc( "Guitar tablature", "Tabs" ) ); 0151 updateInterface( InitState ); 0152 return; 0153 } 0154 0155 const QString state = data[ "state" ].toString(); 0156 const QString artistName = data[ "artist" ].toString(); 0157 const QString titleName = data[ "title" ].toString(); 0158 if( data.contains( "state" ) && state.contains( "Fetching" ) ) 0159 { 0160 if( canAnimate() ) 0161 setBusy( true ); 0162 setHeaderText( i18nc( "Guitar tablature", "Tabs: Fetching..." ) ); 0163 updateInterface( FetchingState ); 0164 return; 0165 } 0166 else if( data.contains( "state" ) && state.contains( "Stopped" ) ) 0167 { 0168 stopped(); 0169 return; 0170 } 0171 else if( data.contains( "state" ) && state.contains( "noTabs") ) 0172 { 0173 // no tabs for the current track 0174 setHeaderText( i18nc( "Guitar tablature", "No Tabs for %1 by %2", titleName, artistName ) ); 0175 updateInterface( NoTabsState ); 0176 return; 0177 } 0178 else if( data.contains( "state" ) && state.contains( "FetchError") ) 0179 { 0180 setHeaderText( i18nc( "Guitar tablature", "Tabs: Fetch Error" ) ); 0181 updateInterface( NoTabsState ); 0182 return; 0183 } 0184 0185 // getting the tab-data from the engine 0186 bool tabFound = false; 0187 for( int i = 0; i < data.size(); i++ ) 0188 { 0189 const QString tabId = QString( "tabs:" ).append( QString::number( i ) ); 0190 if( data.contains( tabId ) ) 0191 { 0192 TabsInfo *item = data[ tabId ].value<TabsInfo *>() ; 0193 if( item ) 0194 { 0195 TabsItem *tabsItem = new TabsItem(); 0196 tabsItem->setTab( item ); 0197 0198 m_tabsView->appendTab( tabsItem ); 0199 if( !tabFound ) 0200 { 0201 // update the applet and display the first tab in list 0202 m_tabsView->showTab( tabsItem ); 0203 0204 // update artist and title in the headerlabel 0205 setHeaderText( i18nc( "Guitar tablature", "Tabs: %1 - %2", titleName, artistName ) ); 0206 updateInterface( TabState ); 0207 tabFound = true; 0208 } 0209 } 0210 } 0211 } 0212 } 0213 0214 void 0215 TabsApplet::updateInterface( const AppletState appletState ) 0216 { 0217 // return if state has not changed (except for init state) 0218 if( m_currentState == appletState && appletState != InitState ) 0219 return; 0220 0221 debug() << "updating interface from state " << m_currentState << " to " << appletState; 0222 m_currentState = appletState; 0223 bool collapse = false; 0224 0225 switch( m_currentState ) 0226 { 0227 case InitState: 0228 case StoppedState: 0229 m_reloadIcon.data()->setEnabled( false ); 0230 m_showTabBrowser = false; 0231 collapse = true; 0232 break; 0233 case NoTabsState: 0234 m_reloadIcon.data()->setEnabled( true ); 0235 m_showTabBrowser = false; 0236 collapse = true; 0237 break; 0238 case FetchingState: 0239 m_reloadIcon.data()->setEnabled( false ); 0240 m_showTabBrowser = false; 0241 break; 0242 case TabState: 0243 m_reloadIcon.data()->setEnabled( true ); 0244 m_showTabBrowser = true; 0245 break; 0246 } 0247 0248 QGraphicsLinearLayout *lo = static_cast<QGraphicsLinearLayout*>( layout() ); 0249 0250 m_showTabBrowser ? lo->addItem( m_tabsView ) : lo->removeItem( m_tabsView ); 0251 m_showTabBrowser ? m_tabsView->show() : m_tabsView->hide(); 0252 0253 collapse ? setCollapseOn() : setCollapseOff(); 0254 0255 updateConstraints(); 0256 update(); 0257 } 0258 0259 void 0260 TabsApplet::createConfigurationInterface( KConfigDialog *parent ) 0261 { 0262 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); 0263 QVBoxLayout *mainLayout = new QVBoxLayout; 0264 parent->setLayout(mainLayout); 0265 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0266 okButton->setDefault(true); 0267 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0268 parent->connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 0269 parent->connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0270 mainLayout->addWidget(buttonBox); 0271 0272 QWidget *settings = new QWidget; 0273 ui_Settings.setupUi( settings ); 0274 0275 if( m_fetchGuitar ) 0276 ui_Settings.cbFetchGuitar->setChecked( true ); 0277 if( m_fetchBass ) 0278 ui_Settings.cbFetchBass->setChecked( true ); 0279 0280 parent->addPage( settings, i18nc( "Guitar tablature settings", "Tabs Settings" ), "preferences-system" ); 0281 connect( parent, SIGNAL(accepted()), this, SLOT(saveSettings()) ); 0282 } 0283 0284 void 0285 TabsApplet::saveSettings() 0286 { 0287 DEBUG_BLOCK 0288 KConfigGroup config = Amarok::config("Tabs Applet"); 0289 0290 bool fetchGuitar = ui_Settings.cbFetchGuitar->isChecked(); 0291 bool fetchBass = ui_Settings.cbFetchBass->isChecked(); 0292 0293 // check if any setting has changed 0294 bool forceUpdate = false; 0295 if( m_fetchGuitar != fetchGuitar || m_fetchBass != fetchBass ) 0296 forceUpdate = true; 0297 0298 if( forceUpdate ) 0299 { 0300 m_fetchGuitar = fetchGuitar; 0301 m_fetchBass = fetchBass; 0302 0303 config.writeEntry( "FetchGuitar", m_fetchGuitar ); 0304 config.writeEntry( "FetchBass", m_fetchBass ); 0305 0306 Plasma::DataEngine *engine = dataEngine( "amarok-tabs" ); 0307 engine->setProperty( "fetchGuitarTabs", m_fetchGuitar ); 0308 engine->setProperty( "fetchBassTabs", m_fetchBass ); 0309 engine->query( QLatin1String( "tabs:forceUpdate" ) ); 0310 } 0311 } 0312 0313 void 0314 TabsApplet::reloadTabs() 0315 { 0316 DEBUG_BLOCK 0317 KDialog reloadDialog; 0318 QWidget *reloadWidget = new QWidget( &reloadDialog ); 0319 0320 Ui::ReloadEditDialog *reloadUI = new Ui::ReloadEditDialog(); 0321 reloadUI->setupUi( reloadWidget ); 0322 0323 reloadDialog.setCaption( i18nc( "Guitar tablature", "Reload Tabs" ) ); 0324 reloadDialog.setButtons( KDialog::Ok|KDialog::Cancel ); 0325 reloadDialog.setDefaultButton( KDialog::Ok ); 0326 reloadDialog.setMainWidget( reloadWidget ); 0327 0328 // query engine for current artist and title 0329 Plasma::DataEngine *engine = dataEngine( "amarok-tabs" ); 0330 QString artistName = engine->property( "artistName" ).toString(); 0331 QString titleName = engine->property( "titleName" ).toString(); 0332 0333 // update ui 0334 reloadUI->artistLineEdit->setText( artistName ); 0335 reloadUI->titleLineEdit->setText( titleName ); 0336 0337 if( reloadDialog.exec() == KDialog::Accepted ) 0338 { 0339 QString newArtist = reloadUI->artistLineEdit->text(); 0340 QString newTitle = reloadUI->titleLineEdit->text(); 0341 if ( newArtist != artistName || newTitle != titleName ) 0342 { 0343 engine->setProperty( "artistName", newArtist ); 0344 engine->setProperty( "titleName", newTitle ); 0345 engine->query( QLatin1String( "tabs:forceUpdateSpecificTitleArtist" ) ); 0346 } 0347 } 0348 } 0349