• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kontact

  • sources
  • kde-4.12
  • kdepim
  • kontact
  • plugins
  • specialdates
sdsummarywidget.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Kontact.
3 
4  Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
5  Copyright (c) 2004,2009 Allen Winter <winter@kde.org>
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, permission is given to link this program
22  with any edition of Qt, and distribute the resulting executable,
23  without including the source code for Qt in the source distribution.
24 */
25 
26 #include "sdsummarywidget.h"
27 
28 #include <KontactInterface/Core>
29 #include <KontactInterface/Plugin>
30 
31 #include <calendarsupport/utils.h>
32 #include <calendarsupport/calendarsingleton.h>
33 
34 #include <Akonadi/ItemFetchJob>
35 #include <Akonadi/ItemFetchScope>
36 #include <Akonadi/EntityDisplayAttribute>
37 #include <Akonadi/Contact/ContactSearchJob>
38 #include <Akonadi/Contact/ContactViewerDialog>
39 
40 #include <KCalCore/Calendar>
41 
42 #include <KMenu>
43 #include <KLocale>
44 #include <KUrlLabel>
45 #include <KIconLoader>
46 #include <KConfigGroup>
47 #include <KToolInvocation>
48 #include <KSystemTimeZones>
49 #include <KHolidays/Holidays>
50 
51 #include <QDate>
52 #include <QEvent>
53 #include <QLabel>
54 #include <QGridLayout>
55 
56 using namespace KHolidays;
57 
58 class BirthdaySearchJob : public Akonadi::ItemSearchJob
59 {
60  public:
61  BirthdaySearchJob( QObject *parent, int daysInAdvance );
62 };
63 
64 BirthdaySearchJob::BirthdaySearchJob( QObject *parent, int daysInAdvance )
65  : ItemSearchJob( QString(), parent )
66 {
67  fetchScope().fetchFullPayload();
68  const QString query = QString::fromLatin1(
69  "prefix nco:<http://www.semanticdesktop.org/ontologies/2007/03/22/nco#> "
70  "prefix xsd:<http://www.w3.org/2001/XMLSchema#> "
71  ""
72  "SELECT DISTINCT ?r "
73  "WHERE { "
74  " graph ?g "
75  " { "
76  " { "
77  " ?r a nco:PersonContact . "
78  " ?r <%1> ?akonadiItemId . "
79  " ?r nco:birthDate ?birthDate . "
80  " FILTER( bif:dayofyear(?birthDate) >= bif:dayofyear(xsd:date(\"%2\")) ) "
81  " FILTER( bif:dayofyear(?birthDate) <= bif:dayofyear(xsd:date(\"%2\")) + %3 ) "
82  " } "
83  " UNION "
84  " { "
85  " ?r a nco:PersonContact . "
86  " ?r <%1> ?akonadiItemId . "
87  " ?r nco:birthDate ?birthDate . "
88  " FILTER( bif:dayofyear(?birthDate) + 365 >= bif:dayofyear(xsd:date(\"%2\")) ) "
89  " FILTER( bif:dayofyear(?birthDate) + 365 <= bif:dayofyear(xsd:date(\"%2\")) + %3 ) "
90  " } "
91  " } "
92  "}" ).
93  arg( QString::fromLatin1( Akonadi::ItemSearchJob::akonadiItemIdUri().toEncoded() ) ).
94  arg( QDate::currentDate().toString( Qt::ISODate ) ).
95  arg( daysInAdvance );
96  Akonadi::ItemSearchJob::setQuery( query );
97 }
98 
99 enum SDIncidenceType {
100  IncidenceTypeContact,
101  IncidenceTypeEvent
102 };
103 
104 enum SDCategory {
105  CategoryBirthday,
106  CategoryAnniversary,
107  CategoryHoliday,
108  CategoryOther
109 };
110 
111 class SDEntry
112 {
113  public:
114  SDIncidenceType type;
115  SDCategory category;
116  int yearsOld;
117  int daysTo;
118  QDate date;
119  QString summary;
120  QString desc;
121  int span; // #days in the special occassion.
122  KABC::Addressee addressee;
123  Akonadi::Item item;
124 
125  bool operator<( const SDEntry &entry ) const
126  {
127  return daysTo < entry.daysTo;
128  }
129 };
130 
131 SDSummaryWidget::SDSummaryWidget( KontactInterface::Plugin *plugin, QWidget *parent )
132  : KontactInterface::Summary( parent ), mPlugin( plugin ), mHolidays( 0 )
133 {
134  mCalendar = CalendarSupport::calendarSingleton();
135  // Create the Summary Layout
136  QVBoxLayout *mainLayout = new QVBoxLayout( this );
137  mainLayout->setSpacing( 3 );
138  mainLayout->setMargin( 3 );
139 
140  //TODO: we want our own special dates icon
141  QWidget *header = createHeader(
142  this, QLatin1String("favorites"), i18n( "Upcoming Special Dates" ) );
143  mainLayout->addWidget( header );
144 
145  mLayout = new QGridLayout();
146  mainLayout->addItem( mLayout );
147  mLayout->setSpacing( 3 );
148  mLayout->setRowStretch( 6, 1 );
149 
150  // Default settings
151  mDaysAhead = 7;
152  mShowBirthdaysFromKAB = true;
153  mShowBirthdaysFromCal = true;
154  mShowAnniversariesFromKAB = true;
155  mShowAnniversariesFromCal = true;
156  mShowHolidays = true;
157  mJobRunning = false;
158  mShowSpecialsFromCal = true;
159 
160  // Setup the Addressbook
161  connect( mPlugin->core(), SIGNAL(dayChanged(QDate)),
162  this, SLOT(updateView()) );
163 
164  connect( mCalendar.data(), SIGNAL(calendarChanged()),
165  this, SLOT(updateView()) );
166  connect( mPlugin->core(), SIGNAL(dayChanged(QDate)),
167  this, SLOT(updateView()) );
168 
169  // Update Configuration
170  configUpdated();
171 }
172 
173 SDSummaryWidget::~SDSummaryWidget()
174 {
175  delete mHolidays;
176 }
177 
178 void SDSummaryWidget::configUpdated()
179 {
180  KConfig config( QLatin1String("kcmsdsummaryrc") );
181 
182  KConfigGroup group = config.group( "Days" );
183  mDaysAhead = group.readEntry( "DaysToShow", 7 );
184 
185  group = config.group( "Show" );
186  mShowBirthdaysFromKAB = group.readEntry( "BirthdaysFromContacts", true );
187  mShowBirthdaysFromCal = group.readEntry( "BirthdaysFromCalendar", true );
188 
189  mShowAnniversariesFromKAB = group.readEntry( "AnniversariesFromContacts", true );
190  mShowAnniversariesFromCal = group.readEntry( "AnniversariesFromCalendar", true );
191 
192  mShowHolidays = group.readEntry( "HolidaysFromCalendar", true );
193 
194  mShowSpecialsFromCal = group.readEntry( "SpecialsFromCalendar", true );
195 
196  group = config.group( "Groupware" );
197  mShowMineOnly = group.readEntry( "ShowMineOnly", false );
198 
199  updateView();
200 }
201 
202 bool SDSummaryWidget::initHolidays()
203 {
204  KConfig _hconfig( QLatin1String("korganizerrc") );
205  KConfigGroup hconfig( &_hconfig, "Time & Date" );
206  QString location = hconfig.readEntry( "Holidays" );
207  if ( !location.isEmpty() ) {
208  delete mHolidays;
209  mHolidays = new HolidayRegion( location );
210  return true;
211  }
212  return false;
213 }
214 
215 // number of days remaining in an Event
216 int SDSummaryWidget::span( const KCalCore::Event::Ptr &event ) const
217 {
218  int span = 1;
219  if ( event->isMultiDay() && event->allDay() ) {
220  QDate d = event->dtStart().date();
221  if ( d < QDate::currentDate() ) {
222  d = QDate::currentDate();
223  }
224  while ( d < event->dtEnd().date() ) {
225  span++;
226  d = d.addDays( 1 );
227  }
228  }
229  return span;
230 }
231 
232 // day of a multiday Event
233 int SDSummaryWidget::dayof( const KCalCore::Event::Ptr &event, const QDate &date ) const
234 {
235  int dayof = 1;
236  QDate d = event->dtStart().date();
237  if ( d < QDate::currentDate() ) {
238  d = QDate::currentDate();
239  }
240  while ( d < event->dtEnd().date() ) {
241  if ( d < date ) {
242  dayof++;
243  }
244  d = d.addDays( 1 );
245  }
246  return dayof;
247 }
248 
249 void SDSummaryWidget::slotBirthdayJobFinished( KJob *job )
250 {
251  // ;)
252  BirthdaySearchJob* bJob = dynamic_cast< BirthdaySearchJob *>( job );
253  if ( bJob ) {
254  foreach ( const Akonadi::Item &item, bJob->items() ) {
255  if ( item.hasPayload<KABC::Addressee>() ) {
256  const KABC::Addressee addressee = item.payload<KABC::Addressee>();
257  const QDate birthday = addressee.birthday().date();
258  if ( birthday.isValid() ) {
259  SDEntry entry;
260  entry.type = IncidenceTypeContact;
261  entry.category = CategoryBirthday;
262  dateDiff( birthday, entry.daysTo, entry.yearsOld );
263 
264  entry.date = birthday;
265  entry.addressee = addressee;
266  entry.item = item;
267  entry.span = 1;
268  mDates.append( entry );
269  }
270  }
271  }
272  // Carry on.
273  createLabels();
274  }
275 
276  mJobRunning = false;
277 }
278 
279 void SDSummaryWidget::createLabels()
280 {
281  KIconLoader loader( QLatin1String("kdepim") );
282 
283  QLabel *label = 0;
284 
285  // Remove all special date labels from the layout and delete them, as we
286  // will re-create all labels below.
287  setUpdatesEnabled( false );
288  foreach ( label, mLabels ) {
289  mLayout->removeWidget( label );
290  delete( label );
291  update();
292  }
293  mLabels.clear();
294 
295  QDate dt;
296  for ( dt = QDate::currentDate();
297  dt <= QDate::currentDate().addDays( mDaysAhead - 1 );
298  dt = dt.addDays( 1 ) ) {
299  KCalCore::Event::List events = mCalendar->events( dt, mCalendar->timeSpec(),
300  KCalCore::EventSortStartDate,
301  KCalCore::SortDirectionAscending );
302  foreach ( const KCalCore::Event::Ptr &ev, events ) {
303  // Optionally, show only my Events
304  /* if ( mShowMineOnly &&
305  !KCalCore::CalHelper::isMyCalendarIncidence( mCalendarAdaptor, ev. ) ) {
306  // FIXME; does isMyCalendarIncidence work !? It's deprecated too.
307  continue;
308  }
309  // TODO: CalHelper is deprecated, remove this?
310  */
311 
312  if ( ev->customProperty( "KABC","BIRTHDAY" ) == QLatin1String("YES") ) {
313  // Skipping, because these are got by the BirthdaySearchJob
314  // See comments in updateView()
315  continue;
316  }
317 
318  if ( !ev->categoriesStr().isEmpty() ) {
319  QStringList::ConstIterator it2;
320  const QStringList c = ev->categories();
321  QStringList::ConstIterator end(c.constEnd());
322  for ( it2 = c.constBegin(); it2 != end; ++it2 ) {
323 
324  const QString itUpper((*it2).toUpper());
325  // Append Birthday Event?
326  if ( mShowBirthdaysFromCal && ( itUpper == QLatin1String("BIRTHDAY") ) ) {
327  SDEntry entry;
328  entry.type = IncidenceTypeEvent;
329  entry.category = CategoryBirthday;
330  entry.date = dt;
331  entry.summary = ev->summary();
332  entry.desc = ev->description();
333  dateDiff( ev->dtStart().date(), entry.daysTo, entry.yearsOld );
334  entry.span = 1;
335 
336  /* The following check is to prevent duplicate entries,
337  * so in case of having a KCal incidence with category birthday
338  * with summary and date equal to some KABC Atendee we don't show it
339  * FIXME: port to akonadi, it's kresource based
340  * */
341  if ( true ) {
342  mDates.append( entry );
343  }
344  break;
345  }
346 
347  // Append Anniversary Event?
348  if ( mShowAnniversariesFromCal && ( itUpper == QLatin1String("ANNIVERSARY") ) ) {
349  SDEntry entry;
350  entry.type = IncidenceTypeEvent;
351  entry.category = CategoryAnniversary;
352  entry.date = dt;
353  entry.summary = ev->summary();
354  entry.desc = ev->description();
355  dateDiff( ev->dtStart().date(), entry.daysTo, entry.yearsOld );
356  entry.span = 1;
357  if ( true ) {
358  mDates.append( entry );
359  }
360  break;
361  }
362 
363  // Append Holiday Event?
364  if ( mShowHolidays && ( itUpper == QLatin1String("HOLIDAY") ) ) {
365  SDEntry entry;
366  entry.type = IncidenceTypeEvent;
367  entry.category = CategoryHoliday;
368  entry.date = dt;
369  entry.summary = ev->summary();
370  entry.desc = ev->description();
371  dateDiff( dt, entry.daysTo, entry.yearsOld );
372  entry.yearsOld = -1; //ignore age of holidays
373  entry.span = span( ev );
374  if ( entry.span > 1 && dayof( ev, dt ) > 1 ) { // skip days 2,3,...
375  break;
376  }
377  mDates.append( entry );
378  break;
379  }
380 
381  // Append Special Occasion Event?
382  if ( mShowSpecialsFromCal && ( itUpper == QLatin1String("SPECIAL OCCASION") ) ) {
383  SDEntry entry;
384  entry.type = IncidenceTypeEvent;
385  entry.category = CategoryOther;
386  entry.date = dt;
387  entry.summary = ev->summary();
388  entry.desc = ev->description();
389  dateDiff( dt, entry.daysTo, entry.yearsOld );
390  entry.yearsOld = -1; //ignore age of special occasions
391  entry.span = span( ev );
392  if ( entry.span > 1 && dayof( ev, dt ) > 1 ) { // skip days 2,3,...
393  break;
394  }
395  mDates.append( entry );
396  break;
397  }
398  }
399  }
400  }
401  }
402 
403  // Seach for Holidays
404  if ( mShowHolidays ) {
405  if ( initHolidays() ) {
406  for ( dt=QDate::currentDate();
407  dt<=QDate::currentDate().addDays( mDaysAhead - 1 );
408  dt=dt.addDays(1) ) {
409  QList<Holiday> holidays = mHolidays->holidays( dt );
410  QList<Holiday>::ConstIterator it = holidays.constBegin();
411  for ( ; it != holidays.constEnd(); ++it ) {
412  SDEntry entry;
413  entry.type = IncidenceTypeEvent;
414  entry.category = ( (*it).dayType() == Holiday::NonWorkday )?
415  CategoryHoliday : CategoryOther;
416  entry.date = dt;
417  entry.summary = (*it).text();
418  dateDiff( dt, entry.daysTo, entry.yearsOld );
419  entry.yearsOld = -1; //ignore age of holidays
420  entry.span = 1;
421 
422  mDates.append( entry );
423  }
424  }
425  }
426  }
427 
428  // Sort, then Print the Special Dates
429  qSort( mDates );
430 
431  if ( !mDates.isEmpty() ) {
432  int counter = 0;
433  QList<SDEntry>::Iterator addrIt;
434  QList<SDEntry>::Iterator addrEnd(mDates.end());
435  for ( addrIt = mDates.begin(); addrIt != addrEnd; ++addrIt ) {
436  const bool makeBold = (*addrIt).daysTo == 0; // i.e., today
437 
438  // Pixmap
439  QImage icon_img;
440  QString icon_name;
441  KABC::Picture pic;
442  switch( (*addrIt).category ) {
443  case CategoryBirthday:
444  icon_name = QLatin1String("view-calendar-birthday");
445  pic = (*addrIt).addressee.photo();
446  if ( pic.isIntern() && !pic.data().isNull() ) {
447  QImage img = pic.data();
448  if ( img.width() > img.height() ) {
449  icon_img = img.scaledToWidth( 32 );
450  } else {
451  icon_img = img.scaledToHeight( 32 );
452  }
453  }
454  break;
455  case CategoryAnniversary:
456  icon_name = QLatin1String("view-calendar-wedding-anniversary");
457  pic = (*addrIt).addressee.photo();
458  if ( pic.isIntern() && !pic.data().isNull() ) {
459  QImage img = pic.data();
460  if ( img.width() > img.height() ) {
461  icon_img = img.scaledToWidth( 32 );
462  } else {
463  icon_img = img.scaledToHeight( 32 );
464  }
465  }
466  break;
467  case CategoryHoliday:
468  icon_name = QLatin1String("view-calendar-holiday");
469  break;
470  case CategoryOther:
471  icon_name = QLatin1String("favorites");
472  break;
473  }
474  label = new QLabel( this );
475  if ( icon_img.isNull() ) {
476  label->setPixmap( KIconLoader::global()->loadIcon( icon_name, KIconLoader::Small ) );
477  } else {
478  label->setPixmap( QPixmap::fromImage( icon_img ) );
479  }
480  label->setMaximumWidth( label->minimumSizeHint().width() );
481  label->setAlignment( Qt::AlignVCenter );
482  mLayout->addWidget( label, counter, 0 );
483  mLabels.append( label );
484 
485  // Event date
486  QString datestr;
487 
488  //Muck with the year -- change to the year 'daysTo' days away
489  int year = QDate::currentDate().addDays( (*addrIt).daysTo ).year();
490  QDate sD = QDate( year, (*addrIt).date.month(), (*addrIt).date.day() );
491 
492  if ( (*addrIt).daysTo == 0 ) {
493  datestr = i18nc( "the special day is today", "Today" );
494  } else if ( (*addrIt).daysTo == 1 ) {
495  datestr = i18nc( "the special day is tomorrow", "Tomorrow" );
496  } else {
497  datestr = KGlobal::locale()->formatDate( sD, KLocale::FancyLongDate );
498  }
499  // Print the date span for multiday, floating events, for the
500  // first day of the event only.
501  if ( (*addrIt).span > 1 ) {
502  QString endstr =
503  KGlobal::locale()->formatDate( sD.addDays( (*addrIt).span - 1 ) );
504  datestr += QLatin1String(" -\n ") + endstr;
505  }
506 
507  label = new QLabel( datestr, this );
508  label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
509  mLayout->addWidget( label, counter, 1 );
510  mLabels.append( label );
511  if ( makeBold ) {
512  QFont font = label->font();
513  font.setBold( true );
514  label->setFont( font );
515  }
516 
517  // Countdown
518  label = new QLabel( this );
519  if ( (*addrIt).daysTo == 0 ) {
520  label->setText( i18n( "now" ) );
521  } else {
522  label->setText( i18np( "in 1 day", "in %1 days", (*addrIt).daysTo ) );
523  }
524 
525  label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
526  mLayout->addWidget( label, counter, 2 );
527  mLabels.append( label );
528 
529  // What
530  QString what;
531  switch( (*addrIt).category ) {
532  case CategoryBirthday:
533  what = i18n( "Birthday" );
534  break;
535  case CategoryAnniversary:
536  what = i18n( "Anniversary" );
537  break;
538  case CategoryHoliday:
539  what = i18n( "Holiday" );
540  break;
541  case CategoryOther:
542  what = i18n( "Special Occasion" );
543  break;
544  }
545  label = new QLabel( this );
546  label->setText( what );
547  label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
548  mLayout->addWidget( label, counter, 3 );
549  mLabels.append( label );
550 
551  // Description
552  if ( (*addrIt).type == IncidenceTypeContact ) {
553  KUrlLabel *urlLabel = new KUrlLabel( this );
554  urlLabel->installEventFilter( this );
555  urlLabel->setUrl( (*addrIt).item.url( Akonadi::Item::UrlWithMimeType ).url() );
556  urlLabel->setText( (*addrIt).addressee.realName() );
557  urlLabel->setTextFormat( Qt::RichText );
558  urlLabel->setWordWrap( true );
559  mLayout->addWidget( urlLabel, counter, 4 );
560  mLabels.append( urlLabel );
561 
562  connect( urlLabel, SIGNAL(leftClickedUrl(QString)),
563  this, SLOT(mailContact(QString)) );
564  connect( urlLabel, SIGNAL(rightClickedUrl(QString)),
565  this, SLOT(popupMenu(QString)) );
566  } else {
567  label = new QLabel( this );
568  label->setText( (*addrIt).summary );
569  label->setTextFormat( Qt::RichText );
570  mLayout->addWidget( label, counter, 4 );
571  mLabels.append( label );
572  if ( !(*addrIt).desc.isEmpty() ) {
573  label->setToolTip( (*addrIt).desc );
574  }
575  }
576 
577  // Age
578  if ( (*addrIt).category == CategoryBirthday ||
579  (*addrIt).category == CategoryAnniversary ) {
580  label = new QLabel( this );
581  if ( (*addrIt).yearsOld <= 0 ) {
582  label->setText( QString() );
583  } else {
584  label->setText( i18np( "one year", "%1 years", (*addrIt).yearsOld ) );
585  }
586  label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
587  mLayout->addWidget( label, counter, 5 );
588  mLabels.append( label );
589  }
590 
591  counter++;
592  }
593  } else {
594  label = new QLabel(
595  i18np( "No special dates within the next 1 day",
596  "No special dates pending within the next %1 days",
597  mDaysAhead ), this );
598  label->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
599  mLayout->addWidget( label, 0, 0 );
600  mLabels.append( label );
601  }
602 
603  QList<QLabel*>::ConstIterator lit;
604  QList<QLabel*>::ConstIterator endLit(mLabels.constEnd());
605  for ( lit = mLabels.constBegin(); lit != endLit; ++lit ) {
606  (*lit)->show();
607  }
608  setUpdatesEnabled( true );
609 }
610 
611 void SDSummaryWidget::updateView()
612 {
613  mDates.clear();
614 
615  /* KABC Birthdays are got through a ItemSearchJob/SPARQL Query
616  * I then added an ETM/CalendarModel because we need to search
617  * for calendar entries that have birthday/anniversary categories too.
618  *
619  * Also, we can't get KABC Anniversaries through nepomuk because the
620  * current S.D.O doesn't support it, so i also them through the ETM.
621  *
622  * So basically we have:
623  * Calendar anniversaries - ETM
624  * Calendar birthdays - ETM
625  * KABC birthdays - BirthdaySearchJob
626  * KABC anniversaries - ETM ( needs Birthday Agent running )
627  *
628  * We could remove thomas' BirthdaySearchJob and use the ETM for that
629  * but it has the advantage that we don't need a Birthday agent running.
630  *
631  **/
632 
633  // Search for Birthdays
634  if ( mShowBirthdaysFromKAB && !mJobRunning ) {
635  BirthdaySearchJob *job = new BirthdaySearchJob( this, mDaysAhead );
636 
637  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotBirthdayJobFinished(KJob*)) );
638  job->start();
639  mJobRunning = true;
640 
641  // The result slot will trigger the rest of the update
642  }
643 }
644 
645 void SDSummaryWidget::mailContact( const QString &url )
646 {
647  const Akonadi::Item item = Akonadi::Item::fromUrl( url );
648  if ( !item.isValid() ) {
649  kDebug() << QLatin1String("Invalid item found");
650  return;
651  }
652 
653  Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item, this );
654  job->fetchScope().fetchFullPayload();
655  connect( job, SIGNAL(result(KJob*)), SLOT(slotItemFetchJobDone(KJob*)) );
656 }
657 
658 void SDSummaryWidget::slotItemFetchJobDone(KJob* job)
659 {
660  if ( job->error() ) {
661  kWarning() << job->errorString();
662  return;
663  }
664  const Akonadi::Item::List lst = qobject_cast<Akonadi::ItemFetchJob*>( job )->items();
665  if ( lst.isEmpty() ) {
666  return;
667  }
668  const KABC::Addressee contact = lst.first().payload<KABC::Addressee>();
669 
670  KToolInvocation::invokeMailer( contact.fullEmail(), QString() );
671 }
672 
673 void SDSummaryWidget::viewContact( const QString &url )
674 {
675  const Akonadi::Item item = Akonadi::Item::fromUrl( url );
676  if ( !item.isValid() ) {
677  kDebug() << "Invalid item found";
678  return;
679  }
680 
681  Akonadi::ContactViewerDialog dlg( this );
682  dlg.setContact( item );
683  dlg.exec();
684 }
685 
686 void SDSummaryWidget::popupMenu( const QString &url )
687 {
688  KMenu popup( this );
689  const QAction *sendMailAction = popup.addAction(
690  KIconLoader::global()->loadIcon( QLatin1String("mail-message-new"), KIconLoader::Small ),
691  i18n( "Send &Mail" ) );
692  const QAction *viewContactAction = popup.addAction(
693  KIconLoader::global()->loadIcon( QLatin1String("view-pim-contacts"), KIconLoader::Small ),
694  i18n( "View &Contact" ) );
695 
696  const QAction *ret = popup.exec( QCursor::pos() );
697  if ( ret == sendMailAction ) {
698  mailContact( url );
699  } else if ( ret == viewContactAction ) {
700  viewContact( url );
701  }
702 }
703 
704 bool SDSummaryWidget::eventFilter( QObject *obj, QEvent *e )
705 {
706  if ( obj->inherits( "KUrlLabel" ) ) {
707  KUrlLabel* label = static_cast<KUrlLabel*>( obj );
708  if ( e->type() == QEvent::Enter ) {
709  emit message( i18n( "Mail to:\"%1\"", label->text() ) );
710  }
711  if ( e->type() == QEvent::Leave ) {
712  emit message( QString::null ); //krazy:exclude=nullstrassign for old broken gcc
713  }
714  }
715 
716  return KontactInterface::Summary::eventFilter( obj, e );
717 }
718 
719 void SDSummaryWidget::dateDiff( const QDate &date, int &days, int &years ) const
720 {
721  QDate currentDate;
722  QDate eventDate;
723 
724  if ( QDate::isLeapYear( date.year() ) && date.month() == 2 && date.day() == 29 ) {
725  currentDate = QDate( date.year(), QDate::currentDate().month(), QDate::currentDate().day() );
726  if ( !QDate::isLeapYear( QDate::currentDate().year() ) ) {
727  eventDate = QDate( date.year(), date.month(), 28 ); // celebrate one day earlier ;)
728  } else {
729  eventDate = QDate( date.year(), date.month(), date.day() );
730  }
731  } else {
732  currentDate = QDate( QDate::currentDate().year(),
733  QDate::currentDate().month(),
734  QDate::currentDate().day() );
735  eventDate = QDate( QDate::currentDate().year(), date.month(), date.day() );
736  }
737 
738  int offset = currentDate.daysTo( eventDate );
739  if ( offset < 0 ) {
740  days = 365 + offset;
741  years = QDate::currentDate().year() + 1 - date.year();
742  } else {
743  days = offset;
744  years = QDate::currentDate().year() - date.year();
745  }
746 }
747 
748 QStringList SDSummaryWidget::configModules() const
749 {
750  return QStringList() << QLatin1String("kcmsdsummary.desktop" );
751 }
752 
753 #include "sdsummarywidget.moc"
CategoryHoliday
Definition: sdsummarywidget.cpp:107
CategoryOther
Definition: sdsummarywidget.cpp:108
SDSummaryWidget::SDSummaryWidget
SDSummaryWidget(KontactInterface::Plugin *plugin, QWidget *parent)
Definition: sdsummarywidget.cpp:131
SDIncidenceType
SDIncidenceType
Definition: planner.cpp:54
date
time_t date() const
CategoryAnniversary
Definition: sdsummarywidget.cpp:106
QWidget
sdsummarywidget.h
QObject
CategoryBirthday
Definition: sdsummarywidget.cpp:105
SDSummaryWidget::configModules
QStringList configModules() const
Definition: sdsummarywidget.cpp:748
IncidenceTypeEvent
Definition: sdsummarywidget.cpp:101
SDCategory
SDCategory
Definition: planner.cpp:59
QLabel
SDSummaryWidget::eventFilter
virtual bool eventFilter(QObject *obj, QEvent *e)
Definition: sdsummarywidget.cpp:704
IncidenceTypeContact
Definition: sdsummarywidget.cpp:100
KJob
SDSummaryWidget::configUpdated
void configUpdated()
Definition: sdsummarywidget.cpp:178
SDSummaryWidget::~SDSummaryWidget
~SDSummaryWidget()
Definition: sdsummarywidget.cpp:173
QList
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:58:30 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kontact

Skip menu "kontact"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal