KCal Library
dndfactory.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00038 #include "dndfactory.h"
00039 #include "vcaldrag.h"
00040 #include "icaldrag.h"
00041 #include "calendar.h"
00042 #include "calendarlocal.h"
00043
00044 #include <kiconloader.h>
00045 #include <kdebug.h>
00046 #include <klocale.h>
00047 #include <kurl.h>
00048
00049 #include <QtGui/QApplication>
00050 #include <QtGui/QClipboard>
00051 #include <QtGui/QDropEvent>
00052 #include <QtGui/QPixmap>
00053
00054 using namespace KCal;
00055
00060
00061 class KCal::DndFactory::Private
00062 {
00063 public:
00064 Private( Calendar *cal )
00065 : mCalendar ( cal )
00066 {}
00067
00068 Incidence * pasteIncidence( Incidence *inc,
00069 const QDate &newDate,
00070 const QTime *newTime = 0 )
00071 {
00072 if ( inc ) {
00073 inc = inc->clone();
00074 inc->recreate();
00075 }
00076
00077 if ( inc && newDate.isValid() ) {
00078 if ( inc->type() == "Event" ) {
00079
00080 Event *anEvent = static_cast<Event*>( inc );
00081
00082 int daysOffset = anEvent->dtStart().date().daysTo(
00083 anEvent->dtEnd().date() );
00084
00085 KDateTime endDate( anEvent->dtEnd() );
00086 endDate.setDate( newDate.addDays( daysOffset ) );
00087
00088 KDateTime startDate( anEvent->dtStart() );
00089 startDate.setDate( newDate );
00090 if ( newTime ) {
00091
00092 int addSecsOffset( anEvent->dtStart().time().secsTo( *newTime ) );
00093 endDate=endDate.addSecs( addSecsOffset );
00094 startDate.setTime( *newTime );
00095 }
00096 anEvent->setDtStart( startDate );
00097 anEvent->setDtEnd( endDate );
00098
00099 } else if ( inc->type() == "Todo" ) {
00100 Todo *anTodo = static_cast<Todo*>( inc );
00101 KDateTime dueDate( anTodo->dtDue() );
00102 dueDate.setDate( newDate );
00103 if ( newTime ) {
00104 dueDate.setTime( *newTime );
00105 }
00106 anTodo->setDtDue( dueDate );
00107 } else if ( inc->type() == "Journal" ) {
00108 Journal *anJournal = static_cast<Journal*>( inc );
00109 KDateTime startDate( anJournal->dtStart() );
00110 startDate.setDate( newDate );
00111 if ( newTime ) {
00112 startDate.setTime( *newTime );
00113 } else {
00114 startDate.setTime( QTime( 0, 0, 0 ) );
00115 }
00116 anJournal->setDtStart( startDate );
00117 } else {
00118 kDebug() << "Trying to paste unknown incidence of type" << inc->type();
00119 }
00120 }
00121
00122 return inc;
00123 }
00124
00125 Calendar *mCalendar;
00126 };
00127
00128
00129 DndFactory::DndFactory( Calendar *cal )
00130 : d( new KCal::DndFactory::Private ( cal ) )
00131 {
00132 }
00133
00134 DndFactory::~DndFactory()
00135 {
00136 delete d;
00137 }
00138
00139 QMimeData *DndFactory::createMimeData()
00140 {
00141 QMimeData *mimeData = new QMimeData;
00142
00143 ICalDrag::populateMimeData( mimeData, d->mCalendar );
00144 VCalDrag::populateMimeData( mimeData, d->mCalendar );
00145
00146 return mimeData;
00147 }
00148
00149 QDrag *DndFactory::createDrag( QWidget *owner )
00150 {
00151 QDrag *drag = new QDrag( owner );
00152 drag->setMimeData( createMimeData() );
00153
00154 return drag;
00155 }
00156
00157 QMimeData *DndFactory::createMimeData( Incidence *incidence )
00158 {
00159 CalendarLocal cal( d->mCalendar->timeSpec() );
00160 Incidence *i = incidence->clone();
00161 cal.addIncidence( i );
00162
00163 QMimeData *mimeData = new QMimeData;
00164
00165 ICalDrag::populateMimeData( mimeData, &cal );
00166 VCalDrag::populateMimeData( mimeData, &cal );
00167
00168 KUrl uri = i->uri();
00169 if ( uri.isValid() ) {
00170 QMap<QString, QString> metadata;
00171 metadata["labels"] = KUrl::toPercentEncoding( i->summary() );
00172 uri.populateMimeData( mimeData, metadata );
00173 }
00174
00175 return mimeData;
00176 }
00177
00178 QDrag *DndFactory::createDrag( Incidence *incidence, QWidget *owner )
00179 {
00180 QDrag *drag = new QDrag( owner );
00181 drag->setMimeData( createMimeData( incidence ) );
00182
00183 if ( incidence->type() == "Event" ) {
00184 drag->setPixmap( BarIcon( "view-calendar-day" ) );
00185 } else if ( incidence->type() == "Todo" ) {
00186 drag->setPixmap( BarIcon( "view-calendar-tasks" ) );
00187 }
00188
00189 return drag;
00190 }
00191
00192 Calendar *DndFactory::createDropCalendar( const QMimeData *md )
00193 {
00194 return createDropCalendar( md, d->mCalendar->timeSpec() );
00195 }
00196
00197 Calendar *DndFactory::createDropCalendar( const QMimeData *md, const KDateTime::Spec &timeSpec )
00198 {
00199 Calendar *cal = new CalendarLocal( timeSpec );
00200
00201 if ( ICalDrag::fromMimeData( md, cal ) ||
00202 VCalDrag::fromMimeData( md, cal ) ){
00203 return cal;
00204 }
00205 delete cal;
00206 return 0;
00207 }
00208
00209 Calendar *DndFactory::createDropCalendar( QDropEvent *de )
00210 {
00211 Calendar *cal = createDropCalendar( de->mimeData() );
00212 if ( cal ) {
00213 de->accept();
00214 return cal;
00215 }
00216 return 0;
00217 }
00218
00219 Event *DndFactory::createDropEvent( const QMimeData *md )
00220 {
00221 kDebug();
00222 Event *ev = 0;
00223 Calendar *cal = createDropCalendar( md );
00224
00225 if ( cal ) {
00226 Event::List events = cal->events();
00227 if ( !events.isEmpty() ) {
00228 ev = new Event( *events.first() );
00229 }
00230 delete cal;
00231 }
00232 return ev;
00233 }
00234
00235 Event *DndFactory::createDropEvent( QDropEvent *de )
00236 {
00237 Event *ev = createDropEvent( de->mimeData() );
00238
00239 if ( ev ) {
00240 de->accept();
00241 }
00242
00243 return ev;
00244 }
00245
00246 Todo *DndFactory::createDropTodo( const QMimeData *md )
00247 {
00248 kDebug();
00249 Todo *todo = 0;
00250 Calendar *cal = createDropCalendar( md );
00251
00252 if ( cal ) {
00253 Todo::List todos = cal->todos();
00254 if ( !todos.isEmpty() ) {
00255 todo = new Todo( *todos.first() );
00256 }
00257 delete cal;
00258 }
00259
00260 return todo;
00261 }
00262
00263 Todo *DndFactory::createDropTodo( QDropEvent *de )
00264 {
00265 Todo *todo = createDropTodo( de->mimeData() );
00266
00267 if ( todo ) {
00268 de->accept();
00269 }
00270
00271 return todo;
00272 }
00273
00274 void DndFactory::cutIncidence( Incidence *selectedInc )
00275 {
00276 Incidence::List list;
00277 list.append( selectedInc );
00278 cutIncidences( list );
00279 }
00280
00281 bool DndFactory::cutIncidences( const Incidence::List &incidences )
00282 {
00283 if ( copyIncidences( incidences ) ) {
00284 Incidence::List::ConstIterator it;
00285 for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
00286 d->mCalendar->deleteIncidence( *it );
00287 }
00288 return true;
00289 } else {
00290 return false;
00291 }
00292 }
00293
00294 bool DndFactory::copyIncidences( const Incidence::List &incidences )
00295 {
00296 QClipboard *cb = QApplication::clipboard();
00297 CalendarLocal cal( d->mCalendar->timeSpec() );
00298
00299 Incidence::List::ConstIterator it;
00300 for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
00301 if ( *it ) {
00302 cal.addIncidence( ( *it )->clone() );
00303 }
00304 }
00305
00306 QMimeData *mimeData = new QMimeData;
00307
00308 ICalDrag::populateMimeData( mimeData, &cal );
00309 VCalDrag::populateMimeData( mimeData, &cal );
00310
00311 if ( cal.incidences().isEmpty() ) {
00312 return false;
00313 } else {
00314 cb->setMimeData( mimeData );
00315 return true;
00316 }
00317 }
00318
00319 bool DndFactory::copyIncidence( Incidence *selectedInc )
00320 {
00321 Incidence::List list;
00322 list.append( selectedInc );
00323 return copyIncidences( list );
00324 }
00325
00326 Incidence::List DndFactory::pasteIncidences( const QDate &newDate,
00327 const QTime *newTime )
00328 {
00329 QClipboard *cb = QApplication::clipboard();
00330 Calendar *cal = createDropCalendar( cb->mimeData() );
00331 Incidence::List list;
00332
00333 if ( !cal ) {
00334 kDebug() << "Can't parse clipboard";
00335 return list;
00336 }
00337
00338
00339
00340 QHash<QString,Incidence*> oldUidToNewInc;
00341
00342 Incidence::List::ConstIterator it;
00343 const Incidence::List incs = cal->incidences();
00344 for ( it = incs.constBegin();
00345 it != incs.constEnd(); ++it ) {
00346 Incidence *inc = d->pasteIncidence( *it, newDate, newTime );
00347 if ( inc ) {
00348 list.append( inc );
00349 oldUidToNewInc[( *it )->uid()] = inc;
00350 }
00351 }
00352
00353
00354 for ( it = list.constBegin(); it != list.constEnd(); ++it ) {
00355 Incidence *inc = *it;
00356 if ( oldUidToNewInc.contains( inc->relatedToUid() ) ) {
00357 Incidence *parentInc = oldUidToNewInc[inc->relatedToUid()];
00358 inc->setRelatedToUid( parentInc->uid() );
00359 inc->setRelatedTo( parentInc );
00360 } else {
00361
00362 inc->setRelatedToUid( QString() );
00363 inc->setRelatedTo( 0 );
00364 }
00365 }
00366
00367 return list;
00368 }
00369
00370 Incidence *DndFactory::pasteIncidence( const QDate &newDate, const QTime *newTime )
00371 {
00372 QClipboard *cb = QApplication::clipboard();
00373 Calendar *cal = createDropCalendar( cb->mimeData() );
00374
00375 if ( !cal ) {
00376 kDebug() << "Can't parse clipboard";
00377 return 0;
00378 }
00379
00380 Incidence::List incList = cal->incidences();
00381 Incidence *inc = incList.isEmpty() ? 0 : incList.first();
00382
00383 Incidence *newInc = d->pasteIncidence( inc, newDate, newTime );
00384 newInc->setRelatedTo( 0 );
00385 return newInc;
00386 }