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

kontact

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

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