File indexing completed on 2025-01-05 04:25:45
0001 /**************************************************************************************** 0002 * Copyright (c) 2009 Joffrey Clavel <jclavel@clabert.info> * 0003 * Copyright (c) 2009 Oleksandr Khayrullin <saniokh@gmail.com> * 0004 * Copyright (c) 2009-2010 Ludovic Deveaux <deveaux.ludovic31@gmail.com> * 0005 * Copyright (c) 2010 Hormiere Guillaume <hormiere.guillaume@gmail.com> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify it under * 0008 * the terms of the GNU General Public License as published by the Free Software * 0009 * Foundation; either version 2 of the License, or (at your option) any later * 0010 * version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0013 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0014 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License along with * 0017 * this program. If not, see <http://www.gnu.org/licenses/>. * 0018 ****************************************************************************************/ 0019 0020 #define DEBUG_PREFIX "UpcomingEventsApplet" 0021 0022 #include "UpcomingEventsApplet.h" 0023 0024 #include "amarokurls/AmarokUrl.h" 0025 #include "context/applets/upcomingevents/LastFmEvent.h" 0026 #include "context/widgets/AppletHeader.h" 0027 #include "core/support/Amarok.h" 0028 #include "core/support/Debug.h" 0029 #include "SvgHandler.h" 0030 #include "LastFmEventXmlParser.h" 0031 #include "UpcomingEventsMapWidget.h" 0032 #include "UpcomingEventsCalendarWidget.h" 0033 #include "UpcomingEventsStack.h" 0034 #include "UpcomingEventsStackItem.h" 0035 0036 #include <KConfigDialog> 0037 #include <KGlobalSettings> 0038 #include <Plasma/IconWidget> 0039 #include <Plasma/Theme> 0040 #include <Plasma/Svg> 0041 0042 #include <QDesktopServices> 0043 #include <QGraphicsLinearLayout> 0044 #include <QXmlStreamReader> 0045 #include <KConfigGroup> 0046 0047 UpcomingEventsApplet::UpcomingEventsApplet( QObject* parent, const QVariantList& args ) 0048 : Context::Applet( parent, args ) 0049 , m_groupVenues( false ) 0050 , m_stack( 0 ) 0051 { 0052 setHasConfigurationInterface( true ); 0053 setBackgroundHints( Plasma::Applet::NoBackground ); 0054 } 0055 0056 UpcomingEventsApplet::~UpcomingEventsApplet() 0057 { 0058 } 0059 0060 void 0061 UpcomingEventsApplet::init() 0062 { 0063 DEBUG_BLOCK 0064 0065 Context::Applet::init(); 0066 0067 enableHeader( true ); 0068 setHeaderText( i18n( "Upcoming Events" ) ); 0069 0070 m_stack = new UpcomingEventsStack( this ); 0071 m_stack->setContentsMargins( 0, 0, 0, 0 ); 0072 0073 connect( m_stack, SIGNAL(collapseStateChanged()), SLOT(collapseStateChanged()) ); 0074 connect( this, SIGNAL(listWidgetRemoved(UpcomingEventsListWidget*)), 0075 m_stack, SLOT(cleanupListWidgets()) ); 0076 0077 QAction *calendarAction = new QAction( this ); 0078 calendarAction->setIcon( QIcon::fromTheme( "view-calendar" ) ); 0079 calendarAction->setToolTip( i18n( "View Events Calendar" ) ); 0080 Plasma::IconWidget *calendarIcon = addLeftHeaderAction( calendarAction ); 0081 connect( calendarIcon, SIGNAL(clicked()), this, SLOT(viewCalendar()) ); 0082 0083 QAction* settingsAction = new QAction( this ); 0084 settingsAction->setIcon( QIcon::fromTheme( "preferences-system" ) ); 0085 settingsAction->setToolTip( i18n( "Settings" ) ); 0086 settingsAction->setEnabled( true ); 0087 Plasma::IconWidget *settingsIcon = addRightHeaderAction( settingsAction ); 0088 connect( settingsIcon, SIGNAL(clicked()), this, SLOT(configure()) ); 0089 0090 m_artistStackItem = m_stack->create( QLatin1String("currentartistevents") ); 0091 m_artistEventsList = new UpcomingEventsListWidget( m_artistStackItem ); 0092 m_artistStackItem->setTitle( i18nc( "@title:group", "No track is currently playing" ) ); 0093 m_artistStackItem->setWidget( m_artistEventsList ); 0094 m_artistStackItem->setCollapsed( true ); 0095 m_artistStackItem->setIcon( QIcon::fromTheme("filename-artist-amarok") ); 0096 connect( m_artistEventsList, SIGNAL(mapRequested(QObject*)), SLOT(handleMapRequest(QObject*)) ); 0097 0098 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout( Qt::Vertical ); 0099 layout->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); 0100 layout->addItem( m_header ); 0101 layout->addItem( m_stack ); 0102 setLayout( layout ); 0103 0104 // Read config and inform the engine. 0105 enableVenueGrouping( Amarok::config("UpcomingEvents Applet").readEntry( "groupVenues", false ) ); 0106 QStringList venueData = Amarok::config("UpcomingEvents Applet").readEntry( "favVenues", QStringList() ); 0107 m_favoriteVenues = venueStringToDataList( venueData ); 0108 0109 Plasma::DataEngine *engine = dataEngine( "amarok-upcomingEvents" ); 0110 connect( engine, SIGNAL(sourceAdded(QString)), SLOT(engineSourceAdded(QString)) ); 0111 engine->query( "artistevents" ); 0112 engine->query( "venueevents" ); 0113 0114 updateConstraints(); 0115 } 0116 0117 void 0118 UpcomingEventsApplet::engineSourceAdded( const QString &source ) 0119 { 0120 if( source == "artistevents" || source == "venueevents" ) 0121 dataEngine( "amarok-upcomingEvents" )->connectSource( source, this ); 0122 } 0123 0124 void 0125 UpcomingEventsApplet::constraintsEvent( Plasma::Constraints constraints ) 0126 { 0127 Context::Applet::constraintsEvent( constraints ); 0128 prepareGeometryChange(); 0129 setHeaderText( i18n( "Upcoming Events" ) ); 0130 update(); 0131 } 0132 0133 void 0134 UpcomingEventsApplet::dataUpdated( const QString &source, const Plasma::DataEngine::Data &data ) 0135 { 0136 const LastFmEvent::List &events = data[ "events" ].value< LastFmEvent::List >(); 0137 if( source == "artistevents" ) 0138 { 0139 QString artistName = data[ "artist" ].toString(); 0140 m_artistEventsList->clear(); 0141 m_artistEventsList->setName( artistName ); 0142 addToStackItem( m_artistStackItem, events, artistName ); 0143 if( !m_artistStackItem->action( "showinmediasources" ) ) 0144 { 0145 QAction *act = new QAction( QIcon::fromTheme("edit-find"), QString(), m_artistStackItem ); 0146 act->setToolTip( i18n( "Show in Media Sources" ) ); 0147 connect( act, SIGNAL(triggered()), this, SLOT(navigateToArtist()) ); 0148 m_artistStackItem->addAction( "showinmediasources", act ); 0149 } 0150 m_artistStackItem->setCollapsed( events.isEmpty() ); 0151 } 0152 else if( source == "venueevents" ) 0153 { 0154 if( !events.isEmpty() ) 0155 { 0156 LastFmVenuePtr venue = data[ "venue" ].value<LastFmVenuePtr>(); 0157 if( m_groupVenues && m_stack->hasItem("favoritevenuesgroup") ) 0158 { 0159 QString title = i18n( "Favorite Venues" ); 0160 addToStackItem( m_stack->item("favoritevenuesgroup"), events, title ); 0161 } 0162 else 0163 { 0164 UpcomingEventsStackItem *stackItem( 0 ); 0165 UpcomingEventsListWidget *listWidget( 0 ); 0166 LastFmEvent::List newEvents; 0167 if( !m_stack->hasItem( venue->name ) ) 0168 { 0169 stackItem = m_stack->create( venue->name ); 0170 listWidget = new UpcomingEventsListWidget( stackItem ); 0171 listWidget->setName( venue->name ); 0172 stackItem->setWidget( listWidget ); 0173 stackItem->setCollapsed( true ); 0174 stackItem->setIcon( QIcon::fromTheme("favorites") ); 0175 stackItem->showCloseButton(); 0176 connect( listWidget, SIGNAL(mapRequested(QObject*)), SLOT(handleMapRequest(QObject*)) ); 0177 connect( listWidget, SIGNAL(destroyed(QObject*)), SLOT(listWidgetDestroyed(QObject*)) ); 0178 emit listWidgetAdded( listWidget ); 0179 newEvents = events; 0180 } 0181 else 0182 { 0183 stackItem = m_stack->item( venue->name ); 0184 typedef UpcomingEventsListWidget UELW; 0185 UELW *widget = static_cast<UELW*>( stackItem->widget() ); 0186 newEvents = events.toSet().subtract( widget->events().toSet() ).toList(); 0187 } 0188 addToStackItem( stackItem, newEvents, venue->name ); 0189 } 0190 update(); 0191 } 0192 else if( m_groupVenues && m_stack->hasItem( QLatin1String("favoritevenuesgroup") ) ) 0193 { 0194 m_stack->remove( QLatin1String("favoritevenuesgroup" ) ); 0195 } 0196 else 0197 { 0198 // remove all venue lists 0199 const QRegExp pattern( QLatin1String("^(?!(currentartistevents|venuemapview|calendar)).*$") ); 0200 QList<UpcomingEventsStackItem*> eventItems = m_stack->items( pattern ); 0201 qDeleteAll( eventItems ); 0202 } 0203 } 0204 } 0205 0206 void 0207 UpcomingEventsApplet::clearVenueItems() 0208 { 0209 m_stack->remove( QLatin1String("favoritevenuesgroup" ) ); 0210 m_stack->remove( QLatin1String("venuemapview" ) ); 0211 } 0212 0213 void 0214 UpcomingEventsApplet::addToStackItem( UpcomingEventsStackItem *item, 0215 const LastFmEvent::List &events, 0216 const QString &name ) 0217 { 0218 UpcomingEventsListWidget *listWidget = static_cast<UpcomingEventsListWidget*>( item->widget() ); 0219 listWidget->addEvents( events ); 0220 0221 QString title; 0222 int added = listWidget->count(); 0223 if( added == 0 ) 0224 { 0225 title = name.isEmpty() ? i18n( "No upcoming events" ) : i18n( "%1: No upcoming events", name ); 0226 } 0227 else 0228 { 0229 title = name.isEmpty() 0230 ? i18ncp( "@title:group Number of upcoming events", "1 event", "%1 events", added ) 0231 : i18ncp( "@title:group Number of upcoming events", "%1: 1 event", "%1: %2 events", name, added ); 0232 } 0233 item->setTitle( title ); 0234 item->layout()->invalidate(); 0235 } 0236 0237 void 0238 UpcomingEventsApplet::paintInterface( QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect ) 0239 { 0240 Q_UNUSED( option ) 0241 Q_UNUSED( contentsRect ) 0242 addGradientToAppletBackground( p ); 0243 } 0244 0245 void 0246 UpcomingEventsApplet::configure() 0247 { 0248 DEBUG_BLOCK 0249 showConfigurationInterface(); 0250 } 0251 0252 void 0253 UpcomingEventsApplet::createConfigurationInterface( KConfigDialog *parent ) 0254 { 0255 QWidget *generalSettings = new QWidget; 0256 QWidget *venueSettings = new QWidget; 0257 ui_GeneralSettings.setupUi( generalSettings ); 0258 ui_VenueSettings.setupUi( venueSettings ); 0259 0260 // TODO bad, it's done manually ... 0261 QString timeSpan = Amarok::config("UpcomingEvents Applet").readEntry( "timeSpan", "AllEvents" ); 0262 if( timeSpan == "AllEvents" ) 0263 ui_GeneralSettings.filterComboBox->setCurrentIndex( 0 ); 0264 else if( timeSpan == "ThisWeek" ) 0265 ui_GeneralSettings.filterComboBox->setCurrentIndex( 1 ); 0266 else if( timeSpan == "ThisMonth" ) 0267 ui_GeneralSettings.filterComboBox->setCurrentIndex( 2 ); 0268 else if( timeSpan == "ThisYear" ) 0269 ui_GeneralSettings.filterComboBox->setCurrentIndex( 3 ); 0270 0271 connect( ui_VenueSettings.searchLineEdit, SIGNAL(returnPressed(QString)), SLOT(searchVenue(QString)) ); 0272 connect( ui_VenueSettings.searchResultsList, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(showVenueInfo(QListWidgetItem*)) ); 0273 connect( ui_VenueSettings.selectedVenuesList, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(showVenueInfo(QListWidgetItem*)) ); 0274 connect( ui_VenueSettings.searchResultsList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(venueResultDoubleClicked(QListWidgetItem*)) ); 0275 connect( ui_VenueSettings.selectedVenuesList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(selectedVenueDoubleClicked(QListWidgetItem*)) ); 0276 connect( ui_VenueSettings.urlValue, SIGNAL(leftClickedUrl(QString)), SLOT(openUrl(QString)) ); 0277 connect( ui_VenueSettings.urlValue, SIGNAL(rightClickedUrl(QString)), SLOT(openUrl(QString)) ); 0278 connect( ui_VenueSettings.websiteValue, SIGNAL(leftClickedUrl(QString)), SLOT(openUrl(QString)) ); 0279 connect( ui_VenueSettings.websiteValue, SIGNAL(rightClickedUrl(QString)), SLOT(openUrl(QString)) ); 0280 connect( parent, SIGNAL(clicked()), SLOT(saveSettings()) ); 0281 0282 ui_VenueSettings.photoLabel->hide(); 0283 ui_VenueSettings.infoGroupBox->setFont( KGlobalSettings::smallestReadableFont() ); 0284 ui_GeneralSettings.groupVenueCheckBox->setCheckState( m_groupVenues ? Qt::Checked : Qt::Unchecked ); 0285 0286 ui_VenueSettings.countryCombo->insertSeparator( 1 ); 0287 const QStringList &countryCodes = KGlobal::locale()->allCountriesList(); 0288 foreach( const QString &code, countryCodes ) 0289 ui_VenueSettings.countryCombo->addItem( KGlobal::locale()->countryCodeToName(code), code ); 0290 0291 foreach( const VenueData &data, m_favoriteVenues ) 0292 { 0293 QListWidgetItem *item = new QListWidgetItem; 0294 item->setData( VenueIdRole, data.id ); 0295 item->setData( VenueCityRole, data.city ); 0296 item->setData( VenueNameRole, data.name ); 0297 item->setText( QString( "%1, %2" ) 0298 .arg( item->data( VenueNameRole ).toString() ) 0299 .arg( item->data( VenueCityRole ).toString() ) ); 0300 ui_VenueSettings.selectedVenuesList->addItem( item ); 0301 } 0302 0303 parent->addPage( generalSettings, i18n( "Upcoming Events Settings" ), "preferences-system"); 0304 parent->addPage( venueSettings, i18n( "Favorite Venues" ), "favorites" ); 0305 } 0306 0307 void 0308 UpcomingEventsApplet::venueResultDoubleClicked( QListWidgetItem *item ) 0309 { 0310 if( !item ) 0311 return; 0312 0313 int row = ui_VenueSettings.searchResultsList->row( item ); 0314 QListWidgetItem *moveItem = ui_VenueSettings.searchResultsList->takeItem( row ); 0315 ui_VenueSettings.searchResultsList->clearSelection(); 0316 ui_VenueSettings.selectedVenuesList->addItem( moveItem ); 0317 ui_VenueSettings.selectedVenuesList->setCurrentItem( moveItem ); 0318 } 0319 0320 void 0321 UpcomingEventsApplet::selectedVenueDoubleClicked( QListWidgetItem *item ) 0322 { 0323 if( !item ) 0324 return; 0325 0326 int row = ui_VenueSettings.selectedVenuesList->row( item ); 0327 QListWidgetItem *moveItem = ui_VenueSettings.selectedVenuesList->takeItem( row ); 0328 ui_VenueSettings.selectedVenuesList->clearSelection(); 0329 ui_VenueSettings.searchResultsList->addItem( moveItem ); 0330 ui_VenueSettings.searchResultsList->setCurrentItem( moveItem ); 0331 } 0332 0333 void 0334 UpcomingEventsApplet::showVenueInfo( QListWidgetItem *item ) 0335 { 0336 if( !item ) 0337 return; 0338 0339 const QString &name = item->data( VenueNameRole ).toString(); 0340 const QString &city = item->data( VenueCityRole ).toString(); 0341 const QString &country = item->data( VenueCountryRole ).toString(); 0342 const QString &street = item->data( VenueStreetRole ).toString(); 0343 const QUrl &url = item->data( VenueUrlRole ).value<QUrl>(); 0344 const QUrl &website = item->data( VenueWebsiteRole ).value<QUrl>(); 0345 const QUrl &photoUrl = item->data( VenuePhotoUrlRole ).value<QUrl>(); 0346 0347 ui_VenueSettings.nameValue->setText( name ); 0348 ui_VenueSettings.cityValue->setText( city ); 0349 ui_VenueSettings.countryValue->setText( country ); 0350 ui_VenueSettings.streetValue->setText( street ); 0351 0352 if( url.isValid() ) 0353 { 0354 ui_VenueSettings.urlValue->setText( i18nc("@label:textbox Url label", "link") ); 0355 ui_VenueSettings.urlValue->setTipText( url.url() ); 0356 ui_VenueSettings.urlValue->setUrl( url.url() ); 0357 } 0358 else 0359 ui_VenueSettings.urlValue->clear(); 0360 0361 if( website.isValid() ) 0362 { 0363 ui_VenueSettings.websiteValue->setText( i18nc("@label:textbox Url label", "link") ); 0364 ui_VenueSettings.websiteValue->setTipText( website.url() ); 0365 ui_VenueSettings.websiteValue->setUrl( website.url() ); 0366 } 0367 else 0368 ui_VenueSettings.websiteValue->clear(); 0369 0370 if( photoUrl.isValid() ) 0371 { 0372 The::networkAccessManager()->getData( photoUrl, this, 0373 SLOT(venuePhotoResult(QUrl,QByteArray,NetworkAccessManagerProxy::Error)) ); 0374 } 0375 else 0376 { 0377 ui_VenueSettings.photoLabel->hide(); 0378 ui_VenueSettings.photoLabel->clear(); 0379 } 0380 } 0381 0382 void 0383 UpcomingEventsApplet::searchVenue( const QString &text ) 0384 { 0385 QUrl url; 0386 url.setScheme( "http" ); 0387 url.setHost( "ws.audioscrobbler.com" ); 0388 url.setPath( "/2.0/" ); 0389 url.addQueryItem( "method", "venue.search" ); 0390 url.addQueryItem( "api_key", Amarok::lastfmApiKey() ); 0391 url.addQueryItem( "venue", text ); 0392 int currentCountryIndex = ui_VenueSettings.countryCombo->currentIndex(); 0393 const QString &countryCode = ui_VenueSettings.countryCombo->itemData( currentCountryIndex ).toString(); 0394 if( !countryCode.isEmpty() ) 0395 url.addQueryItem( "country", countryCode ); 0396 The::networkAccessManager()->getData( url, this, 0397 SLOT(venueResults(QUrl,QByteArray,NetworkAccessManagerProxy::Error)) ); 0398 } 0399 0400 void 0401 UpcomingEventsApplet::venueResults( const QUrl &url, QByteArray data, NetworkAccessManagerProxy::Error e ) 0402 { 0403 Q_UNUSED( url ) 0404 if( e.code != QNetworkReply::NoError ) 0405 { 0406 debug() << "Failed to get venue results:" << e.description; 0407 return; 0408 } 0409 0410 ui_VenueSettings.searchResultsList->clear(); 0411 QXmlStreamReader xml( data ); 0412 while( !xml.atEnd() ) 0413 { 0414 xml.readNext(); 0415 if( xml.isStartElement() && xml.name() == "venue" ) 0416 { 0417 LastFmVenueXmlParser venueParser( xml ); 0418 if( venueParser.read() ) 0419 { 0420 QListWidgetItem *item = new QListWidgetItem; 0421 0422 LastFmVenuePtr venue = venueParser.venue(); 0423 item->setData( VenueIdRole, venue->id ); 0424 item->setData( VenueNameRole, venue->name ); 0425 item->setData( VenuePhotoUrlRole, venue->imageUrls[LastFmEvent::Large] ); 0426 item->setData( VenueUrlRole, venue->url ); 0427 item->setData( VenueWebsiteRole, venue->website ); 0428 0429 LastFmLocationPtr location = venue->location; 0430 item->setData( VenueCityRole, location->city ); 0431 item->setData( VenueCountryRole, location->country ); 0432 item->setData( VenueStreetRole, location->street ); 0433 0434 item->setText( QString( "%1, %2" ) 0435 .arg( item->data( VenueNameRole ).toString() ) 0436 .arg( item->data( VenueCityRole ).toString() ) ); 0437 ui_VenueSettings.searchResultsList->addItem( item ); 0438 } 0439 } 0440 } 0441 } 0442 0443 void 0444 UpcomingEventsApplet::venuePhotoResult( const QUrl &url, QByteArray data, NetworkAccessManagerProxy::Error e ) 0445 { 0446 Q_UNUSED( url ) 0447 if( e.code != QNetworkReply::NoError ) 0448 { 0449 debug() << "Failed to get venue photo:" << e.description; 0450 return; 0451 } 0452 0453 QPixmap photo; 0454 if( photo.loadFromData( data ) ) 0455 { 0456 photo = photo.scaled( 140, 140, Qt::KeepAspectRatio, Qt::SmoothTransformation ); 0457 photo = The::svgHandler()->addBordersToPixmap( photo, 5, QString(), true ); 0458 ui_VenueSettings.photoLabel->setPixmap( photo ); 0459 ui_VenueSettings.photoLabel->show(); 0460 } 0461 } 0462 0463 QList<UpcomingEventsApplet::VenueData> 0464 UpcomingEventsApplet::venueStringToDataList( const QStringList &list ) 0465 { 0466 // config qstringlist is stored as format: QString(id;name;city), QString(id;name;city), ... 0467 QList<VenueData> dataList; 0468 foreach( const QString &item, list ) 0469 { 0470 const QStringList &frag = item.split( QChar(';') ); 0471 VenueData data = { frag.at( 0 ).toInt(), frag.at( 1 ), frag.at( 2 ) }; 0472 dataList << data; 0473 } 0474 return dataList; 0475 } 0476 0477 void 0478 UpcomingEventsApplet::openUrl( const QString &url ) 0479 { 0480 QDesktopServices::openUrl( QUrl(url) ); 0481 } 0482 0483 UpcomingEventsMapWidget * 0484 UpcomingEventsApplet::mapView() 0485 { 0486 if( m_stack->hasItem("venuemapview") ) 0487 { 0488 UpcomingEventsStackItem *item = m_stack->item( "venuemapview" ); 0489 return static_cast<UpcomingEventsMapWidget*>( item->widget() ); 0490 } 0491 0492 UpcomingEventsStackItem *stackItem = m_stack->create( QLatin1String("venuemapview") ); 0493 UpcomingEventsMapWidget *view = new UpcomingEventsMapWidget( stackItem ); 0494 stackItem->setIcon( QIcon::fromTheme( "edit-find" ) ); 0495 stackItem->setTitle( i18n( "Map View" ) ); 0496 stackItem->setWidget( view ); 0497 stackItem->setMinimumWidth( 50 ); 0498 stackItem->showCloseButton(); 0499 m_stack->setMinimumWidth( 50 ); 0500 const QRegExp pattern( QLatin1String("^(?!(venuemapview|calendar)).*$") ); 0501 QList<UpcomingEventsStackItem*> eventItems = m_stack->items( pattern ); 0502 foreach( UpcomingEventsStackItem *item, eventItems ) 0503 { 0504 typedef UpcomingEventsListWidget LW; 0505 if( item ) 0506 view->addEventsListWidget( qgraphicsitem_cast<LW*>( item->widget() ) ); 0507 } 0508 connect( this, SIGNAL(listWidgetAdded(UpcomingEventsListWidget*)), 0509 view, SLOT(addEventsListWidget(UpcomingEventsListWidget*)) ); 0510 connect( this, SIGNAL(listWidgetRemoved(UpcomingEventsListWidget*)), 0511 view, SLOT(removeEventsListWidget(UpcomingEventsListWidget*)) ); 0512 return view; 0513 } 0514 0515 void 0516 UpcomingEventsApplet::collapseStateChanged() 0517 { 0518 emit sizeHintChanged( Qt::PreferredSize ); 0519 } 0520 0521 void 0522 UpcomingEventsApplet::viewCalendar() 0523 { 0524 if( m_stack->hasItem("calendar") ) 0525 { 0526 m_stack->item("calendar")->setCollapsed( false ); 0527 return; 0528 } 0529 0530 UpcomingEventsStackItem *stackItem = m_stack->create( QLatin1String("calendar") ); 0531 UpcomingEventsCalendarWidget *calendar = new UpcomingEventsCalendarWidget( stackItem ); 0532 stackItem->setIcon( QIcon::fromTheme( "view-calendar" ) ); 0533 stackItem->setTitle( i18n( "Events Calendar" ) ); 0534 stackItem->setWidget( calendar ); 0535 stackItem->setMinimumWidth( 50 ); 0536 stackItem->showCloseButton(); 0537 stackItem->addAction( "jumptotoday", calendar->todayAction() ); 0538 const QRegExp pattern( QLatin1String("^(?!(venuemapview|calendar)).*$") ); 0539 QList<UpcomingEventsStackItem*> eventItems = m_stack->items( pattern ); 0540 foreach( UpcomingEventsStackItem *item, eventItems ) 0541 { 0542 typedef UpcomingEventsListWidget LW; 0543 if( item ) 0544 calendar->addEvents( qgraphicsitem_cast<LW*>( item->widget() )->events() ); 0545 } 0546 } 0547 0548 QString 0549 UpcomingEventsApplet::currentTimeSpan() 0550 { 0551 QString span = ui_GeneralSettings.filterComboBox->currentText(); 0552 if( span == i18n("This week") ) 0553 return "ThisWeek"; 0554 else if( span == i18n("This month") ) 0555 return "ThisMonth"; 0556 else if( span == i18n("This year") ) 0557 return "ThisYear"; 0558 else 0559 return "AllEvents"; 0560 } 0561 0562 void 0563 UpcomingEventsApplet::navigateToArtist() 0564 { 0565 if( m_artistEventsList->name().isEmpty() ) 0566 return; 0567 0568 AmarokUrl url; 0569 url.setCommand( "navigate" ); 0570 url.setPath( "collections" ); 0571 url.setArg( "filter", "artist:\"" + m_artistEventsList->name() + "\"" ); 0572 url.run(); 0573 } 0574 0575 void 0576 UpcomingEventsApplet::handleMapRequest( QObject *widget ) 0577 { 0578 if( !mapView()->isLoaded() ) 0579 { 0580 UpcomingEventsWidget *eventWidget = static_cast<UpcomingEventsWidget*>( widget ); 0581 LastFmVenuePtr venue = eventWidget->eventPtr()->venue(); 0582 mapView()->centerAt( venue ); 0583 m_stack->maximizeItem( QLatin1String("venuemapview") ); 0584 } 0585 } 0586 0587 void 0588 UpcomingEventsApplet::listWidgetDestroyed( QObject *obj ) 0589 { 0590 UpcomingEventsListWidget *widget = static_cast<UpcomingEventsListWidget*>( obj ); 0591 emit listWidgetRemoved( widget ); 0592 } 0593 0594 void 0595 UpcomingEventsApplet::saveTimeSpan() 0596 { 0597 DEBUG_BLOCK 0598 Amarok::config("UpcomingEvents Applet").writeEntry( "timeSpan", currentTimeSpan() ); 0599 dataEngine( "amarok-upcomingEvents" )->query( QString( "timespan:update" ) ); 0600 } 0601 0602 void 0603 UpcomingEventsApplet::saveSettings() 0604 { 0605 clearVenueItems(); 0606 saveTimeSpan(); 0607 0608 // save venue settings 0609 QStringList venueConfig; 0610 m_favoriteVenues.clear(); 0611 for( int i = 0, count = ui_VenueSettings.selectedVenuesList->count() ; i < count; ++i ) 0612 { 0613 int itemId = ui_VenueSettings.selectedVenuesList->item( i )->data( VenueIdRole ).toString().toInt(); 0614 QString itemCity = ui_VenueSettings.selectedVenuesList->item( i )->data( VenueCityRole ).toString(); 0615 QString itemName = ui_VenueSettings.selectedVenuesList->item( i )->data( VenueNameRole ).toString(); 0616 VenueData data = { itemId, itemName, itemCity }; 0617 m_favoriteVenues << data; 0618 venueConfig << (QStringList() << QString::number(itemId) << itemName << itemCity).join( QChar(';') ); 0619 } 0620 Amarok::config("UpcomingEvents Applet").writeEntry( "favVenues", venueConfig ); 0621 0622 enableVenueGrouping( ui_GeneralSettings.groupVenueCheckBox->checkState() == Qt::Checked ); 0623 Amarok::config("UpcomingEvents Applet").writeEntry( "groupVenues", m_groupVenues ); 0624 0625 if( !m_favoriteVenues.isEmpty() ) 0626 dataEngine( "amarok-upcomingEvents" )->query( "venueevents:update" ); 0627 } 0628 0629 void 0630 UpcomingEventsApplet::enableVenueGrouping( bool enable ) 0631 { 0632 m_groupVenues = enable; 0633 if( enable ) 0634 { 0635 if( !m_stack->hasItem("favoritevenuesgroup") ) 0636 { 0637 UpcomingEventsStackItem *item = m_stack->create( QLatin1String("favoritevenuesgroup") ); 0638 UpcomingEventsListWidget *listWidget = new UpcomingEventsListWidget( item ); 0639 listWidget->setName( i18nc( "@title:group", "Favorite Venues" ) ); 0640 QString title = i18ncp("@title:group Number of upcoming events", 0641 "%1: 1 event", "%1: %2 events", 0642 listWidget->name(), listWidget->count()); 0643 item->setTitle( title ); 0644 item->setIcon( "favorites" ); 0645 item->setWidget( listWidget ); 0646 connect( listWidget, SIGNAL(mapRequested(QObject*)), SLOT(handleMapRequest(QObject*)) ); 0647 connect( listWidget, SIGNAL(destroyed(QObject*)), SLOT(listWidgetDestroyed(QObject*)) ); 0648 emit listWidgetAdded( listWidget ); 0649 } 0650 } 0651 else 0652 { 0653 m_stack->remove( QLatin1String("favoritevenuesgroup" ) ); 0654 } 0655 updateConstraints(); 0656 } 0657