KCalUtils Library
dndfactory.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the kcalutils library. 00003 00004 Copyright (c) 1998 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 2001,2002 Cornelius Schumacher <schumacher@kde.org> 00006 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 00007 Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net> 00008 Copyright (c) 2008 Thomas Thrainer <tom_t@gmx.at> 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Library General Public 00012 License as published by the Free Software Foundation; either 00013 version 2 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Library General Public License for more details. 00019 00020 You should have received a copy of the GNU Library General Public License 00021 along with this library; see the file COPYING.LIB. If not, write to 00022 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00023 Boston, MA 02110-1301, USA. 00024 */ 00037 #include "dndfactory.h" 00038 #include "icaldrag.h" 00039 #include "vcaldrag.h" 00040 00041 #include <KDebug> 00042 #include <KIconLoader> // for BarIcon 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 //@cond PRIVATE 00060 class KCalUtils::DndFactory::Private 00061 { 00062 public: 00063 Private( const MemoryCalendar::Ptr &calendar ) 00064 : mCalendar ( calendar ) 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 // in seconds 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 //@endcond 00118 00119 DndFactory::DndFactory( const MemoryCalendar::Ptr &calendar ) 00120 : d( new KCalUtils::DndFactory::Private ( calendar ) ) 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 *mimeData ) 00178 { 00179 return createDropCalendar( mimeData, d->mCalendar->timeSpec() ); 00180 } 00181 00182 MemoryCalendar::Ptr DndFactory::createDropCalendar( const QMimeData *mimeData, 00183 const KDateTime::Spec &timeSpec ) 00184 { 00185 MemoryCalendar::Ptr calendar( new MemoryCalendar( timeSpec ) ); 00186 00187 if ( ICalDrag::fromMimeData( mimeData, calendar ) || 00188 VCalDrag::fromMimeData( mimeData, calendar ) ){ 00189 return calendar; 00190 } 00191 00192 return MemoryCalendar::Ptr(); 00193 } 00194 00195 MemoryCalendar::Ptr DndFactory::createDropCalendar( QDropEvent *dropEvent ) 00196 { 00197 MemoryCalendar::Ptr calendar( createDropCalendar( dropEvent->mimeData() ) ); 00198 if ( calendar ) { 00199 dropEvent->accept(); 00200 return calendar; 00201 } 00202 return MemoryCalendar::Ptr(); 00203 } 00204 00205 Event::Ptr DndFactory::createDropEvent( const QMimeData *mimeData ) 00206 { 00207 kDebug(); 00208 Event::Ptr event; 00209 MemoryCalendar::Ptr calendar( createDropCalendar( mimeData ) ); 00210 00211 if ( calendar ) { 00212 Event::List events = calendar->events(); 00213 if ( !events.isEmpty() ) { 00214 event = Event::Ptr( new Event( *events.first() ) ); 00215 } 00216 } 00217 return event; 00218 } 00219 00220 Event::Ptr DndFactory::createDropEvent( QDropEvent *dropEvent ) 00221 { 00222 Event::Ptr event = createDropEvent( dropEvent->mimeData() ); 00223 00224 if ( event ) { 00225 dropEvent->accept(); 00226 } 00227 00228 return event; 00229 } 00230 00231 Todo::Ptr DndFactory::createDropTodo( const QMimeData *mimeData ) 00232 { 00233 kDebug(); 00234 Todo::Ptr todo; 00235 MemoryCalendar::Ptr calendar( createDropCalendar( mimeData ) ); 00236 00237 if ( calendar ) { 00238 Todo::List todos = calendar->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 *dropEvent ) 00248 { 00249 Todo::Ptr todo = createDropTodo( dropEvent->mimeData() ); 00250 00251 if ( todo ) { 00252 dropEvent->accept(); 00253 } 00254 00255 return todo; 00256 } 00257 00258 void DndFactory::cutIncidence( const Incidence::Ptr &selectedIncidence ) 00259 { 00260 Incidence::List list; 00261 list.append( selectedIncidence ); 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 *clipboard = QApplication::clipboard(); 00281 Q_ASSERT( clipboard ); 00282 MemoryCalendar::Ptr calendar( new MemoryCalendar( d->mCalendar->timeSpec() ) ); 00283 00284 Incidence::List::ConstIterator it; 00285 for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) { 00286 if ( *it ) { 00287 calendar->addIncidence( Incidence::Ptr( ( *it )->clone() ) ); 00288 } 00289 } 00290 00291 QMimeData *mimeData = new QMimeData; 00292 00293 ICalDrag::populateMimeData( mimeData, calendar ); 00294 VCalDrag::populateMimeData( mimeData, calendar ); 00295 00296 if ( calendar->incidences().isEmpty() ) { 00297 return false; 00298 } else { 00299 clipboard->setMimeData( mimeData ); 00300 return true; 00301 } 00302 } 00303 00304 bool DndFactory::copyIncidence( const Incidence::Ptr &selectedInc ) 00305 { 00306 Incidence::List list; 00307 list.append( selectedInc ); 00308 return copyIncidences( list ); 00309 } 00310 00311 Incidence::List DndFactory::pasteIncidences( const KDateTime &newDateTime, 00312 const QFlags<PasteFlag> &pasteOptions ) 00313 { 00314 QClipboard *clipboard = QApplication::clipboard(); 00315 Q_ASSERT( clipboard ); 00316 MemoryCalendar::Ptr calendar( createDropCalendar( clipboard->mimeData() ) ); 00317 Incidence::List list; 00318 00319 if ( !calendar ) { 00320 kDebug() << "Can't parse clipboard"; 00321 return list; 00322 } 00323 00324 // All pasted incidences get new uids, must keep track of old uids, 00325 // so we can update child's parents 00326 QHash<QString, Incidence::Ptr> oldUidToNewInc; 00327 00328 Incidence::List::ConstIterator it; 00329 const Incidence::List incidences = calendar->incidences(); 00330 for ( it = incidences.constBegin(); 00331 it != incidences.constEnd(); ++it ) { 00332 Incidence::Ptr incidence = d->pasteIncidence( *it, newDateTime, pasteOptions ); 00333 if ( incidence ) { 00334 list.append( incidence ); 00335 oldUidToNewInc[(*it)->uid()] = *it; 00336 } 00337 } 00338 00339 // update relations 00340 for ( it = list.constBegin(); it != list.constEnd(); ++it ) { 00341 Incidence::Ptr incidence = *it; 00342 if ( oldUidToNewInc.contains( incidence->relatedTo() ) ) { 00343 Incidence::Ptr parentInc = oldUidToNewInc[incidence->relatedTo()]; 00344 incidence->setRelatedTo( parentInc->uid() ); 00345 } else { 00346 // not related to anything in the clipboard 00347 incidence->setRelatedTo( QString() ); 00348 } 00349 } 00350 00351 return list; 00352 } 00353 00354 Incidence::Ptr DndFactory::pasteIncidence( const KDateTime &newDateTime, 00355 const QFlags<PasteFlag> &pasteOptions ) 00356 { 00357 QClipboard *clipboard = QApplication::clipboard(); 00358 MemoryCalendar::Ptr calendar( createDropCalendar( clipboard->mimeData() ) ); 00359 00360 if ( !calendar ) { 00361 kDebug() << "Can't parse clipboard"; 00362 return Incidence::Ptr(); 00363 } 00364 00365 Incidence::List incidenceList = calendar->incidences(); 00366 Incidence::Ptr incidence = incidenceList.isEmpty() ? Incidence::Ptr() : incidenceList.first(); 00367 00368 return d->pasteIncidence( incidence, newDateTime, pasteOptions ); 00369 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:18:01 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:18:01 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.