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

calendarsupport

  • sources
  • kde-4.12
  • kdepim
  • calendarsupport
utils.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2009, 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
3  Author: Frank Osterfeld <osterfeld@kde.org>
4  Author: Andras Mantia <andras@kdab.com>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License along
17  with this program; if not, write to the Free Software Foundation, Inc.,
18  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of Qt, and distribute the resulting executable,
22  without including the source code for Qt in the source distribution.
23 */
24 
25 #include "utils.h"
26 #include "kcalprefs.h"
27 
28 #include <Akonadi/Collection>
29 #include <Akonadi/CollectionDialog>
30 #include <Akonadi/EntityDisplayAttribute>
31 #include <Akonadi/EntityTreeModel>
32 #include <Akonadi/Item>
33 #include <Akonadi/Calendar/ETMCalendar>
34 #include <akonadi/calendar/publishdialog.h>
35 #include <akonadi/calendar/calendarsettings.h>
36 
37 #include <KHolidays/Holidays>
38 
39 #include <KCalCore/CalFilter>
40 #include <KCalCore/Event>
41 #include <KCalCore/FreeBusy>
42 #include <KCalCore/Incidence>
43 #include <KCalCore/Journal>
44 #include <KCalCore/MemoryCalendar>
45 #include <KCalCore/Todo>
46 #include <KCalCore/ICalFormat>
47 #include <KCalCore/FileStorage>
48 
49 #include <KCalUtils/DndFactory>
50 #include <KCalUtils/ICalDrag>
51 #include <KCalUtils/VCalDrag>
52 
53 #include <Mailtransport/TransportManager>
54 
55 #include <KIconLoader>
56 #include <KUrl>
57 
58 #include <QAbstractItemModel>
59 #include <QDrag>
60 #include <QMimeData>
61 #include <QModelIndex>
62 #include <QPixmap>
63 #include <QPointer>
64 
65 #include <boost/bind.hpp>
66 #include <KMessageBox>
67 #include <KPIMIdentities/IdentityManager>
68 #include <KFileDialog>
69 #include <KIO/NetAccess>
70 
71 using namespace CalendarSupport;
72 using namespace KHolidays;
73 using namespace KCalCore;
74 
75 KCalCore::Incidence::Ptr CalendarSupport::incidence( const Akonadi::Item &item )
76 {
77  //relying on exception for performance reasons
78  try {
79  return item.payload<KCalCore::Incidence::Ptr>();
80  } catch( Akonadi::PayloadException ) {
81  return KCalCore::Incidence::Ptr();
82  }
83 }
84 
85 KCalCore::Event::Ptr CalendarSupport::event( const Akonadi::Item &item )
86 {
87  //relying on exception for performance reasons
88  try {
89  KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
90  if ( incidence && incidence->type() == KCalCore::Incidence::TypeEvent ) {
91  return item.payload<KCalCore::Event::Ptr>();
92  }
93  } catch( Akonadi::PayloadException ) {
94  return KCalCore::Event::Ptr();
95  }
96  return KCalCore::Event::Ptr();
97 }
98 
99 KCalCore::Event::List CalendarSupport::eventsFromItems( const Akonadi::Item::List &items )
100 {
101  KCalCore::Event::List events;
102  Q_FOREACH ( const Akonadi::Item &item, items ) {
103  if ( const KCalCore::Event::Ptr e = CalendarSupport::event( item ) ) {
104  events.push_back( e );
105  }
106  }
107  return events;
108 }
109 
110 KCalCore::Incidence::List CalendarSupport::incidencesFromItems( const Akonadi::Item::List &items )
111 {
112  KCalCore::Incidence::List incidences;
113  Q_FOREACH ( const Akonadi::Item &item, items ) {
114  if ( const KCalCore::Incidence::Ptr e = CalendarSupport::incidence( item ) ) {
115  incidences.push_back( e );
116  }
117  }
118  return incidences;
119 }
120 
121 KCalCore::Todo::Ptr CalendarSupport::todo( const Akonadi::Item &item )
122 {
123  try {
124  KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
125  if ( incidence && incidence->type() == KCalCore::Incidence::TypeTodo ) {
126  return item.payload<KCalCore::Todo::Ptr>();
127  }
128  } catch( Akonadi::PayloadException ) {
129  return KCalCore::Todo::Ptr();
130  }
131  return KCalCore::Todo::Ptr();
132 }
133 
134 KCalCore::Journal::Ptr CalendarSupport::journal( const Akonadi::Item &item )
135 {
136  try {
137  KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
138  if ( incidence && incidence->type() == KCalCore::Incidence::TypeJournal ) {
139  return item.payload<KCalCore::Journal::Ptr>();
140  }
141  } catch( Akonadi::PayloadException ) {
142  return KCalCore::Journal::Ptr();
143  }
144  return KCalCore::Journal::Ptr();
145 }
146 
147 bool CalendarSupport::hasIncidence( const Akonadi::Item &item )
148 {
149  return item.hasPayload<KCalCore::Incidence::Ptr>();
150 }
151 
152 bool CalendarSupport::hasEvent( const Akonadi::Item &item )
153 {
154  return item.hasPayload<KCalCore::Event::Ptr>();
155 }
156 
157 bool CalendarSupport::hasTodo( const Akonadi::Item &item )
158 {
159  return item.hasPayload<KCalCore::Todo::Ptr>();
160 }
161 
162 bool CalendarSupport::hasJournal( const Akonadi::Item &item )
163 {
164  return item.hasPayload<KCalCore::Journal::Ptr>();
165 }
166 
167 QMimeData *CalendarSupport::createMimeData( const Akonadi::Item::List &items,
168  const KDateTime::Spec &timeSpec )
169 {
170  if ( items.isEmpty() ) {
171  return 0;
172  }
173 
174  KCalCore::MemoryCalendar::Ptr cal( new KCalCore::MemoryCalendar( timeSpec ) );
175 
176  QList<QUrl> urls;
177  int incidencesFound = 0;
178  Q_FOREACH ( const Akonadi::Item &item, items ) {
179  const KCalCore::Incidence::Ptr incidence( CalendarSupport::incidence( item ) );
180  if ( !incidence ) {
181  continue;
182  }
183  ++incidencesFound;
184  urls.push_back( item.url() );
185  KCalCore::Incidence::Ptr i( incidence->clone() );
186  cal->addIncidence( i );
187  }
188 
189  if ( incidencesFound == 0 ) {
190  return 0;
191  }
192 
193  std::auto_ptr<QMimeData> mimeData( new QMimeData );
194 
195  mimeData->setUrls( urls );
196 
197  KCalUtils::ICalDrag::populateMimeData( mimeData.get(), cal );
198  KCalUtils::VCalDrag::populateMimeData( mimeData.get(), cal );
199 
200  return mimeData.release();
201 }
202 
203 QMimeData *CalendarSupport::createMimeData( const Akonadi::Item &item,
204  const KDateTime::Spec &timeSpec )
205 {
206  return createMimeData( Akonadi::Item::List() << item, timeSpec );
207 }
208 
209 #ifndef QT_NO_DRAGANDDROP
210 QDrag *CalendarSupport::createDrag( const Akonadi::Item &item,
211  const KDateTime::Spec &timeSpec, QWidget *parent )
212 {
213  return createDrag( Akonadi::Item::List() << item, timeSpec, parent );
214 }
215 #endif
216 
217 static QByteArray findMostCommonType( const Akonadi::Item::List &items )
218 {
219  QByteArray prev;
220  if ( items.isEmpty() ) {
221  return "Incidence";
222  }
223 
224  Q_FOREACH ( const Akonadi::Item &item, items ) {
225  if ( !CalendarSupport::hasIncidence( item ) ) {
226  continue;
227  }
228  const QByteArray type = CalendarSupport::incidence( item )->typeStr();
229  if ( !prev.isEmpty() && type != prev ) {
230  return "Incidence";
231  }
232  prev = type;
233  }
234  return prev;
235 }
236 
237 #ifndef QT_NO_DRAGANDDROP
238 QDrag *CalendarSupport::createDrag( const Akonadi::Item::List &items,
239  const KDateTime::Spec &timeSpec, QWidget *parent )
240 {
241  std::auto_ptr<QDrag> drag( new QDrag( parent ) );
242  drag->setMimeData( CalendarSupport::createMimeData( items, timeSpec ) );
243 
244  const QByteArray common = findMostCommonType( items );
245  if ( common == "Event" ) {
246  drag->setPixmap( BarIcon( QLatin1String( "view-calendar-day" ) ) );
247  } else if ( common == "Todo" ) {
248  drag->setPixmap( BarIcon( QLatin1String( "view-calendar-tasks" ) ) );
249  }
250 
251  return drag.release();
252 }
253 #endif
254 
255 static bool itemMatches( const Akonadi::Item &item, const KCalCore::CalFilter *filter )
256 {
257  assert( filter );
258  KCalCore::Incidence::Ptr inc = CalendarSupport::incidence( item );
259  if ( !inc ) {
260  return false;
261  }
262  return filter->filterIncidence( inc );
263 }
264 
265 Akonadi::Item::List CalendarSupport::applyCalFilter( const Akonadi::Item::List &items_,
266  const KCalCore::CalFilter *filter )
267 {
268  Q_ASSERT( filter );
269  Akonadi::Item::List items( items_ );
270  items.erase( std::remove_if( items.begin(), items.end(),
271  !bind( itemMatches, _1, filter ) ), items.end() );
272  return items;
273 }
274 
275 bool CalendarSupport::isValidIncidenceItemUrl( const KUrl &url,
276  const QStringList &supportedMimeTypes )
277 {
278  if ( !url.isValid() ) {
279  return false;
280  }
281 
282  if ( url.scheme() != QLatin1String( "akonadi" ) ) {
283  return false;
284  }
285 
286  return supportedMimeTypes.contains( url.queryItem( QLatin1String( "type" ) ) );
287 }
288 
289 bool CalendarSupport::isValidIncidenceItemUrl( const KUrl &url )
290 {
291  return isValidIncidenceItemUrl( url,
292  QStringList() << KCalCore::Event::eventMimeType()
293  << KCalCore::Todo::todoMimeType()
294  << KCalCore::Journal::journalMimeType()
295  << KCalCore::FreeBusy::freeBusyMimeType() );
296 }
297 
298 static bool containsValidIncidenceItemUrl( const QList<QUrl>& urls )
299 {
300  return
301  std::find_if( urls.begin(), urls.end(),
302  bind( CalendarSupport::isValidIncidenceItemUrl, _1 ) ) != urls.constEnd();
303 }
304 
305 bool CalendarSupport::isValidTodoItemUrl( const KUrl &url )
306 {
307  if ( !url.isValid() || url.scheme() != QLatin1String( "akonadi" ) ) {
308  return false;
309  }
310 
311  return url.queryItem( QLatin1String( "type" ) ) == KCalCore::Todo::todoMimeType();
312 }
313 
314 bool CalendarSupport::canDecode( const QMimeData *md )
315 {
316  Q_ASSERT( md );
317  return
318  containsValidIncidenceItemUrl( md->urls() ) ||
319  KCalUtils::ICalDrag::canDecode( md ) ||
320  KCalUtils::VCalDrag::canDecode( md );
321 }
322 
323 QList<KUrl> CalendarSupport::incidenceItemUrls( const QMimeData *mimeData )
324 {
325  QList<KUrl> urls;
326  Q_FOREACH ( const KUrl &i, mimeData->urls() ) {
327  if ( isValidIncidenceItemUrl( i ) ) {
328  urls.push_back( i );
329  }
330  }
331  return urls;
332 }
333 
334 QList<KUrl> CalendarSupport::todoItemUrls( const QMimeData *mimeData )
335 {
336  QList<KUrl> urls;
337 
338  Q_FOREACH ( const KUrl &i, mimeData->urls() ) {
339  if ( isValidIncidenceItemUrl( i, QStringList() << KCalCore::Todo::todoMimeType() ) ) {
340  urls.push_back( i );
341  }
342  }
343  return urls;
344 }
345 
346 bool CalendarSupport::mimeDataHasTodo( const QMimeData *mimeData )
347 {
348  return !todoItemUrls( mimeData ).isEmpty() || !todos( mimeData, KDateTime::Spec() ).isEmpty();
349 }
350 
351 bool CalendarSupport::mimeDataHasIncidence( const QMimeData *mimeData )
352 {
353  return !incidenceItemUrls( mimeData ).isEmpty() ||
354  !incidences( mimeData, KDateTime::Spec() ).isEmpty();
355 }
356 
357 KCalCore::Todo::List CalendarSupport::todos( const QMimeData *mimeData,
358  const KDateTime::Spec &spec )
359 {
360  KCalCore::Todo::List todos;
361 
362 #ifndef QT_NO_DRAGANDDROP
363  KCalCore::Calendar::Ptr cal( KCalUtils::DndFactory::createDropCalendar( mimeData, spec ) );
364  if ( cal ) {
365  Q_FOREACH ( const KCalCore::Todo::Ptr &i, cal->todos() ) {
366  todos.push_back( KCalCore::Todo::Ptr( i->clone() ) );
367  }
368  }
369 #endif
370 
371  return todos;
372 }
373 
374 KCalCore::Incidence::List CalendarSupport::incidences( const QMimeData *mimeData,
375  const KDateTime::Spec &spec )
376 {
377  KCalCore::Incidence::List incidences;
378 
379 #ifndef QT_NO_DRAGANDDROP
380  KCalCore::Calendar::Ptr cal( KCalUtils::DndFactory::createDropCalendar( mimeData, spec ) );
381  if ( cal ) {
382  KCalCore::Incidence::List calIncidences = cal->incidences();
383  Q_FOREACH ( const KCalCore::Incidence::Ptr &i, calIncidences ) {
384  incidences.push_back( KCalCore::Incidence::Ptr( i->clone() ) );
385  }
386  }
387 #endif
388 
389  return incidences;
390 }
391 
392 Akonadi::Collection CalendarSupport::selectCollection( QWidget *parent,
393  int &dialogCode,
394  const QStringList &mimeTypes,
395  const Akonadi::Collection &defCollection )
396 {
397  QPointer<Akonadi::CollectionDialog> dlg( new Akonadi::CollectionDialog( parent ) );
398  dlg->setCaption( i18n( "Select Calendar" ) );
399  dlg->setDescription( i18n( "Select the calendar where this item will be stored." ) );
400  dlg->changeCollectionDialogOptions( Akonadi::CollectionDialog::KeepTreeExpanded );
401  kDebug() << "selecting collections with mimeType in " << mimeTypes;
402 
403  dlg->setMimeTypeFilter( mimeTypes );
404  dlg->setAccessRightsFilter( Akonadi::Collection::CanCreateItem );
405  if ( defCollection.isValid() ) {
406  dlg->setDefaultCollection( defCollection );
407  }
408  Akonadi::Collection collection;
409 
410  // FIXME: don't use exec.
411  dialogCode = dlg->exec();
412  if ( dlg && dialogCode == QDialog::Accepted ) {
413  collection = dlg->selectedCollection();
414 
415  if ( !collection.isValid() ) {
416  kWarning() << "An invalid collection was selected!";
417  }
418  }
419  delete dlg;
420  return collection;
421 }
422 
423 Akonadi::Item CalendarSupport::itemFromIndex( const QModelIndex &idx )
424 {
425  Akonadi::Item item = idx.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
426  item.setParentCollection(
427  idx.data( Akonadi::EntityTreeModel::ParentCollectionRole ).value<Akonadi::Collection>() );
428  return item;
429 }
430 
431 Akonadi::Collection::List CalendarSupport::collectionsFromModel( const QAbstractItemModel *model,
432  const QModelIndex &parentIndex,
433  int start, int end )
434 {
435  const int endRow = end >= 0 ? end : model->rowCount( parentIndex ) - 1;
436  Akonadi::Collection::List collections;
437  int row = start;
438  QModelIndex i = model->index( row, 0, parentIndex );
439  while ( row <= endRow ) {
440  const Akonadi::Collection collection = collectionFromIndex( i );
441  if ( collection.isValid() ) {
442  collections << collection;
443  QModelIndex childIndex = i.child( 0, 0 );
444  if ( childIndex.isValid() ) {
445  collections << collectionsFromModel( model, i );
446  }
447  }
448  ++row;
449  i = i.sibling( row, 0 );
450  }
451  return collections;
452 }
453 
454 Akonadi::Item::List CalendarSupport::itemsFromModel( const QAbstractItemModel * model,
455  const QModelIndex &parentIndex,
456  int start, int end )
457 {
458  const int endRow = end >= 0 ? end : model->rowCount( parentIndex ) - 1;
459  Akonadi::Item::List items;
460  int row = start;
461  QModelIndex i = model->index( row, 0, parentIndex );
462  while ( row <= endRow ) {
463  const Akonadi::Item item = itemFromIndex( i );
464  if ( CalendarSupport::hasIncidence( item ) ) {
465  items << item;
466  } else {
467  QModelIndex childIndex = i.child( 0, 0 );
468  if ( childIndex.isValid() ) {
469  items << itemsFromModel( model, i );
470  }
471  }
472  ++row;
473  i = i.sibling( row, 0 );
474  }
475  return items;
476 }
477 
478 Akonadi::Collection CalendarSupport::collectionFromIndex( const QModelIndex &index )
479 {
480  return index.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
481 }
482 
483 Akonadi::Collection::Id CalendarSupport::collectionIdFromIndex( const QModelIndex &index )
484 {
485  return index.data( Akonadi::EntityTreeModel::CollectionIdRole ).value<Akonadi::Collection::Id>();
486 }
487 
488 Akonadi::Collection::List CalendarSupport::collectionsFromIndexes( const QModelIndexList &indexes )
489 {
490  Akonadi::Collection::List l;
491  Q_FOREACH ( const QModelIndex &idx, indexes ) {
492  l.push_back( collectionFromIndex( idx ) );
493  }
494  return l;
495 }
496 
497 QString CalendarSupport::displayName( Akonadi::ETMCalendar *calendar, const Akonadi::Collection &c )
498 {
499  Akonadi::Collection fullCollection;
500  if ( calendar && calendar->collection( c.id() ).isValid() ) {
501  fullCollection = calendar->collection( c.id() );
502  } else {
503  fullCollection = c;
504  }
505 
506  QString cName = fullCollection.name();
507  const QString resourceName = fullCollection.resource();
508 
509  // Kolab Groupware
510  if ( resourceName.contains( QLatin1String( "kolabproxy" ) ) ) {
511  QString typeStr = cName; // contents type: "Calendar", "Tasks", etc
512  QString ownerStr; // folder owner: "fred", "ethel", etc
513  QString nameStr; // folder name: "Public", "Test", etc
514  if ( calendar ) {
515  Akonadi::Collection p = c.parentCollection();
516  while ( p != Akonadi::Collection::root() ) {
517  Akonadi::Collection tCol = calendar->collection( p.id() );
518  const QString tName = tCol.name();
519  if ( tName.toLower().startsWith( QLatin1String( "shared.cal" ) ) ) {
520  ownerStr = QLatin1String("Shared");
521  nameStr = cName;
522  typeStr = QLatin1String("Calendar");
523  break;
524  } else if ( tName.toLower().startsWith( QLatin1String( "shared.tasks" ) ) ||
525  tName.toLower().startsWith( QLatin1String( "shared.todo" ) ) ) {
526  ownerStr = QLatin1String("Shared");
527  nameStr = cName;
528  typeStr = QLatin1String("Tasks");
529  break;
530  } else if ( tName.toLower().startsWith( QLatin1String( "shared.journal" ) ) ) {
531  ownerStr = QLatin1String("Shared");
532  nameStr = cName;
533  typeStr = QLatin1String("Journal");
534  break;
535  } else if ( tName.toLower().startsWith( QLatin1String( "shared.notes" ) ) ) {
536  ownerStr = QLatin1String("Shared");
537  nameStr = cName;
538  typeStr = QLatin1String("Notes");
539  break;
540  } else if ( tName != i18n( "Calendar" ) &&
541  tName != i18n( "Tasks" ) &&
542  tName != i18n( "Journal" ) &&
543  tName != i18n( "Notes" ) ) {
544  ownerStr = tName;
545  break;
546  } else {
547  nameStr = typeStr;
548  typeStr = tName;
549  }
550  p = p.parentCollection();
551  }
552  }
553 
554  if ( !ownerStr.isEmpty() ) {
555  if ( ownerStr.toUpper() == QLatin1String( "INBOX" ) ) {
556  return i18nc( "%1 is folder contents",
557  "My Kolab %1", typeStr );
558  } else if ( ownerStr.toUpper() == QLatin1String( "SHARED" ) ) {
559  return i18nc( "%1 is folder name, %2 is folder contents",
560  "Shared Kolab %1 %2", nameStr, typeStr );
561  } else {
562  if ( nameStr.isEmpty() ) {
563  return i18nc( "%1 is folder owner name, %2 is folder contents",
564  "%1's Kolab %2", ownerStr, typeStr );
565  } else {
566  return i18nc( "%1 is folder owner name, %2 is folder name, %3 is folder contents",
567  "%1's %2 Kolab %3", ownerStr, nameStr, typeStr );
568  }
569  }
570  } else {
571  return i18nc( "%1 is folder contents",
572  "Kolab %1", typeStr );
573  }
574  } //end kolab section
575 
576  // Dav Groupware
577  if ( resourceName.contains( QLatin1String( "davgroupware" ) ) ) {
578  return i18nc( "%1 is the folder name", "%1 CalDav Calendar", cName );
579  } //end caldav section
580 
581  // Google
582  if ( resourceName.contains( QLatin1String( "google" ) ) ) {
583  QString ownerStr; // folder owner: "user@gmail.com"
584  if ( calendar ) {
585  Akonadi::Collection p = c.parentCollection();
586  ownerStr = calendar->collection( p.id() ).displayName();
587  }
588 
589  const QString nameStr = c.displayName(); // folder name: can be anything
590 
591  QString typeStr;
592  const QString mimeStr = c.contentMimeTypes().join( QLatin1String(",") );
593  if ( mimeStr.contains( QLatin1String(".event") ) ) {
594  typeStr = i18n( "Calendar" );
595  } else if ( mimeStr.contains( QLatin1String(".todo") ) ) {
596  typeStr = i18n( "Tasks" );
597  } else if ( mimeStr.contains( QLatin1String(".journal") ) ) {
598  typeStr = i18n( "Journal" );
599  } else if ( mimeStr.contains( QLatin1String(".note") ) ) {
600  typeStr = i18n( "Notes" );
601  } else {
602  typeStr = mimeStr;
603  }
604 
605  if ( !ownerStr.isEmpty() ) {
606  const int atChar = ownerStr.lastIndexOf( QLatin1Char('@') );
607  ownerStr = ownerStr.left( atChar );
608  if ( nameStr.isEmpty() ) {
609  return i18nc( "%1 is folder owner name, %2 is folder contents",
610  "%1's Google %2", ownerStr, typeStr );
611  } else {
612  return i18nc( "%1 is folder owner name, %2 is folder name",
613  "%1's %2", ownerStr, nameStr );
614  }
615  } else {
616  return i18nc( "%1 is folder contents",
617  "Google %1", typeStr );
618  }
619  } //end google section
620 
621  // Not groupware so the collection is "mine"
622  const QString dName = fullCollection.displayName();
623 
624  if ( !dName.isEmpty() ) {
625  return fullCollection.name().startsWith( QLatin1String( "akonadi_" ) ) ? i18n( "My %1", dName ) : fullCollection.name();
626  } else {
627  return i18nc( "unknown resource", "Unknown" );
628  }
629 }
630 
631 QString CalendarSupport::subMimeTypeForIncidence( const KCalCore::Incidence::Ptr &incidence )
632 {
633  return incidence->mimeType();
634 }
635 
636 QList<QDate> CalendarSupport::workDays( const QDate &startDate,
637  const QDate &endDate )
638 {
639  QList<QDate> result;
640 
641  const int mask( ~( KCalPrefs::instance()->mWorkWeekMask ) );
642  const int numDays = startDate.daysTo( endDate ) + 1;
643 
644  for ( int i = 0; i < numDays; ++i ) {
645  const QDate date = startDate.addDays( i );
646  if ( !( mask & ( 1 << ( date.dayOfWeek() - 1 ) ) ) ) {
647  result.append( date );
648  }
649  }
650 
651  if ( KCalPrefs::instance()->mExcludeHolidays ) {
652  // NOTE: KOGlobals, where this method comes from, used to hold a pointer to
653  // a KHolidays object. I'm not sure about how expensive it is, just
654  // creating one here.
655  const HolidayRegion holidays( KCalPrefs::instance()->mHolidays );
656  const Holiday::List list = holidays.holidays( startDate, endDate );
657  const int listCount( list.count() );
658  for ( int i = 0; i < listCount; ++i ) {
659  const Holiday &h = list.at( i );
660  if ( h.dayType() == Holiday::NonWorkday ) {
661  result.removeAll( h.date() );
662  }
663  }
664  }
665 
666  return result;
667 }
668 
669 QStringList CalendarSupport::holiday( const QDate &date )
670 {
671  QStringList hdays;
672 
673  const HolidayRegion holidays( KCalPrefs::instance()->mHolidays );
674  const Holiday::List list = holidays.holidays( date );
675  const int listCount( list.count() );
676  for ( int i = 0; i < listCount; ++i ) {
677  hdays.append( list.at( i ).text() );
678  }
679  return hdays;
680 }
681 
682 void CalendarSupport::saveAttachments( const Akonadi::Item &item, QWidget *parentWidget )
683 {
684  Incidence::Ptr incidence = CalendarSupport::incidence( item );
685 
686  if ( !incidence ) {
687  KMessageBox::sorry(
688  parentWidget,
689  i18n( "No item selected." ) );
690  return;
691  }
692 
693  Attachment::List attachments = incidence->attachments();
694 
695  if ( attachments.empty() ) {
696  return;
697  }
698 
699  QString targetFile, targetDir;
700  if ( attachments.count() > 1 ) {
701  // get the dir
702  targetDir = KFileDialog::getExistingDirectory( KUrl( "kfiledialog:///saveAttachment" ),
703  parentWidget,
704  i18n( "Save Attachments To" ) );
705  if ( targetDir.isEmpty() ) {
706  return;
707  }
708 
709  // we may not get a slash-terminated url out of KFileDialog
710  if ( !targetDir.endsWith( QLatin1Char('/') ) ) {
711  targetDir.append( QLatin1Char('/') );
712  }
713  } else {
714  // only one item, get the desired filename
715  QString fileName = attachments.first()->label();
716  if ( fileName.isEmpty() ) {
717  fileName = i18nc( "filename for an unnamed attachment", "attachment.1" );
718  }
719  targetFile = KFileDialog::getSaveFileName( KUrl( QLatin1String("kfiledialog:///saveAttachment/") + fileName ),
720  QString(),
721  parentWidget,
722  i18n( "Save Attachment" ) );
723  if ( targetFile.isEmpty() ) {
724  return;
725  }
726 
727  targetDir = QFileInfo( targetFile ).absolutePath() + QLatin1Char('/');
728  }
729 
730  Q_FOREACH ( Attachment::Ptr attachment, attachments ) {
731  targetFile = targetDir + attachment->label();
732  KUrl sourceUrl;
733  if ( attachment->isUri() ) {
734  sourceUrl = attachment->uri();
735  } else {
736  sourceUrl = incidence->writeAttachmentToTempFile( attachment );
737  }
738  // save the attachment url
739  if ( !KIO::NetAccess::file_copy( sourceUrl, KUrl( targetFile ) ) &&
740  KIO::NetAccess::lastError() ) {
741  KMessageBox::error( parentWidget, KIO::NetAccess::lastErrorString() );
742  }
743  }
744 }
745 
746 QStringList CalendarSupport::categories( const KCalCore::Incidence::List &incidences )
747 {
748  QStringList cats, thisCats;
749  // @TODO: For now just iterate over all incidences. In the future,
750  // the list of categories should be built when reading the file.
751  Q_FOREACH ( const KCalCore::Incidence::Ptr &incidence, incidences ) {
752  thisCats = incidence->categories();
753  for ( QStringList::ConstIterator si = thisCats.constBegin();
754  si != thisCats.constEnd(); ++si ) {
755  if ( !cats.contains( *si ) ) {
756  cats.append( *si );
757  }
758  }
759  }
760  return cats;
761 }
762 
763 bool CalendarSupport::mergeCalendar(const QString &srcFilename, const KCalCore::Calendar::Ptr &destCalendar)
764 {
765  if (srcFilename.isEmpty()) {
766  kError() << "Empty filename.";
767  return false;
768  }
769 
770  if (!QFile::exists(srcFilename)) {
771  kError() << "File'" << srcFilename << "' doesn't exist.";
772  }
773 
774  bool loadedSuccesfully = true;
775 
776  // merge in a file
777  destCalendar->startBatchAdding();
778  KCalCore::FileStorage storage(destCalendar);
779  storage.setFileName(srcFilename);
780  loadedSuccesfully = storage.load();
781  destCalendar->endBatchAdding();
782 
783  return loadedSuccesfully;
784 }
findMostCommonType
static QByteArray findMostCommonType(const Akonadi::Item::List &items)
Definition: utils.cpp:217
CalendarSupport::createMimeData
CALENDARSUPPORT_EXPORT QMimeData * createMimeData(const Akonadi::Item &item, const KDateTime::Spec &timeSpec)
creates mime data object for dragging an akonadi item containing an incidence
Definition: utils.cpp:203
CalendarSupport::createDrag
CALENDARSUPPORT_EXPORT QDrag * createDrag(const Akonadi::Item &item, const KDateTime::Spec &timeSpec, QWidget *parent)
creates a drag object for dragging an akonadi item containing an incidence
Definition: utils.cpp:210
CalendarSupport::isValidIncidenceItemUrl
CALENDARSUPPORT_EXPORT bool isValidIncidenceItemUrl(const KUrl &url, const QStringList &supportedMimeTypes)
returns true if the URL represents an Akonadi item and has one of the given mimetypes.
Definition: utils.cpp:275
QWidget
CalendarSupport::incidence
CALENDARSUPPORT_EXPORT KCalCore::Incidence::Ptr incidence(const Akonadi::Item &item)
returns the incidence from an akonadi item, or a null pointer if the item has no such payload ...
Definition: utils.cpp:75
itemMatches
static bool itemMatches(const Akonadi::Item &item, const KCalCore::CalFilter *filter)
Definition: utils.cpp:255
CalendarSupport::hasIncidence
CALENDARSUPPORT_EXPORT bool hasIncidence(const Akonadi::Item &item)
returns whether an Akonadi item contains an incidence
Definition: utils.cpp:147
kcalprefs.h
CalendarSupport::todo
CALENDARSUPPORT_EXPORT KCalCore::Todo::Ptr todo(const Akonadi::Item &item)
returns the todo from an akonadi item, or a null pointer if the item has no such payload ...
Definition: utils.cpp:121
utils.h
QModelIndexList
QList< QModelIndex > QModelIndexList
Definition: utils.h:57
CalendarSupport::mimeDataHasIncidence
CALENDARSUPPORT_EXPORT bool mimeDataHasIncidence(const QMimeData *mimeData)
Definition: utils.cpp:351
CalendarSupport::selectCollection
CALENDARSUPPORT_EXPORT Akonadi::Collection selectCollection(QWidget *parent, int &dialogCode, const QStringList &mimeTypes, const Akonadi::Collection &defaultCollection=Akonadi::Collection())
Shows a modal dialog that allows to select a collection.
Definition: utils.cpp:392
CalendarSupport::subMimeTypeForIncidence
CALENDARSUPPORT_EXPORT QString subMimeTypeForIncidence(const KCalCore::Incidence::Ptr &incidence)
Definition: utils.cpp:631
CalendarSupport::todoItemUrls
CALENDARSUPPORT_EXPORT QList< KUrl > todoItemUrls(const QMimeData *mimeData)
Definition: utils.cpp:334
CalendarSupport::categories
CALENDARSUPPORT_EXPORT QStringList categories(const KCalCore::Incidence::List &incidences)
Definition: utils.cpp:746
CalendarSupport::incidences
CALENDARSUPPORT_EXPORT KCalCore::Incidence::List incidences(const QMimeData *mimeData, const KDateTime::Spec &timeSpec)
Definition: utils.cpp:374
CalendarSupport::incidencesFromItems
CALENDARSUPPORT_EXPORT KCalCore::Incidence::List incidencesFromItems(const Akonadi::Item::List &items)
returns incidence pointers from an akonadi item.
Definition: utils.cpp:110
CalendarSupport::eventsFromItems
CALENDARSUPPORT_EXPORT KCalCore::Event::List eventsFromItems(const Akonadi::Item::List &items)
returns event pointers from an akonadi item, or a null pointer if the item has no such payload ...
Definition: utils.cpp:99
CalendarSupport::KCalPrefs::instance
static KCalPrefs * instance()
Get instance of KCalPrefs.
Definition: kcalprefs.cpp:75
CalendarSupport::itemsFromModel
CALENDARSUPPORT_EXPORT Akonadi::Item::List itemsFromModel(const QAbstractItemModel *model, const QModelIndex &parentIndex=QModelIndex(), int start=0, int end=-1)
Definition: utils.cpp:454
CalendarSupport::displayName
CALENDARSUPPORT_EXPORT QString displayName(Akonadi::ETMCalendar *calendar, const Akonadi::Collection &coll)
Definition: utils.cpp:497
CalendarSupport::hasEvent
CALENDARSUPPORT_EXPORT bool hasEvent(const Akonadi::Item &item)
returns whether an Akonadi item contains an event
Definition: utils.cpp:152
CalendarSupport::collectionsFromIndexes
CALENDARSUPPORT_EXPORT Akonadi::Collection::List collectionsFromIndexes(const QModelIndexList &indexes)
Definition: utils.cpp:488
CalendarSupport::collectionFromIndex
CALENDARSUPPORT_EXPORT Akonadi::Collection collectionFromIndex(const QModelIndex &index)
Definition: utils.cpp:478
CalendarSupport::hasTodo
CALENDARSUPPORT_EXPORT bool hasTodo(const Akonadi::Item &item)
returns whether an Akonadi item contains a todo
Definition: utils.cpp:157
CalendarSupport::saveAttachments
CALENDARSUPPORT_EXPORT void saveAttachments(const Akonadi::Item &item, QWidget *parentWidget=0)
Definition: utils.cpp:682
CalendarSupport::collectionIdFromIndex
CALENDARSUPPORT_EXPORT Akonadi::Collection::Id collectionIdFromIndex(const QModelIndex &index)
Definition: utils.cpp:483
CalendarSupport::mimeDataHasTodo
CALENDARSUPPORT_EXPORT bool mimeDataHasTodo(const QMimeData *mimeData)
Definition: utils.cpp:346
CalendarSupport::workDays
CALENDARSUPPORT_EXPORT QList< QDate > workDays(const QDate &start, const QDate &end)
Returns a list containing work days between start and .
Definition: utils.cpp:636
CalendarSupport::journal
CALENDARSUPPORT_EXPORT KCalCore::Journal::Ptr journal(const Akonadi::Item &item)
returns the journal from an akonadi item, or a null pointer if the item has no such payload ...
Definition: utils.cpp:134
CalendarSupport::applyCalFilter
CALENDARSUPPORT_EXPORT Akonadi::Item::List applyCalFilter(const Akonadi::Item::List &items, const KCalCore::CalFilter *filter)
Applies a filter to a list of items containing incidences.
Definition: utils.cpp:265
CalendarSupport::event
CALENDARSUPPORT_EXPORT KCalCore::Event::Ptr event(const Akonadi::Item &item)
returns the event from an akonadi item, or a null pointer if the item has no such payload ...
Definition: utils.cpp:85
CalendarSupport::canDecode
CALENDARSUPPORT_EXPORT bool canDecode(const QMimeData *mimeData)
returns true if the mime data object contains any of the following:
Definition: utils.cpp:314
CalendarSupport::holiday
CALENDARSUPPORT_EXPORT QStringList holiday(const QDate &date)
Returns a list of holidays that occur at.
Definition: utils.cpp:669
CalendarSupport::itemFromIndex
CALENDARSUPPORT_EXPORT Akonadi::Item itemFromIndex(const QModelIndex &index)
Definition: utils.cpp:423
CalendarSupport::todos
CALENDARSUPPORT_EXPORT KCalCore::Todo::List todos(const QMimeData *mimeData, const KDateTime::Spec &timeSpec)
Definition: utils.cpp:357
containsValidIncidenceItemUrl
static bool containsValidIncidenceItemUrl(const QList< QUrl > &urls)
Definition: utils.cpp:298
CalendarSupport::hasJournal
CALENDARSUPPORT_EXPORT bool hasJournal(const Akonadi::Item &item)
returns whether an Akonadi item contains a journal
Definition: utils.cpp:162
CalendarSupport::collectionsFromModel
CALENDARSUPPORT_EXPORT Akonadi::Collection::List collectionsFromModel(const QAbstractItemModel *model, const QModelIndex &parentIndex=QModelIndex(), int start=0, int end=-1)
Definition: utils.cpp:431
CalendarSupport::incidenceItemUrls
CALENDARSUPPORT_EXPORT QList< KUrl > incidenceItemUrls(const QMimeData *mimeData)
Definition: utils.cpp:323
CalendarSupport::mergeCalendar
CALENDARSUPPORT_EXPORT bool mergeCalendar(const QString &srcFilename, const KCalCore::Calendar::Ptr &destCalendar)
Definition: utils.cpp:763
CalendarSupport::isValidTodoItemUrl
CALENDARSUPPORT_EXPORT bool isValidTodoItemUrl(const KUrl &url)
returns true if the URL represents an Akonadi item and has one of the given mimetypes.
Definition: utils.cpp:305
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:54:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

calendarsupport

Skip menu "calendarsupport"
  • Main Page
  • Namespace List
  • Namespace Members
  • 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