korganizer/summarywidget.cpp
1/*
2 This file is part of Kontact.
3 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 As a special exception, permission is given to link this program
20 with any edition of TQt, and distribute the resulting executable,
21 without including the source code for TQt in the source distribution.
22*/
23
24#include <tqcursor.h>
25#include <tqlabel.h>
26#include <tqlayout.h>
27#include <tqtooltip.h>
28
29#include <kdialog.h>
30#include <tdeglobal.h>
31#include <kiconloader.h>
32#include <tdelocale.h>
33#include <tdeparts/part.h>
34#include <tdepopupmenu.h>
35#include <tdestandarddirs.h>
36#include <kurllabel.h>
37#include <libkcal/event.h>
38#include <libkcal/resourcecalendar.h>
39#include <libkcal/resourcelocal.h>
40#include <libkcal/incidenceformatter.h>
41#include <libtdepim/kpimprefs.h>
42
43#include "korganizeriface_stub.h"
44
45#include "core.h"
46#include "plugin.h"
47#include "korganizerplugin.h"
48
49#include "korganizer/stdcalendar.h"
50
51#include "summarywidget.h"
52
53SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, TQWidget *parent,
54 const char *name )
55 : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
56{
57 TQVBoxLayout *mainLayout = new TQVBoxLayout( this, 3, 3 );
58
59 TQPixmap icon = TDEGlobal::iconLoader()->loadIcon( "kontact_date",
60 TDEIcon::Desktop, TDEIcon::SizeMedium );
61 TQWidget *header = createHeader( this, icon, i18n( "Calendar" ) );
62 mainLayout->addWidget( header );
63
64 mLayout = new TQGridLayout( mainLayout, 7, 5, 3 );
65 mLayout->setRowStretch( 6, 1 );
66
67 mCalendar = KOrg::StdCalendar::self();
68
69 connect( mCalendar, TQ_SIGNAL( calendarChanged() ), TQ_SLOT( updateView() ) );
70 connect( mPlugin->core(), TQ_SIGNAL( dayChanged( const TQDate& ) ),
71 TQ_SLOT( updateView() ) );
72
73 updateView();
74}
75
76SummaryWidget::~SummaryWidget()
77{
78}
79
80void SummaryWidget::updateView()
81{
82 mLabels.setAutoDelete( true );
83 mLabels.clear();
84 mLabels.setAutoDelete( false );
85
86 TDEIconLoader loader( "tdepim" );
87
88 TDEConfig config( "kcmkorgsummaryrc" );
89
90 config.setGroup( "Calendar" );
91 int days = config.readNumEntry( "DaysToShow", 1 );
92
93 TQLabel *label = 0;
94 int counter = 0;
95 TQPixmap pm = loader.loadIcon( "appointment", TDEIcon::Small );
96 TQPixmap pmb = loader.loadIcon( "calendarbirthday", TDEIcon::Small );
97 TQPixmap pma = loader.loadIcon( "calendaranniversary", TDEIcon::Small );
98
99 TQDate dt;
100 TQDate currentDate = TQDate::currentDate();
101 for ( dt=currentDate;
102 dt<=currentDate.addDays( days - 1 );
103 dt=dt.addDays(1) ) {
104
105 KCal::Event::List events = mCalendar->events( dt );
106
107 // sort the events for this date by summary
108 events = KCal::Calendar::sortEventsForDate( &events,
109 dt,
110 KCal::EventSortSummary,
111 KCal::SortDirectionAscending );
112 // sort the events for this date by start date
113 events = KCal::Calendar::sortEventsForDate( &events,
114 dt,
115 KCal::EventSortStartDate,
116 KCal::SortDirectionAscending );
117
118 KCal::Event::List::ConstIterator it = events.begin();
119 for ( it=events.begin(); it!=events.end(); ++it ) {
120 KCal::Event *ev = *it;
121
122 // Count number of days remaining in multiday event
123 int span=1; int dayof=1;
124 if ( ev->isMultiDay() ) {
125 TQDate d = ev->dtStart().date();
126 if ( d < currentDate ) {
127 d = currentDate;
128 }
129 while ( d < ev->dtEnd().date() ) {
130 if ( d < dt ) {
131 dayof++;
132 }
133 span++;
134 d=d.addDays( 1 );
135 }
136 }
137
138 // If this date is part of a floating, multiday event, then we
139 // only make a print for the first day of the event.
140 if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 ) continue;
141
142 // Fill Appointment Pixmap Field
143 label = new TQLabel( this );
144 if ( ev->categories().contains( "Birthday" ) ) {
145 label->setPixmap( pmb );
146 } else if ( ev->categories().contains( "Anniversary" ) ) {
147 label->setPixmap( pma );
148 } else {
149 label->setPixmap( pm );
150 }
151 label->setMaximumWidth( label->minimumSizeHint().width() );
152 label->setAlignment( AlignVCenter );
153 mLayout->addWidget( label, counter, 0 );
154 mLabels.append( label );
155
156 // Fill Event Date Field
157 bool makeBold = false;
158 TQString datestr;
159
160 // Modify event date for printing
161 TQDate sD = TQDate( dt.year(), dt.month(), dt.day() );
162 if ( ( sD.month() == currentDate.month() ) &&
163 ( sD.day() == currentDate.day() ) ) {
164 datestr = i18n( "Today" );
165 makeBold = true;
166 } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) &&
167 ( sD.day() == currentDate.addDays( 1 ).day() ) ) {
168 datestr = i18n( "Tomorrow" );
169 } else {
170 datestr = TDEGlobal::locale()->formatDate( sD );
171 }
172
173 // Print the date span for multiday, floating events, for the
174 // first day of the event only.
175 if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
176 datestr = TDEGlobal::locale()->formatDate( ev->dtStart().date() );
177 datestr += " -\n " +
178 TDEGlobal::locale()->formatDate( sD.addDays( span-1 ) );
179 }
180
181 label = new TQLabel( datestr, this );
182 label->setAlignment( AlignLeft | AlignVCenter );
183 if ( makeBold ) {
184 TQFont font = label->font();
185 font.setBold( true );
186 label->setFont( font );
187 }
188 mLayout->addWidget( label, counter, 1 );
189 mLabels.append( label );
190
191 // Fill Event Summary Field
192 TQString newtext = ev->summary();
193 if ( ev->isMultiDay() && !ev->doesFloat() ) {
194 newtext.append( TQString(" (%1/%2)").arg( dayof ).arg( span ) );
195 }
196
197 KURLLabel *urlLabel = new KURLLabel( this );
198 urlLabel->setText( newtext );
199 urlLabel->setURL( ev->uid() );
200 urlLabel->installEventFilter( this );
201 urlLabel->setAlignment( urlLabel->alignment() | TQt::WordBreak );
202 mLayout->addWidget( urlLabel, counter, 2 );
203 mLabels.append( urlLabel );
204
205 connect( urlLabel, TQ_SIGNAL( leftClickedURL( const TQString& ) ),
206 this, TQ_SLOT( viewEvent( const TQString& ) ) );
207 connect( urlLabel, TQ_SIGNAL( rightClickedURL( const TQString& ) ),
208 this, TQ_SLOT( popupMenu( const TQString& ) ) );
209
210 TQString tipText( KCal::IncidenceFormatter::toolTipStr( mCalendar, ev, dt, true ) );
211 if ( !tipText.isEmpty() ) {
212 TQToolTip::add( urlLabel, tipText );
213 }
214
215 // Fill Event Time Range Field (only for non-floating Events)
216 if ( !ev->doesFloat() ) {
217 TQTime sST = ev->dtStart().time();
218 TQTime sET = ev->dtEnd().time();
219 if ( ev->isMultiDay() ) {
220 if ( ev->dtStart().date() < dt ) {
221 sST = TQTime( 0, 0 );
222 }
223 if ( ev->dtEnd().date() > dt ) {
224 sET = TQTime( 23, 59 );
225 }
226 }
227 datestr = i18n( "Time from - to", "%1 - %2" )
228 .arg( TDEGlobal::locale()->formatTime( sST ) )
229 .arg( TDEGlobal::locale()->formatTime( sET ) );
230 label = new TQLabel( datestr, this );
231 label->setAlignment( AlignLeft | AlignVCenter );
232 mLayout->addWidget( label, counter, 3 );
233 mLabels.append( label );
234 }
235
236 counter++;
237 }
238 }
239
240 if ( !counter ) {
241 TQLabel *noEvents = new TQLabel(
242 i18n( "No appointments pending within the next day",
243 "No appointments pending within the next %n days",
244 days ), this, "nothing to see" );
245 noEvents->setAlignment( AlignHCenter | AlignVCenter );
246 mLayout->addWidget( noEvents, 0, 2 );
247 mLabels.append( noEvents );
248 }
249
250 for ( label = mLabels.first(); label; label = mLabels.next() )
251 label->show();
252}
253
254void SummaryWidget::viewEvent( const TQString &uid )
255{
256 mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
257 KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
258 iface.editIncidence( uid );
259}
260
261void SummaryWidget::removeEvent( const TQString &uid )
262{
263 mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
264 KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
265 iface.deleteIncidence( uid, false );
266}
267
268void SummaryWidget::popupMenu( const TQString &uid )
269{
270 TDEPopupMenu popup( this );
271 TQToolTip::remove( this );
272 popup.insertItem( i18n( "&Edit Appointment..." ), 0 );
273 popup.insertItem( TDEGlobal::iconLoader()->loadIcon( "edit-delete", TDEIcon::Small),
274 i18n( "&Delete Appointment" ), 1 );
275
276 switch ( popup.exec( TQCursor::pos() ) ) {
277 case 0:
278 viewEvent( uid );
279 break;
280 case 1:
281 removeEvent( uid );
282 break;
283 }
284}
285
286bool SummaryWidget::eventFilter( TQObject *obj, TQEvent* e )
287{
288 if ( obj->inherits( "KURLLabel" ) ) {
289 KURLLabel* label = static_cast<KURLLabel*>( obj );
290 if ( e->type() == TQEvent::Enter )
291 emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
292 if ( e->type() == TQEvent::Leave )
293 emit message( TQString() );
294 }
295
296 return Kontact::Summary::eventFilter( obj, e );
297}
298
299TQStringList SummaryWidget::configModules() const
300{
301 return TQStringList( "kcmkorgsummary.desktop" );
302}
303
304#include "summarywidget.moc"
static Event::List sortEventsForDate(Event::List *eventList, const TQDate &date, EventSortField sortField, SortDirection sortDirection)
virtual TQDateTime dtEnd() const
bool isMultiDay() const
bool doesFloat() const
TQString uid() const
virtual TQDateTime dtStart() const
TQStringList categories() const
TQString summary() const