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

calendarsupport

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