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