29 #include <tqtooltip.h> 31 #include <dcopclient.h> 33 #include <tdeabc/stdaddressbook.h> 34 #include <korganizer/stdcalendar.h> 35 #include <tdeapplication.h> 37 #include <tdeglobal.h> 38 #include <kiconloader.h> 39 #include <tdelocale.h> 40 #include <tdeparts/part.h> 41 #include <tdepopupmenu.h> 42 #include <kstandarddirs.h> 43 #include <kurllabel.h> 44 #include <libkcal/event.h> 45 #include <libkcal/resourcecalendar.h> 46 #include <libkcal/resourcelocal.h> 47 #include <libtdepim/kpimprefs.h> 52 #include "sdsummarywidget.h" 54 enum SDIncidenceType {
55 IncidenceTypeContact, IncidenceTypeEvent
58 CategoryBirthday, CategoryAnniversary, CategoryHoliday, CategoryOther
72 TDEABC::Addressee addressee;
74 bool operator<(
const SDEntry &entry )
const 76 return daysTo < entry.daysTo;
80 SDSummaryWidget::SDSummaryWidget(
Kontact::Plugin *plugin, TQWidget *parent,
82 :
Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 ), mHolidays( 0 )
85 TQVBoxLayout *mainLayout =
new TQVBoxLayout(
this, 3, 3 );
87 TQPixmap
icon = TDEGlobal::iconLoader()->loadIcon(
"cookie",
88 TDEIcon::Desktop, TDEIcon::SizeMedium );
90 TQWidget *header = createHeader(
this, icon, i18n(
"Special Dates" ) );
91 mainLayout->addWidget(header);
93 mLayout =
new TQGridLayout( mainLayout, 7, 6, 3 );
94 mLayout->setRowStretch( 6, 1 );
97 TDEABC::StdAddressBook *ab = TDEABC::StdAddressBook::self(
true );
98 connect( ab, TQT_SIGNAL( addressBookChanged( AddressBook* ) ),
99 this, TQT_SLOT( updateView() ) );
100 connect( mPlugin->core(), TQT_SIGNAL( dayChanged(
const TQDate& ) ),
101 this, TQT_SLOT( updateView() ) );
105 mCalendar->readConfig();
107 KCal::CalendarResourceManager *manager = mCalendar->resourceManager();
108 if ( manager->isEmpty() ) {
109 TDEConfig config(
"korganizerrc" );
110 config.setGroup(
"General" );
111 TQString fileName = config.readPathEntry(
"Active Calendar" );
113 TQString resourceName;
114 if ( fileName.isEmpty() ) {
115 fileName = locateLocal(
"data",
"korganizer/std.ics" );
116 resourceName = i18n(
"Default KOrganizer resource" );
118 resourceName = i18n(
"Active Calendar" );
124 defaultResource->setResourceName( resourceName );
126 manager->add( defaultResource );
127 manager->setStandardResource( defaultResource );
129 mCalendar = KOrg::StdCalendar::self();
131 connect( mCalendar, TQT_SIGNAL( calendarChanged() ),
132 this, TQT_SLOT( updateView() ) );
133 connect( mPlugin->core(), TQT_SIGNAL( dayChanged(
const TQDate& ) ),
134 this, TQT_SLOT( updateView() ) );
140 void SDSummaryWidget::configUpdated()
142 TDEConfig config(
"kcmsdsummaryrc" );
144 config.setGroup(
"Days" );
145 mDaysAhead = config.readNumEntry(
"DaysToShow", 7 );
147 config.setGroup(
"EventTypes" );
148 mShowBirthdaysFromKAB =
149 config.readBoolEntry(
"ShowBirthdaysFromContacts",
true );
150 mShowBirthdaysFromCal =
151 config.readBoolEntry(
"ShowBirthdaysFromCalendar",
true );
153 mShowAnniversariesFromKAB =
154 config.readBoolEntry(
"ShowAnniversariesFromContacts",
true );
155 mShowAnniversariesFromCal =
156 config.readBoolEntry(
"ShowAnniversariesFromCalendar",
true );
159 config.readBoolEntry(
"ShowHolidays",
true );
161 mShowSpecialsFromCal =
162 config.readBoolEntry(
"ShowSpecialsFromCalendar",
true );
167 bool SDSummaryWidget::initHolidays()
169 TDEConfig hconfig(
"korganizerrc" );
170 hconfig.setGroup(
"Time & Date" );
171 TQString location = hconfig.readEntry(
"Holidays" );
172 if ( !location.isEmpty() ) {
173 if ( mHolidays )
delete mHolidays;
174 mHolidays =
new KHolidays( location );
184 if ( event->
isMultiDay() &&
event->doesFloat() ) {
185 TQDate d =
event->dtStart().date();
186 if ( d < TQDate::currentDate() ) {
187 d = TQDate::currentDate();
189 while ( d < event->dtEnd().date() ) {
198 int SDSummaryWidget::dayof(
KCal::Event *event,
const TQDate& date )
201 TQDate d =
event->dtStart().date();
202 if ( d < TQDate::currentDate() ) {
203 d = TQDate::currentDate();
205 while ( d < event->dtEnd().date() ) {
216 void SDSummaryWidget::updateView()
218 mLabels.setAutoDelete(
true );
220 mLabels.setAutoDelete(
false );
222 TDEIconLoader loader(
"tdepim" );
224 TDEABC::StdAddressBook *ab = TDEABC::StdAddressBook::self(
true );
225 TQValueList<SDEntry> dates;
229 TQString savefmt = TDEGlobal::locale()->dateFormat();
230 TDEGlobal::locale()->setDateFormat( TDEGlobal::locale()->
231 dateFormat().replace(
'Y',
' ' ) );
234 TDEABC::AddressBook::Iterator it;
235 for ( it = ab->begin(); it != ab->end(); ++it ) {
236 TQDate birthday = (*it).birthday().date();
237 if ( birthday.isValid() && mShowBirthdaysFromKAB ) {
239 entry.type = IncidenceTypeContact;
240 entry.category = CategoryBirthday;
241 dateDiff( birthday, entry.daysTo, entry.yearsOld );
243 entry.date = birthday;
244 entry.addressee = *it;
246 if ( entry.daysTo <= mDaysAhead )
247 dates.append( entry );
250 TQString anniversaryAsString =
251 (*it).custom(
"KADDRESSBOOK" ,
"X-Anniversary" );
252 if ( !anniversaryAsString.isEmpty() ) {
253 TQDate anniversary = TQDate::fromString( anniversaryAsString, Qt::ISODate );
254 if ( anniversary.isValid() && mShowAnniversariesFromKAB ) {
256 entry.type = IncidenceTypeContact;
257 entry.category = CategoryAnniversary;
258 dateDiff( anniversary, entry.daysTo, entry.yearsOld );
260 entry.date = anniversary;
261 entry.addressee = *it;
263 if ( entry.daysTo <= mDaysAhead )
264 dates.append( entry );
272 TQDate currentDate = TQDate::currentDate();
273 for ( dt=currentDate;
274 dt<=currentDate.addDays( mDaysAhead - 1 );
276 KCal::Event::List events = mCalendar->events( dt,
277 KCal::EventSortStartDate,
278 KCal::SortDirectionAscending );
280 KCal::Event::List::ConstIterator it;
281 for ( it=events.begin(); it!=events.end(); ++it ) {
284 TQStringList::ConstIterator it2;
286 for ( it2=c.begin(); it2!=c.end(); ++it2 ) {
289 if ( mShowBirthdaysFromCal &&
290 ( ( *it2 ).upper() == i18n(
"BIRTHDAY" ) ) ) {
292 entry.type = IncidenceTypeEvent;
293 entry.category = CategoryBirthday;
297 dateDiff( ev->
dtStart().date(), entry.daysTo, entry.yearsOld );
299 dates.append( entry );
304 if ( mShowAnniversariesFromCal &&
305 ( ( *it2 ).upper() == i18n(
"ANNIVERSARY" ) ) ) {
307 entry.type = IncidenceTypeEvent;
308 entry.category = CategoryAnniversary;
312 dateDiff( ev->
dtStart().date(), entry.daysTo, entry.yearsOld );
314 dates.append( entry );
319 if ( mShowHolidays &&
320 ( ( *it2 ).upper() == i18n(
"HOLIDAY" ) ) ) {
322 entry.type = IncidenceTypeEvent;
323 entry.category = CategoryHoliday;
327 dateDiff( dt, entry.daysTo, entry.yearsOld );
329 entry.span = span( ev );
330 if ( entry.span > 1 && dayof( ev, dt ) > 1 )
332 dates.append( entry );
337 if ( mShowSpecialsFromCal &&
338 ( ( *it2 ).upper() == i18n(
"SPECIAL OCCASION" ) ) ) {
340 entry.type = IncidenceTypeEvent;
341 entry.category = CategoryOther;
345 dateDiff( dt, entry.daysTo, entry.yearsOld );
347 entry.span = span( ev );
348 if ( entry.span > 1 && dayof( ev, dt ) > 1 )
350 dates.append( entry );
359 if ( mShowHolidays ) {
360 if ( initHolidays() ) {
361 for ( dt=currentDate;
362 dt<=currentDate.addDays( mDaysAhead - 1 );
364 TQValueList<KHoliday> holidays = mHolidays->getHolidays( dt );
365 TQValueList<KHoliday>::ConstIterator it = holidays.begin();
366 for ( ; it != holidays.end(); ++it ) {
368 entry.type = IncidenceTypeEvent;
369 entry.category = ((*it).Category==KHolidays::HOLIDAY)?CategoryHoliday:CategoryOther;
371 entry.summary = (*it).text;
372 dateDiff( dt, entry.daysTo, entry.yearsOld );
375 dates.append( entry );
384 if ( !dates.isEmpty() ) {
386 TQValueList<SDEntry>::Iterator addrIt;
388 for ( addrIt = dates.begin(); addrIt != dates.end(); ++addrIt ) {
389 bool makeBold = (*addrIt).daysTo == 0;
395 switch( (*addrIt).category ) {
396 case CategoryBirthday:
397 icon_name =
"calendarbirthday";
398 pic = (*addrIt).addressee.photo();
399 if ( pic.isIntern() && !pic.data().isNull() ) {
400 TQImage img = pic.data();
401 if ( img.width() > img.height() ) {
402 icon_img = img.scaleWidth( 32 );
404 icon_img = img.scaleHeight( 32 );
408 case CategoryAnniversary:
409 icon_name =
"calendaranniversary";
410 pic = (*addrIt).addressee.photo();
411 if ( pic.isIntern() && !pic.data().isNull() ) {
412 TQImage img = pic.data();
413 if ( img.width() > img.height() ) {
414 icon_img = img.scaleWidth( 32 );
416 icon_img = img.scaleHeight( 32 );
420 case CategoryHoliday:
421 icon_name =
"calendarholiday";
break;
423 icon_name =
"cookie";
break;
425 label =
new TQLabel(
this );
426 if ( icon_img.isNull() ) {
427 label->setPixmap( TDEGlobal::iconLoader()->loadIcon( icon_name,
430 label->setPixmap( icon_img );
432 label->setMaximumWidth( label->minimumSizeHint().width() );
433 label->setAlignment( AlignVCenter );
434 mLayout->addWidget( label, counter, 0 );
435 mLabels.append( label );
441 int year = currentDate.addDays( (*addrIt).daysTo ).year();
442 TQDate sD = TQDate( year, (*addrIt).date.month(), (*addrIt).date.day() );
444 if ( (*addrIt).daysTo == 0 ) {
445 datestr = i18n(
"Today" );
446 }
else if ( (*addrIt).daysTo == 1 ) {
447 datestr = i18n(
"Tomorrow" );
449 datestr = TDEGlobal::locale()->formatDate( sD );
453 if ( (*addrIt).span > 1 ) {
455 TDEGlobal::locale()->formatDate( sD.addDays( (*addrIt).span - 1 ) );
456 datestr +=
" -\n " + endstr;
459 label =
new TQLabel( datestr,
this );
460 label->setAlignment( AlignLeft | AlignVCenter );
461 mLayout->addWidget( label, counter, 1 );
462 mLabels.append( label );
464 TQFont font = label->font();
465 font.setBold(
true );
466 label->setFont( font );
470 label =
new TQLabel(
this );
471 if ( (*addrIt).daysTo == 0 ) {
472 label->setText( i18n(
"now" ) );
474 label->setText( i18n(
"in 1 day",
"in %n days", (*addrIt).daysTo ) );
477 label->setAlignment( AlignLeft | AlignVCenter );
478 mLayout->addWidget( label, counter, 2 );
479 mLabels.append( label );
483 switch( (*addrIt).category ) {
484 case CategoryBirthday:
485 what = i18n(
"Birthday" );
break;
486 case CategoryAnniversary:
487 what = i18n(
"Anniversary" );
break;
488 case CategoryHoliday:
489 what = i18n(
"Holiday" );
break;
491 what = i18n(
"Special Occasion" );
break;
493 label =
new TQLabel(
this );
494 label->setText( what );
495 label->setAlignment( AlignLeft | AlignVCenter );
496 mLayout->addWidget( label, counter, 3 );
497 mLabels.append( label );
500 if ( (*addrIt).type == IncidenceTypeContact ) {
501 KURLLabel *urlLabel =
new KURLLabel(
this );
502 urlLabel->installEventFilter(
this );
503 urlLabel->setURL( (*addrIt).addressee.uid() );
504 urlLabel->setText( (*addrIt).addressee.realName() );
505 urlLabel->setTextFormat( TQt::RichText );
506 mLayout->addWidget( urlLabel, counter, 4 );
507 mLabels.append( urlLabel );
509 connect( urlLabel, TQT_SIGNAL( leftClickedURL(
const TQString& ) ),
510 this, TQT_SLOT( mailContact(
const TQString& ) ) );
511 connect( urlLabel, TQT_SIGNAL( rightClickedURL(
const TQString& ) ),
512 this, TQT_SLOT( popupMenu(
const TQString& ) ) );
514 label =
new TQLabel(
this );
515 label->setText( (*addrIt).summary );
516 label->setTextFormat( TQt::RichText );
517 mLayout->addWidget( label, counter, 4 );
518 mLabels.append( label );
519 if ( !(*addrIt).desc.isEmpty() ) {
520 TQToolTip::add( label, (*addrIt).desc );
525 if ( (*addrIt).category == CategoryBirthday ||
526 (*addrIt).category == CategoryAnniversary ) {
527 label =
new TQLabel(
this );
528 if ( (*addrIt).yearsOld <= 0 ) {
529 label->setText(
"" );
531 label->setText( i18n(
"one year",
"%n years", (*addrIt).yearsOld ) );
533 label->setAlignment( AlignLeft | AlignVCenter );
534 mLayout->addWidget( label, counter, 5 );
535 mLabels.append( label );
542 i18n(
"No special dates within the next 1 day",
543 "No special dates pending within the next %n days",
544 mDaysAhead ),
this,
"nothing to see" );
545 label->setAlignment( AlignHCenter | AlignVCenter );
546 mLayout->addMultiCellWidget( label, 0, 0, 0, 4 );
547 mLabels.append( label );
550 for ( label = mLabels.first(); label; label = mLabels.next() )
553 TDEGlobal::locale()->setDateFormat( savefmt );
556 void SDSummaryWidget::mailContact(
const TQString &uid )
558 TDEABC::StdAddressBook *ab = TDEABC::StdAddressBook::self(
true );
559 TQString email = ab->findByUid( uid ).fullEmail();
561 kapp->invokeMailer( email, TQString() );
564 void SDSummaryWidget::viewContact(
const TQString &uid )
566 if ( !mPlugin->isRunningStandalone() )
567 mPlugin->core()->selectPlugin(
"kontact_kaddressbookplugin" );
569 mPlugin->bringToForeground();
571 DCOPRef dcopCall(
"kaddressbook",
"KAddressBookIface" );
572 dcopCall.send(
"showContactEditor(TQString)", uid );
575 void SDSummaryWidget::popupMenu(
const TQString &uid )
577 TDEPopupMenu popup(
this );
578 popup.insertItem( TDEGlobal::iconLoader()->loadIcon(
"kmail", TDEIcon::Small ),
579 i18n(
"Send &Mail" ), 0 );
580 popup.insertItem( TDEGlobal::iconLoader()->loadIcon(
"kaddressbook", TDEIcon::Small ),
581 i18n(
"View &Contact" ), 1 );
583 switch ( popup.exec( TQCursor::pos() ) ) {
593 bool SDSummaryWidget::eventFilter( TQObject *obj, TQEvent* e )
595 if ( obj->inherits(
"KURLLabel" ) ) {
596 KURLLabel* label =
static_cast<KURLLabel*
>( TQT_TQWIDGET(obj) );
597 if ( e->type() == TQEvent::Enter )
598 emit message( i18n(
"Mail to:\"%1\"" ).arg( label->text() ) );
599 if ( e->type() == TQEvent::Leave )
600 emit message( TQString() );
603 return Kontact::Summary::eventFilter( obj, e );
606 void SDSummaryWidget::dateDiff(
const TQDate &date,
int &days,
int &years )
611 if ( TQDate::leapYear( date.year() ) && date.month() == 2 && date.day() == 29 ) {
612 currentDate = TQDate( date.year(), TQDate::currentDate().month(), TQDate::currentDate().day() );
613 if ( !TQDate::leapYear( TQDate::currentDate().year() ) )
614 eventDate = TQDate( date.year(), date.month(), 28 );
616 eventDate = TQDate( date.year(), date.month(), date.day() );
618 currentDate = TQDate( 0, TQDate::currentDate().month(), TQDate::currentDate().day() );
619 eventDate = TQDate( 0, date.month(), date.day() );
622 int offset = currentDate.daysTo( eventDate );
625 years = TQDate::currentDate().year() + 1 - date.year();
628 years = TQDate::currentDate().year() - date.year();
632 TQStringList SDSummaryWidget::configModules()
const 634 return TQStringList(
"kcmsdsummary.desktop" );
637 #include "sdsummarywidget.moc" virtual TQDateTime dtStart() const
TQString description() const
TQStringList categories() const
TQString icon() const
Returns the icon name.
TQString categoriesStr() const
Base class for all Plugins in Kontact.
virtual void configUpdated()
This function is called whenever the config dialog has been closed successfully.