1 /****************************************************************************************
2  * Copyright (c) 2010 Rick W. Chen <stuffcorpse@archlinux.us>                           *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16 
17 #include "UpcomingEventsCalendarWidget.h"
18 #include "PaletteHandler.h"
19 
20 #include <KColorUtils>
21 #include <KDateTime>
22 #include <KGlobal>
23 #include <QIcon>
24 #include <KLocale>
25 #include <KSystemTimeZones>
26 
27 #include <QAction>
28 #include <QCalendarWidget>
29 #include <QTextCharFormat>
30 #include <QTimer>
31 
32 class UpcomingEventsCalendarWidgetPrivate
33 {
34 public:
UpcomingEventsCalendarWidgetPrivate(UpcomingEventsCalendarWidget * parent)35     UpcomingEventsCalendarWidgetPrivate( UpcomingEventsCalendarWidget* parent )
36         : todayAction( 0 )
37         , q_ptr( parent )
38     {
39         calendar = new QCalendarWidget;
40         calendar->setGridVisible( true );
41         calendar->setNavigationBarVisible( true );
42         calendar->setFirstDayOfWeek( Qt::DayOfWeek(KGlobal::locale()->weekStartDay()) );
43     }
44 
~UpcomingEventsCalendarWidgetPrivate()45     ~UpcomingEventsCalendarWidgetPrivate() {}
46 
addEvent(const LastFmEventPtr & e)47     void addEvent( const LastFmEventPtr &e )
48     {
49         events << e;
50         QDate dt = e->date().date();
51         QTextCharFormat format = calendar->dateTextFormat( dt );
52         format.setFontUnderline( true );
53         format.setToolTip( e->name() );
54         format.setBackground( eventBackground );
55         calendar->setDateTextFormat( dt, format );
56     }
57 
addEvents(const LastFmEvent::List & e)58     void addEvents( const LastFmEvent::List &e )
59     {
60         QSet<LastFmEventPtr> newEvents = e.toSet().subtract( events );
61         foreach( const LastFmEventPtr &event, newEvents )
62             addEvent( event );
63     }
64 
_updateToday()65     void _updateToday()
66     {
67         Q_Q( UpcomingEventsCalendarWidget );
68         QDateTime now = QDateTime::currentDateTime();
69         int updateIn = (24 * 60 * 60) - (now.toTime_t() + KSystemTimeZones::local().currentOffset()) % (24 * 60 * 60);
70         QTimer::singleShot( updateIn * 1000, q, SLOT(_updateToday()) );
71 
72         if( !todayDate.isNull() )
73         {
74             QTextCharFormat format = calendar->dateTextFormat( todayDate );
75             format.setFontWeight( QFont::Normal );
76             calendar->setDateTextFormat( todayDate, format );
77         }
78 
79         todayDate = now.date();
80         QTextCharFormat format = calendar->dateTextFormat( todayDate );
81         format.setFontWeight( QFont::Bold );
82         calendar->setDateTextFormat( todayDate, format );
83     }
84 
_jumpToToday()85     void _jumpToToday()
86     {
87         calendar->showToday();
88         calendar->setSelectedDate( todayDate );
89     }
90 
_paletteChanged(const QPalette & palette)91     void _paletteChanged( const QPalette &palette )
92     {
93         QColor base = palette.color( QPalette::Base );
94         QColor high = palette.color( QPalette::Highlight );
95         eventBackground = QBrush( KColorUtils::tint( base, high, 0.4 ) );
96 
97         QList<QDate> eventDates;
98         foreach( const LastFmEventPtr &event, events )
99             eventDates << event->date().date();
100 
101         foreach( const QDate &date, eventDates )
102         {
103             QTextCharFormat format = calendar->dateTextFormat( date );
104             format.setBackground( eventBackground );
105             calendar->setDateTextFormat( date, format );
106         }
107     }
108 
109     QAction *todayAction;
110     QDate todayDate;
111     QBrush eventBackground;
112     QCalendarWidget *calendar;
113     QSet<LastFmEventPtr> events;
114 
115 private:
116     UpcomingEventsCalendarWidget *const q_ptr;
117     Q_DECLARE_PUBLIC( UpcomingEventsCalendarWidget )
118 };
119 
UpcomingEventsCalendarWidget(QGraphicsItem * parent,Qt::WindowFlags wFlags)120 UpcomingEventsCalendarWidget::UpcomingEventsCalendarWidget( QGraphicsItem *parent, Qt::WindowFlags wFlags )
121     : QGraphicsProxyWidget( parent, wFlags )
122     , d_ptr( new UpcomingEventsCalendarWidgetPrivate( this ) )
123 {
124     Q_D( UpcomingEventsCalendarWidget );
125     setWidget( d->calendar );
126     QColor base = The::paletteHandler()->palette().color( QPalette::Base );
127     QColor high = The::paletteHandler()->palette().color( QPalette::Highlight );
128     d->eventBackground = QBrush( KColorUtils::tint( base, high, 0.4 ) );
129     d->_updateToday();
130     connect( The::paletteHandler(), SIGNAL(newPalette(QPalette)), SLOT(_paletteChanged(QPalette)) );
131 }
132 
~UpcomingEventsCalendarWidget()133 UpcomingEventsCalendarWidget::~UpcomingEventsCalendarWidget()
134 {
135     delete d_ptr;
136 }
137 
138 void
clear()139 UpcomingEventsCalendarWidget::clear()
140 {
141     Q_D( UpcomingEventsCalendarWidget );
142     d->calendar->setDateTextFormat( QDate(), QTextCharFormat() );
143     d->events.clear();
144 }
145 
146 LastFmEvent::List
events() const147 UpcomingEventsCalendarWidget::events() const
148 {
149     Q_D( const UpcomingEventsCalendarWidget );
150     return d->events.toList();
151 }
152 
153 QAction *
todayAction()154 UpcomingEventsCalendarWidget::todayAction()
155 {
156     Q_D( UpcomingEventsCalendarWidget );
157     if( !d->todayAction )
158     {
159         d->todayAction = new QAction( QIcon::fromTheme("go-jump-today"), QString(), this );
160         d->todayAction->setToolTip( i18nc( "@info:tooltip Calendar action", "Jump to Today" ) );
161         connect( d->todayAction, SIGNAL(triggered()), SLOT(_jumpToToday()) );
162     }
163     return d->todayAction;
164 }
165 
166 void
addEvent(const LastFmEventPtr & event)167 UpcomingEventsCalendarWidget::addEvent( const LastFmEventPtr &event )
168 {
169     Q_D( UpcomingEventsCalendarWidget );
170     d->addEvent( event );
171 }
172 
173 void
addEvents(const LastFmEvent::List & events)174 UpcomingEventsCalendarWidget::addEvents( const LastFmEvent::List &events )
175 {
176     Q_D( UpcomingEventsCalendarWidget );
177     d->addEvents( events );
178 }
179 
180