kontact

sdsummarywidget.cpp
00001 /*
00002     This file is part of Kontact.
00003     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00004     Copyright (c) 2004 Allen Winter <winter@kde.org>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of TQt, and distribute the resulting executable,
00022     without including the source code for TQt in the source distribution.
00023 */
00024 
00025 #include <tqcursor.h>
00026 #include <tqlabel.h>
00027 #include <tqlayout.h>
00028 #include <tqimage.h>
00029 #include <tqtooltip.h>
00030 
00031 #include <dcopclient.h>
00032 #include <dcopref.h>
00033 #include <kabc/stdaddressbook.h>
00034 #include <korganizer/stdcalendar.h>
00035 #include <kapplication.h>
00036 #include <kdialog.h>
00037 #include <kglobal.h>
00038 #include <kiconloader.h>
00039 #include <klocale.h>
00040 #include <kparts/part.h>
00041 #include <kpopupmenu.h>
00042 #include <kstandarddirs.h>
00043 #include <kurllabel.h>
00044 #include <libkcal/event.h>
00045 #include <libkcal/resourcecalendar.h>
00046 #include <libkcal/resourcelocal.h>
00047 #include <libkdepim/kpimprefs.h>
00048 
00049 #include "core.h"
00050 #include "plugin.h"
00051 
00052 #include "sdsummarywidget.h"
00053 
00054 enum SDIncidenceType {
00055   IncidenceTypeContact, IncidenceTypeEvent
00056 };
00057 enum SDCategory {
00058   CategoryBirthday, CategoryAnniversary, CategoryHoliday, CategoryOther
00059 };
00060 
00061 class SDEntry
00062 {
00063   public:
00064     SDIncidenceType type;
00065     SDCategory category;
00066     int yearsOld;
00067     int daysTo;
00068     TQDate date;
00069     TQString summary;
00070     TQString desc;
00071     int span; // #days in the special occassion.
00072     KABC::Addressee addressee;
00073 
00074     bool operator<( const SDEntry &entry ) const
00075     {
00076       return daysTo < entry.daysTo;
00077     }
00078 };
00079 
00080 SDSummaryWidget::SDSummaryWidget( Kontact::Plugin *plugin, TQWidget *parent,
00081                                     const char *name )
00082   : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 ), mHolidays( 0 )
00083 {
00084   // Create the Summary Layout
00085   TQVBoxLayout *mainLayout = new TQVBoxLayout( this, 3, 3 );
00086 
00087   TQPixmap icon = KGlobal::iconLoader()->loadIcon( "cookie",
00088                     KIcon::Desktop, KIcon::SizeMedium );
00089 
00090   TQWidget *header = createHeader( this, icon, i18n( "Special Dates" ) );
00091   mainLayout->addWidget(header);
00092 
00093   mLayout = new TQGridLayout( mainLayout, 7, 6, 3 );
00094   mLayout->setRowStretch( 6, 1 );
00095 
00096   // Setup the Addressbook
00097   KABC::StdAddressBook *ab = KABC::StdAddressBook::self( true );
00098   connect( ab, TQT_SIGNAL( addressBookChanged( AddressBook* ) ),
00099            this, TQT_SLOT( updateView() ) );
00100   connect( mPlugin->core(), TQT_SIGNAL( dayChanged( const TQDate& ) ),
00101            this, TQT_SLOT( updateView() ) );
00102 
00103   // Setup the Calendar
00104   mCalendar = new KCal::CalendarResources( KPimPrefs::timezone() );
00105   mCalendar->readConfig();
00106 
00107   KCal::CalendarResourceManager *manager = mCalendar->resourceManager();
00108   if ( manager->isEmpty() ) {
00109     KConfig config( "korganizerrc" );
00110     config.setGroup( "General" );
00111     TQString fileName = config.readPathEntry( "Active Calendar" );
00112 
00113     TQString resourceName;
00114     if ( fileName.isEmpty() ) {
00115       fileName = locateLocal( "data", "korganizer/std.ics" );
00116       resourceName = i18n( "Default KOrganizer resource" );
00117     } else {
00118       resourceName = i18n( "Active Calendar" );
00119     }
00120 
00121     KCal::ResourceCalendar *defaultResource =
00122       new KCal::ResourceLocal( fileName );
00123 
00124     defaultResource->setResourceName( resourceName );
00125 
00126     manager->add( defaultResource );
00127     manager->setStandardResource( defaultResource );
00128   }
00129   mCalendar = KOrg::StdCalendar::self();
00130 
00131   connect( mCalendar, TQT_SIGNAL( calendarChanged() ),
00132            this, TQT_SLOT( updateView() ) );
00133   connect( mPlugin->core(), TQT_SIGNAL( dayChanged( const TQDate& ) ),
00134            this, TQT_SLOT( updateView() ) );
00135 
00136   // Update Configuration
00137   configUpdated();
00138 }
00139 
00140 void SDSummaryWidget::configUpdated()
00141 {
00142   KConfig config( "kcmsdsummaryrc" );
00143 
00144   config.setGroup( "Days" );
00145   mDaysAhead = config.readNumEntry( "DaysToShow", 7 );
00146 
00147   config.setGroup( "EventTypes" );
00148   mShowBirthdaysFromKAB =
00149     config.readBoolEntry( "ShowBirthdaysFromContacts", true );
00150   mShowBirthdaysFromCal =
00151     config.readBoolEntry( "ShowBirthdaysFromCalendar", true );
00152 
00153   mShowAnniversariesFromKAB =
00154     config.readBoolEntry( "ShowAnniversariesFromContacts", true );
00155   mShowAnniversariesFromCal =
00156     config.readBoolEntry( "ShowAnniversariesFromCalendar", true );
00157 
00158   mShowHolidays =
00159     config.readBoolEntry( "ShowHolidays", true );
00160 
00161   mShowSpecialsFromCal =
00162     config.readBoolEntry( "ShowSpecialsFromCalendar", true );
00163 
00164   updateView();
00165 }
00166 
00167 bool SDSummaryWidget::initHolidays()
00168 {
00169   KConfig hconfig( "korganizerrc" );
00170   hconfig.setGroup( "Time & Date" );
00171   TQString location = hconfig.readEntry( "Holidays" );
00172   if ( !location.isEmpty() ) {
00173     if ( mHolidays ) delete mHolidays;
00174     mHolidays = new KHolidays( location );
00175     return true;
00176   }
00177   return false;
00178 }
00179 
00180 // number of days remaining in an Event
00181 int SDSummaryWidget::span( KCal::Event *event )
00182 {
00183   int span=1;
00184   if ( event->isMultiDay() && event->doesFloat() ) {
00185     TQDate d = event->dtStart().date();
00186     if ( d < TQDate::currentDate() ) {
00187       d = TQDate::currentDate();
00188     }
00189     while ( d < event->dtEnd().date() ) {
00190       span++;
00191       d=d.addDays( 1 );
00192     }
00193   }
00194   return span;
00195 }
00196 
00197 // day of a multiday Event
00198 int SDSummaryWidget::dayof( KCal::Event *event, const TQDate& date )
00199 {
00200   int dayof=1;
00201   TQDate d = event->dtStart().date();
00202   if ( d < TQDate::currentDate() ) {
00203     d = TQDate::currentDate();
00204   }
00205   while ( d < event->dtEnd().date() ) {
00206     if ( d < date ) {
00207       dayof++;
00208     }
00209     d = d.addDays( 1 );
00210   }
00211   return dayof;
00212 }
00213 
00214 
00215 
00216 void SDSummaryWidget::updateView()
00217 {
00218   mLabels.setAutoDelete( true );
00219   mLabels.clear();
00220   mLabels.setAutoDelete( false );
00221 
00222   KIconLoader loader( "kdepim" );
00223 
00224   KABC::StdAddressBook *ab = KABC::StdAddressBook::self( true );
00225   TQValueList<SDEntry> dates;
00226   TQLabel *label = 0;
00227 
00228   // No reason to show the date year
00229   TQString savefmt = KGlobal::locale()->dateFormat();
00230   KGlobal::locale()->setDateFormat( KGlobal::locale()->
00231                                     dateFormat().replace( 'Y', ' ' ) );
00232 
00233   // Search for Birthdays and Anniversaries in the Addressbook
00234   KABC::AddressBook::Iterator it;
00235   for ( it = ab->begin(); it != ab->end(); ++it ) {
00236     TQDate birthday = (*it).birthday().date();
00237     if ( birthday.isValid() && mShowBirthdaysFromKAB ) {
00238       SDEntry entry;
00239       entry.type = IncidenceTypeContact;
00240       entry.category = CategoryBirthday;
00241       dateDiff( birthday, entry.daysTo, entry.yearsOld );
00242 
00243       entry.date = birthday;
00244       entry.addressee = *it;
00245       entry.span = 1;
00246       if ( entry.daysTo <= mDaysAhead )
00247         dates.append( entry );
00248     }
00249 
00250     TQString anniversaryAsString =
00251       (*it).custom( "KADDRESSBOOK" , "X-Anniversary" );
00252     if ( !anniversaryAsString.isEmpty() ) {
00253       TQDate anniversary = TQDate::fromString( anniversaryAsString, Qt::ISODate );
00254       if ( anniversary.isValid() && mShowAnniversariesFromKAB ) {
00255         SDEntry entry;
00256         entry.type = IncidenceTypeContact;
00257         entry.category = CategoryAnniversary;
00258         dateDiff( anniversary, entry.daysTo, entry.yearsOld );
00259 
00260         entry.date = anniversary;
00261         entry.addressee = *it;
00262         entry.span = 1;
00263         if ( entry.daysTo <= mDaysAhead )
00264           dates.append( entry );
00265       }
00266     }
00267   }
00268 
00269   // Search for Birthdays, Anniversaries, Holidays, and Special Occasions
00270   // in the Calendar
00271   TQDate dt;
00272   TQDate currentDate = TQDate::currentDate();
00273   for ( dt=currentDate;
00274         dt<=currentDate.addDays( mDaysAhead - 1 );
00275         dt=dt.addDays(1) ) {
00276     KCal::Event::List events = mCalendar->events( dt,
00277                                                   KCal::EventSortStartDate,
00278                                                   KCal::SortDirectionAscending );
00279     KCal::Event *ev;
00280     KCal::Event::List::ConstIterator it;
00281     for ( it=events.begin(); it!=events.end(); ++it ) {
00282       ev = *it;
00283       if ( !ev->categoriesStr().isEmpty() ) {
00284         TQStringList::ConstIterator it2;
00285         TQStringList c = ev->categories();
00286         for ( it2=c.begin(); it2!=c.end(); ++it2 ) {
00287 
00288           // Append Birthday Event?
00289           if ( mShowBirthdaysFromCal &&
00290                ( ( *it2 ).upper() == i18n( "BIRTHDAY" ) ) ) {
00291             SDEntry entry;
00292             entry.type = IncidenceTypeEvent;
00293             entry.category = CategoryBirthday;
00294             entry.date = dt;
00295             entry.summary = ev->summary();
00296             entry.desc = ev->description();
00297             dateDiff( ev->dtStart().date(), entry.daysTo, entry.yearsOld );
00298             entry.span = 1;
00299             dates.append( entry );
00300             break;
00301           }
00302 
00303           // Append Anniversary Event?
00304           if ( mShowAnniversariesFromCal &&
00305                ( ( *it2 ).upper() == i18n( "ANNIVERSARY" ) ) ) {
00306             SDEntry entry;
00307             entry.type = IncidenceTypeEvent;
00308             entry.category = CategoryAnniversary;
00309             entry.date = dt;
00310             entry.summary = ev->summary();
00311             entry.desc = ev->description();
00312             dateDiff( ev->dtStart().date(), entry.daysTo, entry.yearsOld );
00313             entry.span = 1;
00314             dates.append( entry );
00315             break;
00316           }
00317 
00318           // Append Holiday Event?
00319           if ( mShowHolidays &&
00320                ( ( *it2 ).upper() == i18n( "HOLIDAY" ) ) ) {
00321             SDEntry entry;
00322             entry.type = IncidenceTypeEvent;
00323             entry.category = CategoryHoliday;
00324             entry.date = dt;
00325             entry.summary = ev->summary();
00326             entry.desc = ev->description();
00327             dateDiff( dt, entry.daysTo, entry.yearsOld );
00328             entry.yearsOld = -1; //ignore age of holidays
00329             entry.span = span( ev );
00330             if ( entry.span > 1 && dayof( ev, dt ) > 1 ) // skip days 2,3,...
00331               break;
00332             dates.append( entry );
00333             break;
00334           }
00335 
00336           // Append Special Occasion Event?
00337           if ( mShowSpecialsFromCal &&
00338                ( ( *it2 ).upper() == i18n( "SPECIAL OCCASION" ) ) ) {
00339             SDEntry entry;
00340             entry.type = IncidenceTypeEvent;
00341             entry.category = CategoryOther;
00342             entry.date = dt;
00343             entry.summary = ev->summary();
00344             entry.desc = ev->description();
00345             dateDiff( dt, entry.daysTo, entry.yearsOld );
00346             entry.yearsOld = -1; //ignore age of special occasions
00347             entry.span = span( ev );
00348             if ( entry.span > 1 && dayof( ev, dt ) > 1 ) // skip days 2,3,...
00349               break;
00350             dates.append( entry );
00351             break;
00352           }
00353         }
00354       }
00355     }
00356   }
00357 
00358   // Seach for Holidays
00359   if ( mShowHolidays ) {
00360     if ( initHolidays() ) {
00361       for ( dt=currentDate;
00362             dt<=currentDate.addDays( mDaysAhead - 1 );
00363             dt=dt.addDays(1) ) {
00364         TQValueList<KHoliday> holidays = mHolidays->getHolidays( dt );
00365         TQValueList<KHoliday>::ConstIterator it = holidays.begin();
00366         for ( ; it != holidays.end(); ++it ) {
00367           SDEntry entry;
00368           entry.type = IncidenceTypeEvent;
00369           entry.category = ((*it).Category==KHolidays::HOLIDAY)?CategoryHoliday:CategoryOther;
00370           entry.date = dt;
00371           entry.summary = (*it).text;
00372           dateDiff( dt, entry.daysTo, entry.yearsOld );
00373           entry.yearsOld = -1; //ignore age of holidays
00374           entry.span = 1;
00375           dates.append( entry );
00376         }
00377       }
00378     }
00379   }
00380 
00381   // Sort, then Print the Special Dates
00382   qHeapSort( dates );
00383 
00384   if ( !dates.isEmpty() ) {
00385     int counter = 0;
00386     TQValueList<SDEntry>::Iterator addrIt;
00387     TQString lines;
00388     for ( addrIt = dates.begin(); addrIt != dates.end(); ++addrIt ) {
00389       bool makeBold = (*addrIt).daysTo == 0; // i.e., today
00390 
00391       // Pixmap
00392       TQImage icon_img;
00393       TQString icon_name;
00394       KABC::Picture pic;
00395       switch( (*addrIt).category ) {
00396       case CategoryBirthday:
00397         icon_name = "calendarbirthday";
00398         pic = (*addrIt).addressee.photo();
00399         if ( pic.isIntern() && !pic.data().isNull() ) {
00400           TQImage img = pic.data();
00401           if ( img.width() > img.height() ) {
00402             icon_img = img.scaleWidth( 32 );
00403           } else {
00404             icon_img = img.scaleHeight( 32 );
00405           }
00406         }
00407         break;
00408       case CategoryAnniversary:
00409         icon_name = "calendaranniversary";
00410         pic = (*addrIt).addressee.photo();
00411         if ( pic.isIntern() && !pic.data().isNull() ) {
00412           TQImage img = pic.data();
00413           if ( img.width() > img.height() ) {
00414             icon_img = img.scaleWidth( 32 );
00415           } else {
00416             icon_img = img.scaleHeight( 32 );
00417           }
00418         }
00419         break;
00420       case CategoryHoliday:
00421         icon_name = "calendarholiday"; break;
00422       case CategoryOther:
00423         icon_name = "cookie"; break;
00424       }
00425       label = new TQLabel( this );
00426       if ( icon_img.isNull() ) {
00427         label->setPixmap( KGlobal::iconLoader()->loadIcon( icon_name,
00428                                                            KIcon::Small ) );
00429       } else {
00430         label->setPixmap( icon_img );
00431       }
00432       label->setMaximumWidth( label->minimumSizeHint().width() );
00433       label->setAlignment( AlignVCenter );
00434       mLayout->addWidget( label, counter, 0 );
00435       mLabels.append( label );
00436 
00437       // Event date
00438       TQString datestr;
00439 
00440       //Muck with the year -- change to the year 'daysTo' days away
00441       int year = currentDate.addDays( (*addrIt).daysTo ).year();
00442       TQDate sD = TQDate( year, (*addrIt).date.month(), (*addrIt).date.day() );
00443 
00444       if ( (*addrIt).daysTo == 0 ) {
00445         datestr = i18n( "Today" );
00446       } else if ( (*addrIt).daysTo == 1 ) {
00447         datestr = i18n( "Tomorrow" );
00448       } else {
00449         datestr = KGlobal::locale()->formatDate( sD );
00450       }
00451       // Print the date span for multiday, floating events, for the
00452       // first day of the event only.
00453       if ( (*addrIt).span > 1 ) {
00454         TQString endstr =
00455           KGlobal::locale()->formatDate( sD.addDays( (*addrIt).span - 1 ) );
00456         datestr += " -\n " + endstr;
00457       }
00458 
00459       label = new TQLabel( datestr, this );
00460       label->setAlignment( AlignLeft | AlignVCenter );
00461       mLayout->addWidget( label, counter, 1 );
00462       mLabels.append( label );
00463       if ( makeBold ) {
00464         TQFont font = label->font();
00465         font.setBold( true );
00466         label->setFont( font );
00467       }
00468 
00469       // Countdown
00470       label = new TQLabel( this );
00471       if ( (*addrIt).daysTo == 0 ) {
00472         label->setText( i18n( "now" ) );
00473       } else {
00474         label->setText( i18n( "in 1 day", "in %n days", (*addrIt).daysTo ) );
00475       }
00476 
00477       label->setAlignment( AlignLeft | AlignVCenter );
00478       mLayout->addWidget( label, counter, 2 );
00479       mLabels.append( label );
00480 
00481       // What
00482       TQString what;
00483       switch( (*addrIt).category ) {
00484       case CategoryBirthday:
00485         what = i18n( "Birthday" ); break;
00486       case CategoryAnniversary:
00487         what = i18n( "Anniversary" ); break;
00488       case CategoryHoliday:
00489         what = i18n( "Holiday" ); break;
00490       case CategoryOther:
00491         what = i18n( "Special Occasion" ); break;
00492       }
00493       label = new TQLabel( this );
00494       label->setText( what );
00495       label->setAlignment( AlignLeft | AlignVCenter );
00496       mLayout->addWidget( label, counter, 3 );
00497       mLabels.append( label );
00498 
00499       // Description
00500       if ( (*addrIt).type == IncidenceTypeContact ) {
00501         KURLLabel *urlLabel = new KURLLabel( this );
00502         urlLabel->installEventFilter( this );
00503         urlLabel->setURL( (*addrIt).addressee.uid() );
00504         urlLabel->setText( (*addrIt).addressee.realName() );
00505         urlLabel->setTextFormat( TQt::RichText );
00506         mLayout->addWidget( urlLabel, counter, 4 );
00507         mLabels.append( urlLabel );
00508 
00509         connect( urlLabel, TQT_SIGNAL( leftClickedURL( const TQString& ) ),
00510                  this, TQT_SLOT( mailContact( const TQString& ) ) );
00511         connect( urlLabel, TQT_SIGNAL( rightClickedURL( const TQString& ) ),
00512                  this, TQT_SLOT( popupMenu( const TQString& ) ) );
00513       } else {
00514         label = new TQLabel( this );
00515         label->setText( (*addrIt).summary );
00516         label->setTextFormat( TQt::RichText );
00517         mLayout->addWidget( label, counter, 4 );
00518         mLabels.append( label );
00519         if ( !(*addrIt).desc.isEmpty() ) {
00520           TQToolTip::add( label, (*addrIt).desc );
00521         }
00522       }
00523 
00524      // Age
00525       if ( (*addrIt).category == CategoryBirthday ||
00526            (*addrIt).category == CategoryAnniversary ) {
00527         label = new TQLabel( this );
00528         if ( (*addrIt).yearsOld <= 0 ) {
00529           label->setText( "" );
00530         } else {
00531           label->setText( i18n( "one year", "%n years", (*addrIt).yearsOld  ) );
00532         }
00533         label->setAlignment( AlignLeft | AlignVCenter );
00534         mLayout->addWidget( label, counter, 5 );
00535         mLabels.append( label );
00536       }
00537 
00538       counter++;
00539     }
00540   } else {
00541     label = new TQLabel(
00542         i18n( "No special dates within the next 1 day",
00543               "No special dates pending within the next %n days",
00544               mDaysAhead ), this, "nothing to see" );
00545     label->setAlignment( AlignHCenter | AlignVCenter );
00546     mLayout->addMultiCellWidget( label, 0, 0, 0, 4 );
00547     mLabels.append( label );
00548   }
00549 
00550   for ( label = mLabels.first(); label; label = mLabels.next() )
00551     label->show();
00552 
00553   KGlobal::locale()->setDateFormat( savefmt );
00554 }
00555 
00556 void SDSummaryWidget::mailContact( const TQString &uid )
00557 {
00558   KABC::StdAddressBook *ab = KABC::StdAddressBook::self( true );
00559   TQString email = ab->findByUid( uid ).fullEmail();
00560 
00561   kapp->invokeMailer( email, TQString() );
00562 }
00563 
00564 void SDSummaryWidget::viewContact( const TQString &uid )
00565 {
00566   if ( !mPlugin->isRunningStandalone() )
00567     mPlugin->core()->selectPlugin( "kontact_kaddressbookplugin" );
00568   else
00569     mPlugin->bringToForeground();
00570 
00571   DCOPRef dcopCall( "kaddressbook", "KAddressBookIface" );
00572   dcopCall.send( "showContactEditor(TQString)", uid );
00573 }
00574 
00575 void SDSummaryWidget::popupMenu( const TQString &uid )
00576 {
00577   KPopupMenu popup( this );
00578   popup.insertItem( KGlobal::iconLoader()->loadIcon( "kmail", KIcon::Small ),
00579                     i18n( "Send &Mail" ), 0 );
00580   popup.insertItem( KGlobal::iconLoader()->loadIcon( "kaddressbook", KIcon::Small ),
00581                     i18n( "View &Contact" ), 1 );
00582 
00583   switch ( popup.exec( TQCursor::pos() ) ) {
00584     case 0:
00585       mailContact( uid );
00586       break;
00587     case 1:
00588       viewContact( uid );
00589       break;
00590   }
00591 }
00592 
00593 bool SDSummaryWidget::eventFilter( TQObject *obj, TQEvent* e )
00594 {
00595   if ( obj->inherits( "KURLLabel" ) ) {
00596     KURLLabel* label = static_cast<KURLLabel*>( TQT_TQWIDGET(obj) );
00597     if ( e->type() == TQEvent::Enter )
00598       emit message( i18n( "Mail to:\"%1\"" ).arg( label->text() ) );
00599     if ( e->type() == TQEvent::Leave )
00600       emit message( TQString() );
00601   }
00602 
00603   return Kontact::Summary::eventFilter( obj, e );
00604 }
00605 
00606 void SDSummaryWidget::dateDiff( const TQDate &date, int &days, int &years )
00607 {
00608   TQDate currentDate;
00609   TQDate eventDate;
00610 
00611   if ( TQDate::leapYear( date.year() ) && date.month() == 2 && date.day() == 29 ) {
00612     currentDate = TQDate( date.year(), TQDate::currentDate().month(), TQDate::currentDate().day() );
00613     if ( !TQDate::leapYear( TQDate::currentDate().year() ) )
00614       eventDate = TQDate( date.year(), date.month(), 28 ); // celebrate one day earlier ;)
00615     else
00616       eventDate = TQDate( date.year(), date.month(), date.day() );
00617   } else {
00618     currentDate = TQDate( 0, TQDate::currentDate().month(), TQDate::currentDate().day() );
00619     eventDate = TQDate( 0, date.month(), date.day() );
00620   }
00621 
00622   int offset = currentDate.daysTo( eventDate );
00623   if ( offset < 0 ) {
00624     days = 365 + offset;
00625     years = TQDate::currentDate().year() + 1 - date.year();
00626   } else {
00627     days = offset;
00628     years = TQDate::currentDate().year() - date.year();
00629   }
00630 }
00631 
00632 TQStringList SDSummaryWidget::configModules() const
00633 {
00634   return TQStringList( "kcmsdsummary.desktop" );
00635 }
00636 
00637 #include "sdsummarywidget.moc"