libkcal

dndfactory.cpp

00001 /*
00002     This file is part of libkcal.
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 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include <qapplication.h>
00025 #include <qclipboard.h>
00026 #include <qmap.h>
00027 
00028 #include <kiconloader.h>
00029 #include <kdebug.h>
00030 #include <kmessagebox.h>
00031 #include <klocale.h>
00032 
00033 #include "vcaldrag.h"
00034 #include "icaldrag.h"
00035 #include "calendar.h"
00036 #include "vcalformat.h"
00037 #include "icalformat.h"
00038 #include "calendarlocal.h"
00039 
00040 #include "dndfactory.h"
00041 
00042 using namespace KCal;
00043 
00044 class DndFactory::Private
00045 {
00046   public:
00047     Incidence * pasteIncidence( Incidence *inc,
00048                                 const QDate &newDate,
00049                                 const QTime *newTime = 0 )
00050     {
00051       if ( inc ) {
00052         inc = inc->clone();
00053         inc->recreate();
00054       }
00055 
00056       if ( inc && newDate.isValid() ) {
00057         if ( inc->type() == "Event" ) {
00058           Event *anEvent = static_cast<Event*>( inc );
00059           // Calculate length of event
00060           int daysOffset = anEvent->dtStart().date().daysTo(
00061             anEvent->dtEnd().date() );
00062           // new end date if event starts at the same time on the new day
00063           QDateTime endDate( newDate.addDays(daysOffset), anEvent->dtEnd().time() );
00064 
00065           if ( newTime ) {
00066             // additional offset for new time of day
00067             int addSecsOffset( anEvent->dtStart().time().secsTo( *newTime ));
00068             endDate=endDate.addSecs( addSecsOffset );
00069             anEvent->setDtStart( QDateTime( newDate, *newTime ) );
00070           } else {
00071             anEvent->setDtStart( QDateTime( newDate, anEvent->dtStart().time() ) );
00072           }
00073           anEvent->setDtEnd( endDate );
00074         } else if ( inc->type() == "Todo" ) {
00075           Todo *anTodo = static_cast<Todo*>( inc );
00076           if ( newTime ) {
00077             anTodo->setDtDue( QDateTime( newDate, *newTime ) );
00078           } else {
00079             anTodo->setDtDue( QDateTime( newDate, anTodo->dtDue().time() ) );
00080           }
00081         } else if ( inc->type() == "Journal" ) {
00082           Journal *anJournal = static_cast<Journal*>( inc );
00083           if ( newTime ) {
00084             anJournal->setDtStart( QDateTime( newDate, *newTime ) );
00085           } else {
00086             anJournal->setDtStart( QDateTime( newDate ) );
00087           }
00088         } else {
00089           kdDebug(5850) << "Trying to paste unknown incidence of type " << inc->type() << endl;
00090         }
00091       }
00092       return inc;
00093     }
00094 };
00095 
00096 DndFactory::DndFactory( Calendar *cal ) :
00097   mCalendar( cal ), d( new Private )
00098 {
00099 }
00100 
00101 DndFactory::~DndFactory()
00102 {
00103   delete d;
00104 }
00105 
00106 ICalDrag *DndFactory::createDrag( Incidence *incidence, QWidget *owner )
00107 {
00108   CalendarLocal cal( mCalendar->timeZoneId() );
00109   Incidence *i = incidence->clone();
00110   cal.addIncidence( i );
00111 
00112   ICalDrag *icd = new ICalDrag( &cal, owner );
00113   if ( i->type() == "Event" )
00114     icd->setPixmap( BarIcon( "appointment" ) );
00115   else if ( i->type() == "Todo" )
00116     icd->setPixmap( BarIcon( "todo" ) );
00117 
00118   return icd;
00119 }
00120 
00121 Event *DndFactory::createDrop(QDropEvent *de)
00122 {
00123   kdDebug(5800) << "DndFactory::createDrop()" << endl;
00124 
00125   CalendarLocal cal( mCalendar->timeZoneId() );
00126 
00127   if ( ICalDrag::decode( de, &cal ) || VCalDrag::decode( de, &cal ) ) {
00128     de->accept();
00129 
00130     Event::List events = cal.events();
00131     if ( !events.isEmpty() ) {
00132       Event *event = new Event( *events.first() );
00133       return event;
00134     }
00135   }
00136 
00137   return 0;
00138 }
00139 
00140 Incidence::List DndFactory::createDropIncidences(QDropEvent *de)
00141 {
00142   kdDebug(5800) << "DndFactory::createIncidenceDrop()" << endl;
00143 
00144   CalendarLocal cal( mCalendar->timeZoneId() );
00145 
00146   Incidence::List incidences;
00147   if ( ICalDrag::decode( de, &cal ) || VCalDrag::decode( de, &cal ) ) {
00148     de->accept();
00149     Incidence::List incidences2 = cal.incidences();
00150     for( uint i=0; i<incidences2.count(); ++i ) {
00151       incidences.append( incidences2[i]->clone() );
00152     }
00153   }
00154 
00155   return incidences;
00156 }
00157 
00158 Todo *DndFactory::createDropTodo(QDropEvent *de)
00159 {
00160   kdDebug(5800) << "VCalFormat::createDropTodo()" << endl;
00161 
00162   CalendarLocal cal( mCalendar->timeZoneId() );
00163 
00164   if ( ICalDrag::decode( de, &cal ) || VCalDrag::decode( de, &cal ) ) {
00165     de->accept();
00166 
00167     Todo::List todos = cal.todos();
00168     if ( !todos.isEmpty() ) {
00169       Todo *todo = new Todo( *todos.first() );
00170       return todo;
00171     }
00172   }
00173 
00174   return 0;
00175 }
00176 
00177 void DndFactory::cutIncidence( Incidence *selectedInc )
00178 {
00179   Incidence::List list;
00180   list.append( selectedInc );
00181   cutIncidences( list );
00182 }
00183 
00184 bool DndFactory::cutIncidences( const Incidence::List &incidences )
00185 {
00186   if ( copyIncidences( incidences ) ) {
00187     Incidence::List::ConstIterator it;
00188     for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
00189       mCalendar->deleteIncidence( *it );
00190     }
00191     return true;
00192   } else {
00193     return false;
00194   }
00195 }
00196 
00197 bool DndFactory::copyIncidences( const Incidence::List &incidences )
00198 {
00199   QClipboard *cb = QApplication::clipboard();
00200   CalendarLocal cal( mCalendar->timeZoneId() );
00201   Incidence::List::ConstIterator it;
00202 
00203   for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
00204     if ( *it ) {
00205       cal.addIncidence( ( *it )->clone() );
00206     }
00207   }
00208 
00209   if ( cal.incidences().isEmpty() ) {
00210     return false;
00211   } else {
00212     cb->setData( new ICalDrag( &cal ) );
00213     return true;
00214   }
00215 }
00216 
00217 bool DndFactory::copyIncidence( Incidence *selectedInc )
00218 {
00219   Incidence::List list;
00220   list.append( selectedInc );
00221   return copyIncidences( list );
00222 }
00223 
00224 Incidence::List DndFactory::pasteIncidences( const QDate &newDate, const QTime *newTime )
00225 {
00226   CalendarLocal cal( mCalendar->timeZoneId() );
00227   QClipboard *cb = QApplication::clipboard();
00228   Incidence::List list;
00229 
00230   if ( !ICalDrag::decode( cb->data(), &cal ) &&
00231        !VCalDrag::decode( cb->data(), &cal ) ) {
00232     kdDebug(5800) << "Can't parse clipboard" << endl;
00233     return list;
00234   }
00235 
00236   // All pasted incidences get new uids, must keep track of old uids,
00237   // so we can update child's parents
00238   QMap<QString,Incidence*> oldUidToNewInc;
00239 
00240   Incidence::List::ConstIterator it;
00241   const Incidence::List incs = cal.incidences();
00242   for ( it = incs.constBegin(); it != incs.constEnd(); ++it ) {
00243     Incidence *inc = d->pasteIncidence( *it, newDate, newTime );
00244     if ( inc ) {
00245       list.append( inc );
00246       oldUidToNewInc[( *it )->uid()] = inc;
00247     }
00248   }
00249 
00250   // update relations
00251   for ( it = list.constBegin(); it != list.constEnd(); ++it ) {
00252     Incidence *inc = *it;
00253     if ( oldUidToNewInc.contains( inc->relatedToUid() ) ) {
00254       Incidence *parentInc = oldUidToNewInc[inc->relatedToUid()];
00255       inc->setRelatedToUid( parentInc->uid() );
00256       inc->setRelatedTo( parentInc );
00257     } else {
00258       // not related to anything in the clipboard
00259       inc->setRelatedToUid( QString() );
00260       inc->setRelatedTo( 0 );
00261     }
00262   }
00263 
00264   return list;
00265 }
00266 
00267 Incidence *DndFactory::pasteIncidence( const QDate &newDate, const QTime *newTime )
00268 {
00269   CalendarLocal cal( mCalendar->timeZoneId() );
00270   QClipboard *cb = QApplication::clipboard();
00271 
00272   if ( !ICalDrag::decode( cb->data(), &cal ) &&
00273        !VCalDrag::decode( cb->data(), &cal ) ) {
00274     kdDebug(5800) << "Can't parse clipboard" << endl;
00275     return 0;
00276   }
00277 
00278   Incidence::List incList = cal.incidences();
00279   Incidence *inc = incList.isEmpty() ? 0 : incList.first();
00280 
00281   Incidence *newInc = d->pasteIncidence( inc, newDate, newTime );
00282   newInc->setRelatedTo( 0 );
00283   return newInc;
00284 }
KDE Home | KDE Accessibility Home | Description of Access Keys